Merge pull request #1823 from rexagod/1815
Support filtering label allowlist by "*"
This commit is contained in:
commit
d5bd2c8274
|
|
@ -42,7 +42,7 @@ Usage of ./kube-state-metrics:
|
|||
--metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.
|
||||
--metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').
|
||||
--metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.
|
||||
--metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]').
|
||||
--metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.
|
||||
--metric-opt-in-list string Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists
|
||||
--namespaces string Comma-separated list of namespaces to be enabled. Defaults to ""
|
||||
--namespaces-denylist string Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, only namespaces that are excluded in namespaces-denylist will be used.
|
||||
|
|
|
|||
|
|
@ -213,11 +213,19 @@ func (b *Builder) WithAllowAnnotations(annotations map[string][]string) {
|
|||
func (b *Builder) WithAllowLabels(labels map[string][]string) error {
|
||||
if len(labels) > 0 {
|
||||
for label := range labels {
|
||||
if !resourceExists(label) {
|
||||
if !resourceExists(label) && label != "*" {
|
||||
return fmt.Errorf("resource %s does not exist. Available resources: %s", label, strings.Join(availableResources(), ","))
|
||||
}
|
||||
}
|
||||
b.allowLabelsList = labels
|
||||
// "*" takes precedence over other specifications
|
||||
if allowedLabels, ok := labels["*"]; ok {
|
||||
m := make(map[string][]string)
|
||||
for _, resource := range b.enabledResources {
|
||||
m[resource] = allowedLabels
|
||||
}
|
||||
b.allowLabelsList = m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Copyright 2022 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package store
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kube-state-metrics/v2/pkg/options"
|
||||
)
|
||||
|
||||
type LabelsAllowList options.LabelsAllowList
|
||||
|
||||
type expectedError struct {
|
||||
expectedResourceError bool
|
||||
expectedLabelError bool
|
||||
expectedNotEqual bool
|
||||
}
|
||||
|
||||
func TestWithAllowLabels(t *testing.T) {
|
||||
tests := []struct {
|
||||
Desc string
|
||||
LabelsAllowlist map[string][]string
|
||||
EnabledResources []string
|
||||
Wanted LabelsAllowList
|
||||
err expectedError
|
||||
}{
|
||||
{
|
||||
Desc: "wildcard key-value as the only element",
|
||||
LabelsAllowlist: map[string][]string{"*": {"*"}},
|
||||
EnabledResources: []string{"cronjobs", "pods", "deployments"},
|
||||
Wanted: LabelsAllowList(map[string][]string{
|
||||
"deployments": {"*"},
|
||||
"pods": {"*"},
|
||||
"cronjobs": {"*"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Desc: "wildcard key-value as not the only element",
|
||||
LabelsAllowlist: map[string][]string{"*": {"*"}, "pods": {"*"}, "cronjobs": {"*"}},
|
||||
EnabledResources: []string{"cronjobs", "pods", "deployments"},
|
||||
Wanted: LabelsAllowList(map[string][]string{
|
||||
"deployments": {"*"},
|
||||
"pods": {"*"},
|
||||
"cronjobs": {"*"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Desc: "wildcard key-value as not the only element, with resource mismatch",
|
||||
LabelsAllowlist: map[string][]string{"*": {"*"}, "pods": {"*"}, "cronjobs": {"*"}, "configmaps": {"*"}},
|
||||
EnabledResources: []string{"cronjobs", "pods", "deployments"},
|
||||
Wanted: LabelsAllowList{},
|
||||
err: expectedError{
|
||||
expectedNotEqual: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "wildcard key-value as not the only element, with other mutually-exclusive keys",
|
||||
LabelsAllowlist: map[string][]string{"*": {"*"}, "foo": {"*"}, "bar": {"*"}, "cronjobs": {"*"}},
|
||||
EnabledResources: []string{"cronjobs", "pods", "deployments"},
|
||||
Wanted: LabelsAllowList(nil),
|
||||
err: expectedError{
|
||||
expectedLabelError: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Desc: "wildcard key-value as not the only element, with other resources that do not exist",
|
||||
LabelsAllowlist: map[string][]string{"*": {"*"}, "cronjobs": {"*"}},
|
||||
EnabledResources: []string{"cronjobs", "pods", "deployments", "foo", "bar"},
|
||||
Wanted: LabelsAllowList{},
|
||||
err: expectedError{
|
||||
expectedResourceError: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
b := NewBuilder()
|
||||
|
||||
// Set the enabled resources.
|
||||
err := b.WithEnabledResources(test.EnabledResources)
|
||||
if err != nil && !test.err.expectedResourceError {
|
||||
t.Log("Did not expect error while setting resources (--resources).")
|
||||
t.Errorf("Test error for Desc: %s. Got Error: %v", test.Desc, err)
|
||||
}
|
||||
|
||||
// Resolve the allow list.
|
||||
err = b.WithAllowLabels(test.LabelsAllowlist)
|
||||
if err != nil && !test.err.expectedLabelError {
|
||||
t.Log("Did not expect error while parsing allow list labels (--metric-labels-allowlist).")
|
||||
t.Errorf("Test error for Desc: %s. Got Error: %v", test.Desc, err)
|
||||
}
|
||||
resolvedAllowLabels := LabelsAllowList(b.allowLabelsList)
|
||||
|
||||
// Evaluate.
|
||||
if !reflect.DeepEqual(resolvedAllowLabels, test.Wanted) && !test.err.expectedNotEqual {
|
||||
t.Log("Expected maps to be equal.")
|
||||
t.Errorf("Test error for Desc: %s\n Want: \n%+v\n Got: \n%#+v", test.Desc, test.Wanted, resolvedAllowLabels)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ func (o *Options) AddFlags() {
|
|||
o.flags.Var(&o.MetricDenylist, "metric-denylist", "Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.")
|
||||
o.flags.Var(&o.MetricOptInList, "metric-opt-in-list", "Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists")
|
||||
o.flags.Var(&o.AnnotationsAllowList, "metric-annotations-allowlist", "Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').")
|
||||
o.flags.Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]').")
|
||||
o.flags.Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.")
|
||||
o.flags.Int32Var(&o.Shard, "shard", int32(0), "The instances shard nominal (zero indexed) within the total number of shards. (default 0)")
|
||||
o.flags.IntVar(&o.TotalShards, "total-shards", 1, "The total number of shards. Sharding is disabled when total shards is set to 1.")
|
||||
|
||||
|
|
|
|||
|
|
@ -373,6 +373,15 @@ func TestLabelsAllowListSet(t *testing.T) {
|
|||
"bar",
|
||||
"*"}}),
|
||||
},
|
||||
{
|
||||
Desc: "with key as wildcard",
|
||||
Value: "*=[*]",
|
||||
Wanted: LabelsAllowList(map[string][]string{
|
||||
"*": {
|
||||
"*",
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
|||
Loading…
Reference in New Issue