diff --git a/go.mod b/go.mod index 2ec80d7c51..965b1bcaea 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,7 @@ require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.0+incompatible // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect diff --git a/internal/store/node.go b/internal/store/node.go index ae464acb5b..354abf25ca 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -23,6 +23,7 @@ import ( "k8s.io/kube-state-metrics/v2/pkg/constant" "k8s.io/kube-state-metrics/v2/pkg/metric" generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator" + basemetrics "k8s.io/component-base/metrics" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -79,10 +80,11 @@ func createNodeCreatedFamilyGenerator() generator.FamilyGenerator { } func createNodeInfoFamilyGenerator() generator.FamilyGenerator { - return *generator.NewFamilyGenerator( + return *generator.NewFamilyGeneratorWithStability( "kube_node_info", "Information about a cluster node.", metric.Gauge, + basemetrics.STABLE, "", wrapNodeFunc(func(n *v1.Node) *metric.Family { labelKeys := []string{ diff --git a/internal/store/node_test.go b/internal/store/node_test.go index 2490720d15..74b54ff215 100644 --- a/internal/store/node_test.go +++ b/internal/store/node_test.go @@ -54,7 +54,7 @@ func TestNodeStore(t *testing.T) { }, }, Want: ` - # HELP kube_node_info Information about a cluster node. + # HELP kube_node_info [STABLE] Information about a cluster node. # HELP kube_node_labels Kubernetes labels converted to Prometheus labels. # HELP kube_node_spec_unschedulable Whether a node can schedule new pods. # TYPE kube_node_info gauge @@ -74,7 +74,7 @@ func TestNodeStore(t *testing.T) { Spec: v1.NodeSpec{}, }, Want: ` - # HELP kube_node_info Information about a cluster node. + # HELP kube_node_info [STABLE] Information about a cluster node. # TYPE kube_node_info gauge kube_node_info{container_runtime_version="",kernel_version="",kubelet_version="",kubeproxy_version="",node="",os_image="",pod_cidr="",provider_id="",internal_ip="",system_uuid=""} 1 `, @@ -127,7 +127,7 @@ func TestNodeStore(t *testing.T) { }, Want: ` # HELP kube_node_created Unix creation timestamp - # HELP kube_node_info Information about a cluster node. + # HELP kube_node_info [STABLE] Information about a cluster node. # HELP kube_node_labels Kubernetes labels converted to Prometheus labels. # HELP kube_node_role The role of a cluster node. # HELP kube_node_spec_unschedulable Whether a node can schedule new pods. diff --git a/pkg/metric_generator/generator.go b/pkg/metric_generator/generator.go index dfde430d21..e8330fab04 100644 --- a/pkg/metric_generator/generator.go +++ b/pkg/metric_generator/generator.go @@ -21,6 +21,7 @@ import ( "strings" "k8s.io/kube-state-metrics/v2/pkg/metric" + basemetrics "k8s.io/component-base/metrics" ) // FamilyGenerator provides everything needed to generate a metric family with a @@ -33,16 +34,19 @@ type FamilyGenerator struct { Type metric.Type OptIn bool DeprecatedVersion string + StabilityLevel basemetrics.StabilityLevel GenerateFunc func(obj interface{}) *metric.Family } -// NewFamilyGenerator creates new FamilyGenerator instances. -func NewFamilyGenerator(name string, help string, metricType metric.Type, deprecatedVersion string, generateFunc func(obj interface{}) *metric.Family) *FamilyGenerator { +// NewFamilyGenerator creates new FamilyGenerator instances with metric +// stabilityLevel. +func NewFamilyGeneratorWithStability(name string, help string, metricType metric.Type, stabilityLevel basemetrics.StabilityLevel, deprecatedVersion string, generateFunc func(obj interface{}) *metric.Family) *FamilyGenerator { f := &FamilyGenerator{ Name: name, Type: metricType, Help: help, OptIn: false, + StabilityLevel: stabilityLevel, DeprecatedVersion: deprecatedVersion, GenerateFunc: generateFunc, } @@ -52,6 +56,11 @@ func NewFamilyGenerator(name string, help string, metricType metric.Type, deprec return f } +// NewFamilyGenerator creates new FamilyGenerator instances. +func NewFamilyGenerator(name string, help string, metricType metric.Type, deprecatedVersion string, generateFunc func(obj interface{}) *metric.Family) *FamilyGenerator { + return NewFamilyGeneratorWithStability(name, help, metricType, basemetrics.ALPHA, deprecatedVersion, generateFunc) +} + // NewOptInFamilyGenerator creates new FamilyGenerator instances for opt-in metric families. func NewOptInFamilyGenerator(name string, help string, metricType metric.Type, deprecatedVersion string, generateFunc func(obj interface{}) *metric.Family) *FamilyGenerator { f := NewFamilyGenerator(name, help, metricType, deprecatedVersion, generateFunc) @@ -75,7 +84,13 @@ func (g *FamilyGenerator) generateHeader() string { header.WriteString("# HELP ") header.WriteString(g.Name) header.WriteByte(' ') - header.WriteString(g.Help) + // Will remove if-else after all metrics are attached with right + // StabilityLevel. + if g.StabilityLevel == basemetrics.STABLE { + header.WriteString(fmt.Sprintf("[%v] %v", g.StabilityLevel, g.Help)) + } else { + header.WriteString(g.Help) + } header.WriteByte('\n') header.WriteString("# TYPE ") header.WriteString(g.Name)