17cad0e5bb7f3fa393980b0558eb6e5a93b35158
[demo.git] / vnfs / DAaaS / microservices / collectd-operator / pkg / controller / utils / collectdutils.go
1 package utils
2
3 import (
4         "context"
5         "crypto/sha256"
6         "fmt"
7         "os"
8         "sort"
9         "sync"
10
11         "github.com/go-logr/logr"
12
13         onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
14
15         appsv1 "k8s.io/api/apps/v1"
16         corev1 "k8s.io/api/core/v1"
17         "k8s.io/apimachinery/pkg/api/errors"
18         "sigs.k8s.io/controller-runtime/pkg/client"
19 )
20
21 // Define the collectdPlugin finalizer for handling deletion
22 const (
23         defaultWatchLabel = "app=collectd"
24         CollectdFinalizer = "finalizer.collectd.onap.org"
25
26         // WatchLabelsEnvVar is the constant for env variable WATCH_LABELS
27         // which is the labels where the watch activity happens.
28         // this value is empty if the operator is running with clusterScope.
29         WatchLabelsEnvVar = "WATCH_LABELS"
30 )
31
32 var lock sync.Mutex
33
34 // ReconcileLock - Used to sync between global and plugin controller
35 var ReconcileLock sync.Mutex
36
37 // ResourceMap to hold objects to update/reload
38 type ResourceMap struct {
39         ConfigMap       *corev1.ConfigMap
40         DaemonSet       *appsv1.DaemonSet
41         CollectdPlugins *[]onapv1alpha1.CollectdPlugin
42 }
43
44 // ComputeSHA256  returns hash of data as string
45 func ComputeSHA256(data []byte) string {
46         hash := sha256.Sum256(data)
47         return fmt.Sprintf("%x", hash)
48 }
49
50 // Contains checks if a string is contained in a list of strings
51 func Contains(list []string, s string) bool {
52         for _, v := range list {
53                 if v == s {
54                         return true
55                 }
56         }
57         return false
58 }
59
60 // Remove removes a string from a list of string
61 func Remove(list []string, s string) []string {
62         for i, v := range list {
63                 if v == s {
64                         list = append(list[:i], list[i+1:]...)
65                 }
66         }
67         return list
68 }
69
70 // GetWatchLabels returns the labels the operator should be watching for changes
71 func GetWatchLabels() (string, error) {
72         labelSelector, found := os.LookupEnv(WatchLabelsEnvVar)
73         if !found {
74                 return defaultWatchLabel, fmt.Errorf("%s must be set", WatchLabelsEnvVar)
75         }
76         return labelSelector, nil
77 }
78
79 // GetCollectdPluginList returns the list of CollectdPlugin instances in the namespace ns
80 func GetCollectdPluginList(rc client.Client, ns string) (*onapv1alpha1.CollectdPluginList, error) {
81         // Get all collectd plugins in the current namespace to rebuild conf.
82         collectdPlugins := &onapv1alpha1.CollectdPluginList{}
83         cpOpts := &client.ListOptions{}
84         cpOpts.InNamespace(ns)
85         err := rc.List(context.TODO(), cpOpts, collectdPlugins)
86         if err != nil {
87                 return nil, err
88         }
89         return collectdPlugins, nil
90 }
91
92 // GetConfigMap returns the GetConfigMap in the namespace ns
93 func GetConfigMap(rc client.Client, reqLogger logr.Logger, ns string) (*corev1.ConfigMap, error) {
94         lock.Lock()
95         defer lock.Unlock()
96
97         reqLogger.Info("Get ConfigMap for collectd.conf")
98         // Get all collectd plugins in the current namespace to rebuild conf.
99         cmList := &corev1.ConfigMapList{}
100         opts := &client.ListOptions{}
101         // Select ConfigMaps with label
102         labelSelector, err := GetWatchLabels()
103         if err != nil {
104                 reqLogger.Error(err, "Failed to get watch labels, continuing with default label")
105         }
106         opts.SetLabelSelector(labelSelector)
107         opts.InNamespace(ns)
108
109         err = rc.List(context.TODO(), opts, cmList)
110         if err != nil {
111                 return nil, err
112         }
113
114         if cmList.Items == nil || len(cmList.Items) == 0 {
115                 return nil, errors.NewNotFound(corev1.Resource("configmap"), "ConfigMap")
116         }
117
118         cm := &cmList.Items[0]
119         return cm, nil
120 }
121
122 // GetCollectdGlobal returns the CollectdGlobal instance in the namespace ns
123 func GetCollectdGlobal(rc client.Client, ns string) (*onapv1alpha1.CollectdGlobal, error) {
124         // Get the CollectdGlobal instance in current namespace to rebuild conf.
125         cgList := &onapv1alpha1.CollectdGlobalList{}
126         cpOpts := &client.ListOptions{}
127         cpOpts.InNamespace(ns)
128         err := rc.List(context.TODO(), cpOpts, cgList)
129         if err != nil {
130                 return nil, err
131         }
132         if cgList.Items == nil || len(cgList.Items) == 0 {
133                 return nil, err
134         }
135         collectdGlobals := &cgList.Items[0]
136         return collectdGlobals, nil
137 }
138
139 // GetPodList returns the list of pods in the namespace ns
140 func GetPodList(rc client.Client, ns string) ([]string, error) {
141         var pods []string
142         podList := &corev1.PodList{}
143         opts := &client.ListOptions{}
144         // Select ConfigMaps with label
145         labelSelector, _ := GetWatchLabels()
146         opts.SetLabelSelector(labelSelector)
147         opts.InNamespace(ns)
148         err := rc.List(context.TODO(), opts, podList)
149         if err != nil {
150                 return nil, err
151         }
152
153         if podList.Items == nil || len(podList.Items) == 0 {
154                 return nil, err
155         }
156
157         for _, pod := range podList.Items {
158                 pods = append(pods, pod.Name)
159         }
160         return pods, nil
161 }
162
163 // RebuildCollectdConf Get all collectd plugins and reconstruct, compute Hash and check for changes
164 func RebuildCollectdConf(rc client.Client, ns string, isDelete bool, delPlugin string) (string, error) {
165         var collectdConf, collectdGlobalConf string
166         // Get the collectd global in the current namespace to rebuild conf.
167         cg, err := GetCollectdGlobal(rc, ns)
168         if err != nil {
169                 return "", err
170         }
171
172         if cg != nil {
173                 collectdGlobalConf += cg.Spec.GlobalOptions + "\n"
174         }
175
176         // Get all collectd plugins in the current namespace to rebuild conf.
177         cp, err := GetCollectdPluginList(rc, ns)
178         if err != nil {
179                 return "", err
180         }
181         cpList := &cp.Items
182         loadPlugin := make(map[string]string)
183         if *cpList != nil && len(*cpList) > 0 {
184                 for _, cp := range *cpList {
185                         // using CollectdPlugin to set global options. If CollectdGlobal CRD is defined do not check for this
186                         if cp.Spec.PluginName == "global" {
187                                 if cg == nil {
188                                         collectdGlobalConf += cp.Spec.PluginConf + "\n"
189                                 }
190                         } else {
191                                 loadPlugin[cp.Spec.PluginName] = cp.Spec.PluginConf
192                         }
193                 }
194         }
195
196         if isDelete {
197                 delete(loadPlugin, delPlugin)
198         } else {
199                 collectdConf += collectdGlobalConf
200         }
201
202         pluginKeys := make([]string, 0, len(loadPlugin))
203         for k := range loadPlugin {
204                 pluginKeys = append(pluginKeys, k)
205         }
206         sort.Strings(pluginKeys)
207
208         for _, cpName := range pluginKeys {
209                 cpConf := loadPlugin[cpName]
210                 collectdConf += "LoadPlugin" + " " + cpName + "\n"
211                 collectdConf += cpConf + "\n"
212         }
213
214         collectdConf += "#Last line (collectd requires ā€˜\\nā€™ at the last line)\n"
215
216         return collectdConf, nil
217 }