Browse Source

[feature] added Prometheus Status metric for the PushSecret objects (#4489)

* [feature] added Prometheus Status metric for the PushSecret objects

Signed-off-by: Nikolai Shmatenkov <nshmatenkov@allegion.com>

* [feature] updated documentation

Signed-off-by: Nikolai Shmatenkov <nshmatenkov@allegion.com>

* Update docs/api/metrics.md

Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>

---------

Signed-off-by: Nikolai Shmatenkov <nshmatenkov@allegion.com>
Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Co-authored-by: Nikolai Shmatenkov <nshmatenkov@allegion.com>
Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
MrImpossibru 1 year ago
parent
commit
17a809a63e

+ 6 - 0
docs/api/metrics.md

@@ -26,6 +26,12 @@ The Operator has [the controller-runtime metrics inherited from kubebuilder](htt
 | `externalsecret_status_condition`              | Gauge     | The status condition of a specific External Secret                                                                                                                                                                      |
 | `externalsecret_reconcile_duration`            | Gauge     | The duration time to reconcile the External Secret                                                                                                                                                                      |
 
+## Push Secret Metrics
+| Name                                    | Type  | Description                                             |
+|-----------------------------------------|-------|---------------------------------------------------------|
+| `pushsecret_status_condition`   | Gauge | The status condition of a specific Push Secret |
+| `pushsecret_reconcile_duration` | Gauge | The duration time to reconcile the Push Secret |
+
 ## Cluster Secret Store Metrics
 | Name                                    | Type  | Description                                             |
 |-----------------------------------------|-------|---------------------------------------------------------|

+ 54 - 1
pkg/controllers/pushsecret/psmetrics/psmetrics.go

@@ -16,14 +16,17 @@ package psmetrics
 
 import (
 	"github.com/prometheus/client_golang/prometheus"
+	v1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/metrics"
 
+	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
 	ctrlmetrics "github.com/external-secrets/external-secrets/pkg/controllers/metrics"
 )
 
 const (
 	PushSecretSubsystem            = "pushsecret"
 	PushSecretReconcileDurationKey = "reconcile_duration"
+	PushSecretStatusConditionKey   = "status_condition"
 )
 
 var gaugeVecMetrics = map[string]*prometheus.GaugeVec{}
@@ -31,19 +34,69 @@ var gaugeVecMetrics = map[string]*prometheus.GaugeVec{}
 // SetUpMetrics is called at the root to set-up the metric logic using the
 // config flags provided.
 func SetUpMetrics() {
+	pushSecretCondition := prometheus.NewGaugeVec(prometheus.GaugeOpts{
+		Subsystem: PushSecretSubsystem,
+		Name:      PushSecretStatusConditionKey,
+		Help:      "The status condition of a specific Push Secret",
+	}, ctrlmetrics.ConditionMetricLabelNames)
+
 	pushSecretReconcileDuration := prometheus.NewGaugeVec(prometheus.GaugeOpts{
 		Subsystem: PushSecretSubsystem,
 		Name:      PushSecretReconcileDurationKey,
 		Help:      "The duration time to reconcile the Push Secret",
 	}, ctrlmetrics.NonConditionMetricLabelNames)
 
-	metrics.Registry.MustRegister(pushSecretReconcileDuration)
+	metrics.Registry.MustRegister(pushSecretReconcileDuration, pushSecretCondition)
 
 	gaugeVecMetrics = map[string]*prometheus.GaugeVec{
+		PushSecretStatusConditionKey:   pushSecretCondition,
 		PushSecretReconcileDurationKey: pushSecretReconcileDuration,
 	}
 }
 
+func UpdatePushSecretCondition(ps *esapi.PushSecret, condition *esapi.PushSecretStatusCondition, value float64) {
+	psInfo := make(map[string]string)
+	psInfo["name"] = ps.Name
+	psInfo["namespace"] = ps.Namespace
+	for k, v := range ps.Labels {
+		psInfo[k] = v
+	}
+	conditionLabels := ctrlmetrics.RefineConditionMetricLabels(psInfo)
+	pushSecretCondition := GetGaugeVec(PushSecretStatusConditionKey)
+
+	switch condition.Type {
+	case esapi.PushSecretReady:
+		// Toggle opposite Status to 0
+		switch condition.Status {
+		case v1.ConditionFalse:
+			pushSecretCondition.With(ctrlmetrics.RefineLabels(conditionLabels,
+				map[string]string{
+					"condition": string(esapi.PushSecretReady),
+					"status":    string(v1.ConditionTrue),
+				})).Set(0)
+		case v1.ConditionTrue:
+			pushSecretCondition.With(ctrlmetrics.RefineLabels(conditionLabels,
+				map[string]string{
+					"condition": string(esapi.PushSecretReady),
+					"status":    string(v1.ConditionFalse),
+				})).Set(0)
+		case v1.ConditionUnknown:
+			break
+		default:
+			break
+		}
+
+	default:
+		break
+	}
+
+	pushSecretCondition.With(ctrlmetrics.RefineLabels(conditionLabels,
+		map[string]string{
+			"condition": string(condition.Type),
+			"status":    string(condition.Status),
+		})).Set(value)
+}
+
 func GetGaugeVec(key string) *prometheus.GaugeVec {
 	return gaugeVecMetrics[key]
 }

+ 7 - 0
pkg/controllers/pushsecret/pushsecret_controller.go

@@ -517,6 +517,7 @@ func setPushSecretCondition(ps *esapi.PushSecret, condition esapi.PushSecretStat
 	currentCond := getPushSecretCondition(ps.Status, condition.Type)
 	if currentCond != nil && currentCond.Status == condition.Status &&
 		currentCond.Reason == condition.Reason && currentCond.Message == condition.Message {
+		psmetrics.UpdatePushSecretCondition(ps, &condition, 1.0)
 		return
 	}
 
@@ -526,6 +527,12 @@ func setPushSecretCondition(ps *esapi.PushSecret, condition esapi.PushSecretStat
 	}
 
 	ps.Status.Conditions = append(filterOutCondition(ps.Status.Conditions, condition.Type), condition)
+
+	if currentCond != nil {
+		psmetrics.UpdatePushSecretCondition(ps, currentCond, 0.0)
+	}
+
+	psmetrics.UpdatePushSecretCondition(ps, &condition, 1.0)
 }
 
 // filterOutCondition returns an empty set of conditions with the provided type.