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
feat: adds controller to allow addon to reconcile on changes #46
base: main
Are you sure you want to change the base?
Conversation
Pull Request Test Coverage Report for Build 9209225475Details
💛 - Coveralls |
Signed-off-by: Israel Blancas <iblancasa@gmail.com>
This reverts commit 0e9894e.
It seems I have permission to push to this branch. I added a commit and reverted it. Added my changes in JoaoBraveCoding#11 |
* Move the watcher cli application to be a go routine Signed-off-by: Israel Blancas <iblancasa@gmail.com> * Fix lint Signed-off-by: Israel Blancas <iblancasa@gmail.com> * Fix lint Signed-off-by: Israel Blancas <iblancasa@gmail.com> * Update internal/controllers/watcher/controller.go Co-authored-by: Joao Marcal <joao.marcal12@gmail.com> * Update internal/controllers/watcher/controller.go Co-authored-by: Joao Marcal <joao.marcal12@gmail.com> * Update main.go Co-authored-by: Joao Marcal <joao.marcal12@gmail.com> * Update main.go Co-authored-by: Joao Marcal <joao.marcal12@gmail.com> * Add suggestion Signed-off-by: Israel Blancas <iblancasa@gmail.com> --------- Signed-off-by: Israel Blancas <iblancasa@gmail.com> Co-authored-by: Joao Marcal <joao.marcal12@gmail.com>
Signed-off-by: Israel Blancas <iblancasa@gmail.com>
What is missing to move from |
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.
@iblancasa some points to improve
client.Client | ||
Log logr.Logger | ||
Scheme *runtime.Scheme | ||
addonnManager *addonmanager.AddonManager |
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.
Can we make this a reference? It will make the trigger code cleaner.
addonnManager *addonmanager.AddonManager | |
addonnManager addonmanager.AddonManager |
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.
Any reason why we didn't move this to a reference? This way we can do r.addonnManager.Trigger(req.Namespace, req.Name)
instead of *(r.addonnManager).Trigger(req.Namespace, req.Name)
func (r *WatcherReconciler) enqueueForClusterWideResource() handler.EventHandler { | ||
return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { | ||
addonList := &addonapiv1alpha1.ManagedClusterAddOnList{} | ||
if err := r.Client.List(ctx, addonList, &client.ListOptions{ | ||
LabelSelector: labels.SelectorFromSet(labels.Set{ | ||
"open-cluster-management.io/addon-name": "multicluster-observability-addon", | ||
}), | ||
}); err != nil { | ||
r.Log.Error(err, "Error listing managedclusteraddon resources in event handler") | ||
return nil | ||
} | ||
|
||
if len(addonList.Items) == 0 { | ||
r.Log.V(2).Info("no managedclusteraddon found") | ||
return nil | ||
} | ||
|
||
clustersetValue, clustersetExists := obj.GetAnnotations()["cluster.open-cluster-management.io/clusterset"] | ||
var clustersInClusterSet map[string]struct{} | ||
if clustersetExists { | ||
clusterList := &clusterv1.ManagedClusterList{} | ||
if err := r.Client.List(ctx, clusterList, &client.ListOptions{ | ||
LabelSelector: labels.SelectorFromSet(labels.Set{ | ||
"cluster.open-cluster-management.io/clusterset": clustersetValue, | ||
}), | ||
}); err != nil { | ||
r.Log.Error(err, "Error listing managedcluster resources in event handler") | ||
return nil | ||
} | ||
clustersInClusterSet = make(map[string]struct{}, len(clusterList.Items)) | ||
for _, cluster := range clusterList.Items { | ||
clustersInClusterSet[cluster.Name] = struct{}{} | ||
} | ||
} | ||
|
||
var requests []reconcile.Request | ||
for _, addon := range addonList.Items { | ||
_, installed := clustersInClusterSet[addon.Namespace] | ||
if clustersetExists && !installed { | ||
continue | ||
} | ||
|
||
requests = append(requests, reconcile.Request{ | ||
NamespacedName: types.NamespacedName{ | ||
Namespace: addon.Namespace, | ||
Name: addon.Name, | ||
}, | ||
}) | ||
} | ||
return requests | ||
}) | ||
} |
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.
In the new design, we can drop this code as it will not be needed
if req.Name == "" { | ||
return ctrl.Result{}, noNameErr | ||
} | ||
if req.Namespace == "" { | ||
return ctrl.Result{}, noNamespaceErr | ||
} |
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 can remove these no? Our code shouldn't be triggering reconciliations with these, if it is then there's a bug somewhere
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.
When I tested I tested without these and saw no extra reconciliations, any reason why we left them? Not sure how it works with the new enqueue function, but again, if we are reconciling things that we don't want then I would say there is a bug in the enqueue function.
}() | ||
} | ||
|
||
// WatcherReconciler reconciles the ManagedClusterAddon to annotate the ManiestWorks 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.
Comment needs to be updated
func (r *WatcherReconciler) SetupWithManager(mgr ctrl.Manager) error { | ||
return ctrl.NewControllerManagedBy(mgr). | ||
For(&addonapiv1alpha1.ManagedClusterAddOn{}, noReconcilePred). | ||
Watches(&corev1.ConfigMap{}, r.enqueueForClusterSpecificResource(), builder.OnlyMetadata). |
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.
In the new design, we should be able to drop ConfigMaps.
Complete(r) | ||
} | ||
|
||
func (r *WatcherReconciler) enqueueForClusterSpecificResource() handler.EventHandler { |
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.
In the new design, this enqueue function needs to be updated so that if secret gets updated:
- If the namespace has a MCOA ManagedClusterAddOn then it should trigger an update for that
- Otherwise, list all MCOA ManifestWorks and check if the secret is referenced in the resources, if it is, trigger a reconciliation for the MCOA ManagedClusterAddOn in the same namespace of the ManifestWorks (I'm also open to ideas/suggestion here on how we can do this better)
FYI: Tested the current version of this PR with some of my suggestions together with #48 and everything worked out 👌 |
* If a secret is updated, check if there is any reference to it in any of the ManifestWorks * Change some comments Signed-off-by: Israel Blancas <iblancasa@gmail.com>
@JoaoBraveCoding I added the changes yesterday. I tested the changes and I think everything is working fine. Is ok if we move to |
@iblancasa yes please move to ready for review. I am constantly skim over this and would like to add my review. Thanks for all the dedication and work you both put in here |
if req.Name == "" { | ||
return ctrl.Result{}, noNameErr | ||
} | ||
if req.Namespace == "" { | ||
return ctrl.Result{}, noNamespaceErr | ||
} |
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.
When I tested I tested without these and saw no extra reconciliations, any reason why we left them? Not sure how it works with the new enqueue function, but again, if we are reconciling things that we don't want then I would say there is a bug in the enqueue function.
client.Client | ||
Log logr.Logger | ||
Scheme *runtime.Scheme | ||
addonnManager *addonmanager.AddonManager |
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.
Any reason why we didn't move this to a reference? This way we can do r.addonnManager.Trigger(req.Namespace, req.Name)
instead of *(r.addonnManager).Trigger(req.Namespace, req.Name)
Watches(&loggingv1.ClusterLogForwarder{}, r.enqueueForClusterSpecificResource(), builder.OnlyMetadata). | ||
Watches(&otelv1alpha1.OpenTelemetryCollector{}, r.enqueueForClusterSpecificResource(), builder.OnlyMetadata). |
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.
Both these are not necessary, since they will be referenced on the ManagedClusterAddon
Status if any changes happen to these resources it will automatically trigger a reconciliation
switch obj.(type) { | ||
case *corev1.Secret: | ||
return r.getSecretReconcileRequests(ctx, obj, addon) | ||
} | ||
return nil |
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.
Since the watcher (for now) will only watch secrets we don't need to have this and we can call directly return r.getSecretReconcileRequests(ctx, obj, addon)
func (r *WatcherReconciler) getSecretReconcileRequests(ctx context.Context, obj client.Object, addon *addonapiv1alpha1.ManagedClusterAddOn) []reconcile.Request { | ||
rqs := []reconcile.Request{} | ||
mws := &workapiv1.ManifestWorkList{} | ||
if err := r.Client.List(ctx, mws); err != nil { |
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.
Here we should list only the ManifestWork that belong to MCOA we can do so in the following way:
if err := r.Client.List(ctx, mws); err != nil { | |
if err := r.Client.List(ctx, mws, &client.ListOptions{ | |
LabelSelector: labels.SelectorFromSet(labels.Set{ | |
"open-cluster-management.io/addon-name": "multicluster-observability-addon", | |
}), | |
}); err != nil { |
reconcile.Request{ | ||
NamespacedName: types.NamespacedName{ | ||
Name: addon.Name, | ||
Namespace: mw.Namespace, |
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 can move this to a contant since this will aways be the same
Signed-off-by: Israel Blancas <iblancasa@gmail.com>
This PR introduces a controller that will watch for resources used for the addon configuration and it will annotate the corresponding ManifestWorks triggering a reconciliation