10 "github.com/go-logr/logr"
12 onapv1alpha1 "collectd-operator/pkg/apis/onap/v1alpha1"
14 appsv1 "k8s.io/api/apps/v1"
15 corev1 "k8s.io/api/core/v1"
16 "k8s.io/apimachinery/pkg/api/errors"
17 "sigs.k8s.io/controller-runtime/pkg/client"
20 // Define the collectdPlugin finalizer for handling deletion
22 defaultWatchLabel = "app=collectd"
23 CollectdFinalizer = "finalizer.collectd.onap.org"
25 // WatchLabelsEnvVar is the constant for env variable WATCH_LABELS
26 // which is the labels where the watch activity happens.
27 // this value is empty if the operator is running with clusterScope.
28 WatchLabelsEnvVar = "WATCH_LABELS"
33 // ResourceMap to hold objects to update/reload
34 type ResourceMap struct {
35 ConfigMap *corev1.ConfigMap
36 DaemonSet *appsv1.DaemonSet
37 CollectdPlugins *[]onapv1alpha1.CollectdPlugin
40 // ComputeSHA256 returns hash of data as string
41 func ComputeSHA256(data []byte) string {
42 hash := sha256.Sum256(data)
43 return fmt.Sprintf("%x", hash)
46 // Contains checks if a string is contained in a list of strings
47 func Contains(list []string, s string) bool {
48 for _, v := range list {
56 // Remove removes a string from a list of string
57 func Remove(list []string, s string) []string {
58 for i, v := range list {
60 list = append(list[:i], list[i+1:]...)
66 // GetWatchLabels returns the labels the operator should be watching for changes
67 func GetWatchLabels() (string, error) {
68 labelSelector, found := os.LookupEnv(WatchLabelsEnvVar)
70 return defaultWatchLabel, fmt.Errorf("%s must be set", WatchLabelsEnvVar)
72 return labelSelector, nil
75 // FindResourceMapForCR returns the configMap, collectd Daemonset and list of Collectd Plugins
76 func FindResourceMapForCR(rc client.Client, reqLogger logr.Logger, ns string) (*ResourceMap, error) {
79 cmList := &corev1.ConfigMapList{}
80 opts := &client.ListOptions{}
81 rmap := &ResourceMap{}
83 // Select ConfigMaps with label
84 labelSelector, err := GetWatchLabels()
86 reqLogger.Error(err, "Failed to get watch labels, continuing with default label")
88 opts.SetLabelSelector(labelSelector)
91 err = rc.List(context.TODO(), opts, cmList)
96 if cmList.Items == nil || len(cmList.Items) == 0 {
97 return rmap, errors.NewNotFound(corev1.Resource("configmap"), "ConfigMap")
100 // Select DaemonSets with label
101 dsList := &appsv1.DaemonSetList{}
102 err = rc.List(context.TODO(), opts, dsList)
107 if dsList.Items == nil || len(dsList.Items) == 0 {
108 return rmap, errors.NewNotFound(corev1.Resource("daemonset"), "DaemonSet")
111 rmap.ConfigMap = &cmList.Items[0]
112 rmap.DaemonSet = &dsList.Items[0]
117 // GetCollectdPluginList returns the list of CollectdPlugin instances in the namespace ns
118 func GetCollectdPluginList(rc client.Client, ns string) (*onapv1alpha1.CollectdPluginList, error) {
119 // Get all collectd plugins in the current namespace to rebuild conf.
120 collectdPlugins := &onapv1alpha1.CollectdPluginList{}
121 cpOpts := &client.ListOptions{}
122 cpOpts.InNamespace(ns)
123 err := rc.List(context.TODO(), cpOpts, collectdPlugins)
127 return collectdPlugins, nil
130 // GetCollectdGlobal returns the CollectdGlobal instance in the namespace ns
131 func GetCollectdGlobal(rc client.Client, ns string) (*onapv1alpha1.CollectdGlobal, error) {
132 // Get the CollectdGlobal instance in current namespace to rebuild conf.
133 cgList := &onapv1alpha1.CollectdGlobalList{}
134 cpOpts := &client.ListOptions{}
135 cpOpts.InNamespace(ns)
136 err := rc.List(context.TODO(), cpOpts, cgList)
140 if cgList.Items == nil || len(cgList.Items) == 0 {
143 collectdGlobals := &cgList.Items[0]
144 return collectdGlobals, nil
147 // GetPodList returns the list of pods in the namespace ns
148 func GetPodList(rc client.Client, ns string) ([]string, error) {
150 podList := &corev1.PodList{}
151 opts := &client.ListOptions{}
152 // Select ConfigMaps with label
153 labelSelector, _ := GetWatchLabels()
154 opts.SetLabelSelector(labelSelector)
156 err := rc.List(context.TODO(), opts, podList)
161 if podList.Items == nil || len(podList.Items) == 0 {
165 for _, pod := range podList.Items {
166 pods = append(pods, pod.Name)
171 // RebuildCollectdConf Get all collectd plugins and reconstruct, compute Hash and check for changes
172 func RebuildCollectdConf(rc client.Client, ns string, isDelete bool, delPlugin string) (string, error) {
173 var collectdConf, collectdGlobalConf string
174 // Get the collectd global in the current namespace to rebuild conf.
175 cg, err := GetCollectdGlobal(rc, ns)
181 collectdGlobalConf += cg.Spec.GlobalOptions + "\n"
184 // Get all collectd plugins in the current namespace to rebuild conf.
185 cp, err := GetCollectdPluginList(rc, ns)
190 loadPlugin := make(map[string]string)
191 if *cpList != nil && len(*cpList) > 0 {
192 for _, cp := range *cpList {
193 // using CollectdPlugin to set global options. If CollectdGlobal CRD is defined do not check for this
194 if cp.Spec.PluginName == "global" {
196 collectdGlobalConf += cp.Spec.PluginConf + "\n"
199 loadPlugin[cp.Spec.PluginName] = cp.Spec.PluginConf
205 delete(loadPlugin, delPlugin)
207 collectdConf += collectdGlobalConf
210 for cpName, cpConf := range loadPlugin {
211 collectdConf += "LoadPlugin" + " " + cpName + "\n"
212 collectdConf += cpConf + "\n"
215 collectdConf += "#Last line (collectd requires ā\\nā at the last line)\n"
217 return collectdConf, nil