@@ -27,6 +27,7 @@ import (
2727 "os"
2828 "path/filepath"
2929 "strconv"
30+ "strings"
3031 "time"
3132
3233 "gopkg.in/yaml.v3"
@@ -47,6 +48,7 @@ import (
4748 "k8s.io/kube-state-metrics/v2/internal/store"
4849 "k8s.io/kube-state-metrics/v2/pkg/allowdenylist"
4950 "k8s.io/kube-state-metrics/v2/pkg/customresource"
51+ "k8s.io/kube-state-metrics/v2/pkg/customresourcestate"
5052 generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator"
5153 "k8s.io/kube-state-metrics/v2/pkg/metricshandler"
5254 "k8s.io/kube-state-metrics/v2/pkg/optin"
@@ -73,8 +75,8 @@ func (pl promLogger) Log(v ...interface{}) error {
7375}
7476
7577// RunKubeStateMetricsWrapper runs KSM with context cancellation.
76- func RunKubeStateMetricsWrapper (ctx context.Context , opts * options.Options , factories ... customresource. RegistryFactory ) error {
77- err := RunKubeStateMetrics (ctx , opts , factories ... )
78+ func RunKubeStateMetricsWrapper (ctx context.Context , opts * options.Options ) error {
79+ err := RunKubeStateMetrics (ctx , opts )
7880 if ctx .Err () == context .Canceled {
7981 klog .Infoln ("Restarting: kube-state-metrics, metrics will be reset" )
8082 return nil
@@ -85,11 +87,10 @@ func RunKubeStateMetricsWrapper(ctx context.Context, opts *options.Options, fact
8587// RunKubeStateMetrics will build and run the kube-state-metrics.
8688// Any out-of-tree custom resource metrics could be registered by newing a registry factory
8789// which implements customresource.RegistryFactory and pass all factories into this function.
88- func RunKubeStateMetrics (ctx context.Context , opts * options.Options , factories ... customresource. RegistryFactory ) error {
90+ func RunKubeStateMetrics (ctx context.Context , opts * options.Options ) error {
8991 promLogger := promLogger {}
9092
9193 storeBuilder := store .NewBuilder ()
92- storeBuilder .WithCustomResourceStoreFactories (factories ... )
9394
9495 ksmMetricsRegistry := prometheus .NewRegistry ()
9596 ksmMetricsRegistry .MustRegister (version .NewCollector ("kube_state_metrics" ))
@@ -144,6 +145,22 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options, factories .
144145 }
145146 }
146147
148+ // Loading custom resource state configuration from cli argument or config file
149+ config , err := resolveCustomResourceConfig (opts )
150+ if err != nil {
151+ return err
152+ }
153+
154+ var factories []customresource.RegistryFactory
155+
156+ if config != nil {
157+ factories , err = customresourcestate .FromConfig (config )
158+ if err != nil {
159+ return fmt .Errorf ("Parsing from Custom Resource State Metrics file failed: %v" , err )
160+ }
161+ }
162+ storeBuilder .WithCustomResourceStoreFactories (factories ... )
163+
147164 if opts .CustomResourceConfigFile != "" {
148165 crcFile , err := os .ReadFile (filepath .Clean (opts .CustomResourceConfigFile ))
149166 if err != nil {
@@ -156,24 +173,22 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options, factories .
156173
157174 }
158175
159- var resources []string
176+ resources := make ([]string , len (factories ))
177+
178+ for i , factory := range factories {
179+ resources [i ] = factory .Name ()
180+ }
181+
160182 switch {
161183 case len (opts .Resources ) == 0 && ! opts .CustomResourcesOnly :
184+ resources = append (resources , options .DefaultResources .AsSlice ()... )
162185 klog .InfoS ("Used default resources" )
163- resources = options .DefaultResources .AsSlice ()
164- // enable custom resource
165- for _ , factory := range factories {
166- resources = append (resources , factory .Name ())
167- }
168186 case opts .CustomResourcesOnly :
169187 // enable custom resource only
170- for _ , factory := range factories {
171- resources = append (resources , factory .Name ())
172- }
173188 klog .InfoS ("Used CRD resources only" , "resources" , resources )
174189 default :
175- klog . InfoS ( "Used resources" , " resources" , opts .Resources .String () )
176- resources = opts . Resources . AsSlice ( )
190+ resources = append ( resources , opts .Resources .AsSlice () ... )
191+ klog . InfoS ( "Used resources" , "resources" , resources )
177192 }
178193
179194 if err := storeBuilder .WithEnabledResources (resources ); err != nil {
@@ -419,3 +434,17 @@ func md5HashAsMetricValue(data []byte) float64 {
419434 copy (bytes , smallSum )
420435 return float64 (binary .LittleEndian .Uint64 (bytes ))
421436}
437+
438+ func resolveCustomResourceConfig (opts * options.Options ) (customresourcestate.ConfigDecoder , error ) {
439+ if s := opts .CustomResourceConfig ; s != "" {
440+ return yaml .NewDecoder (strings .NewReader (s )), nil
441+ }
442+ if file := opts .CustomResourceConfigFile ; file != "" {
443+ f , err := os .Open (filepath .Clean (file ))
444+ if err != nil {
445+ return nil , fmt .Errorf ("Custom Resource State Metrics file could not be opened: %v" , err )
446+ }
447+ return yaml .NewDecoder (f ), nil
448+ }
449+ return nil , nil
450+ }
0 commit comments