diff --git a/docs/secret-metrics.md b/docs/secret-metrics.md index ca5c3c71c3..ac0d6904ac 100644 --- a/docs/secret-metrics.md +++ b/docs/secret-metrics.md @@ -8,3 +8,4 @@ | kube_secret_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](./cli-arguments.md) | `secret`=<secret-name>
`namespace`=<secret-namespace>
`label_SECRET_LABEL`=<SECRET_LABEL> | STABLE | | kube_secret_created | Gauge | | `secret`=<secret-name>
`namespace`=<secret-namespace> | STABLE | | kube_secret_metadata_resource_version | Gauge | | `secret`=<secret-name>
`namespace`=<secret-namespace> | EXPERIMENTAL | +| kube_secret_owner | Gauge | | `secret`=<secret-name>
`namespace`=<secret-namespace>
`owner_kind`=<owner kind>
`owner_name`=<owner name>
`owner_is_controller`=<whether owner is controller> | EXPERIMENTAL | diff --git a/internal/store/secret.go b/internal/store/secret.go index a989fbbe6f..79b9f7afae 100644 --- a/internal/store/secret.go +++ b/internal/store/secret.go @@ -18,6 +18,7 @@ package store import ( "context" + "strconv" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -153,6 +154,52 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene } }), ), + *generator.NewFamilyGeneratorWithStability( + "kube_secret_owner", + "Information about the Secret's owner.", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapSecretFunc(func(j *v1.Secret) *metric.Family { + labelKeys := []string{"owner_kind", "owner_name", "owner_is_controller"} + + owners := j.GetOwnerReferences() + + if len(owners) == 0 { + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: []string{"", "", ""}, + Value: 1, + }, + }, + } + } + + ms := make([]*metric.Metric, len(owners)) + + for i, owner := range owners { + if owner.Controller != nil { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, strconv.FormatBool(*owner.Controller)}, + Value: 1, + } + } else { + ms[i] = &metric.Metric{ + LabelKeys: labelKeys, + LabelValues: []string{owner.Kind, owner.Name, "false"}, + Value: 1, + } + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ), } } diff --git a/internal/store/secret_test.go b/internal/store/secret_test.go index f518a7d852..67d651236e 100644 --- a/internal/store/secret_test.go +++ b/internal/store/secret_test.go @@ -26,6 +26,7 @@ import ( ) func TestSecretStore(t *testing.T) { + var test = true startTime := 1501569018 metav1StartTime := metav1.Unix(int64(startTime), 0) cases := []generateMetricsTestCase{ @@ -43,17 +44,20 @@ func TestSecretStore(t *testing.T) { # HELP kube_secret_info [STABLE] Information about secret. # HELP kube_secret_labels [STABLE] Kubernetes labels converted to Prometheus labels. # HELP kube_secret_metadata_resource_version Resource version representing a specific version of secret. + # HELP kube_secret_owner Information about the Secret's owner. # HELP kube_secret_type [STABLE] Type about secret. # TYPE kube_secret_created gauge # TYPE kube_secret_info gauge # TYPE kube_secret_labels gauge # TYPE kube_secret_metadata_resource_version gauge + # TYPE kube_secret_owner gauge # TYPE kube_secret_type gauge kube_secret_info{namespace="ns1",secret="secret1"} 1 + kube_secret_owner{namespace="ns1",owner_is_controller="",owner_kind="",owner_name="",secret="secret1"} 1 kube_secret_type{namespace="ns1",secret="secret1",type="Opaque"} 1 kube_secret_metadata_resource_version{namespace="ns1",secret="secret1"} 0 `, - MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, + MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type", "kube_secret_owner"}, }, { Obj: &v1.Secret{ @@ -70,17 +74,20 @@ func TestSecretStore(t *testing.T) { # HELP kube_secret_info [STABLE] Information about secret. # HELP kube_secret_labels [STABLE] Kubernetes labels converted to Prometheus labels. # HELP kube_secret_metadata_resource_version Resource version representing a specific version of secret. + # HELP kube_secret_owner Information about the Secret's owner. # HELP kube_secret_type [STABLE] Type about secret. # TYPE kube_secret_created gauge # TYPE kube_secret_info gauge # TYPE kube_secret_labels gauge # TYPE kube_secret_metadata_resource_version gauge + # TYPE kube_secret_owner gauge # TYPE kube_secret_type gauge kube_secret_info{namespace="ns2",secret="secret2"} 1 + kube_secret_owner{namespace="ns2",owner_is_controller="",owner_kind="",owner_name="",secret="secret2"} 1 kube_secret_type{namespace="ns2",secret="secret2",type="kubernetes.io/service-account-token"} 1 kube_secret_created{namespace="ns2",secret="secret2"} 1.501569018e+09 `, - MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, + MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type", "kube_secret_owner"}, }, { Obj: &v1.Secret{ @@ -98,18 +105,60 @@ func TestSecretStore(t *testing.T) { # HELP kube_secret_info [STABLE] Information about secret. # HELP kube_secret_labels [STABLE] Kubernetes labels converted to Prometheus labels. # HELP kube_secret_metadata_resource_version Resource version representing a specific version of secret. + # HELP kube_secret_owner Information about the Secret's owner. # HELP kube_secret_type [STABLE] Type about secret. # TYPE kube_secret_created gauge # TYPE kube_secret_info gauge # TYPE kube_secret_labels gauge # TYPE kube_secret_metadata_resource_version gauge + # TYPE kube_secret_owner gauge # TYPE kube_secret_type gauge kube_secret_info{namespace="ns3",secret="secret3"} 1 + kube_secret_owner{namespace="ns3",owner_is_controller="",owner_kind="",owner_name="",secret="secret3"} 1 kube_secret_type{namespace="ns3",secret="secret3",type="kubernetes.io/dockercfg"} 1 kube_secret_created{namespace="ns3",secret="secret3"} 1.501569018e+09 kube_secret_metadata_resource_version{namespace="ns3",secret="secret3"} 0 `, - MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, + MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type", "kube_secret_owner"}, + }, + { + Obj: &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secret4", + Namespace: "ns4", + CreationTimestamp: metav1StartTime, + Labels: map[string]string{"test-4": "test-4"}, + ResourceVersion: "0", + OwnerReferences: []metav1.OwnerReference{ + { + Name: "managed-secret4", + Kind: "ManagedSecret", + Controller: &test, + }, + }, + }, + Type: v1.SecretTypeOpaque, + }, + Want: ` + # HELP kube_secret_created [STABLE] Unix creation timestamp + # HELP kube_secret_info [STABLE] Information about secret. + # HELP kube_secret_labels [STABLE] Kubernetes labels converted to Prometheus labels. + # HELP kube_secret_metadata_resource_version Resource version representing a specific version of secret. + # HELP kube_secret_owner Information about the Secret's owner. + # HELP kube_secret_type [STABLE] Type about secret. + # TYPE kube_secret_created gauge + # TYPE kube_secret_info gauge + # TYPE kube_secret_labels gauge + # TYPE kube_secret_metadata_resource_version gauge + # TYPE kube_secret_owner gauge + # TYPE kube_secret_type gauge + kube_secret_info{namespace="ns4",secret="secret4"} 1 + kube_secret_owner{namespace="ns4",owner_is_controller="true",owner_kind="ManagedSecret",owner_name="managed-secret4",secret="secret4"} 1 + kube_secret_type{namespace="ns4",secret="secret4",type="Opaque"} 1 + kube_secret_created{namespace="ns4",secret="secret4"} 1.501569018e+09 + kube_secret_metadata_resource_version{namespace="ns4",secret="secret4"} 0 +`, + MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type", "kube_secret_owner"}, }, } for i, c := range cases {