9 onapv1alpha1 "demo/vnfs/DAaaS/microservices/collectd-operator/pkg/apis/onap/v1alpha1"
11 corev1 "k8s.io/api/core/v1"
12 extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
13 "k8s.io/apimachinery/pkg/api/errors"
14 "k8s.io/apimachinery/pkg/runtime"
15 "sigs.k8s.io/controller-runtime/pkg/client"
16 "sigs.k8s.io/controller-runtime/pkg/controller"
17 "sigs.k8s.io/controller-runtime/pkg/handler"
18 "sigs.k8s.io/controller-runtime/pkg/manager"
19 "sigs.k8s.io/controller-runtime/pkg/reconcile"
20 logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
21 "sigs.k8s.io/controller-runtime/pkg/source"
24 var log = logf.Log.WithName("controller_collectdplugin")
26 // ResourceMap to hold objects to update/reload
27 type ResourceMap struct {
28 configMap *corev1.ConfigMap
29 daemonSet *extensionsv1beta1.DaemonSet
30 collectdPlugins *[]onapv1alpha1.CollectdPlugin
34 * USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
35 * business logic. Delete these comments after modifying this file.*
38 // Add creates a new CollectdPlugin Controller and adds it to the Manager. The Manager will set fields on the Controller
39 // and Start it when the Manager is Started.
40 func Add(mgr manager.Manager) error {
41 return add(mgr, newReconciler(mgr))
44 // newReconciler returns a new reconcile.Reconciler
45 func newReconciler(mgr manager.Manager) reconcile.Reconciler {
46 return &ReconcileCollectdPlugin{client: mgr.GetClient(), scheme: mgr.GetScheme()}
49 // add adds a new Controller to mgr with r as the reconcile.Reconciler
50 func add(mgr manager.Manager, r reconcile.Reconciler) error {
51 // Create a new controller
52 log.V(1).Info("Creating a new controller for CollectdPlugin")
53 c, err := controller.New("collectdplugin-controller", mgr, controller.Options{Reconciler: r})
58 // Watch for changes to primary resource CollectdPlugin
59 log.V(1).Info("Add watcher for primary resource CollectdPlugin")
60 err = c.Watch(&source.Kind{Type: &onapv1alpha1.CollectdPlugin{}}, &handler.EnqueueRequestForObject{})
68 // blank assignment to verify that ReconcileCollectdPlugin implements reconcile.Reconciler
69 var _ reconcile.Reconciler = &ReconcileCollectdPlugin{}
71 // ReconcileCollectdPlugin reconciles a CollectdPlugin object
72 type ReconcileCollectdPlugin struct {
73 // This client, initialized using mgr.Client() above, is a split client
74 // that reads objects from the cache and writes to the apiserver
76 scheme *runtime.Scheme
79 // Reconcile reads that state of the cluster for a CollectdPlugin object and makes changes based on the state read
80 // and what is in the CollectdPlugin.Spec
81 // TODO(user): Modify this Reconcile function to implement your Controller logic. This example creates
82 // a Pod as an example
84 // The Controller will requeue the Request to be processed again if the returned error is non-nil or
85 // Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
86 func (r *ReconcileCollectdPlugin) Reconcile(request reconcile.Request) (reconcile.Result, error) {
87 reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
88 reqLogger.Info("Reconciling CollectdPlugin")
90 // Fetch the CollectdPlugin instance
91 instance := &onapv1alpha1.CollectdPlugin{}
92 err := r.client.Get(context.TODO(), request.NamespacedName, instance)
94 if errors.IsNotFound(err) {
95 // Request object not found, could have been deleted after reconcile request.
96 // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
97 // Return and don't requeue
98 reqLogger.V(1).Info("CollectdPlugin object Not found")
99 return reconcile.Result{}, nil
101 // Error reading the object - requeue the request.
102 reqLogger.V(1).Info("Error reading the CollectdPlugin object, Requeuing")
103 return reconcile.Result{}, err
106 rmap, err := findResourceMapForCR(r, instance)
108 reqLogger.Info("Skip reconcile: ConfigMap not found")
109 return reconcile.Result{}, err
114 reqLogger.V(1).Info("Found ResourceMap")
115 reqLogger.V(1).Info("ConfigMap.Namespace", cm.Namespace, "ConfigMap.Name", cm.Name)
116 reqLogger.V(1).Info("DaemonSet.Namespace", ds.Namespace, "DaemonSet.Name", ds.Name)
118 //hasChanged, err := buildCollectdConf(r, instance)
120 //Restart Collectd Pods
121 ts := time.Now().Format(time.RFC850)
122 reqLogger.V(1).Info("Timestamp : ", ts)
123 ds.Spec.Template.SetAnnotations(map[string]string{
124 "daaas-random": ComputeSHA256([]byte(ts)),
126 cm.SetAnnotations(map[string]string{
127 "daaas-random": ComputeSHA256([]byte(ts)),
130 // Update the ConfigMap with new Spec and reload DaemonSets
131 reqLogger.Info("Updating the ConfigMap", "ConfigMap.Namespace", cm.Namespace, "ConfigMap.Name", cm.Name)
132 log.Info("ConfigMap Data", "Map: ", cm.Data)
133 err = r.client.Update(context.TODO(), cm)
135 return reconcile.Result{}, err
138 err = r.client.Update(context.TODO(), ds)
140 return reconcile.Result{}, err
144 reqLogger.Info("Updated the ConfigMap", "ConfigMap.Namespace", cm.Namespace, "ConfigMap.Name", cm.Name)
145 return reconcile.Result{}, nil
148 // ComputeSHA256 returns hash of data as string
149 func ComputeSHA256(data []byte) string {
150 hash := sha256.Sum256(data)
151 return fmt.Sprintf("%x", hash)
154 // findConfigMapForCR returns the configMap used by collectd Daemonset
155 func findResourceMapForCR(r *ReconcileCollectdPlugin, cr *onapv1alpha1.CollectdPlugin) (ResourceMap, error) {
156 cmList := &corev1.ConfigMapList{}
157 opts := &client.ListOptions{}
158 rmap := ResourceMap{}
160 // Select ConfigMaps with label app=collectd
161 opts.SetLabelSelector("app=collectd")
162 opts.InNamespace(cr.Namespace)
163 err := r.client.List(context.TODO(), opts, cmList)
168 if cmList.Items == nil || len(cmList.Items) == 0 {
172 // Select DaemonSets with label app=collectd
173 dsList := &extensionsv1beta1.DaemonSetList{}
174 err = r.client.List(context.TODO(), opts, dsList)
179 if dsList.Items == nil || len(dsList.Items) == 0 {
183 // Get all collectd plugins in the current namespace to rebuild conf.
184 collectdPlugins := &onapv1alpha1.CollectdPluginList{}
185 cpOpts := &client.ListOptions{}
186 cpOpts.InNamespace(cr.Namespace)
187 err = r.client.List(context.TODO(), cpOpts, collectdPlugins)
192 rmap.configMap = &cmList.Items[0]
193 rmap.daemonSet = &dsList.Items[0]
194 rmap.collectdPlugins = &collectdPlugins.Items //will be nil if no plugins exist
198 // Get all collectd plugins and reconstruct, compute Hash and check for changes
199 func buildCollectdConf() {