github.com/verrazzano/verrazzano@v1.7.1/application-operator/controllers/metricsbinding/metricsbinding_delete.go (about) 1 // Copyright (c) 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package metricsbinding 5 6 import ( 7 "context" 8 "fmt" 9 10 "github.com/Jeffail/gabs/v2" 11 vzapi "github.com/verrazzano/verrazzano/application-operator/apis/app/v1alpha1" 12 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 13 "github.com/verrazzano/verrazzano/pkg/metricsutils" 14 k8scorev1 "k8s.io/api/core/v1" 15 k8scontroller "sigs.k8s.io/controller-runtime" 16 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 17 "sigs.k8s.io/yaml" 18 ) 19 20 // reconcileBindingDelete completes the reconcile process for an object that is being deleted 21 func (r *Reconciler) reconcileBindingDelete(ctx context.Context, metricsBinding *vzapi.MetricsBinding, log vzlog.VerrazzanoLogger) (k8scontroller.Result, error) { 22 log.Debugw("Reconcile for deleted object", "resource", metricsBinding.GetName()) 23 24 // If a ConfigMap is populated, delete the existing scrape config from the ConfigMap 25 var configMap = getPromConfigMap(metricsBinding) 26 if configMap != nil { 27 log.Debugf("ConfigMap %s/%s found in the MetricsBinding, deleting scrape config", configMap.GetName(), configMap.GetNamespace()) 28 if err := r.deleteFromPrometheusConfigMap(ctx, metricsBinding, configMap, log); err != nil { 29 return k8scontroller.Result{Requeue: true}, err 30 } 31 } 32 // If the Secret exists, delete the existing config from the Secret 33 secret, key := getPromConfigSecret(metricsBinding) 34 if secret != nil { 35 log.Debugf("Secret %s/%s found in the MetricsBinding, deleting scrape config", secret.GetName(), secret.GetNamespace()) 36 if err := r.deleteFromPrometheusConfigSecret(ctx, metricsBinding, secret, key, log); err != nil { 37 return k8scontroller.Result{Requeue: true}, err 38 } 39 } 40 41 // Remove the finalizer if deletion was successful 42 _, err := controllerutil.CreateOrUpdate(ctx, r.Client, metricsBinding, func() error { 43 controllerutil.RemoveFinalizer(metricsBinding, finalizerName) 44 return nil 45 }) 46 if err != nil { 47 return k8scontroller.Result{Requeue: true}, err 48 } 49 50 return k8scontroller.Result{}, nil 51 } 52 53 // deleteFromPrometheusConfigMap deletes the scrape config from the Prometheus ConfigMap 54 func (r *Reconciler) deleteFromPrometheusConfigMap(ctx context.Context, metricsBinding *vzapi.MetricsBinding, configMap *k8scorev1.ConfigMap, log vzlog.VerrazzanoLogger) error { 55 log.Debugw("Prometheus target ConfigMap is being altered", "resource", configMap.GetName()) 56 _, err := controllerutil.CreateOrUpdate(ctx, r.Client, configMap, func() error { 57 // Get data from the configmap 58 promConfig, err := getConfigData(configMap) 59 if err != nil { 60 return log.ErrorfNewErr("Failed to get Prometheus ConfigMap Data: %v", err) 61 } 62 // scrape configs would have been edited in-place, in the promConfig Container, so ignore 63 // that return value 64 _, err = r.deleteScrapeConfig(metricsBinding, promConfig, log, true) 65 if err != nil { 66 return log.ErrorfNewErr("Failed to delete scrape config from Prometheus ConfigMap: %v", err) 67 } 68 // scrape configs would have been edited in-place, in the promConfig Container, so serialize 69 // the whole thing for the new data. 70 newPromConfigData, err := yaml.JSONToYAML(promConfig.Bytes()) 71 if err != nil { 72 return log.ErrorfNewErr("Failed to convert scrape config JSON to YAML: %v", err) 73 } 74 configMap.Data[prometheusConfigKey] = string(newPromConfigData) 75 return nil 76 }) 77 return err 78 } 79 80 // deleteFromPrometheusConfigSecret deletes the scrape config from the Prometheus config Secret 81 func (r *Reconciler) deleteFromPrometheusConfigSecret(ctx context.Context, metricsBinding *vzapi.MetricsBinding, secret *k8scorev1.Secret, key string, log vzlog.VerrazzanoLogger) error { 82 log.Debugw("Prometheus target config Secret is being altered", "resource", secret.GetName()) 83 _, err := controllerutil.CreateOrUpdate(ctx, r.Client, secret, func() error { 84 scrapeConfigData, err := getConfigDataFromSecret(secret, key) 85 if err != nil { 86 return err 87 } 88 updatedScrapeConfigs, err := r.deleteScrapeConfig(metricsBinding, scrapeConfigData, log, false) 89 if err != nil { 90 return err 91 } 92 newPromConfigData, err := yaml.JSONToYAML(updatedScrapeConfigs.Bytes()) 93 if err != nil { 94 return log.ErrorfNewErr("Failed to convert scrape config JSON to YAML: %v", err) 95 } 96 secret.Data[key] = newPromConfigData 97 return nil 98 }) 99 return err 100 } 101 102 // deleteScrapeConfig is a mutation function that deletes the scrape config data from the Prometheus ConfigMap 103 func (r *Reconciler) deleteScrapeConfig(metricsBinding *vzapi.MetricsBinding, configData *gabs.Container, log vzlog.VerrazzanoLogger, isPromConfigMap bool) (*gabs.Container, error) { 104 log.Debugw("Scrape Config is being deleted from the Prometheus Config", "resource", metricsBinding.GetName()) 105 106 // Verify the Owner Reference exists 107 if len(metricsBinding.OwnerReferences) < 1 { 108 return nil, fmt.Errorf("Failed to find Owner Reference found in the MetricsBinding: %s", metricsBinding.GetName()) 109 } 110 111 // Delete scrape config with job name matching resource 112 // parse the scrape config so we can manipulate it 113 jobNameToDelete := createJobName(metricsBinding) 114 115 var updatedConfigData *gabs.Container 116 var err error 117 if isPromConfigMap { 118 err = metricsutils.EditScrapeJobInPrometheusConfig(configData, prometheusScrapeConfigsLabel, jobNameToDelete, nil) 119 updatedConfigData = configData 120 } else { 121 updatedConfigData, err = metricsutils.EditScrapeJob(configData, jobNameToDelete, nil) 122 } 123 if err != nil { 124 return nil, err 125 } 126 return updatedConfigData, err 127 }