From ad6a739433bc22e12709064030dee1aeaf9157c4 Mon Sep 17 00:00:00 2001 From: Christian Schlotter Date: Wed, 24 Aug 2022 08:13:46 +0200 Subject: [PATCH] Prevent multiple custom resource configurations for the same resource --- docs/customresourcestate-metrics.md | 10 ++++++---- pkg/customresourcestate/config.go | 8 +++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/customresourcestate-metrics.md b/docs/customresourcestate-metrics.md index 501db66add..bb9262a4ef 100644 --- a/docs/customresourcestate-metrics.md +++ b/docs/customresourcestate-metrics.md @@ -9,12 +9,14 @@ A YAML configuration file described below is required to define your custom reso Two flags can be used: - * `--custom-resource-state-config "inline yaml (see example)"` or - * `--custom-resource-state-config-file /path/to/config.yaml` +* `--custom-resource-state-config "inline yaml (see example)"` or +* `--custom-resource-state-config-file /path/to/config.yaml` -If both flags are provided, the inline configuration will take precedence. +Both flags can be provided multiple times to load multiple configurations. +When multiple entries for the same resource exist, kube-state-metrics will refuse to start. +This includes configuration which refers to a different API version. -In addition to specifying one of `--custom-resource-state-config*` flags, you should also add the custom resource *Kind*s in plural form to the list of exposed resources in the `--resources` flag. If you don't specify `--resources`, then all known custom resources configured in `--custom-resource-state-config-*` and all available default kubernetes objects will be taken into account by kube-state-metrics. +In addition to specifying one of `--custom-resource-state-config*` flags, you should also add the custom resource *Kind*s in plural form to the list of exposed resources in the `--resources` flag. If you don't specify `--resources`, then all known custom resources configured in `--custom-resource-state-config*` and all available default kubernetes objects will be taken into account by kube-state-metrics. ```yaml apiVersion: apps/v1 diff --git a/pkg/customresourcestate/config.go b/pkg/customresourcestate/config.go index 01dfd8fa8f..76e7786763 100644 --- a/pkg/customresourcestate/config.go +++ b/pkg/customresourcestate/config.go @@ -162,8 +162,10 @@ type ConfigDecoder interface { } // FromConfig decodes a configuration source into a slice of customresource.RegistryFactory that are ready to use. -func FromConfig(decoder ConfigDecoder) (factories []customresource.RegistryFactory, err error) { +func FromConfig(decoder ConfigDecoder) ([]customresource.RegistryFactory, error) { var crconfig Metrics + var factories []customresource.RegistryFactory + factoriesIndex := map[string]bool{} if err := decoder.Decode(&crconfig); err != nil { return nil, fmt.Errorf("failed to parse Custom Resource State metrics: %w", err) } @@ -172,6 +174,10 @@ func FromConfig(decoder ConfigDecoder) (factories []customresource.RegistryFacto if err != nil { return nil, fmt.Errorf("failed to create metrics factory for %s: %w", resource.GroupVersionKind, err) } + if _, ok := factoriesIndex[factory.Name()]; ok { + return nil, fmt.Errorf("found multiple custom resource configurations for the same resource %s", factory.Name()) + } + factoriesIndex[factory.Name()] = true factories = append(factories, factory) } return factories, nil