-
-
Notifications
You must be signed in to change notification settings - Fork 593
[STK-322] Initial implementation #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@faizanahmad055 Yikes! You better fix it before anyone else finds out! Build 1 has Failed! |
@faizanahmad055 Image is available for testing. |
@faizanahmad055 Image is available for testing. |
@faizanahmad055 Image is available for testing. |
@faizanahmad055 Image is available for testing. |
os.Exit(1) | ||
} | ||
os.Exit(0) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File is not goimports-ed
func Run() error { | ||
cmd := cmd.NewReloaderCommand() | ||
return cmd.Execute() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File is not goimports-ed
internal/pkg/cmd/reloader.go
Outdated
"github.com/stakater/Reloader/internal/pkg/controller" | ||
"github.com/stakater/Reloader/pkg/kube" | ||
"github.com/sirupsen/logrus" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File is not goimports-ed
} | ||
//If file exists so use that config settings | ||
if _, err := os.Stat(kubeconfigPath); err == nil { | ||
config, err = clientcmd.BuildConfigFromFlags("", kubeconfigPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ineffectual assignment to err
pkg/kube/client.go
Outdated
if _, err := os.Stat(kubeconfigPath); err == nil { | ||
config, err = clientcmd.BuildConfigFromFlags("", kubeconfigPath) | ||
} else { //Use Incluster Configuration | ||
config, err = rest.InClusterConfig() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ineffectual assignment to err
) | ||
|
||
const ( | ||
updateOnChangeAnnotation = "reloader.stakater.com.io/update-on-change" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateOnChangeAnnotation
is unused
type Event struct { | ||
key string | ||
eventType string | ||
namespace string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
namespace
is unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't be needing the namespace in the event. This seems to be a direct copy from chowkidar. Please don't copy paste blindly. Try to understand how reloader should work and write code based on that yourself.
key string | ||
eventType string | ||
namespace string | ||
resourceType string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resourceType
is unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I don't know if this can be used in the future in Reloader
|
||
var ( | ||
client, _ = kube.GetClient() | ||
configmapNamePrefix = "testconfigmap-reloader" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configmapNamePrefix
is unused
letters = []rune("abcdefghijklmnopqrstuvwxyz") | ||
) | ||
|
||
func randSeq(n int) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
randSeq
is unused
time.Sleep(15 * time.Second) | ||
}*/ | ||
|
||
func initConfigmap(namespace string, configmapName string) *v1.ConfigMap { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initConfigmap
is unused
} | ||
} | ||
|
||
func updateConfigmap(namespace string, configmapName string) *v1.ConfigMap { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateConfigmap
is unused
internal/pkg/actions/action.go
Outdated
configMapName := oldObj.(*v1.ConfigMap).Name | ||
configMapVersion := convertConfigMapToToken(oldObj.(*v1.ConfigMap)) | ||
|
||
deployments, err := client.Apps().Deployments(ns).List(meta_v1.ListOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client.Apps is deprecated: please explicitly pick a version if possible.
internal/pkg/actions/action.go
Outdated
updateContainers(containers, annotationValue, configMapVersion) | ||
|
||
// update the deployment | ||
_, err := client.Apps().Deployments(ns).Update(&d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client.Apps is deprecated: please explicitly pick a version if possible.
internal/pkg/actions/action.go
Outdated
for _, d := range deployments.Items { | ||
containers := d.Spec.Template.Spec.Containers | ||
// match deployments with the correct annotation | ||
annotationValue, _ := d.ObjectMeta.Annotations[updateOnChangeAnnotation] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should write annotationValue := d.ObjectMeta.Annotations[updateOnChangeAnnotation] instead of annotationValue, _ := d.ObjectMeta.Annotations[updateOnChangeAnnotation]
var ( | ||
client, _ = kube.GetClient() | ||
configmapNamePrefix = "testconfigmap-reloader" | ||
letters = []rune("abcdefghijklmnopqrstuvwxyz") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var letters is unused
@faizanahmad055 Image is available for testing. |
configMapName := oldObj.(*v1.ConfigMap).Name | ||
configMapVersion := convertConfigMapToToken(oldObj.(*v1.ConfigMap)) | ||
|
||
deployments, err := client.Apps().Deployments(ns).List(meta_v1.ListOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client.Apps is deprecated: please explicitly pick a version if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't just be deployments, do something like
rollingUpgradeResource(resourceType.Deployment)
rollingUpgradeResource(resourceType.StatefulSet)
rollingUpgradeResource(resourceType.DaemonSet)
It's just an idea. Think on how you can make it generic for all type of resources
updateContainers(containers, annotationValue, configMapVersion) | ||
|
||
// update the deployment | ||
_, err := client.Apps().Deployments(ns).Update(&d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client.Apps is deprecated: please explicitly pick a version if possible.
for _, d := range deployments.Items { | ||
containers := d.Spec.Template.Spec.Containers | ||
// match deployments with the correct annotation | ||
annotationValue, _ := d.ObjectMeta.Annotations[updateOnChangeAnnotation] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should write annotationValue := d.ObjectMeta.Annotations[updateOnChangeAnnotation] instead of annotationValue, _ := d.ObjectMeta.Annotations[updateOnChangeAnnotation]
@faizanahmad055 Image is available for testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on what I've seen in the PR, here are a few comments
- Don't copy paste stuff from Chowkidar or ConfigMapController. I've seen rollingUpgradeDeployments, updateContainers, convertToEnvVarName, convertConfigMapToToken methods which are copied from CMC and I don't think that is the perfect way of doing things. The logic can be improved and rewritten in our way
- Use VS Code for GO Projects since its go extension takes care of all the linting and formatting etc
- Don't add any new functionality to this PR. Just make sure that you're able to get configmaps and secrets in the create and update methods. And write test cases for that. Once that is merged, then proceed towards the next step
- Use your own logic wherever possible. I've seen comments from Chowkidar which were pods specific and are present here as well
template: | ||
metadata: | ||
annotations: | ||
configmap.fabric8.io/update-on-change: {{ template "reloader-name" . }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this here? Is it needed for reloader? And this seems to be for the old cmc
README.md
Outdated
# Reloader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a specific format for our readme's. This is just copied from cmc's repo
name: {{ template "reloader-name" . }} | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1beta1 | ||
kind: ClusterRole |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a cluster role? Isn't this supposed to run in the namespaces we want sir @rasheedamir ? I think we should restrict RBAC's to namespace level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've decided that the controller should only be able to run in 1 namespace that is specified in the env variable. Once that is done, we can easily implement all-namespace support keeping in mind the performance of the controller
glide.yaml
Outdated
- package: k8s.io/client-go | ||
version: 5.0.0 | ||
- package: github.com/spf13/cobra | ||
version: ef82de70bb3f60c65fb8eebacbb2d122ef517385 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use version numbers instead of git sha
|
||
const ( | ||
updateOnChangeAnnotation = "reloader.stakater.com/update-on-change" | ||
// AllNamespaces as our controller will be looking for events in all namespaces |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this
) | ||
|
||
var ( | ||
client, _ = kube.GetClient() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without checking error is a bad practice. Make sure there's no error or there's no point in going forward to the tests
return string(b) | ||
} | ||
|
||
// Creating a Controller for Updating Pod with Default Action without Resources so messages printed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks copy pasted
time.Sleep(10 * time.Second) | ||
|
||
logrus.Infof("Updating Configmap %q.\n", configmap.GetObjectMeta().GetName()) | ||
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why this is needed. Explain please
} | ||
|
||
func updateConfigmap(namespace string, configmapName string) *v1.ConfigMap { | ||
return &v1.ConfigMap{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating the label of the configmap shouldn't restart the pods. So update the data in the configmap
pkg/kube/resourcemapper.go
Outdated
) | ||
|
||
// MapToRuntimeObject maps the resource type string to the actual resource | ||
func MapToRuntimeObject(resourceType string) runtime.Object { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this since we don't have a default resource type
@faizanahmad055 Image is available for testing. |
internal/pkg/cmd/reloader.go
Outdated
"github.com/stakater/Reloader/internal/pkg/controller" | ||
"github.com/stakater/Reloader/pkg/kube" | ||
"github.com/sirupsen/logrus" | ||
"k8s.io/apimachinery/pkg/apis/meta/v1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File is not goimports-ed
|
||
var ( | ||
client, err = kube.GetClient() | ||
configmapNamePrefix = "testconfigmap-reloader" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configmapNamePrefix
is unused
// TODO: Add functionality to verify reloader functionality here | ||
|
||
if updateErr != nil { | ||
controller.client.CoreV1().ConfigMaps(namespace).Delete(configmapName, &metav1.DeleteOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error return value of (github.com/stakater/Reloader/vendor/k8s.io/client-go/kubernetes/typed/core/v1.ConfigMapInterface).Delete
is not checked
} | ||
time.Sleep(10 * time.Second) | ||
logrus.Infof("Deleting Configmap %q.\n", configmap.GetObjectMeta().GetName()) | ||
controller.client.CoreV1().ConfigMaps(namespace).Delete(configmapName, &metav1.DeleteOptions{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error return value of (github.com/stakater/Reloader/vendor/k8s.io/client-go/kubernetes/typed/core/v1.ConfigMapInterface).Delete
is not checked
) | ||
|
||
var ( | ||
client, err = kube.GetClient() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err
is unused
@faizanahmad055 Yikes! You better fix it before anyone else finds out! Build 9 has Failed! |
@faizanahmad055 Image is available for testing. |
@faizanahmad055 Image is available for testing. |
internal/pkg/cmd/reloader.go
Outdated
|
||
// NewReloaderCommand starts the reloader controller | ||
func NewReloaderCommand() *cobra.Command { | ||
cmds := &cobra.Command{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be cmd
indexer cache.Indexer | ||
queue workqueue.RateLimitingInterface | ||
informer cache.Controller | ||
resource string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be a part of controller. Its just used for initializing
|
||
indexer, informer := cache.NewIndexerInformer(listWatcher, kube.ResourceMap[resource], 0, cache.ResourceEventHandlerFuncs{ | ||
AddFunc: c.Add, | ||
UpdateFunc: c.Update, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add delete func with log
) | ||
|
||
// ResourceUpdated contains new or updated objects | ||
type ResourceUpdated struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename it to ResourceHandler
Move it to internal/pkg/handler/resourcehandler.go
Call handler.Handle() on the item
Have 2 resouce handlers
- ResourceCreatedHandler
- ResourceUpdatedHandler
Just log items in both their handle functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Names should be newResource and oldResource
|
||
func (c *Controller) processNextItem() bool { | ||
// Wait until there is a new item in the working queue | ||
resourceUpdated, quit := c.queue.Get() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the name based on the struct
defer c.queue.Done(resourceUpdated) | ||
|
||
// Invoke the method containing the business logic | ||
err := c.takeAction(resourceUpdated.(ResourceUpdated)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just call resourceHandler.Handle() method and remove the method below
_, err = configmapClient.Create(initConfigmap(namespace, configmapName)) | ||
if err != nil { | ||
logrus.Infof("Error detected %s.\n", err) | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use panic anywhere in code. Use logrus fatal methods
if error != nil { | ||
panic(error) | ||
} | ||
//time.Sleep(10 * time.Second) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code if its not necessary
@faizanahmad055 Image is available for testing. |
}) | ||
} | ||
|
||
// Delete function to add an 'update' event to the queue in case of deleting a resource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix typo in the comment
) | ||
|
||
var ( | ||
client, _ = kube.GetClient() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either properly check that the client is successfully created if it's global, or created it in each test and check for error
|
||
// ResourceCreatedHandler contains new objects | ||
type ResourceCreatedHandler struct { | ||
NewResource interface{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this to just Resource
@@ -0,0 +1,58 @@ | |||
package handler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename this to handler.go
} | ||
|
||
// ResourceCreatedHandler contains new objects | ||
type ResourceCreatedHandler struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor these created and updated handlers to separate files. created-handler.go, updated-handler.go
@faizanahmad055 Image is available for testing. |
func TestControllerForUpdatingConfigmapShouldUpdateDeployment(t *testing.T) { | ||
client, err := kube.GetClient() | ||
if err != nil { | ||
logrus.Infof("Unable to create Kubernetes client error = %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error logs shouldn't be treated as info
internal/pkg/handler/handler.go
Outdated
} | ||
|
||
// Handle processes the newly created resource | ||
func (r ResourceCreatedHandler) Handle() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to created handler so it needs to be moved to that file
internal/pkg/handler/handler.go
Outdated
} | ||
|
||
// Handle processes the updated resource | ||
func (r ResourceUpdatedHandler) Handle() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to updated handler so it needs to be moved to that file
@faizanahmad055 Image is available for testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix usage of log severity throughout the code
build/package/Dockerfile
Outdated
@@ -0,0 +1,5 @@ | |||
FROM scratch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be 3 dockerfiles, Verify and remove the unused one, it will probably be this one
glide.yaml
Outdated
- package: github.com/spf13/pflag | ||
version: 1.0.1 | ||
- package: github.com/sirupsen/logrus | ||
version: ~1.0.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does ~
specify? I think we don't need it and should use specific version
internal/pkg/cmd/reloader.go
Outdated
currentNamespace := os.Getenv("KUBERNETES_NAMESPACE") | ||
if len(currentNamespace) == 0 { | ||
currentNamespace = v1.NamespaceAll | ||
logrus.Infof("Warning: KUBERNETES_NAMESPACE is unset, will detect changes in all namespaces.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log this as a warning, we won't need to specify "Warning" text then
// Delete function to add an object to the queue in case of deleting a resource | ||
func (c *Controller) Delete(old interface{}) { | ||
// TODO Added this function for future usecase | ||
logrus.Infof("Deleted resource has been added to queue") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the comment text clearer that Delete resource does not do anything for now
|
||
// This controller retries 5 times if something goes wrong. After that, it stops trying. | ||
if c.queue.NumRequeues(key) < 5 { | ||
logrus.Infof("Error syncing events %v: %v", key, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Log this as error if its an error instead of info
if updateErr != nil { | ||
err := controller.client.CoreV1().Secrets(namespace).Delete(secretName, &metav1.DeleteOptions{}) | ||
if err != nil { | ||
logrus.Infof("Error while deleting the secret %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error log
if err != nil { | ||
logrus.Infof("Error while deleting the secret %v", err) | ||
} | ||
logrus.Infof("Error while deleting the secret %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error log
logrus.Infof("Deleting Secret %q.\n", secretName) | ||
err = controller.client.CoreV1().Secrets(namespace).Delete(secretName, &metav1.DeleteOptions{}) | ||
if err != nil { | ||
logrus.Infof("Error while deleting the secret %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error log
} else if _, ok := r.Resource.(*v1.Secret); ok { | ||
logrus.Infof("Performing 'Added' action for resource of type 'secret'") | ||
} else { | ||
logrus.Infof("Invalid resource") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this info, warn or error?
} else if _, ok := r.Resource.(*v1.Secret); ok { | ||
logrus.Infof("Performing 'Updated' action for resource of type 'secret'") | ||
} else { | ||
logrus.Infof("Invalid resource") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
info warn or error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please elaborate the log message
@faizanahmad055 Image is available for testing. |
* Initial * State * State * Revert unintentional change * Update * Update * Fix tests * Support patching for both reload strategies * rolling_upgrade tests * Update * More tests * Remove unnecessary stuff
No description provided.