From 3e4d91c4ba0fbc6aa7ac4636ffed6036c26634ce Mon Sep 17 00:00:00 2001 From: opeco17 Date: Mon, 14 Aug 2023 13:18:38 +0000 Subject: [PATCH 1/9] feat: implement kube_pod_status_initialized_time --- docs/pod-metrics.md | 1 + internal/store/pod.go | 28 ++++++++++++++++++++ internal/store/pod_test.go | 53 +++++++++++++++++++++++++++++++++++++- pkg/app/server_test.go | 2 ++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md index 3037372e..faa191c3 100644 --- a/docs/pod-metrics.md +++ b/docs/pod-metrics.md @@ -24,6 +24,7 @@ | kube_pod_container_status_last_terminated_reason | Gauge | Describes the last reason the container was in terminated state | |`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`reason`=<last-terminated-reason>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_status_last_terminated_exitcode | Gauge | Describes the exit code for the last container in terminated state. | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_status_ready | Gauge | Describes whether the containers readiness check succeeded | |`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | - | +| kube_pod_status_initialized_time | Gauge | Time when the pod is initialized. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | | kube_pod_status_ready_time | Gauge | Time when pod passed readiness probes. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | | kube_pod_status_container_ready_time | Gauge | Time when the container of the pod entered Ready state. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | | kube_pod_container_status_restarts_total | Counter | The number of container restarts per container | | `container`=<container-name>
`namespace`=<pod-namespace>
`pod`=<pod-name>
`uid`=<pod-uid> | STABLE | - | diff --git a/internal/store/pod.go b/internal/store/pod.go index 233fb271..fe149491 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -85,6 +85,7 @@ func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat createPodStatusQosClassFamilyGenerator(), createPodStatusReadyFamilyGenerator(), createPodStatusReadyTimeFamilyGenerator(), + createPodStatusInitializedTimeFamilyGenerator(), createPodStatusContainerReadyTimeFamilyGenerator(), createPodStatusReasonFamilyGenerator(), createPodStatusScheduledFamilyGenerator(), @@ -1337,6 +1338,33 @@ func createPodStatusPhaseFamilyGenerator() generator.FamilyGenerator { ) } +func createPodStatusInitializedTimeFamilyGenerator() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_pod_status_initialized_time", + "Initialized time in unix timestamp for a pod.", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapPodFunc(func(p *v1.Pod) *metric.Family { + ms := []*metric.Metric{} + + for _, c := range p.Status.Conditions { + if c.Type == v1.PodInitialized && c.Status == v1.ConditionTrue { + ms = append(ms, &metric.Metric{ + LabelKeys: []string{}, + LabelValues: []string{}, + Value: float64((c.LastTransitionTime).Unix()), + }) + } + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + func createPodStatusContainerReadyTimeFamilyGenerator() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( "kube_pod_status_container_ready_time", diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index e1ae2d00..791884d3 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -1434,6 +1434,57 @@ func TestPodStore(t *testing.T) { `, MetricNames: []string{"kube_pod_status_reason"}, }, + { + Obj: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "ns1", + UID: "uid1", + }, + Status: v1.PodStatus{ + Conditions: []v1.PodCondition{ + { + Type: v1.PodInitialized, + Status: v1.ConditionTrue, + LastTransitionTime: metav1.Time{ + Time: time.Unix(1501666018, 0), + }, + }, + }, + }, + }, + Want: ` + # HELP kube_pod_status_initialized_time Initialized time in unix timestamp for a pod. + # TYPE kube_pod_status_initialized_time gauge + kube_pod_status_initialized_time{namespace="ns1",pod="pod1",uid="uid1"} 1.501666018e+09 + `, + MetricNames: []string{"kube_pod_status_initialized_time"}, + }, + { + Obj: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "ns1", + UID: "uid1", + }, + Status: v1.PodStatus{ + Conditions: []v1.PodCondition{ + { + Type: v1.PodInitialized, + Status: v1.ConditionFalse, + LastTransitionTime: metav1.Time{ + Time: time.Unix(1501666018, 0), + }, + }, + }, + }, + }, + Want: ` + # HELP kube_pod_status_initialized_time Initialized time in unix timestamp for a pod. + # TYPE kube_pod_status_initialized_time gauge + `, + MetricNames: []string{"kube_pod_status_initialized_time"}, + }, { Obj: &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -2181,7 +2232,7 @@ func BenchmarkPodStore(b *testing.B) { }, } - expectedFamilies := 51 + expectedFamilies := 52 for n := 0; n < b.N; n++ { families := f(pod) if len(families) != expectedFamilies { diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go index daf693b2..9adbe506 100644 --- a/pkg/app/server_test.go +++ b/pkg/app/server_test.go @@ -242,6 +242,7 @@ func TestFullScrapeCycle(t *testing.T) { # HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly [STABLE] Describes whether a persistentvolumeclaim is mounted read only. # HELP kube_pod_start_time [STABLE] Start time in unix timestamp for a pod. # HELP kube_pod_status_container_ready_time Readiness achieved time in unix timestamp for a pod containers. +# HELP kube_pod_status_initialized_time Initialized time in unix timestamp for a pod. # HELP kube_pod_status_qos_class The pods current qosClass. # HELP kube_pod_status_phase [STABLE] The pods current phase. # HELP kube_pod_status_ready_time Readiness achieved time in unix timestamp for a pod. @@ -292,6 +293,7 @@ func TestFullScrapeCycle(t *testing.T) { # TYPE kube_pod_spec_volumes_persistentvolumeclaims_readonly gauge # TYPE kube_pod_start_time gauge # TYPE kube_pod_status_container_ready_time gauge +# TYPE kube_pod_status_initialized_time gauge # TYPE kube_pod_status_phase gauge # TYPE kube_pod_status_qos_class gauge # TYPE kube_pod_status_ready gauge From 6de105ebbe0eeb5d97d9e6adf1cc83314434e8cc Mon Sep 17 00:00:00 2001 From: opeco17 Date: Mon, 14 Aug 2023 08:29:10 +0000 Subject: [PATCH 2/9] feat: disable labels and annotations metrics when metric-annotations-allowlist and metric-labels-allowlist are not provided --- internal/store/certificatesigningrequest.go | 6 ++++++ internal/store/certificatesigningrequest_test.go | 6 ------ internal/store/clusterrole.go | 6 ++++++ internal/store/clusterrolebinding.go | 6 ++++++ internal/store/configmap.go | 6 ++++++ internal/store/cronjob.go | 6 ++++++ internal/store/cronjob_test.go | 4 ---- internal/store/daemonset.go | 6 ++++++ internal/store/daemonset_test.go | 3 --- internal/store/deployment.go | 6 ++++++ internal/store/deployment_test.go | 3 --- internal/store/endpoint.go | 6 ++++++ internal/store/endpoint_test.go | 4 ---- internal/store/endpointslice.go | 6 ++++++ internal/store/endpointslice_test.go | 1 - internal/store/horizontalpodautoscaler.go | 6 ++++++ internal/store/horizontalpodautoscaler_test.go | 3 --- internal/store/ingress.go | 6 ++++++ internal/store/ingress_test.go | 7 ------- internal/store/ingressclass.go | 6 ++++++ internal/store/ingressclass_test.go | 1 - internal/store/job.go | 6 ++++++ internal/store/job_test.go | 8 -------- internal/store/namespace.go | 7 +++++++ internal/store/namespace_test.go | 10 ---------- internal/store/networkpolicy.go | 6 ++++++ internal/store/networkpolicy_test.go | 1 - internal/store/node.go | 6 ++++++ internal/store/node_test.go | 2 -- internal/store/persistentvolume.go | 6 ++++++ internal/store/persistentvolume_test.go | 4 ---- internal/store/persistentvolumeclaim.go | 6 ++++++ internal/store/persistentvolumeclaim_test.go | 5 ----- internal/store/pod.go | 6 ++++++ internal/store/pod_test.go | 1 - internal/store/poddisruptionbudget.go | 6 ++++++ internal/store/poddisruptionbudget_test.go | 4 ---- internal/store/replicaset.go | 6 ++++++ internal/store/replicaset_test.go | 4 ---- internal/store/role.go | 6 ++++++ internal/store/rolebinding.go | 6 ++++++ internal/store/secret.go | 6 ++++++ internal/store/secret_test.go | 3 --- internal/store/service.go | 6 ++++++ internal/store/service_test.go | 12 ------------ internal/store/serviceaccount.go | 6 ++++++ internal/store/statefulset.go | 6 ++++++ internal/store/statefulset_test.go | 5 ----- internal/store/storageclass.go | 6 ++++++ internal/store/storageclass_test.go | 1 - pkg/app/server_test.go | 2 -- 51 files changed, 169 insertions(+), 94 deletions(-) diff --git a/internal/store/certificatesigningrequest.go b/internal/store/certificatesigningrequest.go index 0c26c756..c70cf801 100644 --- a/internal/store/certificatesigningrequest.go +++ b/internal/store/certificatesigningrequest.go @@ -49,6 +49,9 @@ func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat basemetrics.ALPHA, "", wrapCSRFunc(func(j *certv1.CertificateSigningRequest) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -68,6 +71,9 @@ func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat basemetrics.STABLE, "", wrapCSRFunc(func(j *certv1.CertificateSigningRequest) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/certificatesigningrequest_test.go b/internal/store/certificatesigningrequest_test.go index 99006194..74942d41 100644 --- a/internal/store/certificatesigningrequest_test.go +++ b/internal/store/certificatesigningrequest_test.go @@ -57,7 +57,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 0 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, @@ -87,7 +86,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 0 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 1 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, @@ -117,7 +115,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, @@ -148,7 +145,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 13 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, @@ -181,7 +177,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 1 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, @@ -220,7 +215,6 @@ func TestCsrStore(t *testing.T) { kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 2 kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 2 - kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1 kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0 `, MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"}, diff --git a/internal/store/clusterrole.go b/internal/store/clusterrole.go index 167f3f9b..ee7a7384 100644 --- a/internal/store/clusterrole.go +++ b/internal/store/clusterrole.go @@ -48,6 +48,9 @@ func clusterRoleMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.ALPHA, "", wrapClusterRoleFunc(func(r *rbacv1.ClusterRole) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -67,6 +70,9 @@ func clusterRoleMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.ALPHA, "", wrapClusterRoleFunc(func(r *rbacv1.ClusterRole) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/clusterrolebinding.go b/internal/store/clusterrolebinding.go index b9a2b921..c046008b 100644 --- a/internal/store/clusterrolebinding.go +++ b/internal/store/clusterrolebinding.go @@ -48,6 +48,9 @@ func clusterRoleBindingMetricFamilies(allowAnnotationsList, allowLabelsList []st basemetrics.ALPHA, "", wrapClusterRoleBindingFunc(func(r *rbacv1.ClusterRoleBinding) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -67,6 +70,9 @@ func clusterRoleBindingMetricFamilies(allowAnnotationsList, allowLabelsList []st basemetrics.ALPHA, "", wrapClusterRoleBindingFunc(func(r *rbacv1.ClusterRoleBinding) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/configmap.go b/internal/store/configmap.go index 619274d5..90e6029a 100644 --- a/internal/store/configmap.go +++ b/internal/store/configmap.go @@ -44,6 +44,9 @@ func configMapMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.ALPHA, "", wrapConfigMapFunc(func(c *v1.ConfigMap) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", c.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -63,6 +66,9 @@ func configMapMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.STABLE, "", wrapConfigMapFunc(func(c *v1.ConfigMap) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", c.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/cronjob.go b/internal/store/cronjob.go index 5976b6c0..5c146538 100644 --- a/internal/store/cronjob.go +++ b/internal/store/cronjob.go @@ -52,6 +52,9 @@ func cronJobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.ALPHA, "", wrapCronJobFunc(func(j *batchv1.CronJob) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -71,6 +74,9 @@ func cronJobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.STABLE, "", wrapCronJobFunc(func(j *batchv1.CronJob) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/cronjob_test.go b/internal/store/cronjob_test.go index 9b992874..442bb838 100644 --- a/internal/store/cronjob_test.go +++ b/internal/store/cronjob_test.go @@ -161,7 +161,6 @@ func TestCronJobStore(t *testing.T) { # TYPE kube_cronjob_status_last_schedule_time gauge kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveRunningCronJob1",namespace="ns1",schedule="0 */6 * * *"} 1 kube_cronjob_annotations{annotation_app_k8s_io_owner="@foo",cronjob="ActiveRunningCronJob1",namespace="ns1"} 1 - kube_cronjob_labels{cronjob="ActiveRunningCronJob1",namespace="ns1"} 1 kube_cronjob_spec_failed_job_history_limit{cronjob="ActiveRunningCronJob1",namespace="ns1"} 1 kube_cronjob_spec_starting_deadline_seconds{cronjob="ActiveRunningCronJob1",namespace="ns1"} 300 kube_cronjob_spec_successful_job_history_limit{cronjob="ActiveRunningCronJob1",namespace="ns1"} 3 @@ -235,7 +234,6 @@ func TestCronJobStore(t *testing.T) { # TYPE kube_cronjob_status_last_schedule_time gauge # TYPE kube_cronjob_status_last_successful_time gauge kube_cronjob_info{concurrency_policy="Forbid",cronjob="SuspendedCronJob1",namespace="ns1",schedule="0 */3 * * *"} 1 - kube_cronjob_labels{cronjob="SuspendedCronJob1",namespace="ns1"} 1 kube_cronjob_spec_failed_job_history_limit{cronjob="SuspendedCronJob1",namespace="ns1"} 1 kube_cronjob_spec_starting_deadline_seconds{cronjob="SuspendedCronJob1",namespace="ns1"} 300 kube_cronjob_spec_successful_job_history_limit{cronjob="SuspendedCronJob1",namespace="ns1"} 3 @@ -295,7 +293,6 @@ func TestCronJobStore(t *testing.T) { # TYPE kube_cronjob_status_last_schedule_time gauge # TYPE kube_cronjob_status_last_successful_time gauge kube_cronjob_info{concurrency_policy="Forbid",cronjob="SuspendedCronJob1",namespace="ns1",schedule="0 */3 * * *"} 1 - kube_cronjob_labels{cronjob="SuspendedCronJob1",namespace="ns1"} 1 kube_cronjob_spec_failed_job_history_limit{cronjob="SuspendedCronJob1",namespace="ns1"} 1 kube_cronjob_spec_starting_deadline_seconds{cronjob="SuspendedCronJob1",namespace="ns1"} 300 kube_cronjob_spec_successful_job_history_limit{cronjob="SuspendedCronJob1",namespace="ns1"} 3 @@ -364,7 +361,6 @@ func TestCronJobStore(t *testing.T) { kube_cronjob_spec_suspend{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 0 kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1",schedule="25 * * * *"} 1 kube_cronjob_created{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 1.520766296e+09 - kube_cronjob_labels{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 1 ` + fmt.Sprintf("kube_cronjob_next_schedule_time{cronjob=\"ActiveCronJob1NoLastScheduled\",namespace=\"ns1\"} %ve+09\n", float64(ActiveCronJob1NoLastScheduledNextScheduleTime.Unix())/math.Pow10(9)), diff --git a/internal/store/daemonset.go b/internal/store/daemonset.go index b9d34d79..31d2911a 100644 --- a/internal/store/daemonset.go +++ b/internal/store/daemonset.go @@ -230,6 +230,9 @@ func daemonSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.ALPHA, "", wrapDaemonSetFunc(func(d *v1.DaemonSet) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", d.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -249,6 +252,9 @@ func daemonSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.STABLE, "", wrapDaemonSetFunc(func(d *v1.DaemonSet) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", d.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/daemonset_test.go b/internal/store/daemonset_test.go index 7a8f06ed..729e75cb 100644 --- a/internal/store/daemonset_test.go +++ b/internal/store/daemonset_test.go @@ -86,7 +86,6 @@ func TestDaemonSetStore(t *testing.T) { kube_daemonset_status_observed_generation{daemonset="ds1",namespace="ns1"} 2 kube_daemonset_status_updated_number_scheduled{daemonset="ds1",namespace="ns1"} 0 kube_daemonset_annotations{annotation_app_k8s_io_owner="@foo",daemonset="ds1",namespace="ns1"} 1 - kube_daemonset_labels{daemonset="ds1",namespace="ns1"} 1 `, MetricNames: []string{ "kube_daemonset_annotations", @@ -149,7 +148,6 @@ func TestDaemonSetStore(t *testing.T) { kube_daemonset_status_number_ready{daemonset="ds2",namespace="ns2"} 0 kube_daemonset_status_number_unavailable{daemonset="ds2",namespace="ns2"} 0 kube_daemonset_status_updated_number_scheduled{daemonset="ds2",namespace="ns2"} 0 - kube_daemonset_labels{daemonset="ds2",namespace="ns2"} 1 kube_daemonset_created{namespace="ns2",daemonset="ds2"} 1.5e+09 `, MetricNames: []string{ @@ -216,7 +214,6 @@ func TestDaemonSetStore(t *testing.T) { kube_daemonset_status_number_ready{daemonset="ds3",namespace="ns3"} 5 kube_daemonset_status_number_unavailable{daemonset="ds3",namespace="ns3"} 5 kube_daemonset_status_updated_number_scheduled{daemonset="ds3",namespace="ns3"} 5 - kube_daemonset_labels{daemonset="ds3",namespace="ns3"} 1 `, MetricNames: []string{ "kube_daemonset_created", diff --git a/internal/store/deployment.go b/internal/store/deployment.go index 0535c3b8..b204cdb3 100644 --- a/internal/store/deployment.go +++ b/internal/store/deployment.go @@ -290,6 +290,9 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.ALPHA, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", d.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -309,6 +312,9 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.STABLE, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", d.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/deployment_test.go b/internal/store/deployment_test.go index 0223011e..31be4a17 100644 --- a/internal/store/deployment_test.go +++ b/internal/store/deployment_test.go @@ -115,7 +115,6 @@ func TestDeploymentStore(t *testing.T) { Want: metadata + ` kube_deployment_annotations{annotation_company_io_team="my-brilliant-team",deployment="depl1",namespace="ns1"} 1 kube_deployment_created{deployment="depl1",namespace="ns1"} 1.5e+09 - kube_deployment_labels{deployment="depl1",namespace="ns1"} 1 kube_deployment_metadata_generation{deployment="depl1",namespace="ns1"} 21 kube_deployment_spec_paused{deployment="depl1",namespace="ns1"} 0 kube_deployment_spec_replicas{deployment="depl1",namespace="ns1"} 200 @@ -170,8 +169,6 @@ func TestDeploymentStore(t *testing.T) { }, }, Want: metadata + ` - kube_deployment_annotations{deployment="depl2",namespace="ns2"} 1 - kube_deployment_labels{deployment="depl2",namespace="ns2"} 1 kube_deployment_metadata_generation{deployment="depl2",namespace="ns2"} 14 kube_deployment_spec_paused{deployment="depl2",namespace="ns2"} 1 kube_deployment_spec_replicas{deployment="depl2",namespace="ns2"} 5 diff --git a/internal/store/endpoint.go b/internal/store/endpoint.go index cd06d00f..fb527eeb 100644 --- a/internal/store/endpoint.go +++ b/internal/store/endpoint.go @@ -86,6 +86,9 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge basemetrics.ALPHA, "", wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", e.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -105,6 +108,9 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge basemetrics.STABLE, "", wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", e.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/endpoint_test.go b/internal/store/endpoint_test.go index 46df12e7..d090a381 100644 --- a/internal/store/endpoint_test.go +++ b/internal/store/endpoint_test.go @@ -89,12 +89,10 @@ func TestEndpointStore(t *testing.T) { }, }, Want: metadata + ` - kube_endpoint_annotations{endpoint="test-endpoint",namespace="default"} 1 kube_endpoint_address_available{endpoint="test-endpoint",namespace="default"} 6 kube_endpoint_address_not_ready{endpoint="test-endpoint",namespace="default"} 6 kube_endpoint_created{endpoint="test-endpoint",namespace="default"} 1.5e+09 kube_endpoint_info{endpoint="test-endpoint",namespace="default"} 1 - kube_endpoint_labels{endpoint="test-endpoint",namespace="default"} 1 kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="http",port_protocol="TCP",port_number="8080"} 1 kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="app",port_protocol="TCP",port_number="8081"} 1 kube_endpoint_ports{endpoint="test-endpoint",namespace="default",port_name="https",port_protocol="TCP",port_number="8443"} 1 @@ -134,12 +132,10 @@ func TestEndpointStore(t *testing.T) { }, }, Want: metadata + ` - kube_endpoint_annotations{endpoint="single-port-endpoint",namespace="default"} 1 kube_endpoint_address_available{endpoint="single-port-endpoint",namespace="default"} 2 kube_endpoint_address_not_ready{endpoint="single-port-endpoint",namespace="default"} 1 kube_endpoint_created{endpoint="single-port-endpoint",namespace="default"} 1.5e+09 kube_endpoint_info{endpoint="single-port-endpoint",namespace="default"} 1 - kube_endpoint_labels{endpoint="single-port-endpoint",namespace="default"} 1 kube_endpoint_ports{endpoint="single-port-endpoint",namespace="default",port_name="",port_number="8080",port_protocol="TCP"} 1 kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="127.0.0.1",ready="true"} 1 kube_endpoint_address{endpoint="single-port-endpoint",namespace="default",ip="10.0.0.1",ready="true"} 1 diff --git a/internal/store/endpointslice.go b/internal/store/endpointslice.go index 548e0ef0..ad72ce79 100644 --- a/internal/store/endpointslice.go +++ b/internal/store/endpointslice.go @@ -174,6 +174,9 @@ func endpointSliceMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapEndpointSliceFunc(func(s *discoveryv1.EndpointSlice) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -193,6 +196,9 @@ func endpointSliceMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapEndpointSliceFunc(func(s *discoveryv1.EndpointSlice) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/endpointslice_test.go b/internal/store/endpointslice_test.go index cca8638c..549fa73b 100644 --- a/internal/store/endpointslice_test.go +++ b/internal/store/endpointslice_test.go @@ -144,7 +144,6 @@ func TestEndpointSliceStore(t *testing.T) { # TYPE kube_endpointslice_annotations gauge # TYPE kube_endpointslice_labels gauge kube_endpointslice_annotations{endpointslice="test_endpointslice-labels",annotation_foo="baz"} 1 - kube_endpointslice_labels{endpointslice="test_endpointslice-labels"} 1 `, MetricNames: []string{ "kube_endpointslice_annotations", "kube_endpointslice_labels", diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index b7ef53cd..4e85cf9c 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -344,6 +344,9 @@ func createHPAAnnotations(allowAnnotationsList []string) generator.FamilyGenerat basemetrics.ALPHA, "", wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", a.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -366,6 +369,9 @@ func createHPALabels(allowLabelsList []string) generator.FamilyGenerator { basemetrics.STABLE, "", wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", a.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index 85c7f51b..25903fe4 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -210,8 +210,6 @@ func TestHPAStore(t *testing.T) { }, Want: metadata + ` kube_horizontalpodautoscaler_info{horizontalpodautoscaler="hpa1",namespace="ns1",scaletargetref_api_version="apps/v1",scaletargetref_kind="Deployment",scaletargetref_name="deployment1"} 1 - kube_horizontalpodautoscaler_annotations{horizontalpodautoscaler="hpa1",namespace="ns1"} 1 - kube_horizontalpodautoscaler_labels{horizontalpodautoscaler="hpa1",namespace="ns1"} 1 kube_horizontalpodautoscaler_metadata_generation{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 4 kube_horizontalpodautoscaler_spec_min_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 @@ -389,7 +387,6 @@ func TestHPAStore(t *testing.T) { Want: metadata + ` kube_horizontalpodautoscaler_info{horizontalpodautoscaler="hpa2",namespace="ns1",scaletargetref_kind="Deployment",scaletargetref_name="deployment1"} 1 kube_horizontalpodautoscaler_annotations{annotation_app_k8s_io_owner="@foo",horizontalpodautoscaler="hpa2",namespace="ns1"} 1 - kube_horizontalpodautoscaler_labels{horizontalpodautoscaler="hpa2",namespace="ns1"} 1 kube_horizontalpodautoscaler_metadata_generation{horizontalpodautoscaler="hpa2",namespace="ns1"} 2 kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="hpa2",namespace="ns1"} 4 kube_horizontalpodautoscaler_spec_min_replicas{horizontalpodautoscaler="hpa2",namespace="ns1"} 2 diff --git a/internal/store/ingress.go b/internal/store/ingress.go index 70f9b2bf..1d27f72a 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -75,6 +75,9 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.ALPHA, "", wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", i.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -94,6 +97,9 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.STABLE, "", wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", i.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/ingress_test.go b/internal/store/ingress_test.go index 123a679c..44fc6690 100644 --- a/internal/store/ingress_test.go +++ b/internal/store/ingress_test.go @@ -75,7 +75,6 @@ func TestIngressStore(t *testing.T) { kube_ingress_info{namespace="ns1",ingress="ingress1",ingressclass="_default"} 1 kube_ingress_metadata_resource_version{namespace="ns1",ingress="ingress1"} 0 kube_ingress_annotations{annotation_app_k8s_io_owner="@foo",namespace="ns1",ingress="ingress1"} 1 - kube_ingress_labels{namespace="ns1",ingress="ingress1"} 1 `, MetricNames: []string{ "kube_ingress_info", @@ -97,7 +96,6 @@ func TestIngressStore(t *testing.T) { kube_ingress_info{namespace="ns2",ingress="ingress2",ingressclass="_default"} 1 kube_ingress_created{namespace="ns2",ingress="ingress2"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns2",ingress="ingress2"} 123456 - kube_ingress_labels{namespace="ns2",ingress="ingress2"} 1 `, MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, }, @@ -114,7 +112,6 @@ func TestIngressStore(t *testing.T) { Want: metadata + ` kube_ingress_info{namespace="ns3",ingress="ingress3",ingressclass="_default"} 1 kube_ingress_created{namespace="ns3",ingress="ingress3"} 1.501569018e+09 - kube_ingress_labels{namespace="ns3",ingress="ingress3"} 1 `, MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, }, @@ -167,7 +164,6 @@ func TestIngressStore(t *testing.T) { Want: metadata + ` kube_ingress_info{namespace="ns4",ingress="ingress4",ingressclass="_default"} 1 kube_ingress_created{namespace="ns4",ingress="ingress4"} 1.501569018e+09 - kube_ingress_labels{namespace="ns4",ingress="ingress4"} 1 kube_ingress_path{namespace="ns4",ingress="ingress4",host="somehost",path="/somepath",service_name="someservice",service_port="1234"} 1 kube_ingress_path{namespace="ns4",ingress="ingress4",host="somehost",path="/somepath2",service_name="",service_port=""} 1 `, @@ -194,7 +190,6 @@ func TestIngressStore(t *testing.T) { Want: metadata + ` kube_ingress_info{namespace="ns5",ingress="ingress5",ingressclass="_default"} 1 kube_ingress_created{namespace="ns5",ingress="ingress5"} 1.501569018e+09 - kube_ingress_labels{namespace="ns5",ingress="ingress5"} 1 kube_ingress_tls{namespace="ns5",ingress="ingress5",tls_host="somehost1",secret="somesecret"} 1 kube_ingress_tls{namespace="ns5",ingress="ingress5",tls_host="somehost2",secret="somesecret"} 1 `, @@ -216,7 +211,6 @@ func TestIngressStore(t *testing.T) { kube_ingress_info{namespace="ns6",ingress="ingress6",ingressclass="test"} 1 kube_ingress_created{namespace="ns6",ingress="ingress6"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns6",ingress="ingress6"} 123456 - kube_ingress_labels{namespace="ns6",ingress="ingress6"} 1 `, MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, }, @@ -236,7 +230,6 @@ func TestIngressStore(t *testing.T) { kube_ingress_info{namespace="ns7",ingress="ingress7",ingressclass="test"} 1 kube_ingress_created{namespace="ns7",ingress="ingress7"} 1.501569018e+09 kube_ingress_metadata_resource_version{namespace="ns7",ingress="ingress7"} 123456 - kube_ingress_labels{namespace="ns7",ingress="ingress7"} 1 `, MetricNames: []string{"kube_ingress_info", "kube_ingress_metadata_resource_version", "kube_ingress_created", "kube_ingress_labels", "kube_ingress_path", "kube_ingress_tls"}, }, diff --git a/internal/store/ingressclass.go b/internal/store/ingressclass.go index bb6c07b1..0aaa8e13 100644 --- a/internal/store/ingressclass.go +++ b/internal/store/ingressclass.go @@ -80,6 +80,9 @@ func ingressClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapIngressClassFunc(func(s *networkingv1.IngressClass) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -99,6 +102,9 @@ func ingressClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapIngressClassFunc(func(s *networkingv1.IngressClass) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/ingressclass_test.go b/internal/store/ingressclass_test.go index 50312d0c..b171814b 100644 --- a/internal/store/ingressclass_test.go +++ b/internal/store/ingressclass_test.go @@ -88,7 +88,6 @@ func TestIngressClassStore(t *testing.T) { # TYPE kube_ingressclass_annotations gauge # TYPE kube_ingressclass_labels gauge kube_ingressclass_annotations{ingressclass="test_ingressclass-labels",annotation_ingressclass_kubernetes_io_is_default_class="true"} 1 - kube_ingressclass_labels{ingressclass="test_ingressclass-labels"} 1 `, MetricNames: []string{ "kube_ingressclass_annotations", "kube_ingressclass_labels", diff --git a/internal/store/job.go b/internal/store/job.go index 1c0e04c9..d778212b 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -51,6 +51,9 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat basemetrics.ALPHA, "", wrapJobFunc(func(j *v1batch.Job) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -70,6 +73,9 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat basemetrics.STABLE, "", wrapJobFunc(func(j *v1batch.Job) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/job_test.go b/internal/store/job_test.go index 223f4c54..b45ac1ab 100644 --- a/internal/store/job_test.go +++ b/internal/store/job_test.go @@ -112,11 +112,9 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` - kube_job_annotations{job_name="RunningJob1",namespace="ns1"} 1 kube_job_owner{job_name="RunningJob1",namespace="ns1",owner_is_controller="true",owner_kind="CronJob",owner_name="cronjob-name"} 1 kube_job_created{job_name="RunningJob1",namespace="ns1"} 1.5e+09 kube_job_info{job_name="RunningJob1",namespace="ns1"} 1 - kube_job_labels{job_name="RunningJob1",namespace="ns1"} 1 kube_job_spec_active_deadline_seconds{job_name="RunningJob1",namespace="ns1"} 900 kube_job_spec_completions{job_name="RunningJob1",namespace="ns1"} 1 kube_job_spec_parallelism{job_name="RunningJob1",namespace="ns1"} 1 @@ -153,13 +151,11 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` - kube_job_annotations{job_name="SuccessfulJob1",namespace="ns1"} 1 kube_job_owner{job_name="SuccessfulJob1",namespace="ns1",owner_is_controller="",owner_kind="",owner_name=""} 1 kube_job_complete{condition="false",job_name="SuccessfulJob1",namespace="ns1"} 0 kube_job_complete{condition="true",job_name="SuccessfulJob1",namespace="ns1"} 1 kube_job_complete{condition="unknown",job_name="SuccessfulJob1",namespace="ns1"} 0 kube_job_info{job_name="SuccessfulJob1",namespace="ns1"} 1 - kube_job_labels{job_name="SuccessfulJob1",namespace="ns1"} 1 kube_job_spec_active_deadline_seconds{job_name="SuccessfulJob1",namespace="ns1"} 900 kube_job_spec_completions{job_name="SuccessfulJob1",namespace="ns1"} 1 kube_job_spec_parallelism{job_name="SuccessfulJob1",namespace="ns1"} 1 @@ -197,13 +193,11 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` - kube_job_annotations{job_name="FailedJob1",namespace="ns1"} 1 kube_job_owner{job_name="FailedJob1",namespace="ns1",owner_is_controller="",owner_kind="",owner_name=""} 1 kube_job_failed{condition="false",job_name="FailedJob1",namespace="ns1"} 0 kube_job_failed{condition="true",job_name="FailedJob1",namespace="ns1"} 1 kube_job_failed{condition="unknown",job_name="FailedJob1",namespace="ns1"} 0 kube_job_info{job_name="FailedJob1",namespace="ns1"} 1 - kube_job_labels{job_name="FailedJob1",namespace="ns1"} 1 kube_job_spec_active_deadline_seconds{job_name="FailedJob1",namespace="ns1"} 900 kube_job_spec_completions{job_name="FailedJob1",namespace="ns1"} 1 kube_job_spec_parallelism{job_name="FailedJob1",namespace="ns1"} 1 @@ -247,10 +241,8 @@ func TestJobStore(t *testing.T) { kube_job_complete{condition="false",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0 kube_job_complete{condition="true",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 - kube_job_annotations{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_complete{condition="unknown",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0 kube_job_info{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 - kube_job_labels{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_spec_completions{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_spec_parallelism{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_status_active{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0 diff --git a/internal/store/namespace.go b/internal/store/namespace.go index ea9a733a..df3f1f05 100644 --- a/internal/store/namespace.go +++ b/internal/store/namespace.go @@ -68,6 +68,10 @@ func namespaceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.ALPHA, "", wrapNamespaceFunc(func(n *v1.Namespace) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -87,6 +91,9 @@ func namespaceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g basemetrics.STABLE, "", wrapNamespaceFunc(func(n *v1.Namespace) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/namespace_test.go b/internal/store/namespace_test.go index 2f8161f0..0838acd6 100644 --- a/internal/store/namespace_test.go +++ b/internal/store/namespace_test.go @@ -56,8 +56,6 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` - kube_namespace_annotations{namespace="nsActiveTest"} 1 - kube_namespace_labels{namespace="nsActiveTest"} 1 kube_namespace_status_phase{namespace="nsActiveTest",phase="Active"} 1 kube_namespace_status_phase{namespace="nsActiveTest",phase="Terminating"} 0 `, @@ -75,8 +73,6 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` - kube_namespace_annotations{namespace="nsTerminateTest"} 1 - kube_namespace_labels{namespace="nsTerminateTest"} 1 kube_namespace_status_phase{namespace="nsTerminateTest",phase="Active"} 0 kube_namespace_status_phase{namespace="nsTerminateTest",phase="Terminating"} 1 `, @@ -99,8 +95,6 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` - kube_namespace_annotations{namespace="nsTerminateWithConditionTest"} 1 - kube_namespace_labels{namespace="nsTerminateWithConditionTest"} 1 kube_namespace_status_phase{namespace="nsTerminateWithConditionTest",phase="Active"} 0 kube_namespace_status_phase{namespace="nsTerminateWithConditionTest",phase="Terminating"} 1 kube_namespace_status_condition{condition="NamespaceDeletionContentFailure",namespace="nsTerminateWithConditionTest",status="false"} 0 @@ -132,9 +126,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` - kube_namespace_annotations{namespace="ns1"} 1 kube_namespace_created{namespace="ns1"} 1.5e+09 - kube_namespace_labels{namespace="ns1"} 1 kube_namespace_status_phase{namespace="ns1",phase="Active"} 1 kube_namespace_status_phase{namespace="ns1",phase="Terminating"} 0 `, @@ -156,8 +148,6 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` - kube_namespace_annotations{namespace="ns2"} 1 - kube_namespace_labels{namespace="ns2"} 1 kube_namespace_status_phase{namespace="ns2",phase="Active"} 1 kube_namespace_status_phase{namespace="ns2",phase="Terminating"} 0 `, diff --git a/internal/store/networkpolicy.go b/internal/store/networkpolicy.go index 62eb87ee..7d546b8c 100644 --- a/internal/store/networkpolicy.go +++ b/internal/store/networkpolicy.go @@ -66,6 +66,9 @@ func networkPolicyMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -85,6 +88,9 @@ func networkPolicyMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/networkpolicy_test.go b/internal/store/networkpolicy_test.go index 22b693c0..8079b9cf 100644 --- a/internal/store/networkpolicy_test.go +++ b/internal/store/networkpolicy_test.go @@ -55,7 +55,6 @@ func TestNetworkPolicyStore(t *testing.T) { }, Want: ` kube_networkpolicy_created{namespace="ns1",networkpolicy="netpol1"} 1.501569018e+09 - kube_networkpolicy_labels{namespace="ns1",networkpolicy="netpol1"} 1 kube_networkpolicy_spec_egress_rules{namespace="ns1",networkpolicy="netpol1"} 3 kube_networkpolicy_spec_ingress_rules{namespace="ns1",networkpolicy="netpol1"} 2 `, diff --git a/internal/store/node.go b/internal/store/node.go index 76f46ac6..fb577a0b 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -164,6 +164,9 @@ func createNodeAnnotationsGenerator(allowAnnotationsList []string) generator.Fam basemetrics.ALPHA, "", wrapNodeFunc(func(n *v1.Node) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -186,6 +189,9 @@ func createNodeLabelsGenerator(allowLabelsList []string) generator.FamilyGenerat basemetrics.STABLE, "", wrapNodeFunc(func(n *v1.Node) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/node_test.go b/internal/store/node_test.go index 0e444317..a28f39c2 100644 --- a/internal/store/node_test.go +++ b/internal/store/node_test.go @@ -61,7 +61,6 @@ func TestNodeStore(t *testing.T) { # TYPE kube_node_labels gauge # TYPE kube_node_spec_unschedulable gauge kube_node_info{container_runtime_version="rkt",kernel_version="kernel",kubelet_version="kubelet",kubeproxy_version="kubeproxy",node="127.0.0.1",os_image="osimage",pod_cidr="172.24.10.0/24",provider_id="provider://i-uniqueid",internal_ip="1.2.3.4",system_uuid="6a934e21-5207-4a84-baea-3a952d926c80"} 1 - kube_node_labels{node="127.0.0.1"} 1 kube_node_spec_unschedulable{node="127.0.0.1"} 0 `, MetricNames: []string{"kube_node_spec_unschedulable", "kube_node_labels", "kube_node_info"}, @@ -142,7 +141,6 @@ func TestNodeStore(t *testing.T) { # TYPE kube_node_status_capacity gauge kube_node_created{node="127.0.0.1"} 1.5e+09 kube_node_info{container_runtime_version="rkt",kernel_version="kernel",kubelet_version="kubelet",kubeproxy_version="kubeproxy",node="127.0.0.1",os_image="osimage",pod_cidr="172.24.10.0/24",provider_id="provider://i-randomidentifier",internal_ip="1.2.3.4",system_uuid="6a934e21-5207-4a84-baea-3a952d926c80"} 1 - kube_node_labels{node="127.0.0.1"} 1 kube_node_role{node="127.0.0.1",role="master"} 1 kube_node_spec_unschedulable{node="127.0.0.1"} 1 kube_node_status_allocatable{node="127.0.0.1",resource="cpu",unit="core"} 3 diff --git a/internal/store/persistentvolume.go b/internal/store/persistentvolume.go index 691adc4d..18778e33 100644 --- a/internal/store/persistentvolume.go +++ b/internal/store/persistentvolume.go @@ -85,6 +85,9 @@ func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []stri basemetrics.ALPHA, "", wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -104,6 +107,9 @@ func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []stri basemetrics.STABLE, "", wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/persistentvolume_test.go b/internal/store/persistentvolume_test.go index d3f07be9..b4e0e15f 100644 --- a/internal/store/persistentvolume_test.go +++ b/internal/store/persistentvolume_test.go @@ -522,7 +522,6 @@ func TestPersistentVolumeStore(t *testing.T) { Want: ` # HELP kube_persistentvolume_labels [STABLE] Kubernetes labels converted to Prometheus labels. # TYPE kube_persistentvolume_labels gauge - kube_persistentvolume_labels{persistentvolume="test-labeled-pv"} 1 `, MetricNames: []string{"kube_persistentvolume_labels"}, }, @@ -538,7 +537,6 @@ func TestPersistentVolumeStore(t *testing.T) { Want: ` # HELP kube_persistentvolume_labels [STABLE] Kubernetes labels converted to Prometheus labels. # TYPE kube_persistentvolume_labels gauge - kube_persistentvolume_labels{persistentvolume="test-unlabeled-pv"} 1 `, MetricNames: []string{"kube_persistentvolume_labels"}, }, @@ -658,8 +656,6 @@ func TestPersistentVolumeStore(t *testing.T) { # HELP kube_persistentvolume_labels [STABLE] Kubernetes labels converted to Prometheus labels. # TYPE kube_persistentvolume_annotations gauge # TYPE kube_persistentvolume_labels gauge - kube_persistentvolume_annotations{persistentvolume="test-defaul-labels-annotations"} 1 - kube_persistentvolume_labels{persistentvolume="test-defaul-labels-annotations"} 1 `, MetricNames: []string{ "kube_persistentvolume_annotations", diff --git a/internal/store/persistentvolumeclaim.go b/internal/store/persistentvolumeclaim.go index 128809da..6a88d629 100644 --- a/internal/store/persistentvolumeclaim.go +++ b/internal/store/persistentvolumeclaim.go @@ -49,6 +49,9 @@ func persistentVolumeClaimMetricFamilies(allowAnnotationsList, allowLabelsList [ basemetrics.STABLE, "", wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -68,6 +71,9 @@ func persistentVolumeClaimMetricFamilies(allowAnnotationsList, allowLabelsList [ basemetrics.ALPHA, "", wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/persistentvolumeclaim_test.go b/internal/store/persistentvolumeclaim_test.go index a226259b..572062d1 100644 --- a/internal/store/persistentvolumeclaim_test.go +++ b/internal/store/persistentvolumeclaim_test.go @@ -90,7 +90,6 @@ func TestPersistentVolumeClaimStore(t *testing.T) { kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="mysql-data",phase="Pending"} 0 kube_persistentvolumeclaim_resource_requests_storage_bytes{namespace="default",persistentvolumeclaim="mysql-data"} 1.073741824e+09 kube_persistentvolumeclaim_annotations{annotation_app_k8s_io_owner="@foo",namespace="default",persistentvolumeclaim="mysql-data"} 1 - kube_persistentvolumeclaim_labels{namespace="default",persistentvolumeclaim="mysql-data"} 1 kube_persistentvolumeclaim_access_mode{namespace="default",persistentvolumeclaim="mysql-data",access_mode="ReadWriteOnce"} 1 kube_persistentvolumeclaim_status_condition{namespace="default",persistentvolumeclaim="mysql-data",status="false",condition="CustomizedType"} 0 kube_persistentvolumeclaim_status_condition{namespace="default",persistentvolumeclaim="mysql-data",status="false",condition="FileSystemResizePending"} 1 @@ -161,7 +160,6 @@ func TestPersistentVolumeClaimStore(t *testing.T) { kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="mysql-data",phase="Lost"} 0 kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="mysql-data",phase="Pending"} 0 kube_persistentvolumeclaim_resource_requests_storage_bytes{namespace="default",persistentvolumeclaim="mysql-data"} 1.073741824e+09 - kube_persistentvolumeclaim_annotations{namespace="default",persistentvolumeclaim="mysql-data"} 1 kube_persistentvolumeclaim_labels{label_app="mysql-server",namespace="default",persistentvolumeclaim="mysql-data"} 1 kube_persistentvolumeclaim_access_mode{namespace="default",persistentvolumeclaim="mysql-data",access_mode="ReadWriteOnce"} 1 kube_persistentvolumeclaim_status_condition{namespace="default",persistentvolumeclaim="mysql-data",status="false",condition="CustomizedType"} 0 @@ -214,7 +212,6 @@ func TestPersistentVolumeClaimStore(t *testing.T) { kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="prometheus-data",phase="Bound"} 0 kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="prometheus-data",phase="Lost"} 0 kube_persistentvolumeclaim_status_phase{namespace="default",persistentvolumeclaim="prometheus-data",phase="Pending"} 1 - kube_persistentvolumeclaim_labels{namespace="default",persistentvolumeclaim="prometheus-data"} 1 kube_persistentvolumeclaim_access_mode{namespace="default",persistentvolumeclaim="prometheus-data",access_mode="ReadWriteOnce"} 1 `, MetricNames: []string{"kube_persistentvolumeclaim_info", "kube_persistentvolumeclaim_status_phase", "kube_persistentvolumeclaim_resource_requests_storage_bytes", "kube_persistentvolumeclaim_labels", "kube_persistentvolumeclaim_access_mode", "kube_persistentvolumeclaim_status_condition", "kube_persistentvolumeclaim_created"}, @@ -261,8 +258,6 @@ func TestPersistentVolumeClaimStore(t *testing.T) { kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="mongo-data",phase="Bound"} 0 kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="mongo-data",phase="Lost"} 1 kube_persistentvolumeclaim_status_phase{namespace="",persistentvolumeclaim="mongo-data",phase="Pending"} 0 - kube_persistentvolumeclaim_labels{namespace="",persistentvolumeclaim="mongo-data"} 1 - kube_persistentvolumeclaim_annotations{namespace="",persistentvolumeclaim="mongo-data"} 1 kube_persistentvolumeclaim_access_mode{namespace="",persistentvolumeclaim="mongo-data",access_mode="ReadWriteOnce"} 1 kube_persistentvolumeclaim_status_condition{namespace="",persistentvolumeclaim="mongo-data",status="false",condition="CustomizedType"} 1 kube_persistentvolumeclaim_status_condition{namespace="",persistentvolumeclaim="mongo-data",status="false",condition="FileSystemResizePending"} 0 diff --git a/internal/store/pod.go b/internal/store/pod.go index 233fb271..75b2d6d8 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -1034,6 +1034,9 @@ func createPodAnnotationsGenerator(allowAnnotations []string) generator.FamilyGe basemetrics.ALPHA, "", wrapPodFunc(func(p *v1.Pod) *metric.Family { + if len(allowAnnotations) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotations) m := metric.Metric{ LabelKeys: annotationKeys, @@ -1055,6 +1058,9 @@ func createPodLabelsGenerator(allowLabelsList []string) generator.FamilyGenerato basemetrics.STABLE, "", wrapPodFunc(func(p *v1.Pod) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) m := metric.Metric{ LabelKeys: labelKeys, diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index e1ae2d00..bf44af86 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -1826,7 +1826,6 @@ func TestPodStore(t *testing.T) { Want: ` # HELP kube_pod_labels [STABLE] Kubernetes labels converted to Prometheus labels. # TYPE kube_pod_labels gauge - kube_pod_labels{namespace="ns1",pod="pod1",uid="uid1"} 1 `, MetricNames: []string{ "kube_pod_labels", diff --git a/internal/store/poddisruptionbudget.go b/internal/store/poddisruptionbudget.go index 0afc0a22..c4fa0cb5 100644 --- a/internal/store/poddisruptionbudget.go +++ b/internal/store/poddisruptionbudget.go @@ -48,6 +48,9 @@ func podDisruptionBudgetMetricFamilies(allowAnnotationsList, allowLabelsList []s basemetrics.ALPHA, "", wrapPodDisruptionBudgetFunc(func(p *policyv1.PodDisruptionBudget) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -67,6 +70,9 @@ func podDisruptionBudgetMetricFamilies(allowAnnotationsList, allowLabelsList []s basemetrics.ALPHA, "", wrapPodDisruptionBudgetFunc(func(p *policyv1.PodDisruptionBudget) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/poddisruptionbudget_test.go b/internal/store/poddisruptionbudget_test.go index 33586c1c..f974412f 100644 --- a/internal/store/poddisruptionbudget_test.go +++ b/internal/store/poddisruptionbudget_test.go @@ -67,8 +67,6 @@ func TestPodDisruptionBudgetStore(t *testing.T) { }, }, Want: metadata + ` - kube_poddisruptionbudget_annotations{namespace="ns1",poddisruptionbudget="pdb1"} 1 - kube_poddisruptionbudget_labels{namespace="ns1",poddisruptionbudget="pdb1"} 1 kube_poddisruptionbudget_created{namespace="ns1",poddisruptionbudget="pdb1"} 1.5e+09 kube_poddisruptionbudget_status_current_healthy{namespace="ns1",poddisruptionbudget="pdb1"} 12 kube_poddisruptionbudget_status_desired_healthy{namespace="ns1",poddisruptionbudget="pdb1"} 10 @@ -93,8 +91,6 @@ func TestPodDisruptionBudgetStore(t *testing.T) { }, }, Want: metadata + ` - kube_poddisruptionbudget_annotations{namespace="ns2",poddisruptionbudget="pdb2"} 1 - kube_poddisruptionbudget_labels{namespace="ns2",poddisruptionbudget="pdb2"} 1 kube_poddisruptionbudget_status_current_healthy{namespace="ns2",poddisruptionbudget="pdb2"} 8 kube_poddisruptionbudget_status_desired_healthy{namespace="ns2",poddisruptionbudget="pdb2"} 9 kube_poddisruptionbudget_status_pod_disruptions_allowed{namespace="ns2",poddisruptionbudget="pdb2"} 0 diff --git a/internal/store/replicaset.go b/internal/store/replicaset.go index e1c957bf..76706aae 100644 --- a/internal/store/replicaset.go +++ b/internal/store/replicaset.go @@ -216,6 +216,9 @@ func replicaSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.ALPHA, "", wrapReplicaSetFunc(func(r *v1.ReplicaSet) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -235,6 +238,9 @@ func replicaSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] basemetrics.STABLE, "", wrapReplicaSetFunc(func(r *v1.ReplicaSet) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/replicaset_test.go b/internal/store/replicaset_test.go index 80d7fabd..963a7792 100644 --- a/internal/store/replicaset_test.go +++ b/internal/store/replicaset_test.go @@ -87,8 +87,6 @@ func TestReplicaSetStore(t *testing.T) { }, }, Want: metadata + ` - kube_replicaset_annotations{replicaset="rs1",namespace="ns1"} 1 - kube_replicaset_labels{replicaset="rs1",namespace="ns1"} 1 kube_replicaset_created{namespace="ns1",replicaset="rs1"} 1.5e+09 kube_replicaset_metadata_generation{namespace="ns1",replicaset="rs1"} 21 kube_replicaset_status_replicas{namespace="ns1",replicaset="rs1"} 5 @@ -121,8 +119,6 @@ func TestReplicaSetStore(t *testing.T) { }, }, Want: metadata + ` - kube_replicaset_annotations{replicaset="rs2",namespace="ns2"} 1 - kube_replicaset_labels{replicaset="rs2",namespace="ns2"} 1 kube_replicaset_metadata_generation{namespace="ns2",replicaset="rs2"} 14 kube_replicaset_status_replicas{namespace="ns2",replicaset="rs2"} 0 kube_replicaset_status_observed_generation{namespace="ns2",replicaset="rs2"} 5 diff --git a/internal/store/role.go b/internal/store/role.go index eed2652d..3d2e8016 100644 --- a/internal/store/role.go +++ b/internal/store/role.go @@ -48,6 +48,9 @@ func roleMetricFamilies(allowAnnotationsList, allowLabelsList []string) []genera basemetrics.ALPHA, "", wrapRoleFunc(func(r *rbacv1.Role) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -67,6 +70,9 @@ func roleMetricFamilies(allowAnnotationsList, allowLabelsList []string) []genera basemetrics.ALPHA, "", wrapRoleFunc(func(r *rbacv1.Role) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/rolebinding.go b/internal/store/rolebinding.go index beca54c4..b3bd6146 100644 --- a/internal/store/rolebinding.go +++ b/internal/store/rolebinding.go @@ -48,6 +48,9 @@ func roleBindingMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.ALPHA, "", wrapRoleBindingFunc(func(r *rbacv1.RoleBinding) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -67,6 +70,9 @@ func roleBindingMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.ALPHA, "", wrapRoleBindingFunc(func(r *rbacv1.RoleBinding) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/secret.go b/internal/store/secret.go index 50572f6b..a989fbbe 100644 --- a/internal/store/secret.go +++ b/internal/store/secret.go @@ -82,6 +82,9 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene basemetrics.ALPHA, "", wrapSecretFunc(func(s *v1.Secret) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -102,6 +105,9 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene basemetrics.STABLE, "", wrapSecretFunc(func(s *v1.Secret) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/secret_test.go b/internal/store/secret_test.go index bb10cc61..f518a7d8 100644 --- a/internal/store/secret_test.go +++ b/internal/store/secret_test.go @@ -52,7 +52,6 @@ func TestSecretStore(t *testing.T) { kube_secret_info{namespace="ns1",secret="secret1"} 1 kube_secret_type{namespace="ns1",secret="secret1",type="Opaque"} 1 kube_secret_metadata_resource_version{namespace="ns1",secret="secret1"} 0 - kube_secret_labels{namespace="ns1",secret="secret1"} 1 `, MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, }, @@ -80,7 +79,6 @@ func TestSecretStore(t *testing.T) { kube_secret_info{namespace="ns2",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 - kube_secret_labels{namespace="ns2",secret="secret2"} 1 `, MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, }, @@ -110,7 +108,6 @@ func TestSecretStore(t *testing.T) { 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 - kube_secret_labels{namespace="ns3",secret="secret3"} 1 `, MetricNames: []string{"kube_secret_info", "kube_secret_metadata_resource_version", "kube_secret_created", "kube_secret_labels", "kube_secret_type"}, }, diff --git a/internal/store/service.go b/internal/store/service.go index d0f4c552..d9308ca0 100644 --- a/internal/store/service.go +++ b/internal/store/service.go @@ -97,6 +97,9 @@ func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.ALPHA, "", wrapSvcFunc(func(s *v1.Service) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) m := metric.Metric{ LabelKeys: annotationKeys, @@ -113,6 +116,9 @@ func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen basemetrics.STABLE, "", wrapSvcFunc(func(s *v1.Service) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) m := metric.Metric{ LabelKeys: labelKeys, diff --git a/internal/store/service_test.go b/internal/store/service_test.go index c291a48a..de21e6bd 100644 --- a/internal/store/service_test.go +++ b/internal/store/service_test.go @@ -73,10 +73,8 @@ func TestServiceStore(t *testing.T) { # TYPE kube_service_info gauge # TYPE kube_service_labels gauge # TYPE kube_service_spec_type gauge - kube_service_annotations{namespace="default",service="test-service1",uid="uid1"} 1 kube_service_created{namespace="default",service="test-service1",uid="uid1"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.4",external_name="",load_balancer_ip="",namespace="default",service="test-service1",uid="uid1"} 1 - kube_service_labels{namespace="default",service="test-service1",uid="uid1"} 1 kube_service_spec_type{namespace="default",service="test-service1",type="ClusterIP",uid="uid1"} 1 `, MetricNames: []string{ @@ -105,10 +103,8 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` - kube_service_annotations{namespace="default",service="test-service2",uid="uid2"} 1 kube_service_created{namespace="default",service="test-service2",uid="uid2"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.5",external_name="",load_balancer_ip="",namespace="default",service="test-service2",uid="uid2"} 1 - kube_service_labels{namespace="default",service="test-service2",uid="uid2"} 1 kube_service_spec_type{namespace="default",service="test-service2",uid="uid2",type="NodePort"} 1 `, }, @@ -130,10 +126,8 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` - kube_service_annotations{namespace="default",service="test-service3",uid="uid3"} 1 kube_service_created{namespace="default",service="test-service3",uid="uid3"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.6",external_name="",load_balancer_ip="1.2.3.7",namespace="default",service="test-service3",uid="uid3"} 1 - kube_service_labels{namespace="default",service="test-service3",uid="uid3"} 1 kube_service_spec_type{namespace="default",service="test-service3",type="LoadBalancer",uid="uid3"} 1 `, }, @@ -154,10 +148,8 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` - kube_service_annotations{namespace="default",service="test-service4",uid="uid4"} 1 kube_service_created{namespace="default",service="test-service4",uid="uid4"} 1.5e+09 kube_service_info{cluster_ip="",external_name="www.example.com",load_balancer_ip="",namespace="default",service="test-service4",uid="uid4"} 1 - kube_service_labels{namespace="default",service="test-service4",uid="uid4"} 1 kube_service_spec_type{namespace="default",service="test-service4",uid="uid4",type="ExternalName"} 1 `, }, @@ -187,10 +179,8 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` - kube_service_annotations{namespace="default",service="test-service5",uid="uid5"} 1 kube_service_created{namespace="default",service="test-service5",uid="uid5"} 1.5e+09 kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service5",uid="uid5"} 1 - kube_service_labels{namespace="default",service="test-service5",uid="uid5"} 1 kube_service_spec_type{namespace="default",service="test-service5",type="LoadBalancer",uid="uid5"} 1 kube_service_status_load_balancer_ingress{hostname="www.example.com",ip="1.2.3.8",namespace="default",service="test-service5",uid="uid5"} 1 `, @@ -215,10 +205,8 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` - kube_service_annotations{namespace="default",service="test-service6",uid="uid6"} 1 kube_service_created{namespace="default",service="test-service6",uid="uid6"} 1.5e+09 kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service6",uid="uid6"} 1 - kube_service_labels{namespace="default",service="test-service6",uid="uid6"} 1 kube_service_spec_type{namespace="default",service="test-service6",uid="uid6",type="ClusterIP"} 1 kube_service_spec_external_ip{external_ip="1.2.3.9",namespace="default",service="test-service6",uid="uid6"} 1 kube_service_spec_external_ip{external_ip="1.2.3.10",namespace="default",service="test-service6",uid="uid6"} 1 diff --git a/internal/store/serviceaccount.go b/internal/store/serviceaccount.go index d17ce867..073ee997 100644 --- a/internal/store/serviceaccount.go +++ b/internal/store/serviceaccount.go @@ -183,6 +183,9 @@ func createServiceAccountAnnotationsGenerator(allowAnnotations []string) generat basemetrics.ALPHA, "", wrapServiceAccountFunc(func(sa *v1.ServiceAccount) *metric.Family { + if len(allowAnnotations) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", sa.Annotations, allowAnnotations) m := metric.Metric{ LabelKeys: annotationKeys, @@ -204,6 +207,9 @@ func createServiceAccountLabelsGenerator(allowLabelsList []string) generator.Fam basemetrics.ALPHA, "", wrapServiceAccountFunc(func(sa *v1.ServiceAccount) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", sa.Labels, allowLabelsList) m := metric.Metric{ LabelKeys: labelKeys, diff --git a/internal/store/statefulset.go b/internal/store/statefulset.go index 528b536c..332b7bfe 100644 --- a/internal/store/statefulset.go +++ b/internal/store/statefulset.go @@ -248,6 +248,9 @@ func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.ALPHA, "", wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -267,6 +270,9 @@ func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ basemetrics.STABLE, "", wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/statefulset_test.go b/internal/store/statefulset_test.go index 211fcf84..34f3302d 100644 --- a/internal/store/statefulset_test.go +++ b/internal/store/statefulset_test.go @@ -99,7 +99,6 @@ func TestStatefulSetStore(t *testing.T) { kube_statefulset_status_observed_generation{namespace="ns1",statefulset="statefulset1"} 1 kube_statefulset_replicas{namespace="ns1",statefulset="statefulset1"} 3 kube_statefulset_metadata_generation{namespace="ns1",statefulset="statefulset1"} 3 - kube_statefulset_labels{namespace="ns1",statefulset="statefulset1"} 1 `, MetricNames: []string{ "kube_statefulset_created", @@ -177,7 +176,6 @@ func TestStatefulSetStore(t *testing.T) { kube_statefulset_status_observed_generation{namespace="ns2",statefulset="statefulset2"} 2 kube_statefulset_replicas{namespace="ns2",statefulset="statefulset2"} 6 kube_statefulset_metadata_generation{namespace="ns2",statefulset="statefulset2"} 21 - kube_statefulset_labels{namespace="ns2",statefulset="statefulset2"} 1 kube_statefulset_status_current_revision{namespace="ns2",revision="cr2",statefulset="statefulset2"} 1 `, MetricNames: []string{ @@ -247,7 +245,6 @@ func TestStatefulSetStore(t *testing.T) { kube_statefulset_status_replicas_updated{namespace="ns3",statefulset="statefulset3"} 0 kube_statefulset_replicas{namespace="ns3",statefulset="statefulset3"} 9 kube_statefulset_metadata_generation{namespace="ns3",statefulset="statefulset3"} 36 - kube_statefulset_labels{namespace="ns3",statefulset="statefulset3"} 1 kube_statefulset_status_current_revision{namespace="ns3",revision="cr3",statefulset="statefulset3"} 1 `, MetricNames: []string{ @@ -321,7 +318,6 @@ func TestStatefulSetStore(t *testing.T) { kube_statefulset_replicas{namespace="ns4",statefulset="statefulset4"} 3 kube_statefulset_metadata_generation{namespace="ns4",statefulset="statefulset4"} 1 kube_statefulset_persistentvolumeclaim_retention_policy{namespace="ns4",statefulset="statefulset4",when_deleted="Retain",when_scaled="Delete"} 1 - kube_statefulset_labels{namespace="ns4",statefulset="statefulset4"} 1 kube_statefulset_status_current_revision{namespace="ns4",revision="cr3",statefulset="statefulset4"} 1 `, MetricNames: []string{ @@ -397,7 +393,6 @@ func TestStatefulSetStore(t *testing.T) { kube_statefulset_replicas{namespace="ns5",statefulset="statefulset5"} 3 kube_statefulset_ordinals_start{namespace="ns5",statefulset="statefulset5"} 2 kube_statefulset_metadata_generation{namespace="ns5",statefulset="statefulset5"} 1 - kube_statefulset_labels{namespace="ns5",statefulset="statefulset5"} 1 kube_statefulset_status_current_revision{namespace="ns5",revision="cr5",statefulset="statefulset5"} 1 `, MetricNames: []string{ diff --git a/internal/store/storageclass.go b/internal/store/storageclass.go index dfb912fd..d5ed3bae 100644 --- a/internal/store/storageclass.go +++ b/internal/store/storageclass.go @@ -92,6 +92,9 @@ func storageClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.ALPHA, "", wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ @@ -111,6 +114,9 @@ func storageClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) basemetrics.STABLE, "", wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ diff --git a/internal/store/storageclass_test.go b/internal/store/storageclass_test.go index 4f086f48..b987d8bb 100644 --- a/internal/store/storageclass_test.go +++ b/internal/store/storageclass_test.go @@ -100,7 +100,6 @@ func TestStorageClassStore(t *testing.T) { Want: ` # HELP kube_storageclass_labels [STABLE] Kubernetes labels converted to Prometheus labels. # TYPE kube_storageclass_labels gauge - kube_storageclass_labels{storageclass="test_storageclass-labels"} 1 `, MetricNames: []string{ "kube_storageclass_labels", diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go index daf693b2..3a4bc35f 100644 --- a/pkg/app/server_test.go +++ b/pkg/app/server_test.go @@ -301,7 +301,6 @@ func TestFullScrapeCycle(t *testing.T) { # TYPE kube_pod_status_scheduled_time gauge # TYPE kube_pod_status_unschedulable gauge # TYPE kube_pod_tolerations gauge -kube_pod_annotations{namespace="default",pod="pod0",uid="abc-0"} 1 kube_pod_container_info{namespace="default",pod="pod0",uid="abc-0",container="pod1_con1",image_spec="k8s.gcr.io/hyperkube2_spec",image="k8s.gcr.io/hyperkube2",image_id="docker://sha256:bbb",container_id="docker://cd456"} 1 kube_pod_container_info{namespace="default",pod="pod0",uid="abc-0",container="pod1_con2",image_spec="k8s.gcr.io/hyperkube3_spec",image="k8s.gcr.io/hyperkube3",image_id="docker://sha256:ccc",container_id="docker://ef789"} 1 kube_pod_container_resource_limits{namespace="default",pod="pod0",uid="abc-0",container="pod1_con1",node="node1",resource="cpu",unit="core"} 0.2 @@ -333,7 +332,6 @@ kube_pod_container_status_waiting{namespace="default",pod="pod0",uid="abc-0",con kube_pod_container_status_waiting{namespace="default",pod="pod0",uid="abc-0",container="pod1_con2"} 0 kube_pod_created{namespace="default",pod="pod0",uid="abc-0"} 1.5e+09 kube_pod_info{namespace="default",pod="pod0",uid="abc-0",host_ip="1.1.1.1",pod_ip="1.2.3.4",node="node1",created_by_kind="",created_by_name="",priority_class="",host_network="false"} 1 -kube_pod_labels{namespace="default",pod="pod0",uid="abc-0"} 1 kube_pod_owner{namespace="default",pod="pod0",uid="abc-0",owner_kind="",owner_name="",owner_is_controller=""} 1 kube_pod_restart_policy{namespace="default",pod="pod0",uid="abc-0",type="Always"} 1 kube_pod_service_account{namespace="default",pod="pod0",uid="abc-0",service_account=""} 1 From e57a28af2fb454bdd708cff506f65a09b6715f04 Mon Sep 17 00:00:00 2001 From: Christian Schlotter Date: Fri, 18 Aug 2023 15:45:54 +0200 Subject: [PATCH 3/9] feat(custommetrics) always extract the metric headers but only write them when we have metrics --- internal/store/builder.go | 68 +----------------------- pkg/metrics_store/metrics_writer.go | 16 +++--- pkg/metrics_store/metrics_writer_test.go | 32 +++++++++++ 3 files changed, 39 insertions(+), 77 deletions(-) diff --git a/internal/store/builder.go b/internal/store/builder.go index 31e9f2e4..691fcd93 100644 --- a/internal/store/builder.go +++ b/internal/store/builder.go @@ -38,10 +38,6 @@ import ( policyv1 "k8s.io/api/policy/v1" rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" @@ -544,10 +540,7 @@ func (b *Builder) buildCustomResourceStores(resourceName string, metricFamilies = generator.FilterFamilyGenerators(b.familyGeneratorFilter, metricFamilies) composedMetricGenFuncs := generator.ComposeMetricGenFuncs(metricFamilies) - var familyHeaders []string - if b.hasResources(resourceName, expectedType) { - familyHeaders = generator.ExtractMetricFamilyHeaders(metricFamilies) - } + familyHeaders := generator.ExtractMetricFamilyHeaders(metricFamilies) gvr := util.GVRFromType(resourceName, expectedType) var gvrString string @@ -590,65 +583,6 @@ func (b *Builder) buildCustomResourceStores(resourceName string, return stores } -func (b *Builder) hasResources(resourceName string, expectedType interface{}) bool { - gvr := util.GVRFromType(resourceName, expectedType) - if gvr == nil { - return true - } - discoveryClient, err := util.CreateDiscoveryClient(b.utilOptions.Apiserver, b.utilOptions.Kubeconfig) - if err != nil { - klog.ErrorS(err, "Failed to create discovery client") - return false - } - g := gvr.Group - v := gvr.Version - r := gvr.Resource - isCRDInstalled, err := discovery.IsResourceEnabled(discoveryClient, schema.GroupVersionResource{ - Group: g, - Version: v, - Resource: r, - }) - if err != nil { - klog.ErrorS(err, "Failed to check if CRD is enabled", "group", g, "version", v, "resource", r) - return false - } - if !isCRDInstalled { - klog.InfoS("CRD is not installed", "group", g, "version", v, "resource", r) - return false - } - // Wait for the resource to come up. - timer := time.NewTimer(ResourceDiscoveryTimeout) - ticker := time.NewTicker(ResourceDiscoveryInterval) - dynamicClient, err := util.CreateDynamicClient(b.utilOptions.Apiserver, b.utilOptions.Kubeconfig) - if err != nil { - klog.ErrorS(err, "Failed to create dynamic client") - return false - } - var list *unstructured.UnstructuredList - for range ticker.C { - select { - case <-timer.C: - klog.InfoS("No CRs found for GVR", "group", g, "version", v, "resource", r) - return false - default: - list, err = dynamicClient.Resource(schema.GroupVersionResource{ - Group: g, - Version: v, - Resource: r, - }).List(b.ctx, metav1.ListOptions{}) - if err != nil { - klog.ErrorS(err, "Failed to list objects", "group", g, "version", v, "resource", r) - return false - } - } - if len(list.Items) > 0 { - break - } - } - - return true -} - // startReflector starts a Kubernetes client-go reflector with the given // listWatcher and registers it with the given store. func (b *Builder) startReflector( diff --git a/pkg/metrics_store/metrics_writer.go b/pkg/metrics_store/metrics_writer.go index 63ac811a..ce86cb88 100644 --- a/pkg/metrics_store/metrics_writer.go +++ b/pkg/metrics_store/metrics_writer.go @@ -58,20 +58,16 @@ func (m MetricsWriter) WriteAll(w io.Writer) error { }(s) } - // If the first store has no headers, but has metrics, we need to write out - // an empty header to ensure that the metrics are written out correctly. - if m.stores[0].headers == nil && m.stores[0].metrics != nil { - m.stores[0].headers = []string{""} - } for i, help := range m.stores[0].headers { if help != "" && help != "\n" { help += "\n" } - // TODO: This writes out the help text for each metric family, before checking if the metrics for it exist, - // TODO: which is not ideal, and furthermore, diverges from the OpenMetrics standard. - _, err := w.Write([]byte(help)) - if err != nil { - return fmt.Errorf("failed to write help text: %v", err) + + if len(m.stores[0].metrics) > 0 { + _, err := w.Write([]byte(help)) + if err != nil { + return fmt.Errorf("failed to write help text: %v", err) + } } for _, s := range m.stores { diff --git a/pkg/metrics_store/metrics_writer_test.go b/pkg/metrics_store/metrics_writer_test.go index b13c1605..73bf1647 100644 --- a/pkg/metrics_store/metrics_writer_test.go +++ b/pkg/metrics_store/metrics_writer_test.go @@ -17,6 +17,7 @@ limitations under the License. package metricsstore_test import ( + "fmt" "strings" "testing" @@ -231,3 +232,34 @@ func TestWriteAllWithMultipleStores(t *testing.T) { } } } + +// TestWriteAllWithEmptyStores checks that nothing is printed if no metrics exist for metric families. +func TestWriteAllWithEmptyStores(t *testing.T) { + genFunc := func(obj interface{}) []metric.FamilyInterface { + mf1 := metric.Family{ + Name: "kube_service_info_1", + Metrics: []*metric.Metric{}, + } + + mf2 := metric.Family{ + Name: "kube_service_info_2", + Metrics: []*metric.Metric{}, + } + + return []metric.FamilyInterface{&mf1, &mf2} + } + store := metricsstore.NewMetricsStore([]string{"Info 1 about services", "Info 2 about services"}, genFunc) + + multiNsWriter := metricsstore.NewMetricsWriter(store) + w := strings.Builder{} + err := multiNsWriter.WriteAll(&w) + if err != nil { + t.Fatalf("failed to write metrics: %v", err) + } + result := w.String() + fmt.Println(result) + + if result != "" { + t.Fatalf("Unexpected output, got %q, want %q", result, "") + } +} From 3070acb5073f857f8494b975fe7af37ad094f967 Mon Sep 17 00:00:00 2001 From: Adrian Berger Date: Tue, 22 Aug 2023 12:32:23 +0000 Subject: [PATCH 4/9] fix(customresourcestate): typo in Error message Signed-off-by: Adrian Berger --- pkg/customresourcestate/registry_factory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/customresourcestate/registry_factory.go b/pkg/customresourcestate/registry_factory.go index 7ed4afd0..27db2ffe 100644 --- a/pkg/customresourcestate/registry_factory.go +++ b/pkg/customresourcestate/registry_factory.go @@ -196,7 +196,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) { } valueFromPath, err := compilePath(m.StateSet.ValueFrom) if err != nil { - return nil, fmt.Errorf("each.gauge.valueFrom: %w", err) + return nil, fmt.Errorf("each.stateSet.valueFrom: %w", err) } return &compiledStateSet{ compiledCommon: *cc, From 6f7269858dc0596d55675a4270e285a3e0fe9dd9 Mon Sep 17 00:00:00 2001 From: Damien Grisonnet Date: Tue, 22 Aug 2023 17:50:18 +0200 Subject: [PATCH 5/9] options: update labels/annotations allowlist doc Signed-off-by: Damien Grisonnet --- docs/cli-arguments.md | 4 ++-- pkg/options/options.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index 0b812011..4c0a3f46 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -53,9 +53,9 @@ Flags: --log_file_max_size uint Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) --logtostderr log to standard error instead of files (default true) --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). + --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'. + --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'. --metric-opt-in-list string Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" --namespaces-denylist string Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, only namespaces that are excluded in namespaces-denylist will be used. diff --git a/pkg/options/options.go b/pkg/options/options.go index 0f55785e..2a60f89c 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -137,8 +137,8 @@ func (o *Options) AddFlags(cmd *cobra.Command) { o.cmd.Flags().StringVar(&o.TelemetryHost, "telemetry-host", "::", `Host to expose kube-state-metrics self metrics on.`) o.cmd.Flags().StringVar(&o.Config, "config", "", "Path to the kube-state-metrics options config file") o.cmd.Flags().StringVar((*string)(&o.Node), "node", "", "Name of the node that contains the kube-state-metrics pod. Most likely it should be passed via the downward API. This is used for daemonset sharding. Only available for resources (pod metrics) that support spec.nodeName fieldSelector. This is experimental.") - o.cmd.Flags().Var(&o.AnnotationsAllowList, "metric-annotations-allowlist", "Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').") - o.cmd.Flags().Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.") + o.cmd.Flags().Var(&o.AnnotationsAllowList, "metric-annotations-allowlist", "Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').") + o.cmd.Flags().Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.") o.cmd.Flags().Var(&o.MetricAllowlist, "metric-allowlist", "Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.") o.cmd.Flags().Var(&o.MetricDenylist, "metric-denylist", "Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.") o.cmd.Flags().Var(&o.MetricOptInList, "metric-opt-in-list", "Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists") From 1536c720f720346d94c9e5fc1f6fad8697695fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Thu, 24 Aug 2023 20:21:13 +0200 Subject: [PATCH 6/9] fix: Index out of range in metrics_store.SanitizeHeaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2023-08-24T18:08:21.796778057Z 2023/08/24 18:08:21 http: panic serving ip:port: runtime error: index out of range [0] with length 0 2023-08-24T18:08:21.796814387Z goroutine 589687 [running]: 2023-08-24T18:08:21.796823334Z net/http.(*conn).serve.func1() 2023-08-24T18:08:21.796830520Z /usr/local/go/src/net/http/server.go:1854 +0xbf 2023-08-24T18:08:21.796838117Z panic({0x19c2060, 0xc0043060a8}) 2023-08-24T18:08:21.796844764Z /usr/local/go/src/runtime/panic.go:890 +0x263 2023-08-24T18:08:21.796852064Z k8s.io/kube-state-metrics/v2/pkg/metrics_store.SanitizeHeaders(...) 2023-08-24T18:08:21.796858974Z /root/go/src/k8s.io/kube-state-metrics/pkg/metrics_store/metrics_writer.go:94 2023-08-24T18:08:21.796866007Z k8s.io/kube-state-metrics/v2/pkg/metricshandler.(*MetricsHandler).ServeHTTP(0xc000221490, {0x1d425a0, 0xc005872700}, 0xc003f9d300) 2023-08-24T18:08:21.796873054Z /root/go/src/k8s.io/kube-state-metrics/pkg/metricshandler/metrics_handler.go:211 +0x8fe ... Signed-off-by: Manuel RĂ¼ger --- pkg/metrics_store/metrics_writer.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/metrics_store/metrics_writer.go b/pkg/metrics_store/metrics_writer.go index 63ac811a..209f3d8c 100644 --- a/pkg/metrics_store/metrics_writer.go +++ b/pkg/metrics_store/metrics_writer.go @@ -91,11 +91,13 @@ func (m MetricsWriter) WriteAll(w io.Writer) error { func SanitizeHeaders(writers MetricsWriterList) MetricsWriterList { var lastHeader string for _, writer := range writers { - for i, header := range writer.stores[0].headers { - if header == lastHeader { - writer.stores[0].headers[i] = "" - } else { - lastHeader = header + if len(writer.stores) > 0 { + for i, header := range writer.stores[0].headers { + if header == lastHeader { + writer.stores[0].headers[i] = "" + } else { + lastHeader = header + } } } } From 2181414c8ddd3bb70c6098e14c6026a06e899808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Fri, 25 Aug 2023 12:23:27 +0200 Subject: [PATCH 7/9] build: Bump dependencies --- .github/workflows/ci.yml | 2 +- Makefile | 4 ++-- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ tests/e2e.sh | 2 +- tools/go.mod | 2 +- tools/go.sum | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b8857d6..a33c1717 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ env: E2E_SETUP_KUBECTL: yes SUDO: sudo GO_VERSION: "^1.20" - GOLANGCI_LINT_VERSION: "v1.53.3" + GOLANGCI_LINT_VERSION: "v1.54.2" jobs: ci-go-lint: diff --git a/Makefile b/Makefile index d2805eb0..38c8f9e5 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ GIT_COMMIT ?= $(shell git rev-parse --short HEAD) OS ?= $(shell uname -s | tr A-Z a-z) ALL_ARCH = amd64 arm arm64 ppc64le s390x PKG = github.com/prometheus/common -PROMETHEUS_VERSION = 2.45.0 -GO_VERSION = 1.20.6 +PROMETHEUS_VERSION = 2.46.0 +GO_VERSION = 1.20.7 IMAGE = $(REGISTRY)/kube-state-metrics MULTI_ARCH_IMG = $(IMAGE)-$(ARCH) USER ?= $(shell id -u -n) diff --git a/go.mod b/go.mod index 30db0c47..3711921f 100644 --- a/go.mod +++ b/go.mod @@ -17,13 +17,13 @@ require ( github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.27.4 - k8s.io/apimachinery v0.27.4 - k8s.io/client-go v0.27.4 - k8s.io/component-base v0.27.4 + k8s.io/api v0.27.5 + k8s.io/apimachinery v0.27.5 + k8s.io/client-go v0.27.5 + k8s.io/component-base v0.27.5 k8s.io/klog/v2 v2.100.1 - k8s.io/sample-controller v0.27.4 - k8s.io/utils v0.0.0-20230711102312-30195339c3c7 + k8s.io/sample-controller v0.27.5 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b ) require ( diff --git a/go.sum b/go.sum index c5e74ce2..d852989b 100644 --- a/go.sum +++ b/go.sum @@ -606,22 +606,22 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.27.4 h1:0pCo/AN9hONazBKlNUdhQymmnfLRbSZjd5H5H3f0bSs= -k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y= -k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs= -k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= -k8s.io/client-go v0.27.4 h1:vj2YTtSJ6J4KxaC88P4pMPEQECWMY8gqPqsTgUKzvjk= -k8s.io/client-go v0.27.4/go.mod h1:ragcly7lUlN0SRPk5/ZkGnDjPknzb37TICq07WhI6Xc= -k8s.io/component-base v0.27.4 h1:Wqc0jMKEDGjKXdae8hBXeskRP//vu1m6ypC+gwErj4c= -k8s.io/component-base v0.27.4/go.mod h1:hoiEETnLc0ioLv6WPeDt8vD34DDeB35MfQnxCARq3kY= +k8s.io/api v0.27.5 h1:49hIzqJNSuOQpA53MMihgAS4YDcQitTy58B9PMFthLc= +k8s.io/api v0.27.5/go.mod h1:zjBZB+c0KDU55Wxb9Bob9WZGxu9zdKHitzHxBtaIVoA= +k8s.io/apimachinery v0.27.5 h1:6Q5HBXYJJPisd6yDVAprLe6FQsmw7a7Cu69dcrpQET8= +k8s.io/apimachinery v0.27.5/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/client-go v0.27.5 h1:sH/fkqzk35kuf0GPx+dZuN7fhEswBSAVCrWFq3E1km0= +k8s.io/client-go v0.27.5/go.mod h1:u+IKnqPZSPw51snIMKiIAV8LQQ+hya5bvxpOOPTUXPI= +k8s.io/component-base v0.27.5 h1:IXo80yOVx7qXG2g1loPpo2g1HUK3CnxNpq9LtGmXAmM= +k8s.io/component-base v0.27.5/go.mod h1:AGJyFHmaxplY4C4lu18UrJBNHcxdv0o6jOL/+HcC0S0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/sample-controller v0.27.4 h1:oeKVVOWw+fVaZVWCw3l9myrAoNUqR8A4BcA91fyyZaU= -k8s.io/sample-controller v0.27.4/go.mod h1:bfGT2cEyzWjfCqVSrWPbNsym9MkgKz7Z7Bwl0tjysOo= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= -k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/sample-controller v0.27.5 h1:N3mMPdEFJ8gdn7HMCIecnTU7h6YVfVJjSDt72nxAocc= +k8s.io/sample-controller v0.27.5/go.mod h1:KtTxV9H5DpvbU5WpM2o/Cpv/fuZykJhqBqCJdNfFRpg= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tests/e2e.sh b/tests/e2e.sh index 074b9482..a033d565 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -30,7 +30,7 @@ KUBE_STATE_METRICS_CURRENT_IMAGE_NAME="registry.k8s.io/kube-state-metrics/kube-s KUBE_STATE_METRICS_IMAGE_NAME="registry.k8s.io/kube-state-metrics/kube-state-metrics-${ARCH}" E2E_SETUP_KIND=${E2E_SETUP_KIND:-} E2E_SETUP_KUBECTL=${E2E_SETUP_KUBECTL:-} -KIND_VERSION=v0.19.0 +KIND_VERSION=v0.20.0 SUDO=${SUDO:-} OS=$(uname -s | awk '{print tolower($0)}') diff --git a/tools/go.mod b/tools/go.mod index 475d136c..fc3d5df0 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -7,7 +7,7 @@ require ( github.com/campoy/embedmd v1.0.0 github.com/google/go-jsonnet v0.20.0 github.com/jsonnet-bundler/jsonnet-bundler v0.5.1 - golang.org/x/perf v0.0.0-20230427221525-d343f6398b76 + golang.org/x/perf v0.0.0-20230822165715-3c60af34b3f4 ) require ( diff --git a/tools/go.sum b/tools/go.sum index 670ee4fc..81c074d1 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -114,8 +114,8 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/perf v0.0.0-20230427221525-d343f6398b76 h1:cPGZx8Liyx5Pq/yX80/6WMKe2yidT0xvVCQBOGa8WHU= -golang.org/x/perf v0.0.0-20230427221525-d343f6398b76/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= +golang.org/x/perf v0.0.0-20230822165715-3c60af34b3f4 h1:ua24l69kDXo72PNOVfgBXbbwGyV322MjcIBBV5ExoYA= +golang.org/x/perf v0.0.0-20230822165715-3c60af34b3f4/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 6071db7f493308fa661830e21e725eec9d3fb9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Fri, 25 Aug 2023 12:38:16 +0200 Subject: [PATCH 8/9] build: Fix lint --- internal/store/cronjob.go | 2 +- internal/store/ingress.go | 2 +- internal/store/ingressclass.go | 2 +- internal/store/persistentvolume_test.go | 4 ++-- internal/store/serviceaccount_test.go | 4 ++-- pkg/customresourcestate/custom_resource_metrics_test.go | 6 +++--- pkg/customresourcestate/registry_factory_test.go | 6 +++--- pkg/options/types_test.go | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/internal/store/cronjob.go b/internal/store/cronjob.go index 5c146538..1450f70c 100644 --- a/internal/store/cronjob.go +++ b/internal/store/cronjob.go @@ -36,7 +36,7 @@ import ( ) var ( - descCronJobAnnotationsName = "kube_cronjob_annotations" + descCronJobAnnotationsName = "kube_cronjob_annotations" //nolint:gosec descCronJobAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descCronJobLabelsName = "kube_cronjob_labels" descCronJobLabelsHelp = "Kubernetes labels converted to Prometheus labels." diff --git a/internal/store/ingress.go b/internal/store/ingress.go index 1d27f72a..be98e25a 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -34,7 +34,7 @@ import ( ) var ( - descIngressAnnotationsName = "kube_ingress_annotations" + descIngressAnnotationsName = "kube_ingress_annotations" //nolint:gosec descIngressAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descIngressLabelsName = "kube_ingress_labels" descIngressLabelsHelp = "Kubernetes labels converted to Prometheus labels." diff --git a/internal/store/ingressclass.go b/internal/store/ingressclass.go index 0aaa8e13..ec7a0f7d 100644 --- a/internal/store/ingressclass.go +++ b/internal/store/ingressclass.go @@ -32,7 +32,7 @@ import ( var ( descIngressClassAnnotationsName = "kube_ingressclass_annotations" descIngressClassAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." - descIngressClassLabelsName = "kube_ingressclass_labels" + descIngressClassLabelsName = "kube_ingressclass_labels" //nolint:gosec descIngressClassLabelsHelp = "Kubernetes labels converted to Prometheus labels." descIngressClassLabelsDefaultLabels = []string{"ingressclass"} ) diff --git a/internal/store/persistentvolume_test.go b/internal/store/persistentvolume_test.go index b4e0e15f..4ff4750d 100644 --- a/internal/store/persistentvolume_test.go +++ b/internal/store/persistentvolume_test.go @@ -23,7 +23,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator" ) @@ -415,7 +415,7 @@ func TestPersistentVolumeStore(t *testing.T) { Spec: v1.PersistentVolumeSpec{ PersistentVolumeSource: v1.PersistentVolumeSource{ Local: &v1.LocalVolumeSource{ - FSType: pointer.String("ext4"), + FSType: ptr.To("ext4"), Path: "/mnt/data", }, }, diff --git a/internal/store/serviceaccount_test.go b/internal/store/serviceaccount_test.go index 1223a5b6..d6d9df3b 100644 --- a/internal/store/serviceaccount_test.go +++ b/internal/store/serviceaccount_test.go @@ -22,7 +22,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator" ) @@ -38,7 +38,7 @@ func TestServiceAccountStore(t *testing.T) { Namespace: "serviceAccountNS", UID: "serviceAccountUID", }, - AutomountServiceAccountToken: pointer.Bool(true), + AutomountServiceAccountToken: ptr.To(true), Secrets: []v1.ObjectReference{ { APIVersion: "v1", diff --git a/pkg/customresourcestate/custom_resource_metrics_test.go b/pkg/customresourcestate/custom_resource_metrics_test.go index e62e333c..928f668d 100644 --- a/pkg/customresourcestate/custom_resource_metrics_test.go +++ b/pkg/customresourcestate/custom_resource_metrics_test.go @@ -22,7 +22,7 @@ import ( "testing" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" ) func TestNewCustomResourceMetrics(t *testing.T) { @@ -130,7 +130,7 @@ func TestNewCustomResourceMetrics(t *testing.T) { }, }, }, - MetricNamePrefix: pointer.String("apps_deployment"), + MetricNamePrefix: ptr.To("apps_deployment"), }, wantErr: false, wantResult: &customResourceMetrics{ @@ -193,7 +193,7 @@ func TestNewCustomResourceMetrics(t *testing.T) { }, }, }, - MetricNamePrefix: pointer.String("apps_deployment"), + MetricNamePrefix: ptr.To("apps_deployment"), }, wantErr: true, wantResult: &customResourceMetrics{ diff --git a/pkg/customresourcestate/registry_factory_test.go b/pkg/customresourcestate/registry_factory_test.go index 3d53c696..a0432ec0 100644 --- a/pkg/customresourcestate/registry_factory_test.go +++ b/pkg/customresourcestate/registry_factory_test.go @@ -23,7 +23,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" "k8s.io/kube-state-metrics/v2/pkg/metric" ) @@ -454,7 +454,7 @@ func Test_fullName(t *testing.T) { { name: "no prefix", args: args{ - resource: r(pointer.String("")), + resource: r(ptr.To("")), f: count, }, want: "count", @@ -462,7 +462,7 @@ func Test_fullName(t *testing.T) { { name: "custom", args: args{ - resource: r(pointer.String("bar_baz")), + resource: r(ptr.To("bar_baz")), f: count, }, want: "bar_baz_count", diff --git a/pkg/options/types_test.go b/pkg/options/types_test.go index 3ccaf4c0..a1b43a2c 100644 --- a/pkg/options/types_test.go +++ b/pkg/options/types_test.go @@ -109,8 +109,8 @@ func TestNamespaceList_GetNamespaces(t *testing.T) { }, } - for _, test := range tests { - ns := &test.Namespaces + for i, test := range tests { + ns := &tests[i].Namespaces allowedNamespaces := ns.GetNamespaces() if !reflect.DeepEqual(allowedNamespaces, test.Wanted) { t.Errorf("Test error for Desc: %s. Want: %+v. Got: %+v.", test.Desc, test.Wanted, allowedNamespaces) From 634c04ef90846ddd4e09a3e55fafdfd6a7329186 Mon Sep 17 00:00:00 2001 From: opeco17 Date: Mon, 28 Aug 2023 13:03:38 +0000 Subject: [PATCH 9/9] feat: enable metric-annotations-allowlist and metric-labels-allowlist for ResourceQuota --- docs/resourcequota-metrics.md | 2 ++ internal/store/builder.go | 2 +- internal/store/resourcequota.go | 54 ++++++++++++++++++++++++++-- internal/store/resourcequota_test.go | 36 +++++++++++++++++-- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/docs/resourcequota-metrics.md b/docs/resourcequota-metrics.md index e98eb415..485d0a6b 100644 --- a/docs/resourcequota-metrics.md +++ b/docs/resourcequota-metrics.md @@ -4,3 +4,5 @@ | ---------- | ----------- | ----------- | ----------- | | kube_resourcequota | Gauge | `resourcequota`=<quota-name>
`namespace`=<namespace>
`resource`=<ResourceName>
`type`=<quota-type> | STABLE | | kube_resourcequota_created | Gauge | `resourcequota`=<quota-name>
`namespace`=<namespace> | STABLE | +| kube_resourcequota_annotations | Gauge | `resourcequota`=<quota-name>
`namespace`=<namespace>
`annotation_RESOURCE_QUOTA_ANNOTATION`=<RESOURCE_QUOTA_ANNOTATION> | EXPERIMENTAL | +| kube_resourcequota_labels | Gauge | `resourcequota`=<quota-name>
`namespace`=<namespace>
`label_RESOURCE_QUOTA_LABEL`=<RESOURCE_QUOTA_LABEL> | EXPERIMENTAL | diff --git a/internal/store/builder.go b/internal/store/builder.go index 31e9f2e4..2c71c23f 100644 --- a/internal/store/builder.go +++ b/internal/store/builder.go @@ -431,7 +431,7 @@ func (b *Builder) buildReplicationControllerStores() []cache.Store { } func (b *Builder) buildResourceQuotaStores() []cache.Store { - return b.buildStoresFunc(resourceQuotaMetricFamilies, &v1.ResourceQuota{}, createResourceQuotaListWatch, b.useAPIServerCache) + return b.buildStoresFunc(resourceQuotaMetricFamilies(b.allowAnnotationsList["resourcequotas"], b.allowLabelsList["resourcequotas"]), &v1.ResourceQuota{}, createResourceQuotaListWatch, b.useAPIServerCache) } func (b *Builder) buildSecretStores() []cache.Store { diff --git a/internal/store/resourcequota.go b/internal/store/resourcequota.go index fe55f98f..adaf4a83 100644 --- a/internal/store/resourcequota.go +++ b/internal/store/resourcequota.go @@ -32,9 +32,15 @@ import ( ) var ( + descResourceQuotaAnnotationsName = "kube_resourcequota_annotations" + descResourceQuotaAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." + descResourceQuotaLabelsName = "kube_resourcequota_labels" + descResourceQuotaLabelsHelp = "Kubernetes labels converted to Prometheus labels." descResourceQuotaLabelsDefaultLabels = []string{"namespace", "resourcequota"} +) - resourceQuotaMetricFamilies = []generator.FamilyGenerator{ +func resourceQuotaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { + return []generator.FamilyGenerator{ *generator.NewFamilyGeneratorWithStability( "kube_resourcequota_created", "Unix creation timestamp", @@ -87,8 +93,52 @@ var ( } }), ), + *generator.NewFamilyGeneratorWithStability( + descResourceQuotaAnnotationsName, + descResourceQuotaAnnotationsHelp, + metric.Gauge, + basemetrics.ALPHA, + "", + wrapResourceQuotaFunc(func(d *v1.ResourceQuota) *metric.Family { + if len(allowAnnotationsList) == 0 { + return &metric.Family{} + } + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", d.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), + *generator.NewFamilyGeneratorWithStability( + descResourceQuotaLabelsName, + descResourceQuotaLabelsHelp, + metric.Gauge, + basemetrics.STABLE, + "", + wrapResourceQuotaFunc(func(d *v1.ResourceQuota) *metric.Family { + if len(allowLabelsList) == 0 { + return &metric.Family{} + } + labelKeys, labelValues := createPrometheusLabelKeysValues("label", d.Labels, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: labelKeys, + LabelValues: labelValues, + Value: 1, + }, + }, + } + }), + ), } -) +} func wrapResourceQuotaFunc(f func(*v1.ResourceQuota) *metric.Family) func(interface{}) *metric.Family { return func(obj interface{}) *metric.Family { diff --git a/internal/store/resourcequota_test.go b/internal/store/resourcequota_test.go index f342065c..2d60650f 100644 --- a/internal/store/resourcequota_test.go +++ b/internal/store/resourcequota_test.go @@ -32,9 +32,13 @@ func TestResourceQuotaStore(t *testing.T) { // output so we only have to modify a single place when doing adjustments. const metadata = ` # HELP kube_resourcequota [STABLE] Information about resource quota. + # HELP kube_resourcequota_annotations Kubernetes annotations converted to Prometheus labels. # TYPE kube_resourcequota gauge # HELP kube_resourcequota_created [STABLE] Unix creation timestamp + # HELP kube_resourcequota_labels [STABLE] Kubernetes labels converted to Prometheus labels. + # TYPE kube_resourcequota_annotations gauge # TYPE kube_resourcequota_created gauge + # TYPE kube_resourcequota_labels gauge ` cases := []generateMetricsTestCase{ // Verify populating base metric and that metric for unset fields are skipped. @@ -132,10 +136,38 @@ func TestResourceQuotaStore(t *testing.T) { kube_resourcequota{namespace="testNS",resource="storage",resourcequota="quotaTest",type="used"} 9e+09 `, }, + // Verify kube_resourcequota_annotations and kube_resourcequota_labels are shown. + { + AllowAnnotationsList: []string{ + "foo", + }, + AllowLabelsList: []string{ + "hello", + }, + Obj: &v1.ResourceQuota{ + ObjectMeta: metav1.ObjectMeta{ + Name: "quotaTest", + CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)}, + Namespace: "testNS", + Annotations: map[string]string{ + "foo": "bar", + }, + Labels: map[string]string{ + "hello": "world", + }, + }, + Status: v1.ResourceQuotaStatus{}, + }, + Want: metadata + ` + kube_resourcequota_annotations{annotation_foo="bar",namespace="testNS",resourcequota="quotaTest"} 1 + kube_resourcequota_created{namespace="testNS",resourcequota="quotaTest"} 1.5e+09 + kube_resourcequota_labels{label_hello="world",namespace="testNS",resourcequota="quotaTest"} 1 + `, + }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(resourceQuotaMetricFamilies) - c.Headers = generator.ExtractMetricFamilyHeaders(resourceQuotaMetricFamilies) + c.Func = generator.ComposeMetricGenFuncs(resourceQuotaMetricFamilies(c.AllowAnnotationsList, c.AllowLabelsList)) + c.Headers = generator.ExtractMetricFamilyHeaders(resourceQuotaMetricFamilies(c.AllowAnnotationsList, c.AllowLabelsList)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) }