-
Notifications
You must be signed in to change notification settings - Fork 58
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
fix: cleaning up grafana datasource on deleting monitoring stack #107
Conversation
6422166
to
b3b9538
Compare
if ms.ObjectMeta.DeletionTimestamp.IsZero() { | ||
if !containsString(ms.ObjectMeta.Finalizers, finalizerName) { | ||
controllerutil.AddFinalizer(ms, finalizerName) | ||
if err := r.k8sClient.Update(ctx, ms); err != nil { | ||
if errors.IsConflict(err) { | ||
return ctrl.Result{RequeueAfter: 2 * time.Second}, nil | ||
} | ||
return ctrl.Result{}, 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.
This part is a bit confusing to understand ... Why does cleanupResources
add a finalizer?
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 change it but then we will need to add a check that DeletionTimestamp
is not zero before we can actually delete the resource. That is what tells us that we are in delete mode.
I feel it better this way as the logic is clear.
@@ -46,11 +46,13 @@ import ( | |||
|
|||
"github.com/go-logr/logr" | |||
monv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" | |||
grafana_operator "github.com/rhobs/monitoring-stack-operator/pkg/controllers/grafana-operator" |
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.
it would be nice if package names didn't use _
- how about goctrl just like in operator.go
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.
Done
|
||
func (r *reconciler) cleanupResources(ctx context.Context, ms *stack.MonitoringStack) (ctrl.Result, error) { | ||
if ms.ObjectMeta.DeletionTimestamp.IsZero() { | ||
if !containsString(ms.ObjectMeta.Finalizers, finalizerName) { |
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 check shouldn't necessary since AddFinalizers
already does this check
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.
Done
|
||
func (r *reconciler) cleanupResources(ctx context.Context, ms *stack.MonitoringStack) (ctrl.Result, error) { | ||
if ms.ObjectMeta.DeletionTimestamp.IsZero() { | ||
if !containsString(ms.ObjectMeta.Finalizers, finalizerName) { |
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 use an existing helper for this: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/controller/controllerutil#ContainsFinalizer
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.
Done
return ctrl.Result{}, err | ||
} | ||
} | ||
} else if containsString(ms.ObjectMeta.Finalizers, finalizerName) { |
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 we check if the finalizer is set before deleting grafanadatasource?
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.
It would have been set in the if
condition, this is just to confirm.
|
||
if err := r.k8sClient.Delete(ctx, grafanaDS); 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.
I think we should ignore errors.IsNotExists()
when deleting
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 you want to ignore the error when deleting, I am not sure about that.
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 think this error is safe to ignore. Otherwise, we can end up in an endless loop if the child resource does not exist because errors are retried.
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.
Done
|
||
f.K8sClient.Delete(context.Background(), ms) | ||
|
||
if err = wait.Poll(5*time.Second, 20*time.Second, func() (done bool, err 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.
can't we use AssertResourceNeverExists
here?
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.
Done
@@ -164,7 +166,41 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu | |||
|
|||
} | |||
} | |||
return r.cleanupResources(ctx, ms) |
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.
wouldn't this run all patchers unnecessarily when a monitoring stack is deleted?
Shouldn't we handle deletion way early on in the reconcile loop .. i.e as soon as get the ms
- MonitoringStack ?
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.
If we move it to the top, when the reconcile loop runs for the first time, the stack is not completely initialised.
Shouldn't we be adding the finalizer only after all components have been created?
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 think the idea is to run this code at the top when the deletion timestamp is set. So the algorithm would be:
- If deletion timestamp is set, delete datasource, remove finalizer and update stack
- else If finalizer not set, set finalizer and update stack
- else reconcile child resources
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.
Done
24496c1
to
b433371
Compare
} | ||
|
||
func (r *reconciler) setupFinalizer(ctx context.Context, ms *stack.MonitoringStack) (ctrl.Result, error) { | ||
if !controllerutil.ContainsFinalizer(ms, finalizerName) { |
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.
if !controllerutil.ContainsFinalizer(ms, finalizerName) { | |
if controllerutil.ContainsFinalizer(ms, finalizerName) { |
|
||
f.AssertResourceEventuallyExists(datasourceName, goctrl.Namespace, grafanaDS) | ||
|
||
assert.NilError(t, err, "grafana data source is not created") |
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 true?
assert.NilError(t, err, "grafana data source is not created") |
assert.NilError(t, err, "grafana data source is not created") | ||
|
||
f.K8sClient.Delete(context.Background(), ms) | ||
|
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.
grafanaDS := &grafanav1alpha1.GrafanaDataSource{} | ||
|
||
f.AssertResourceEventuallyExists(datasourceName, goctrl.Namespace, grafanaDS) | ||
|
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.
assert.NilError(t, err, "failed to create a monitoring stack") | ||
|
||
grafanaDS := &grafanav1alpha1.GrafanaDataSource{} | ||
|
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 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.
Almost good to go.
this fix will clean up the grafana data source created by the monitoring stack on deleting the monitoring stack
return ctrl.Result{}, err | ||
} | ||
|
||
func (r *reconciler) setupFinalizer(ctx context.Context, ms *stack.MonitoringStack) (ctrl.Result, 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.
@prashbnair I think it is worth having a test that validates that the finalizer is set on a monitoring stack
Note ... This can be done is a follow up PR as well.
|
||
grafanaDS := &grafanav1alpha1.GrafanaDataSource{} | ||
f.AssertResourceEventuallyExists(datasourceName, goctrl.Namespace, grafanaDS)(t) | ||
|
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 add another validation here that the finalizer is set on the ms
that was created above
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.
@prashbnair I am approving so that we can merge this PR that has been waiting for a longtime. However, I do think we need to validate that the finalizer is set.
this fix will clean up the grafana data source created by the monitoring
stack on deleting the monitoring stack