diff --git a/controllers/operandrequest/reconcile_operand.go b/controllers/operandrequest/reconcile_operand.go index b70dc387..f977bc6f 100644 --- a/controllers/operandrequest/reconcile_operand.go +++ b/controllers/operandrequest/reconcile_operand.go @@ -1116,6 +1116,7 @@ func (r *Reconciler) updateK8sResource(ctx context.Context, existingK8sRes unstr if err != nil { return false, errors.Wrapf(err, "failed to get k8s resource -- Kind: %s, NamespacedName: %s/%s", kind, namespace, name) } + resourceVersion := existingRes.GetResourceVersion() if !r.CheckLabel(existingRes, map[string]string{constant.OpreqLabel: "true"}) && (newLabels == nil || newLabels[constant.OpreqLabel] != "true") { @@ -1253,7 +1254,7 @@ func (r *Reconciler) updateK8sJob(ctx context.Context, existingK8sRes unstructur } newAnnotations[constant.HashedData] = newHashedData - if err := r.deleteK8sResource(ctx, existingRes, namespace); err != nil { + if err := r.deleteK8sResource(ctx, existingRes, newLabels, namespace); err != nil { return errors.Wrap(err, "failed to update k8s resource") } if err := r.createK8sResource(ctx, templatek8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences, optionalFields); err != nil { @@ -1312,7 +1313,7 @@ func (r *Reconciler) updateK8sRoute(ctx context.Context, existingK8sRes unstruct templatek8sRes.SetName(name) templatek8sRes.SetNamespace(namespace) - if err := r.deleteK8sResource(ctx, existingRes, namespace); err != nil { + if err := r.deleteK8sResource(ctx, existingRes, newLabels, namespace); err != nil { return errors.Wrap(err, "failed to delete Route for recreation") } if err := r.createK8sResource(ctx, templatek8sRes, k8sResConfig, newLabels, newAnnotations, ownerReferences, optionalFields); err != nil { @@ -1324,7 +1325,56 @@ func (r *Reconciler) updateK8sRoute(ctx context.Context, existingK8sRes unstruct return nil } -func (r *Reconciler) deleteK8sResource(ctx context.Context, existingK8sRes unstructured.Unstructured, namespace string) error { +// deleteAllK8sResource remove k8s resource base on OperandConfig +func (r *Reconciler) deleteAllK8sResource(ctx context.Context, csc *operatorv1alpha1.OperandConfig, operandName, namespace string) error { + + service := csc.GetService(operandName) + if service == nil { + return nil + } + + var k8sResourceList []operatorv1alpha1.ConfigResource + k8sResourceList = append(k8sResourceList, service.Resources...) + + merr := &util.MultiErr{} + var ( + wg sync.WaitGroup + ) + for _, k8sRes := range k8sResourceList { + k8sResShouldBeDeleted := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": k8sRes.APIVersion, + "kind": k8sRes.Kind, + "metadata": map[string]interface{}{ + "name": k8sRes.Name, + }, + }, + } + k8sNamespace := namespace + if k8sRes.Namespace != "" { + k8sNamespace = k8sRes.Namespace + } + + wg.Add(1) + go func() { + defer wg.Done() + if err := r.deleteK8sResource(ctx, k8sResShouldBeDeleted, k8sRes.Labels, k8sNamespace); err != nil { + r.Mutex.Lock() + defer r.Mutex.Unlock() + merr.Add(err) + return + } + }() + } + wg.Wait() + + if len(merr.Errors) != 0 { + return merr + } + return nil +} + +func (r *Reconciler) deleteK8sResource(ctx context.Context, existingK8sRes unstructured.Unstructured, newLabels map[string]string, namespace string) error { kind := existingK8sRes.GetKind() apiversion := existingK8sRes.GetAPIVersion() @@ -1346,7 +1396,13 @@ func (r *Reconciler) deleteK8sResource(ctx context.Context, existingK8sRes unstr if apierrors.IsNotFound(err) { klog.V(3).Infof("There is no k8s resource: %s from kind: %s", name, kind) } else { - if r.CheckLabel(k8sResShouldBeDeleted, map[string]string{constant.OpreqLabel: "true"}) && !r.CheckLabel(k8sResShouldBeDeleted, map[string]string{constant.NotUninstallLabel: "true"}) { + // If the existing k8s resources has the OpreqLabel and does not have the NotUninstallLabel, delete it + // If the OpreqLabel is difined in OperandConfig resource, delete it + hasOpreqLabel := r.CheckLabel(k8sResShouldBeDeleted, map[string]string{constant.OpreqLabel: "true"}) + hasNotUninstallLabel := r.CheckLabel(k8sResShouldBeDeleted, map[string]string{constant.NotUninstallLabel: "true"}) + opreqLabelInConfig := newLabels != nil && newLabels[constant.OpreqLabel] == "true" + + if (hasOpreqLabel && !hasNotUninstallLabel) || opreqLabelInConfig { klog.V(3).Infof("Deleting k8s resource: %s from kind: %s", name, kind) err := r.Delete(ctx, &k8sResShouldBeDeleted, client.PropagationPolicy(metav1.DeletePropagationBackground)) if err != nil && !apierrors.IsNotFound(err) { @@ -1378,55 +1434,6 @@ func (r *Reconciler) deleteK8sResource(ctx context.Context, existingK8sRes unstr return nil } -// deleteAllK8sResource remove k8s resource base on OperandConfig -func (r *Reconciler) deleteAllK8sResource(ctx context.Context, csc *operatorv1alpha1.OperandConfig, operandName, namespace string) error { - - service := csc.GetService(operandName) - if service == nil { - return nil - } - - var k8sResourceList []operatorv1alpha1.ConfigResource - k8sResourceList = append(k8sResourceList, service.Resources...) - - merr := &util.MultiErr{} - var ( - wg sync.WaitGroup - ) - for _, k8sRes := range k8sResourceList { - k8sResShouldBeDeleted := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": k8sRes.APIVersion, - "kind": k8sRes.Kind, - "metadata": map[string]interface{}{ - "name": k8sRes.Name, - }, - }, - } - k8sNamespace := namespace - if k8sRes.Namespace != "" { - k8sNamespace = k8sRes.Namespace - } - - wg.Add(1) - go func() { - defer wg.Done() - if err := r.deleteK8sResource(ctx, k8sResShouldBeDeleted, k8sNamespace); err != nil { - r.Mutex.Lock() - defer r.Mutex.Unlock() - merr.Add(err) - return - } - }() - } - wg.Wait() - - if len(merr.Errors) != 0 { - return merr - } - return nil -} - func (r *Reconciler) checkResAuth(ctx context.Context, verbs []string, k8sResTemplate unstructured.Unstructured) bool { kind := k8sResTemplate.GetKind() apiversion := k8sResTemplate.GetAPIVersion()