From ba052559cf7acf7deaf4c045a94723a128956e97 Mon Sep 17 00:00:00 2001
From: paulfantom <pawel@krupa.net.pl>
Date: Thu, 14 Jan 2021 15:56:55 +0100
Subject: [PATCH] jsonnet: separate mixins into components

Signed-off-by: paulfantom <pawel@krupa.net.pl>
---
 .../alertmanager/alertmanager.libsonnet       | 28 +++++++++
 .../kube-prometheus/kube-prometheus.libsonnet | 41 +++++++++----
 .../kube-state-metrics.libsonnet              | 31 +++++++++-
 .../mixins/monitoring-mixins.libsonnet        | 42 -------------
 .../node-exporter/node-exporter.libsonnet     | 53 +++++++++++++----
 .../prometheus-operator.libsonnet             | 29 +++++++++
 .../prometheus/prometheus.libsonnet           | 59 +++++++++++--------
 7 files changed, 191 insertions(+), 92 deletions(-)

diff --git a/jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet b/jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet
index 2fee6e1e..452a2cc2 100644
--- a/jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet
+++ b/jsonnet/kube-prometheus/alertmanager/alertmanager.libsonnet
@@ -55,6 +55,14 @@ local defaults = {
     ],
   },
   replicas: 3,
+  mixin: {
+    ruleLabels: {},
+    _config: {
+      alertmanagerName: '{{ $labels.namespace }}/{{ $labels.pod}}',
+      alertmanagerClusterLabels: 'namespace,service',
+      alertmanagerSelector: 'job="alertmanager-' + defaults.name + '",namespace="' + defaults.namespace + '"',
+    },
+  },
 };
 
 
@@ -63,6 +71,26 @@ function(params) {
   config:: defaults + params,
   // Safety check
   assert std.isObject(am.config.resources),
+  assert std.isObject(am.config.mixin._config),
+
+  mixin:: (import 'github.com/prometheus/alertmanager/doc/alertmanager-mixin/mixin.libsonnet') {
+    _config+:: am.config.mixin._config,
+  },
+
+  prometheusRule: {
+    apiVersion: 'monitoring.coreos.com/v1',
+    kind: 'PrometheusRule',
+    metadata: {
+      labels: am.config.commonLabels + am.config.mixin.ruleLabels,
+      name: am.config.name + '-rules',
+      namespace: am.config.namespace,
+    },
+    spec: {
+      local r = if std.objectHasAll(am.mixin, 'prometheusRules') then am.mixin.prometheusRules else {},
+      local a = if std.objectHasAll(am.mixin, 'prometheusAlerts') then am.mixin.prometheusAlerts else {},
+      groups: a + r,
+    },
+  },
 
   secret: {
     apiVersion: 'v1',
diff --git a/jsonnet/kube-prometheus/kube-prometheus.libsonnet b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
index e97f07f1..6688f023 100644
--- a/jsonnet/kube-prometheus/kube-prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
@@ -5,6 +5,7 @@ local nodeExporter = import './node-exporter/node-exporter.libsonnet';
 local prometheusAdapter = import './prometheus-adapter/prometheus-adapter.libsonnet';
 local prometheusOperator = import './prometheus-operator/prometheus-operator.libsonnet';
 local prometheus = import './prometheus/prometheus.libsonnet';
+local prometheusOperator = import './prometheus-operator/prometheus-operator.libsonnet';
 
 local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
 
@@ -15,6 +16,9 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     namespace: $._config.namespace,
     version: '0.21.0',
     image: 'quay.io/prometheus/alertmanager:v0.21.0',
+    mixin+: {
+      ruleLabels: $._config.ruleLabels,
+    },
   }),
   blackboxExporter: blackboxExporter({
     namespace: $._config.namespace,
@@ -25,11 +29,17 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     namespace: $._config.namespace,
     version: '1.9.7',
     image: 'quay.io/coreos/kube-state-metrics:v1.9.7',
+    mixin+: {
+      ruleLabels: $._config.ruleLabels,
+    },
   }),
   nodeExporter: nodeExporter({
     namespace: $._config.namespace,
     version: '1.0.1',
     image: 'quay.io/prometheus/node-exporter:v1.0.1',
+    mixin+: {
+      ruleLabels: $._config.ruleLabels,
+    },
   }),
   prometheus: prometheus({
     namespace: $._config.namespace,
@@ -37,7 +47,9 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     image: 'quay.io/prometheus/prometheus:v2.24.0',
     name: $._config.prometheusName,
     alertmanagerName: $._config.alertmanagerName,
-    rules: $.allRules,
+    mixin+: {
+      ruleLabels: $._config.ruleLabels,
+    },
   }),
   prometheusAdapter: prometheusAdapter({
     namespace: $._config.namespace,
@@ -53,25 +65,26 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     commonLabels+: {
       'app.kubernetes.io/part-of': 'kube-prometheus',
     },
+    mixin+: {
+      ruleLabels: $._config.ruleLabels,
+    },
   }),
   mixins+:: monitoringMixins({
     namespace: $._config.namespace,
-    alertmanagerName: $._config.alertmanagerName,
-    prometheusName: $._config.prometheusName,
   }),
 
   // FIXME(paulfantom) Remove this variable by moving each mixin to its own component
   // Example: node_exporter mixin could be added in ./node-exporter/node-exporter.libsonnet
   allRules::
-    $.mixins.nodeExporter.prometheusRules +
+    //$.mixins.nodeExporter.prometheusRules +
     $.mixins.kubernetes.prometheusRules +
     $.mixins.base.prometheusRules +
-    $.mixins.kubeStateMetrics.prometheusAlerts +
-    $.mixins.nodeExporter.prometheusAlerts +
-    $.mixins.alertmanager.prometheusAlerts +
-    $.mixins.prometheusOperator.prometheusAlerts +
+    //$.mixins.kubeStateMetrics.prometheusAlerts +
+    //$.mixins.nodeExporter.prometheusAlerts +
+    //$.mixins.alertmanager.prometheusAlerts +
+    //$.mixins.prometheusOperator.prometheusAlerts +
     $.mixins.kubernetes.prometheusAlerts +
-    $.mixins.prometheus.prometheusAlerts +
+    //$.mixins.prometheus.prometheusAlerts +
     $.mixins.base.prometheusAlerts,
 
   kubePrometheus+:: {
@@ -118,6 +131,10 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
     namespace: 'default',
     prometheusName: 'k8s',
     alertmanagerName: 'main',
+    ruleLabels: {
+      role: 'alert-rules',
+      prometheus: $._config.prometheusName,
+    },
 
     versions+:: { grafana: '7.3.5' },
 
@@ -131,9 +148,9 @@ local monitoringMixins = import './mixins/monitoring-mixins.libsonnet';
       // FIXME(paulfantom): Same as with rules and alerts.
       // This should be gathering all dashboards from components without having to enumerate all dashboards.
       dashboards:
-        $.mixins.nodeExporter.grafanaDashboards +
-        $.mixins.kubernetes.grafanaDashboards +
-        $.mixins.prometheus.grafanaDashboards,
+        //$.mixins.nodeExporter.grafanaDashboards +
+        $.mixins.kubernetes.grafanaDashboards,
+      //$.mixins.prometheus.grafanaDashboards,
     },
   },
 }
diff --git a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet b/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
index 037d023b..c3236589 100644
--- a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
+++ b/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
@@ -2,6 +2,7 @@ local krp = (import '../kube-rbac-proxy/container.libsonnet');
 
 local defaults = {
   local defaults = self,
+  name: 'kube-state-metrics',
   namespace: error 'must provide namespace',
   version: error 'must provide version',
   image: error 'must provide version',
@@ -13,7 +14,7 @@ local defaults = {
   scrapeInterval: '30s',
   scrapeTimeout: '30s',
   commonLabels:: {
-    'app.kubernetes.io/name': 'kube-state-metrics',
+    'app.kubernetes.io/name': defaults.name,
     'app.kubernetes.io/version': defaults.version,
     'app.kubernetes.io/component': 'exporter',
     'app.kubernetes.io/part-of': 'kube-prometheus',
@@ -23,6 +24,12 @@ local defaults = {
     for labelName in std.objectFields(defaults.commonLabels)
     if !std.setMember(labelName, ['app.kubernetes.io/version'])
   },
+  mixin: {
+    ruleLabels: {},
+    _config: {
+      kubeStateMetricsSelector: 'job="' + defaults.name + '"',
+    },
+  },
 };
 
 function(params) (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics/kube-state-metrics.libsonnet') {
@@ -30,14 +37,34 @@ function(params) (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-
   config:: defaults + params,
   // Safety check
   assert std.isObject(ksm.config.resources),
+  assert std.isObject(ksm.config.mixin._config),
 
-  name:: 'kube-state-metrics',
+  name:: ksm.config.name,
   namespace:: ksm.config.namespace,
   version:: ksm.config.version,
   image:: ksm.config.image,
   commonLabels:: ksm.config.commonLabels,
   podLabels:: ksm.config.selectorLabels,
 
+  mixin:: (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics-mixin/mixin.libsonnet') {
+    _config+:: ksm.config.mixin._config,
+  },
+
+  prometheusRule: {
+    apiVersion: 'monitoring.coreos.com/v1',
+    kind: 'PrometheusRule',
+    metadata: {
+      labels: ksm.config.commonLabels + ksm.config.mixin.ruleLabels,
+      name: ksm.config.name + '-rules',
+      namespace: ksm.config.namespace,
+    },
+    spec: {
+      local r = if std.objectHasAll(ksm.mixin, 'prometheusRules') then ksm.mixin.prometheusRules else {},
+      local a = if std.objectHasAll(ksm.mixin, 'prometheusAlerts') then ksm.mixin.prometheusAlerts else {},
+      groups: a + r,
+    },
+  },
+
   service+: {
     spec+: {
       ports: [
diff --git a/jsonnet/kube-prometheus/mixins/monitoring-mixins.libsonnet b/jsonnet/kube-prometheus/mixins/monitoring-mixins.libsonnet
index bb035837..95b88db6 100644
--- a/jsonnet/kube-prometheus/mixins/monitoring-mixins.libsonnet
+++ b/jsonnet/kube-prometheus/mixins/monitoring-mixins.libsonnet
@@ -1,7 +1,5 @@
 local defaults = {
   namespace: error 'must provide namespace',
-  prometheusName: error 'must provide Prometheus resource name',
-  alertmanagerName: error 'must provide Alertmanager resource name',
 };
 
 function(params) {
@@ -34,44 +32,4 @@ function(params) {
         hostNetworkInterfaceSelector: 'device!~"veth.+"',
       },
     },
-
-  kubeStateMetrics:
-    (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics-mixin/mixin.libsonnet') {
-      _config+:: {
-        kubeStateMetricsSelector: 'job="kube-state-metrics"',
-      },
-    },
-
-  prometheusOperator:
-    (import 'github.com/prometheus-operator/prometheus-operator/jsonnet/mixin/mixin.libsonnet') {
-      _config+:: {
-        prometheusOperatorSelector: 'job="prometheus-operator",namespace="' + m.config.namespace + '"',
-      },
-    },
-
-  prometheus:
-    (import 'github.com/prometheus/prometheus/documentation/prometheus-mixin/mixin.libsonnet') {
-      _config+:: {
-        prometheusSelector: 'job="prometheus-' + m.config.prometheusName + '",namespace="' + m.config.namespace + '"',
-        prometheusName: '{{$labels.namespace}}/{{$labels.pod}}',
-      },
-    },
-
-  alertmanager:
-    (import 'github.com/prometheus/alertmanager/doc/alertmanager-mixin/mixin.libsonnet') {
-      _config+:: {
-        alertmanagerName: '{{ $labels.namespace }}/{{ $labels.pod}}',
-        alertmanagerClusterLabels: 'namespace,service',
-        alertmanagerSelector: 'job="alertmanager-' + m.config.alertmanagerName + '",namespace="' + m.config.namespace + '"',
-      },
-    },
-
-  nodeExporter:
-    (import 'github.com/prometheus/node_exporter/docs/node-mixin/mixin.libsonnet') {
-      _config+:: {
-        nodeExporterSelector: 'job="node-exporter"',
-        fsSpaceFillingUpCriticalThreshold: 15,
-        diskDeviceSelector: 'device=~"mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|dasd.+"',
-      },
-    },
 }
diff --git a/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet b/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet
index bb16fc41..1c4321b1 100644
--- a/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet
+++ b/jsonnet/kube-prometheus/node-exporter/node-exporter.libsonnet
@@ -2,6 +2,7 @@ local krp = (import '../kube-rbac-proxy/container.libsonnet');
 
 local defaults = {
   local defaults = self,
+  name: 'node-exporter',
   namespace: error 'must provide namespace',
   version: error 'must provide version',
   image: error 'must provide version',
@@ -12,7 +13,7 @@ local defaults = {
   listenAddress: '127.0.0.1',
   port: 9100,
   commonLabels:: {
-    'app.kubernetes.io/name': 'node-exporter',
+    'app.kubernetes.io/name': defaults.name,
     'app.kubernetes.io/version': defaults.version,
     'app.kubernetes.io/component': 'exporter',
     'app.kubernetes.io/part-of': 'kube-prometheus',
@@ -22,6 +23,14 @@ local defaults = {
     for labelName in std.objectFields(defaults.commonLabels)
     if !std.setMember(labelName, ['app.kubernetes.io/version'])
   },
+  mixin: {
+    ruleLabels: {},
+    _config: {
+      nodeExporterSelector: 'job="' + defaults.name + '"',
+      fsSpaceFillingUpCriticalThreshold: 15,
+      diskDeviceSelector: 'device=~"mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|dasd.+"',
+    },
+  },
 };
 
 
@@ -30,22 +39,42 @@ function(params) {
   config:: defaults + params,
   // Safety check
   assert std.isObject(ne.config.resources),
+  assert std.isObject(ne.config.mixin._config),
+
+  mixin:: (import 'github.com/prometheus/node_exporter/docs/node-mixin/mixin.libsonnet') {
+    _config+:: ne.config.mixin._config,
+  },
+
+  prometheusRule: {
+    apiVersion: 'monitoring.coreos.com/v1',
+    kind: 'PrometheusRule',
+    metadata: {
+      labels: ne.config.commonLabels + ne.config.mixin.ruleLabels,
+      name: ne.config.name + '-rules',
+      namespace: ne.config.namespace,
+    },
+    spec: {
+      local r = if std.objectHasAll(ne.mixin, 'prometheusRules') then ne.mixin.prometheusRules else {},
+      local a = if std.objectHasAll(ne.mixin, 'prometheusAlerts') then ne.mixin.prometheusAlerts else {},
+      groups: a + r,
+    },
+  },
 
   clusterRoleBinding: {
     apiVersion: 'rbac.authorization.k8s.io/v1',
     kind: 'ClusterRoleBinding',
     metadata: {
-      name: 'node-exporter',
+      name: ne.config.name,
       labels: ne.config.commonLabels,
     },
     roleRef: {
       apiGroup: 'rbac.authorization.k8s.io',
       kind: 'ClusterRole',
-      name: 'node-exporter',
+      name: ne.config.name,
     },
     subjects: [{
       kind: 'ServiceAccount',
-      name: 'node-exporter',
+      name: ne.config.name,
       namespace: ne.config.namespace,
     }],
   },
@@ -54,7 +83,7 @@ function(params) {
     apiVersion: 'rbac.authorization.k8s.io/v1',
     kind: 'ClusterRole',
     metadata: {
-      name: 'node-exporter',
+      name: ne.config.name,
       labels: ne.config.commonLabels,
     },
     rules: [
@@ -75,7 +104,7 @@ function(params) {
     apiVersion: 'v1',
     kind: 'ServiceAccount',
     metadata: {
-      name: 'node-exporter',
+      name: ne.config.name,
       namespace: ne.config.namespace,
       labels: ne.config.commonLabels,
     },
@@ -85,7 +114,7 @@ function(params) {
     apiVersion: 'v1',
     kind: 'Service',
     metadata: {
-      name: 'node-exporter',
+      name: ne.config.name,
       namespace: ne.config.namespace,
       labels: ne.config.commonLabels,
     },
@@ -102,7 +131,7 @@ function(params) {
     apiVersion: 'monitoring.coreos.com/v1',
     kind: 'ServiceMonitor',
     metadata: {
-      name: 'node-exporter',
+      name: ne.config.name,
       namespace: ne.config.namespace,
       labels: ne.config.commonLabels,
     },
@@ -134,7 +163,7 @@ function(params) {
 
   daemonset:
     local nodeExporter = {
-      name: 'node-exporter',
+      name: ne.config.name,
       image: ne.config.image,
       args: [
         '--web.listen-address=' + std.join(':', [ne.config.listenAddress, std.toString(ne.config.port)]),
@@ -177,7 +206,7 @@ function(params) {
       apiVersion: 'apps/v1',
       kind: 'DaemonSet',
       metadata: {
-        name: 'node-exporter',
+        name: ne.config.name,
         namespace: ne.config.namespace,
         labels: ne.config.commonLabels,
       },
@@ -199,7 +228,7 @@ function(params) {
               { name: 'sys', hostPath: { path: '/sys' } },
               { name: 'root', hostPath: { path: '/' } },
             ],
-            serviceAccountName: 'node-exporter',
+            serviceAccountName: ne.config.name,
             securityContext: {
               runAsUser: 65534,
               runAsNonRoot: true,
@@ -210,4 +239,6 @@ function(params) {
         },
       },
     },
+
+
 }
diff --git a/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet b/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
index 26940c61..b1497416 100644
--- a/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
+++ b/jsonnet/kube-prometheus/prometheus-operator/prometheus-operator.libsonnet
@@ -23,6 +23,15 @@ local defaults = {
     for labelName in std.objectFields(defaults.commonLabels)
     if !std.setMember(labelName, ['app.kubernetes.io/version'])
   },
+  mixin: {
+    ruleLabels: {
+      role: 'alert-rules',
+      prometheus: defaults.name,
+    },
+    _config: {
+      prometheusOperatorSelector: 'job="prometheus-operator",namespace="' + defaults.namespace + '"',
+    },
+  },
 };
 
 function(params)
@@ -31,6 +40,26 @@ function(params)
   assert std.isObject(config.resources);
 
   prometheusOperator(config) {
+    local po = self,
+    mixin:: (import 'github.com/prometheus-operator/prometheus-operator/jsonnet/mixin/mixin.libsonnet') {
+      _config+:: config.mixin._config,
+    },
+
+    prometheusRule: {
+      apiVersion: 'monitoring.coreos.com/v1',
+      kind: 'PrometheusRule',
+      metadata: {
+        labels: config.commonLabels + config.mixin.ruleLabels,
+        name: config.name + '-rules',
+        namespace: config.namespace,
+      },
+      spec: {
+        local r = if std.objectHasAll(po.mixin, 'prometheusRules') then po.mixin.prometheusRules else {},
+        local a = if std.objectHasAll(po.mixin, 'prometheusAlerts') then po.mixin.prometheusAlerts else {},
+        groups: a + r,
+      },
+    },
+
     service+: {
       spec+: {
         ports: [
diff --git a/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet b/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet
index e1b66923..1673c9e7 100644
--- a/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/prometheus/prometheus.libsonnet
@@ -13,9 +13,6 @@ local defaults = {
   alertmanagerName: error 'must provide alertmanagerName',
   namespaces: ['default', 'kube-system', defaults.namespace],
   replicas: 2,
-  rules: {
-    groups: [],
-  },
   commonLabels:: {
     'app.kubernetes.io/name': 'prometheus',
     'app.kubernetes.io/version': defaults.version,
@@ -27,6 +24,19 @@ local defaults = {
     for labelName in std.objectFields(defaults.commonLabels)
     if !std.setMember(labelName, ['app.kubernetes.io/version'])
   } + { prometheus: defaults.name },
+  ruleSelector: {
+    matchLabels: defaults.mixin.ruleLabels,
+  },
+  mixin: {
+    ruleLabels: {
+      role: 'alert-rules',
+      prometheus: defaults.name,
+    },
+    _config: {
+      prometheusSelector: 'job="prometheus-' + defaults.name + '",namespace="' + defaults.namespace + '"',
+      prometheusName: '{{$labels.namespace}}/{{$labels.pod}}',
+    },
+  },
 };
 
 
@@ -35,6 +45,26 @@ function(params) {
   config:: defaults + params,
   // Safety check
   assert std.isObject(p.config.resources),
+  assert std.isObject(p.config.mixin._config),
+
+  mixin:: (import 'github.com/prometheus/prometheus/documentation/prometheus-mixin/mixin.libsonnet') {
+    _config+:: p.config.mixin._config,
+  },
+
+  prometheusRule: {
+    apiVersion: 'monitoring.coreos.com/v1',
+    kind: 'PrometheusRule',
+    metadata: {
+      labels: p.config.commonLabels + p.config.mixin.ruleLabels,
+      name: p.config.name + '-rules',
+      namespace: p.config.namespace,
+    },
+    spec: {
+      local r = if std.objectHasAll(p.mixin, 'prometheusRules') then p.mixin.prometheusRules else {},
+      local a = if std.objectHasAll(p.mixin, 'prometheusAlerts') then p.mixin.prometheusAlerts else {},
+      groups: a + r,
+    },
+  },
 
   serviceAccount: {
     apiVersion: 'v1',
@@ -63,22 +93,6 @@ function(params) {
     },
   },
 
-  rules: {
-    apiVersion: 'monitoring.coreos.com/v1',
-    kind: 'PrometheusRule',
-    metadata: {
-      labels: {
-        prometheus: p.config.name,
-        role: 'alert-rules',
-      } + p.config.commonLabels,
-      name: 'prometheus-' + p.config.name + '-rules',
-      namespace: p.config.namespace,
-    },
-    spec: {
-      groups: p.config.rules.groups,
-    },
-  },
-
   roleBindingSpecificNamespaces:
     local newSpecificRoleBinding(namespace) = {
       apiVersion: 'rbac.authorization.k8s.io/v1',
@@ -230,12 +244,7 @@ function(params) {
       podMonitorNamespaceSelector: {},
       probeNamespaceSelector: {},
       nodeSelector: { 'kubernetes.io/os': 'linux' },
-      ruleSelector: {
-        matchLabels: {
-          role: 'alert-rules',
-          prometheus: p.config.name,
-        },
-      },
+      ruleSelector: p.config.ruleSelector,
       resources: p.config.resources,
       alerting: {
         alertmanagers: [{
-- 
GitLab