aboutsummaryrefslogtreecommitdiffstats
path: root/vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go
diff options
context:
space:
mode:
Diffstat (limited to 'vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go')
-rw-r--r--vnfs/DAaaS/microservices/visualization-operator/pkg/controller/grafanadatasource/grafanadatasource_controller.go181
1 files changed, 170 insertions, 11 deletions
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
+}