Ver Fonte

add check for promtail daemonset running

Alexander Belanger há 3 anos atrás
pai
commit
76c982e991

+ 10 - 0
internal/opa/config.yaml

@@ -107,6 +107,16 @@ porter_agent_loki_pod:
   policies:
   - path: "./policies/pod/running.rego"
     name: "pod.running"
+porter_agent_promtail_daemonset:
+  kind: "daemonset"
+  match:
+    namespace: porter-agent-system
+    labels:
+      app.kubernetes.io/instance: "porter-agent"
+      app.kubernetes.io/name: "promtail"
+  policies:
+  - path: "./policies/daemonset/running.rego"
+    name: "daemonset.running"
 certificates:
   kind: "crd_list"
   match:

+ 61 - 0
internal/opa/opa.go

@@ -36,6 +36,7 @@ const (
 	HelmRelease KubernetesBuiltInKind = "helm_release"
 	Pod         KubernetesBuiltInKind = "pod"
 	CRDList     KubernetesBuiltInKind = "crd_list"
+	Daemonset   KubernetesBuiltInKind = "daemonset"
 )
 
 type KubernetesOPAQueryCollection struct {
@@ -122,6 +123,8 @@ func (runner *KubernetesOPARunner) GetRecommendations(categories []string) ([]*O
 				currResults, err = runner.runPodQueries(name, queryCollection)
 			case CRDList:
 				currResults, err = runner.runCRDListQueries(name, queryCollection)
+			case Daemonset:
+				currResults, err = runner.runDaemonsetQueries(name, queryCollection)
 			default:
 				fmt.Printf("%s is not a supported query kind", queryCollection.Kind)
 				continue
@@ -315,6 +318,64 @@ func (runner *KubernetesOPARunner) runPodQueries(name string, collection Kuberne
 	return res, nil
 }
 
+func (runner *KubernetesOPARunner) runDaemonsetQueries(name string, collection KubernetesOPAQueryCollection) ([]*OPARecommenderQueryResult, error) {
+	res := make([]*OPARecommenderQueryResult, 0)
+
+	lselArr := make([]string, 0)
+
+	for k, v := range collection.Match.Labels {
+		lselArr = append(lselArr, fmt.Sprintf("%s=%s", k, v))
+	}
+
+	lsel := strings.Join(lselArr, ",")
+
+	daemonsets, err := runner.k8sAgent.Clientset.AppsV1().DaemonSets(collection.Match.Namespace).List(context.Background(), v1.ListOptions{
+		LabelSelector: lsel,
+	})
+
+	if err != nil {
+		return nil, err
+	}
+
+	for _, ds := range daemonsets.Items {
+		unstructuredDS, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&ds)
+
+		if err != nil {
+			return nil, err
+		}
+
+		for _, query := range collection.Queries {
+			results, err := query.Eval(
+				context.Background(),
+				rego.EvalInput(unstructuredDS),
+			)
+
+			if err != nil {
+				return nil, err
+			}
+
+			if len(results) == 1 {
+				rawQueryRes := &rawQueryResult{}
+
+				err = mapstructure.Decode(results[0].Expressions[0].Value, rawQueryRes)
+
+				if err != nil {
+					return nil, err
+				}
+
+				res = append(res, rawQueryResToRecommenderQueryResult(
+					rawQueryRes,
+					fmt.Sprintf("daemonset/%s/%s", ds.Namespace, ds.Name),
+					name,
+					collection,
+				))
+			}
+		}
+	}
+
+	return res, nil
+}
+
 func (runner *KubernetesOPARunner) runCRDListQueries(name string, collection KubernetesOPAQueryCollection) ([]*OPARecommenderQueryResult, error) {
 	res := make([]*OPARecommenderQueryResult, 0)
 

+ 25 - 0
internal/opa/policies/daemonset/running.rego

@@ -0,0 +1,25 @@
+package daemonset.running
+
+import future.keywords.contains
+import future.keywords.every
+import future.keywords.if
+import future.keywords.in
+
+POLICY_ID := "daemonset_running"
+
+POLICY_VERSION := "v0.0.1"
+
+POLICY_SEVERITY := "high"
+
+POLICY_TITLE := sprintf("Daemonset %s in namespace %s should have all replicas available", [input.metadata.name, input.metadata.namespace])
+
+POLICY_SUCCESS_MESSAGE := sprintf("Success: daemonset has %d / %d pods running", [input.status.numberReady, input.status.desiredNumberScheduled])
+
+allow if {
+	input.status.numberReady == input.status.desiredNumberScheduled
+}
+
+FAILURE_MESSAGE contains msg1 if {
+	input.status.numberReady != input.status.desiredNumberScheduled
+	msg1 := sprintf("Daemonset %s only has %d out of %d pods running", [input.metadata.name, input.status.numberReady, input.status.desiredNumberScheduled])
+}