Skip to content

Commit

Permalink
Allow defining custom resource flags multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
chrischdi committed Aug 19, 2022
1 parent 25f3b8f commit 3593279
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
10 changes: 6 additions & 4 deletions docs/customresourcestate-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 10 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func main() {
}

var factories []customresource.RegistryFactory
if config, set := resolveCustomResourceConfig(opts); set {
crf, err := customresourcestate.FromConfig(config)
if configs := resolveCustomResourceConfigs(opts); len(configs) > 0 {
crf, err := customresourcestate.FromConfigs(configs)
if err != nil {
klog.ErrorS(err, "Parsing from Custom Resource State Metrics file failed")
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
Expand All @@ -69,17 +69,18 @@ func main() {
}
}

func resolveCustomResourceConfig(opts *options.Options) (customresourcestate.ConfigDecoder, bool) {
if s := opts.CustomResourceConfig; s != "" {
return yaml.NewDecoder(strings.NewReader(s)), true
func resolveCustomResourceConfigs(opts *options.Options) []customresourcestate.ConfigDecoder {
decoders := []customresourcestate.ConfigDecoder{}
for _, s := range opts.CustomResourceConfigs {
decoders = append(decoders, yaml.NewDecoder(strings.NewReader(s)))
}
if file := opts.CustomResourceConfigFile; file != "" {
for _, file := range opts.CustomResourceConfigFiles {
f, err := os.Open(file)
if err != nil {
klog.ErrorS(err, "Custom Resource State Metrics file could not be opened")
klog.ErrorS(err, "Custom Resource State Metrics file could not be opened", "file", file)
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
}
return yaml.NewDecoder(f), true
decoders = append(decoders, yaml.NewDecoder(f))
}
return nil, false
return decoders
}
25 changes: 23 additions & 2 deletions pkg/customresourcestate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,30 @@ type ConfigDecoder interface {
Decode(v interface{}) (err error)
}

// 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) {
// FromConfigs decodes a configuration source into a slice of customresource.RegistryFactory that are ready to use.
func FromConfigs(decoders []ConfigDecoder) ([]customresource.RegistryFactory, error) {
factoriesIndex := map[string]bool{}
var factories []customresource.RegistryFactory
for _, decoder := range decoders {
fs, err := fromConfig(decoder)
if err != nil {
return nil, err
}
for _, f := range fs {
if _, ok := factoriesIndex[f.Name()]; ok {
return nil, fmt.Errorf("found multiple custom resource configurations for the same resource %s", f.Name())
}
factoriesIndex[f.Name()] = true
factories = append(factories, f)
}
}

return factories, nil
}

func fromConfig(decoder ConfigDecoder) ([]customresource.RegistryFactory, error) {
var crconfig Metrics
var factories []customresource.RegistryFactory
if err := decoder.Decode(&crconfig); err != nil {
return nil, fmt.Errorf("failed to parse Custom Resource State metrics: %w", err)
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ type Options struct {

UseAPIServerCache bool

CustomResourceConfig string
CustomResourceConfigFile string
CustomResourceConfigs []string
CustomResourceConfigFiles []string

flags *pflag.FlagSet
}
Expand Down Expand Up @@ -115,8 +115,8 @@ func (o *Options) AddFlags() {
o.flags.BoolVarP(&o.Version, "version", "", false, "kube-state-metrics build version information")
o.flags.BoolVar(&o.EnableGZIPEncoding, "enable-gzip-encoding", false, "Gzip responses when requested by clients via 'Accept-Encoding: gzip' header.")

o.flags.StringVar(&o.CustomResourceConfig, "custom-resource-state-config", "", "Inline Custom Resource State Metrics config YAML (experimental)")
o.flags.StringVar(&o.CustomResourceConfigFile, "custom-resource-state-config-file", "", "Path to a Custom Resource State Metrics config file (experimental)")
o.flags.StringArrayVar(&o.CustomResourceConfigs, "custom-resource-state-config", []string{}, "Inline Custom Resource State Metrics config YAML (experimental)")
o.flags.StringArrayVar(&o.CustomResourceConfigFiles, "custom-resource-state-config-file", []string{}, "Path to a Custom Resource State Metrics config file (experimental)")
}

// Parse parses the flag definitions from the argument list.
Expand Down

0 comments on commit 3593279

Please sign in to comment.