Collectd Operator - Added TypesDB feature support 64/93264/3
authorDileep Ranganathan <dileep.ranganathan@intel.com>
Sat, 10 Aug 2019 22:15:49 +0000 (15:15 -0700)
committerDileep Ranganathan <dileep.ranganathan@intel.com>
Mon, 12 Aug 2019 17:51:22 +0000 (10:51 -0700)
Added support for typesDB. CollectGlobal CR can now add, update, delete
TypesDB and custom TypesDB to the conf. This is achieved via creating a
configmap for the types.db files and then passing the configmap name in
the CR Spec.

Issue-ID: ONAPARC-461
Signed-off-by: Dileep Ranganathan <dileep.ranganathan@intel.com>
Change-Id: Idb27d7981c72f67863f193bd5013f6907362ede9

14 files changed:
vnfs/DAaaS/microservices/collectd-operator/Makefile
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/collectdglobal.yaml [moved from vnfs/DAaaS/microservices/collectd-operator/deploy/crds/collectdglobal.yaml with 100% similarity]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/cpu_collectdplugin_cr.yaml [moved from vnfs/DAaaS/microservices/collectd-operator/deploy/crds/cpu_collectdplugin_cr.yaml with 100% similarity]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/kustomization.yaml [new file with mode: 0644]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/memory_collectdplugin_cr.yaml [moved from vnfs/DAaaS/microservices/collectd-operator/deploy/crds/memory_collectdplugin_cr.yaml with 100% similarity]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/prometheus_collectdplugin_cr.yaml [moved from vnfs/DAaaS/microservices/collectd-operator/deploy/crds/prometheus_collectdplugin_cr.yaml with 100% similarity]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/types.db [new file with mode: 0644]
vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/vcmts.types.db [new file with mode: 0644]
vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdglobal_types.go
vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1/collectdplugin_types.go
vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdglobal/collectdglobal_controller.go
vnfs/DAaaS/microservices/collectd-operator/pkg/controller/collectdplugin/collectdplugin_controller.go
vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/collectdutils.go
vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go [new file with mode: 0644]

index 7effedf..52c779c 100644 (file)
@@ -26,7 +26,6 @@ build: clean
        GOOS=linux GOARCH=amd64
        operator-sdk generate k8s --verbose
        operator-sdk generate openapi --verbose
-       #@go build -o ${COP} -gcflags all=-trimpath=${ROOTPATH} -asmflags all=-trimpath=${ROOTPATH} collectd-operator/cmd/manager
        @go build -o ${COP_LOCAL} collectd-operator/cmd/manager
        @operator-sdk build ${IMAGE_NAME} --verbose
 
diff --git a/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/kustomization.yaml b/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/kustomization.yaml
new file mode 100644 (file)
index 0000000..17ff7ae
--- /dev/null
@@ -0,0 +1,5 @@
+configMapGenerator:
+- name: typesdb-configmap
+  files:
+  - resources/types.db
+  - resources/vbng.types.db
diff --git a/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/types.db b/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/types.db
new file mode 100644 (file)
index 0000000..15da66d
--- /dev/null
@@ -0,0 +1,3 @@
+DDDDDD 111111
+EEEEEE wdasdsadsa
+dsadsadas      sdsadsa
diff --git a/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/vcmts.types.db b/vnfs/DAaaS/microservices/collectd-operator/examples/collectd/resources/vcmts.types.db
new file mode 100644 (file)
index 0000000..33f5c05
--- /dev/null
@@ -0,0 +1,3 @@
+111111 KKKKKK
+222222 LLLLLL
+333333 MMMMMM
index 1094271..d5c69fb 100644 (file)
@@ -12,8 +12,8 @@ type CollectdGlobalSpec struct {
        // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
        // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
        // Add custom validation using kubebuilder tags: https://book.kubebuilder.io/beyond_basics/generating_crd.html
-       GlobalOptions   string  `json:"globalOptions"`
-       ConfigMap               string  `json:"configMap,omitempty"`
+       GlobalOptions string `json:"globalOptions"`
+       ConfigMap     string `json:"configMap,omitempty"`
 }
 
 // CollectdGlobalStatus defines the observed state of CollectdGlobal
index 065f14c..eb33863 100644 (file)
@@ -4,18 +4,17 @@ import (
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-
 const (
        //Initial indicates the initial status of CollectdPlugin
-       Initial         = ""
+       Initial = ""
        //Created indicates the status of CollectdPlugin after first reconcile
-       Created     = "Created"
+       Created = "Created"
        //Enabled indicates the status of CollectdPlugin after all the pods are reloaded
-       Enabled     = "Enabled"
+       Enabled = "Enabled"
        //Deleting state
-       Deleting        = "Deleting"
+       Deleting = "Deleting"
        //Deprecated state when a plugin with same name is created. Old plugin gets deprecated and deleted eventually.
-       Deprecated      = "Deprecated"
+       Deprecated = "Deprecated"
 )
 
 // EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
index c48c2f5..539b680 100644 (file)
@@ -12,6 +12,7 @@ import (
 
        onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
        collectdutils "collectd-operator/pkg/controller/utils"
+       dsutils "collectd-operator/pkg/controller/utils"
 
        appsv1 "k8s.io/api/apps/v1"
        corev1 "k8s.io/api/core/v1"
@@ -213,7 +214,7 @@ func (r *ReconcileCollectdGlobal) handleCollectdGlobal(reqLogger logr.Logger, cr
                ds.Spec.Template.SetAnnotations(map[string]string{
                        "daaas-random": collectdutils.ComputeSHA256([]byte(collectdConf)),
                })
-               r.handleAdditonalConfigMap(reqLogger, cr, ds)
+               r.handleTypesDB(reqLogger, cr, ds, isDelete)
                updateErr := r.client.Update(context.TODO(), ds)
                return updateErr
        })
@@ -311,7 +312,12 @@ func (r *ReconcileCollectdGlobal) addFinalizer(reqLogger logr.Logger, cr *onapv1
        return nil
 }
 
-func (r *ReconcileCollectdGlobal) handleAdditonalConfigMap(reqLogger logr.Logger, cr *onapv1alpha1.CollectdGlobal, ds *extensionsv1beta1.DaemonSet) error {
+func (r *ReconcileCollectdGlobal) handleTypesDB(reqLogger logr.Logger, cr *onapv1alpha1.CollectdGlobal, ds *extensionsv1beta1.DaemonSet, isDelete bool) error {
+       if isDelete || cr.Spec.ConfigMap == "" {
+               dsutils.RemoveTypesDB(ds)
+               return nil
+       }
+
        cm := &corev1.ConfigMap{}
        key := types.NamespacedName{Namespace: cr.Namespace, Name: cr.Spec.ConfigMap}
        err := r.client.Get(context.TODO(), key, cm)
@@ -319,6 +325,6 @@ func (r *ReconcileCollectdGlobal) handleAdditonalConfigMap(reqLogger logr.Logger
                reqLogger.Info("Error getting TypesDB")
                return nil
        }
-       // TODO: Implement Types.DB mounting
+       dsutils.UpsertTypesDB(ds, cm, cr)
        return nil
 }
index 0e3af8d..98d770a 100644 (file)
@@ -29,7 +29,6 @@ import (
 
 var log = logf.Log.WithName("controller_collectdplugin")
 
-
 // Add creates a new CollectdPlugin Controller and adds it to the Manager. The Manager will set fields on the Controller
 // and Start it when the Manager is Started.
 func Add(mgr manager.Manager) error {
@@ -61,7 +60,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
        err = c.Watch(
                &source.Kind{Type: &appsv1.DaemonSet{}},
                &handler.EnqueueRequestsFromMapFunc{
-                       ToRequests: handler.ToRequestsFunc(func (a handler.MapObject) []reconcile.Request {
+                       ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
                                labelSelector, err := collectdutils.GetWatchLabels()
                                labels := strings.Split(labelSelector, "=")
                                if err != nil {
@@ -69,7 +68,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
                                }
                                rcp := r.(*ReconcileCollectdPlugin)
                                // Select the Daemonset with labelSelector (Defautl  is app=collectd)
-                               if a.Meta.GetLabels()[labels[0]] == labels[1]  {
+                               if a.Meta.GetLabels()[labels[0]] == labels[1] {
                                        var requests []reconcile.Request
                                        cpList, err := collectdutils.GetCollectdPluginList(rcp.client, a.Meta.GetNamespace())
                                        if err != nil {
@@ -91,7 +90,6 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
        return nil
 }
 
-
 // blank assignment to verify that ReconcileCollectdPlugin implements reconcile.Reconciler
 var _ reconcile.Reconciler = &ReconcileCollectdPlugin{}
 
@@ -103,7 +101,6 @@ type ReconcileCollectdPlugin struct {
        scheme *runtime.Scheme
 }
 
-
 // Reconcile reads that state of the cluster for a CollectdPlugin object and makes changes based on the state read
 // and what is in the CollectdPlugin.Spec
 // TODO(user): Modify this Reconcile function to implement your Controller logic.  This example creates
index b3ee805..0b3cf3f 100644 (file)
@@ -19,7 +19,7 @@ import (
 
 // Define the collectdPlugin finalizer for handling deletion
 const (
-       defaultWatchLabel       = "app=collectd"
+       defaultWatchLabel = "app=collectd"
        CollectdFinalizer = "finalizer.collectd.onap.org"
 
        // WatchLabelsEnvVar is the constant for env variable WATCH_LABELS
@@ -200,7 +200,7 @@ func RebuildCollectdConf(rc client.Client, ns string, isDelete bool, delPlugin s
                        }
                }
        }
-       
+
        if isDelete {
                delete(loadPlugin, delPlugin)
        } else {
diff --git a/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go b/vnfs/DAaaS/microservices/collectd-operator/pkg/controller/utils/dsutils.go
new file mode 100644 (file)
index 0000000..d6c60cc
--- /dev/null
@@ -0,0 +1,117 @@
+package utils
+
+import (
+       "path/filepath"
+       "strings"
+       "strconv"
+
+       onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
+
+       corev1 "k8s.io/api/core/v1"
+       extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
+       logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
+)
+
+var log = logf.Log.WithName("dsutils")
+
+const (
+       collectdContainerName = "collectd"
+
+       // canonical label for the volume created for TypesDB
+       // reason - a DNS-1123 label must consist of lower case alphanumeric characters
+       //                      or '-', and must start and end with an alphanumeric character
+       typesDB = "types-db"
+)
+
+// RemoveTypesDB - removes TypesDB volumes and volume mounts from collectd pods.
+func RemoveTypesDB(ds *extensionsv1beta1.DaemonSet) {
+       vols := &ds.Spec.Template.Spec.Volumes
+       for i:=0; i < len(*vols); i++ {
+               if (*vols)[i].Name == typesDB {
+                       *vols = append((*vols)[:i], (*vols)[i+1:]...)
+                       i--
+               }
+       }
+
+       containers := &ds.Spec.Template.Spec.Containers
+       for j, container := range *containers {
+               if container.Name == collectdContainerName {
+                       vms := &(*containers)[j].VolumeMounts
+                       for i:=0; i < len(*vms); i++ {
+                               if (*vms)[i].Name == typesDB {
+                                       *vms = append((*vms)[:i], (*vms)[i+1:]...)
+                                       i--
+                               }
+                       }
+               }
+       }
+}
+
+// UpsertTypesDB - Insert/Update TypesDB volumes and volume mounts to collectd pods.
+func UpsertTypesDB(ds *extensionsv1beta1.DaemonSet, cm *corev1.ConfigMap, cr *onapv1alpha1.CollectdGlobal) {
+       typesVM := findMountInfo(cr)
+       if *typesVM == nil || len(*typesVM) == 0 {
+               return
+       }
+       typesDBVolume := &corev1.ConfigMapVolumeSource{
+               LocalObjectReference: corev1.LocalObjectReference{Name: cm.Name},
+       }
+       vols := &ds.Spec.Template.Spec.Volumes
+       var hasUpdated bool
+       for i, vol := range *vols {
+               // Update case
+               if vol.Name == typesDB {
+                       (*vols)[i].ConfigMap = typesDBVolume
+                       hasUpdated = true
+               }
+       }
+
+       if !hasUpdated {
+               //Insert case
+               *vols = append(*vols, corev1.Volume{
+                       Name: typesDB,
+                       VolumeSource: corev1.VolumeSource{
+                               ConfigMap: typesDBVolume,
+                       },
+               })
+       }
+
+       containers := &ds.Spec.Template.Spec.Containers
+
+       for j, container := range *containers {
+               if container.Name == collectdContainerName {
+                       vms := &(*containers)[j].VolumeMounts
+                       for i:=0; i < len(*vms); i++ {
+                               // Update case (Equivalent to remove and add)
+                               if (*vms)[i].Name == typesDB {
+                                       *vms = append((*vms)[:i], (*vms)[i+1:]...)
+                                       i--
+                               }
+                       }
+
+                       *vms = append(*vms, *typesVM...)
+               }
+       }
+}
+
+func findMountInfo(cr *onapv1alpha1.CollectdGlobal) *[]corev1.VolumeMount {
+       log.V(1).Info(":::::Entering findMountInfo:::::")
+       var typesVM []corev1.VolumeMount
+       globalOpts := strings.Split(cr.Spec.GlobalOptions, "\n")
+       log.V(1).Info(":::::findMountInfo:::::", "GlobalOptions", globalOpts)
+       for i, globalOpt := range globalOpts {
+               log.V(1).Info(":::::For Loop:::::", "Item No:", i, "LineEntry:", globalOpt)
+               s := strings.Fields(globalOpt)
+               log.V(1).Info(":::::s:::::", "s:", s)
+               if s != nil && len(s) != 0 && s[0] == "TypesDB" {
+                       path,_ := strconv.Unquote(s[1])
+                       _, file := filepath.Split(path)
+                       log.V(1).Info(":::::file:::::", "s[1]:", path, "file:", file)
+                       vm := corev1.VolumeMount{Name: typesDB, MountPath: path, SubPath: file}
+                       typesVM = append(typesVM, vm)
+                       log.V(1).Info(":::::TypesVM:::::", "TypesVM:", typesVM)
+               }
+       }
+       log.V(1).Info(":::::Exiting findMountInfo:::::")
+       return &typesVM
+}