X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=vnfs%2FDAaaS%2Fmicroservices%2Fvisualization-operator%2Fpkg%2Fcontroller%2Fgrafanadatasource%2Fgrafanadatasource_controller.go;fp=vnfs%2FDAaaS%2Fmicroservices%2Fvisualization-operator%2Fpkg%2Fcontroller%2Fgrafanadatasource%2Fgrafanadatasource_controller.go;h=88b8a925c06099ad9f8bc782147cdd90f18720c4;hb=c3ef7c3f40f6aa4a14a98301ae12bfa11b1a12c3;hp=f46cf1b49fecf0a654c09e1ce39a2c8d0eecb2e9;hpb=b2651f39b6dbe79e05d42f8a3bfbbc11c42c5d4c;p=demo.git diff --git a/vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go b/vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go index f46cf1b4..88b8a925 100644 --- a/vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go +++ b/vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go @@ -1,11 +1,16 @@ package grafanadatasource import ( + logr "github.com/go-logr/logr" + "bytes" "context" "encoding/json" + "fmt" + "io/ioutil" onapv1alpha1 "visualization-operator/pkg/apis/onap/v1alpha1" + visualizationutils "visualization-operator/pkg/controller/utils" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -77,13 +82,51 @@ func (r *ReconcileGrafanaDataSource) Reconcile(request reconcile.Request) (recon // Request object not found, could have been deleted after reconcile request. // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. // Return and don't requeue + reqLogger.Info("GrafanaDatasource object not found") return reconcile.Result{}, nil } // Error reading the object - requeue the request. - + reqLogger.Info("Error reading the Grafanadatasource object, Requeing") return reconcile.Result{}, err } + //Check if deletion timestamp is set. If yes, delete the GrafanaDataSource object + isBeingDeleted := checkDeletionTimestamp(reqLogger, instance) + if isBeingDeleted { + //Delete the datasource from grafana + err := deleteDatasource(instance) + if err != nil { + reqLogger.Error(err, "Unable to delete datasource") + return reconcile.Result{}, err + } + //remove Finalizer after deletion + if visualizationutils.Contains(instance.GetFinalizers(), visualizationutils.VisualizationFinalizer) { + if err := removeFinalizer(reqLogger, instance); err != nil { + return reconcile.Result{}, err + } + err := r.client.Update(context.TODO(), instance) + if err != nil { + reqLogger.Error(err, "Unable to update instance") + return reconcile.Result{}, err + } + return reconcile.Result{}, nil + } + } + + //Add finalizer for the CR object + if !visualizationutils.Contains(instance.GetFinalizers(), visualizationutils.VisualizationFinalizer) { + reqLogger.Info("Adding finalizer for GrafanaDatasource") + if err := addFinalizer(reqLogger, instance); err != nil { + return reconcile.Result{}, err + } + err := r.client.Update(context.TODO(), instance) + if err != nil { + reqLogger.Error(err, "Unable to update instance") + return reconcile.Result{}, err + } + return reconcile.Result{}, nil + } + datasources := instance.Spec.Datasources grafana := instance.Spec.Grafana @@ -110,6 +153,25 @@ func (r *ReconcileGrafanaDataSource) Reconcile(request reconcile.Request) (recon return reconcile.Result{}, err } + respBody, err := ioutil.ReadAll(getResp.Body) + if err != nil { + reqLogger.Error(err, "Response data not read properly") + return reconcile.Result{}, err + } + + respBodyBytes := []byte(respBody) + var respData map[string]interface{} + + if err := json.Unmarshal(respBodyBytes, &respData); err != nil { + reqLogger.Error(err, "JSON unmarshalling error") + return reconcile.Result{}, err + } + + respURL := fmt.Sprintf("%v", respData["url"]) + respID := fmt.Sprintf("%v", respData["id"]) + respIsDefault := respData["isDefault"] + respAccess := fmt.Sprintf("%v", respData["access"]) + defer getResp.Body.Close() //add datasource if datasource does not exist already @@ -120,19 +182,24 @@ func (r *ReconcileGrafanaDataSource) Reconcile(request reconcile.Request) (recon return reconcile.Result{}, err } } else if getResp.StatusCode == http.StatusOK { - //if datasource already exists + //if datasource already exists and there is any change in the spec - update it reqLogger.V(1).Info("datasource already exists", "datasource", datasource.Name) - } else { - reqLogger.Error(err, "unknown error", datasource.Name) + if respURL != datasource.URL || respIsDefault.(bool) != datasource.IsDefault || respAccess != datasource.Access { + if err := updateDatasource(grafana, datasource, respID); err != nil { + return reconcile.Result{}, err + } + } else { + reqLogger.Info("No creation/updation of datasource needed") + return reconcile.Result{}, nil + } } - } return reconcile.Result{}, nil } func createDataSource(grafana map[string]string, datasource onapv1alpha1.Datasource) error { reqLogger := log.WithValues("Datasource name", datasource.Name, "Datasource URL", datasource.URL) - reqLogger.Info("creating datasource") + reqLogger.Info("Creating datasource") grafanaURL := grafana["url"] + "/api/datasources" grafanaUsername := grafana["username"] @@ -145,19 +212,19 @@ func createDataSource(grafana map[string]string, datasource onapv1alpha1.Datasou return err } - req, err := http.NewRequest("POST", grafanaURL, bytes.NewBuffer(postBody)) + postReq, err := http.NewRequest("POST", grafanaURL, bytes.NewBuffer(postBody)) if err != nil { reqLogger.Error(err, "POST REQUEST error") return err } - req.Header.Set("Content-Type", "application/json") - req.SetBasicAuth(grafanaUsername, grafanaPassword) - postResp, err := client.Do(req) + postReq.Header.Set("Content-Type", "application/json") + postReq.SetBasicAuth(grafanaUsername, grafanaPassword) + postResp, err := client.Do(postReq) if err != nil { reqLogger.Error(err, "POST RESPONSE error") return err } - defer req.Body.Close() + defer postReq.Body.Close() if postResp.StatusCode == http.StatusOK { reqLogger.Info("Datasource created") @@ -165,3 +232,95 @@ func createDataSource(grafana map[string]string, datasource onapv1alpha1.Datasou } return err } + +func updateDatasource(grafana map[string]string, datasource onapv1alpha1.Datasource, datasourceID string) error { + reqLogger := log.WithValues("Datasource name", datasource.Name, "Datasource URL", datasource.URL) + reqLogger.Info("Updating datasource") + + grafanaURL := grafana["url"] + "/api/datasources/" + datasourceID + grafanaUsername := grafana["username"] + grafanaPassword := grafana["password"] + + client := &http.Client{} + putBody, err := json.Marshal(datasource) + if err != nil { + reqLogger.Error(err, "JSON Marshalling error") + return err + } + putReq, err := http.NewRequest("PUT", grafanaURL, bytes.NewBuffer(putBody)) + if err != nil { + reqLogger.Error(err, "PUT REQUEST error") + return err + } + putReq.Header.Set("Content-Type", "application/json") + putReq.Header.Set("Accept", "application/json") + putReq.SetBasicAuth(grafanaUsername, grafanaPassword) + + putResp, err := client.Do(putReq) + if err != nil { + reqLogger.Error(err, "PUT RESPONSE error") + return err + } + defer putReq.Body.Close() + + if putResp.StatusCode == http.StatusOK { + reqLogger.Info("Datasource updated") + return nil + } + return err +} + +func deleteDatasource(instance *onapv1alpha1.GrafanaDataSource) error { + + datasources := instance.Spec.Datasources + grafana := instance.Spec.Grafana + + for _, datasource := range datasources { + + reqLogger := log.WithValues("Datasource name", datasource.Name, "Datasource URL", datasource.URL) + reqLogger.Info("Deleting datasource") + + grafanaURL := grafana["url"] + "/api/datasources/name/" + datasource.Name + grafanaUsername := grafana["username"] + grafanaPassword := grafana["password"] + + client := &http.Client{} + deleteReq, err := http.NewRequest("DELETE", grafanaURL, nil) + if err != nil { + reqLogger.Error(err, "DELETE request error") + return err + } + + deleteReq.SetBasicAuth(grafanaUsername, grafanaPassword) + + deleteResp, err := client.Do(deleteReq) + if err != nil { + reqLogger.Error(err, "DELETE RESPONSE error") + return err + } + + if deleteResp.StatusCode == http.StatusOK { + reqLogger.Info("Datasource deleted") + return nil + } + return err + } + return nil +} + +func checkDeletionTimestamp(reqlogger logr.Logger, instance *onapv1alpha1.GrafanaDataSource) bool { + isMarkedForDeletion := instance.GetDeletionTimestamp() != nil + return isMarkedForDeletion +} + +func addFinalizer(reqlogger logr.Logger, instance *onapv1alpha1.GrafanaDataSource) error { + reqlogger.Info("Adding finalizer for the GrafanaDatasource") + instance.SetFinalizers(append(instance.GetFinalizers(), visualizationutils.VisualizationFinalizer)) + return nil +} + +func removeFinalizer(reqlogger logr.Logger, instance *onapv1alpha1.GrafanaDataSource) error { + reqlogger.Info("Removing finalizer for the GrafanaDatasource") + instance.SetFinalizers(visualizationutils.Remove(instance.GetFinalizers(), visualizationutils.VisualizationFinalizer)) + return nil +}