From 83d174846d1d85fe5f5c2b95b317282d79cf6a52 Mon Sep 17 00:00:00 2001
From: Kaustav Majumder <kaustav.majumder@ibm.com>
Date: Tue, 20 Feb 2024 11:36:07 +0530
Subject: [PATCH] Added k8smetrics service monitor

Signed-off-by: Kaustav Majumder <kaustav.majumder@ibm.com>
---
 .../ocsinitialization_controller.go           | 29 ++++++++
 templates/k8smetricsservicemonitor.go         | 70 +++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 templates/k8smetricsservicemonitor.go

diff --git a/controllers/ocsinitialization/ocsinitialization_controller.go b/controllers/ocsinitialization/ocsinitialization_controller.go
index 36956fbcff..88596c592a 100644
--- a/controllers/ocsinitialization/ocsinitialization_controller.go
+++ b/controllers/ocsinitialization/ocsinitialization_controller.go
@@ -212,6 +212,12 @@ func (r *OCSInitializationReconciler) Reconcile(ctx context.Context, request rec
 		return reconcile.Result{}, err
 	}
 
+	err = r.reconcileK8sMetricsServiceMonitor(instance)
+	if err != nil {
+		r.Log.Error(err, "Failed to ensure k8sMetricsService Monitor")
+		return reconcile.Result{}, err
+	}
+
 	reason := ocsv1.ReconcileCompleted
 	message := ocsv1.ReconcileCompletedMessage
 	util.SetCompleteCondition(&instance.Status.Conditions, reason, message)
@@ -594,3 +600,26 @@ func (r *OCSInitializationReconciler) reconcilePrometheusProxyNetworkPolicy(init
 	r.Log.Info("Prometheus proxy network policy creation succeeded", "Name", promethuesProxyNetworkPolicy.Name)
 	return nil
 }
+
+func (r *OCSInitializationReconciler) reconcileK8sMetricsServiceMonitor(initialData *ocsv1.OCSInitialization) error {
+	var err error
+
+	k8sMetricsServiceMonitor := &promv1.ServiceMonitor{}
+	k8sMetricsServiceMonitor.Name = ""
+	k8sMetricsServiceMonitor.Namespace = initialData.Namespace
+
+	_, err = ctrl.CreateOrUpdate(r.ctx, r.Client, k8sMetricsServiceMonitor, func() error {
+		if err := ctrl.SetControllerReference(initialData, k8sMetricsServiceMonitor, r.Scheme); err != nil {
+			return err
+		}
+		k8sMetricsServiceMonitor.Spec = templates.K8sMetricsServiceMonitorTemplate.DeepCopy().Spec
+		return nil
+	})
+	if err != nil {
+		r.Log.Error(err, "Failed to create/update K8s Metrics Service Monitor")
+		return err
+	}
+	r.Log.Info("K8s Metrics Service Monitor creation succeeded", "Name", k8sMetricsServiceMonitor.Name)
+	return nil
+
+}
diff --git a/templates/k8smetricsservicemonitor.go b/templates/k8smetricsservicemonitor.go
new file mode 100644
index 0000000000..93587e8499
--- /dev/null
+++ b/templates/k8smetricsservicemonitor.go
@@ -0,0 +1,70 @@
+package templates
+
+import (
+	promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+var params = map[string][]string{
+	"match[]": {
+		"{__name__='kube_node_status_condition'}",
+		"{__name__='kube_persistentvolume_info'}",
+		"{__name__='kube_storageclass_info'}",
+		"{__name__='kube_persistentvolumeclaim_info'}",
+		"{__name__='kube_deployment_spec_replicas'}",
+		"{__name__='kube_pod_status_phase'}",
+		"{__name__='kubelet_volume_stats_capacity_bytes'}",
+		"{__name__='kubelet_volume_stats_used_bytes'}",
+		"{__name__='node_disk_read_time_seconds_total'}",
+		"{__name__='node_disk_write_time_seconds_total'}",
+		"{__name__='node_disk_reads_completed_total'}",
+		"{__name__='node_disk_writes_completed_total'}",
+	},
+}
+
+var K8sMetricsServiceMonitorTemplate = promv1.ServiceMonitor{
+	Spec: promv1.ServiceMonitorSpec{
+		Endpoints: []promv1.Endpoint{
+			{
+				Port:          "web",
+				Path:          "/federate",
+				Scheme:        "https",
+				ScrapeTimeout: "1m",
+				Interval:      "2m",
+				HonorLabels:   true,
+				MetricRelabelConfigs: []*promv1.RelabelConfig{
+					{
+						Action: "labeldrop",
+						Regex:  "prometheus_replica",
+					},
+				},
+				RelabelConfigs: []*promv1.RelabelConfig{
+					{
+						Action:      "replace",
+						Regex:       "prometheus-k8s-.*",
+						Replacement: "",
+						SourceLabels: []promv1.LabelName{
+							"pod",
+						},
+						TargetLabel: "pod",
+					},
+				},
+				TLSConfig: &promv1.TLSConfig{
+					SafeTLSConfig: promv1.SafeTLSConfig{
+						InsecureSkipVerify: true,
+					},
+				},
+				Params:          params,
+				BearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token",
+			},
+		},
+		NamespaceSelector: promv1.NamespaceSelector{
+			MatchNames: []string{"openshift-monitoring"},
+		},
+		Selector: metav1.LabelSelector{
+			MatchLabels: map[string]string{
+				"app.kubernetes.io/component": "prometheus",
+			},
+		},
+	},
+}