Skip to content

Commit 8b40296

Browse files
committed
Implement metric-gen tool
Implements the metric-gen tool which could get used to create custom resource configurations directly from code, similar to what controller-gen does.
1 parent 622efee commit 8b40296

File tree

16 files changed

+1115
-8
lines changed

16 files changed

+1115
-8
lines changed

docs/cli-arguments.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Usage:
3434

3535
Available Commands:
3636
completion Generate completion script for kube-state-metrics.
37+
generate Generate custom resource metrics configuration from go-code markers.
3738
help Help about any command
3839
version Print version information.
3940

go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ require (
2424
k8s.io/klog/v2 v2.110.1
2525
k8s.io/sample-controller v0.28.4
2626
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
27+
sigs.k8s.io/controller-tools v0.13.0
2728
)
2829

2930
require (
@@ -34,6 +35,7 @@ require (
3435
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3536
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
3637
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
38+
github.com/fatih/color v1.15.0 // indirect
3739
github.com/go-kit/log v0.2.1 // indirect
3840
github.com/go-logfmt/logfmt v0.5.1 // indirect
3941
github.com/go-logr/logr v1.3.0 // indirect
@@ -53,6 +55,8 @@ require (
5355
github.com/json-iterator/go v1.1.12 // indirect
5456
github.com/magiconair/properties v1.8.7 // indirect
5557
github.com/mailru/easyjson v0.7.7 // indirect
58+
github.com/mattn/go-colorable v0.1.13 // indirect
59+
github.com/mattn/go-isatty v0.0.17 // indirect
5660
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
5761
github.com/mitchellh/mapstructure v1.5.0 // indirect
5862
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -73,18 +77,21 @@ require (
7377
go.uber.org/multierr v1.11.0 // indirect
7478
golang.org/x/crypto v0.16.0 // indirect
7579
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
80+
golang.org/x/mod v0.12.0 // indirect
7681
golang.org/x/net v0.19.0 // indirect
7782
golang.org/x/oauth2 v0.15.0 // indirect
7883
golang.org/x/sync v0.5.0 // indirect
7984
golang.org/x/sys v0.15.0 // indirect
8085
golang.org/x/term v0.15.0 // indirect
8186
golang.org/x/text v0.14.0 // indirect
8287
golang.org/x/time v0.5.0 // indirect
88+
golang.org/x/tools v0.13.0 // indirect
8389
google.golang.org/appengine v1.6.7 // indirect
8490
google.golang.org/protobuf v1.31.0 // indirect
8591
gopkg.in/inf.v0 v0.9.1 // indirect
8692
gopkg.in/ini.v1 v1.67.0 // indirect
8793
gopkg.in/yaml.v2 v2.4.0 // indirect
94+
k8s.io/apiextensions-apiserver v0.28.0 // indirect
8895
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
8996
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
9097
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect

go.sum

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhF
1818
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
1919
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
2020
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
21+
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
22+
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
2123
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
2224
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
2325
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
@@ -78,6 +80,11 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
7880
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
7981
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
8082
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
83+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
84+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
85+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
86+
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
87+
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
8188
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
8289
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
8390
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@@ -91,10 +98,12 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
9198
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
9299
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
93100
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
101+
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
94102
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
95103
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
104+
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
96105
github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
97-
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
106+
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
98107
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
99108
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
100109
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -156,6 +165,8 @@ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjs
156165
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
157166
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
158167
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
168+
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
169+
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
159170
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
160171
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
161172
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -173,6 +184,7 @@ golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
173184
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
174185
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
175186
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
187+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
176188
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
177189
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
178190
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
@@ -189,6 +201,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
189201
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
190202
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
191203
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
204+
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
192205
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
193206
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
194207
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -206,6 +219,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
206219
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
207220
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
208221
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
222+
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
209223
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
210224
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
211225
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
@@ -214,6 +228,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
214228
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
215229
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
216230
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
231+
k8s.io/apiextensions-apiserver v0.28.0 h1:CszgmBL8CizEnj4sj7/PtLGey6Na3YgWyGCPONv7E9E=
232+
k8s.io/apiextensions-apiserver v0.28.0/go.mod h1:uRdYiwIuu0SyqJKriKmqEN2jThIJPhVmOWETm8ud1VE=
217233
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
218234
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
219235
k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
@@ -228,6 +244,8 @@ k8s.io/sample-controller v0.28.4 h1:qghAHWGAFbDaTssOEiktdjbpq9avioOKRMB+KEwBIR0=
228244
k8s.io/sample-controller v0.28.4/go.mod h1:XXL627j2rVrUQTMpebt6imNnSE30tmFnAOvZsYUsWpo=
229245
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
230246
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
247+
sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI=
248+
sigs.k8s.io/controller-tools v0.13.0/go.mod h1:5vw3En2NazbejQGCeWKRrE7q4P+CW8/klfVqP8QZkgA=
231249
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
232250
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
233251
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=

main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"k8s.io/klog/v2"
2222

2323
"k8s.io/kube-state-metrics/v2/internal"
24+
"k8s.io/kube-state-metrics/v2/pkg/customresourcestate/generate"
2425
"k8s.io/kube-state-metrics/v2/pkg/options"
2526
)
2627

@@ -30,6 +31,7 @@ func main() {
3031
cmd.Run = func(cmd *cobra.Command, args []string) {
3132
internal.RunKubeStateMetricsWrapper(opts)
3233
}
34+
cmd.AddCommand(generate.GenerateCommand)
3335
opts.AddFlags(cmd)
3436
if err := opts.Parse(); err != nil {
3537
klog.FlushAndExit(klog.ExitFlushTimeout, 1)

pkg/customresourcestate/config.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ func (gvk GroupVersionKind) String() string {
100100
// Labels is common configuration of labels to add to metrics.
101101
type Labels struct {
102102
// CommonLabels are added to all metrics.
103-
CommonLabels map[string]string `yaml:"commonLabels" json:"commonLabels"`
103+
CommonLabels map[string]string `yaml:"commonLabels" json:"commonLabels,omitempty"`
104104
// LabelsFromPath adds additional labels where the value is taken from a field in the resource.
105-
LabelsFromPath map[string][]string `yaml:"labelsFromPath" json:"labelsFromPath"`
105+
LabelsFromPath map[string][]string `yaml:"labelsFromPath" json:"labelsFromPath,omitempty"`
106106
}
107107

108108
// Merge combines the labels from two configs, returning a new config. The other Labels will overwrite keys in this Labels.
@@ -140,7 +140,7 @@ type Generator struct {
140140
// Labels are added to all metrics. Labels from Each will overwrite these if using the same key.
141141
Labels `yaml:",inline" json:",inline"` // json will inline because it is already tagged
142142
// ErrorLogV defines the verbosity threshold for errors logged for this metric. Must be non-zero to override the resource setting.
143-
ErrorLogV klog.Level `yaml:"errorLogV" json:"errorLogV"`
143+
ErrorLogV klog.Level `yaml:"errorLogV" json:"errorLogV,omitempty"`
144144
}
145145

146146
// Metric defines a metric to expose.
@@ -152,13 +152,13 @@ type Metric struct {
152152

153153
// Gauge defines a gauge metric.
154154
// +optional
155-
Gauge *MetricGauge `yaml:"gauge" json:"gauge"`
155+
Gauge *MetricGauge `yaml:"gauge,omitempty" json:"gauge,omitempty"`
156156
// StateSet defines a state set metric.
157157
// +optional
158-
StateSet *MetricStateSet `yaml:"stateSet" json:"stateSet"`
158+
StateSet *MetricStateSet `yaml:"stateSet,omitempty" json:"stateSet,omitempty"`
159159
// Info defines an info metric.
160160
// +optional
161-
Info *MetricInfo `yaml:"info" json:"info"`
161+
Info *MetricInfo `yaml:"info,omitempty" json:"info,omitempty"`
162162
}
163163

164164
// ConfigDecoder is for use with FromConfig.

pkg/customresourcestate/config_metrics_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const (
2929
// MetricMeta are variables which may used for any metric type.
3030
type MetricMeta struct {
3131
// LabelsFromPath adds additional labels where the value of the label is taken from a field under Path.
32-
LabelsFromPath map[string][]string `yaml:"labelsFromPath" json:"labelsFromPath"`
32+
LabelsFromPath map[string][]string `yaml:"labelsFromPath,omitempty" json:"labelsFromPath,omitempty"`
3333
// Path is the path to to generate metric(s) for.
3434
Path []string `yaml:"path" json:"path"`
3535
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package generate
18+
19+
import (
20+
"fmt"
21+
"os"
22+
23+
"github.com/spf13/cobra"
24+
"sigs.k8s.io/controller-tools/pkg/genall"
25+
"sigs.k8s.io/controller-tools/pkg/genall/help"
26+
prettyhelp "sigs.k8s.io/controller-tools/pkg/genall/help/pretty"
27+
"sigs.k8s.io/controller-tools/pkg/loader"
28+
"sigs.k8s.io/controller-tools/pkg/markers"
29+
30+
"k8s.io/kube-state-metrics/v2/pkg/customresourcestate/generate/generator"
31+
)
32+
33+
const (
34+
generatorName = "metric"
35+
)
36+
37+
var (
38+
// optionsRegistry contains all the marker definitions used to process command line options
39+
optionsRegistry = &markers.Registry{}
40+
41+
generateWhichMarkersFlag bool
42+
)
43+
44+
// GenerateCommand runs the kube-state-metrics custom resource config generator.
45+
var GenerateCommand = &cobra.Command{
46+
Use: "generate [flags] /path/to/package [/path/to/package]",
47+
Short: "Generate custom resource metrics configuration from go-code markers.",
48+
DisableFlagsInUseLine: true,
49+
Args: cobra.MinimumNArgs(1),
50+
RunE: func(cmd *cobra.Command, args []string) error {
51+
if generateWhichMarkersFlag {
52+
PrintMarkerDocs()
53+
return nil
54+
}
55+
56+
// Register the metric generator itself as marker so genall.FromOptions is able to initialize the runtime properly.
57+
// This also registers the markers inside the optionsRegistry so its available to print the marker docs.
58+
metricGenerator := generator.CustomResourceConfigGenerator{}
59+
defn := markers.Must(markers.MakeDefinition(generatorName, markers.DescribesPackage, metricGenerator))
60+
if err := optionsRegistry.Register(defn); err != nil {
61+
return err
62+
}
63+
64+
// Load the passed packages as roots.
65+
roots, err := loader.LoadRoots(args...)
66+
if err != nil {
67+
return fmt.Errorf("loading packages %w", err)
68+
}
69+
70+
// Set up the generator runtime using controller-tools and passing our optionsRegistry.
71+
rt, err := genall.FromOptions(optionsRegistry, []string{generatorName})
72+
if err != nil {
73+
return fmt.Errorf("%v", err)
74+
}
75+
76+
// Setup the generation context with the loaded roots.
77+
rt.GenerationContext.Roots = roots
78+
// Setup the runtime to output to stdout.
79+
rt.OutputRules = genall.OutputRules{Default: genall.OutputToStdout}
80+
81+
// Run the generator using the runtime.
82+
if hadErrs := rt.Run(); hadErrs {
83+
return fmt.Errorf("generator did not run successfully")
84+
}
85+
86+
return nil
87+
},
88+
Example: "kube-state-metrics generate ./apis/... > custom-resource-config.yaml",
89+
}
90+
91+
func init() {
92+
GenerateCommand.Flags().BoolVarP(&generateWhichMarkersFlag, "which-markers", "w", false, "Print out all markers available with the requested generators.")
93+
}
94+
95+
// PrintMarkerDocs prints out marker help for the given generators specified in
96+
// the rawOptions
97+
func PrintMarkerDocs() error {
98+
// Register the metric generator itself as marker so genall.FromOptions is able to initialize the runtime properly.
99+
// This also registers the markers inside the optionsRegistry so its available to print the marker docs.
100+
metricGenerator := generator.CustomResourceConfigGenerator{}
101+
defn := markers.Must(markers.MakeDefinition(generatorName, markers.DescribesPackage, metricGenerator))
102+
if err := optionsRegistry.Register(defn); err != nil {
103+
return err
104+
}
105+
106+
// just grab a registry so we don't lag while trying to load roots
107+
// (like we'd do if we just constructed the full runtime).
108+
reg, err := genall.RegistryFromOptions(optionsRegistry, []string{generatorName})
109+
if err != nil {
110+
return err
111+
}
112+
113+
helpInfo := help.ByCategory(reg, help.SortByCategory)
114+
115+
for _, cat := range helpInfo {
116+
if cat.Category == "" {
117+
continue
118+
}
119+
contents := prettyhelp.MarkersDetails(false, cat.Category, cat.Markers)
120+
if err := contents.WriteTo(os.Stderr); err != nil {
121+
return err
122+
}
123+
}
124+
return nil
125+
}

0 commit comments

Comments
 (0)