Merge remote-tracking branch 'origin/master' into annotations

This commit is contained in:
Sylvain Rabot 2021-07-07 09:31:49 +02:00
commit 754aeb786b
No known key found for this signature in database
GPG Key ID: 13D27DFB503A8D91
8 changed files with 67 additions and 113 deletions

View File

@ -7,6 +7,7 @@
**What this PR does / why we need it**:
**How does this change affect the cardinality of KSM**: *(increases, decreases or does not change cardinality)*
**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

View File

@ -2,8 +2,8 @@
| Metric name| Metric type | Labels/tags | Status |
| ---------- | ----------- | ----------- | ----------- |
| kube_certificatesigningrequest_annotations | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt;| STABLE |
| kube_certificatesigningrequest_created| Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt;| STABLE |
| kube_certificatesigningrequest_condition | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `condition`=&lt;approved\|denied&gt; | STABLE |
| kube_certificatesigningrequest_labels | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt;| STABLE |
| kube_certificatesigningrequest_cert_length | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt;| STABLE |
| kube_certificatesigningrequest_annotations | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `signer_name`=&lt;certificatesigningrequest-signer-name&gt;| STABLE |
| kube_certificatesigningrequest_created| Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `signer_name`=&lt;certificatesigningrequest-signer-name&gt;| STABLE |
| kube_certificatesigningrequest_condition | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `signer_name`=&lt;certificatesigningrequest-signer-name&gt; <br> `condition`=&lt;approved\|denied&gt; | STABLE |
| kube_certificatesigningrequest_labels | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `signer_name`=&lt;certificatesigningrequest-signer-name&gt;| STABLE |
| kube_certificatesigningrequest_cert_length | Gauge | `certificatesigningrequest`=&lt;certificatesigningrequest-name&gt; <br> `signer_name`=&lt;certificatesigningrequest-signer-name&gt;| STABLE |

View File

@ -51,6 +51,10 @@ import (
"k8s.io/kube-state-metrics/v2/pkg/watch"
)
// Make sure the internal Builder implements the public BuilderInterface.
// New Builder methods should be added to the public BuilderInterface.
var _ ksmtypes.BuilderInterface = &Builder{}
// Builder helps to build store. It follows the builder pattern
// (https://en.wikipedia.org/wiki/Builder_pattern).
type Builder struct {

View File

@ -35,7 +35,7 @@ var (
descCSRAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels."
descCSRLabelsName = "kube_certificatesigningrequest_labels"
descCSRLabelsHelp = "Kubernetes labels converted to Prometheus labels."
descCSRLabelsDefaultLabels = []string{"certificatesigningrequest"}
descCSRLabelsDefaultLabels = []string{"certificatesigningrequest", "signer_name"}
)
func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator {
@ -134,7 +134,7 @@ func wrapCSRFunc(f func(*certv1.CertificateSigningRequest) *metric.Family) func(
for _, m := range metricFamily.Metrics {
m.LabelKeys = append(descCSRLabelsDefaultLabels, m.LabelKeys...)
m.LabelValues = append([]string{csr.Name}, m.LabelValues...)
m.LabelValues = append([]string{csr.Name, csr.Spec.SignerName}, m.LabelValues...)
}
return metricFamily

View File

@ -49,14 +49,16 @@ func TestCsrStore(t *testing.T) {
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
},
Status: certv1.CertificateSigningRequestStatus{},
Spec: certv1.CertificateSigningRequestSpec{},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 0
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 0
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 0
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},
@ -77,14 +79,16 @@ func TestCsrStore(t *testing.T) {
},
},
},
Spec: certv1.CertificateSigningRequestSpec{},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 0
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 1
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 0
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 0
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 1
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},
@ -105,14 +109,16 @@ func TestCsrStore(t *testing.T) {
},
},
},
Spec: certv1.CertificateSigningRequestSpec{},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 0
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},
@ -126,6 +132,9 @@ func TestCsrStore(t *testing.T) {
},
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
Status: certv1.CertificateSigningRequestStatus{
Certificate: []byte("just for test"),
Conditions: []certv1.CertificateSigningRequestCondition{
@ -136,11 +145,11 @@ func TestCsrStore(t *testing.T) {
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 13
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 0
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 13
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},
@ -154,6 +163,9 @@ func TestCsrStore(t *testing.T) {
},
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
Status: certv1.CertificateSigningRequestStatus{
Conditions: []certv1.CertificateSigningRequestCondition{
{
@ -166,11 +178,11 @@ func TestCsrStore(t *testing.T) {
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 1
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 0
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 1
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 1
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},
@ -184,6 +196,9 @@ func TestCsrStore(t *testing.T) {
},
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
},
Spec: certv1.CertificateSigningRequestSpec{
SignerName: "signer",
},
Status: certv1.CertificateSigningRequestStatus{
Conditions: []certv1.CertificateSigningRequestCondition{
{
@ -202,11 +217,11 @@ func TestCsrStore(t *testing.T) {
},
},
Want: metadata + `
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="approved"} 2
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",condition="denied"} 2
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test"} 0
kube_certificatesigningrequest_created{certificatesigningrequest="certificate-test",signer_name="signer"} 1.5e+09
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="approved"} 2
kube_certificatesigningrequest_condition{certificatesigningrequest="certificate-test",signer_name="signer",condition="denied"} 2
kube_certificatesigningrequest_labels{certificatesigningrequest="certificate-test",signer_name="signer"} 1
kube_certificatesigningrequest_cert_length{certificatesigningrequest="certificate-test",signer_name="signer"} 0
`,
MetricNames: []string{"kube_certificatesigningrequest_created", "kube_certificatesigningrequest_condition", "kube_certificatesigningrequest_labels", "kube_certificatesigningrequest_cert_length"},
},

View File

@ -84,6 +84,11 @@ func (b *Builder) WithAllowDenyList(l ksmtypes.AllowDenyLister) {
b.internal.WithAllowDenyList(l)
}
// WithAllowLabels configures which labels can be returned for metrics
func (b *Builder) WithAllowLabels(l map[string][]string) {
b.internal.WithAllowLabels(l)
}
// WithGenerateStoreFunc configures a custom generate store function
func (b *Builder) WithGenerateStoreFunc(f ksmtypes.BuildStoreFunc) {
b.internal.WithGenerateStoreFunc(f)

View File

@ -39,6 +39,7 @@ type BuilderInterface interface {
WithVPAClient(c vpaclientset.Interface)
WithAllowDenyList(l AllowDenyLister)
WithGenerateStoreFunc(f BuildStoreFunc)
WithAllowLabels(l map[string][]string)
DefaultGenerateStoreFunc() BuildStoreFunc
Build() []cache.Store
}

View File

@ -17,7 +17,6 @@ limitations under the License.
package listwatch
import (
"context"
"fmt"
"strings"
"sync"
@ -25,82 +24,11 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/cache"
)
// NewUnprivilegedNamespaceListWatchFromClient mimics
// cache.NewListWatchFromClient.
// It allows for the creation of a cache.ListWatch for namespaces from a client
// that does not have `List` privileges. If the slice of namespaces contains
// only v1.NamespaceAll, then this func assumes that the client has List and
// Watch privileges and returns a regular cache.ListWatch, since there is no
// other way to get all namespaces.
//
// The allowed namespaces and denied namespaces are mutually exclusive.
// See NewFilteredUnprivilegedNamespaceListWatchFromClient for a description on how they are applied.
func NewUnprivilegedNamespaceListWatchFromClient(c cache.Getter, allowedNamespaces, deniedNamespaces []string, fieldSelector fields.Selector) cache.ListerWatcher {
optionsModifier := func(options *metav1.ListOptions) {
options.FieldSelector = fieldSelector.String()
}
return NewFilteredUnprivilegedNamespaceListWatchFromClient(c, allowedNamespaces, deniedNamespaces, optionsModifier)
}
// NewFilteredUnprivilegedNamespaceListWatchFromClient mimics
// cache.NewUnprivilegedNamespaceListWatchFromClient.
// It allows for the creation of a cache.ListWatch for allowed or denied namespaces
// from a client that does not have `List` privileges.
//
// If the given allowed namespaces contain only v1.NamespaceAll,
// then this function assumes that the client has List and
// Watch privileges and returns a regular cache.ListWatch, since there is no
// other way to get all namespaces.
//
// The given allowed and denied namespaces are mutually exclusive.
// If allowed namespaces contain multiple items, the given denied namespaces have no effect.
// If the allowed namespaces includes exactly one entry with the value v1.NamespaceAll (empty string),
// the given denied namespaces are applied.
func NewFilteredUnprivilegedNamespaceListWatchFromClient(c cache.Getter, allowedNamespaces, deniedNamespaces []string, optionsModifier func(options *metav1.ListOptions)) cache.ListerWatcher {
// If the only namespace given is `v1.NamespaceAll`, then this
// cache.ListWatch must be privileged. In this case, return a regular
// cache.ListWatch decorated with a denylist watcher
// filtering the given denied namespaces.
if IsAllNamespaces(allowedNamespaces) {
return newDenylistListerWatcher(
deniedNamespaces,
cache.NewFilteredListWatchFromClient(c, "namespaces", metav1.NamespaceAll, optionsModifier),
)
}
listFunc := func(options metav1.ListOptions) (runtime.Object, error) {
optionsModifier(&options)
list := &v1.NamespaceList{}
for _, name := range allowedNamespaces {
result := &v1.Namespace{}
err := c.Get().
Resource("namespaces").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(context.TODO()).
Into(result)
if err != nil {
return nil, err
}
list.Items = append(list.Items, *result)
}
return list, nil
}
watchFunc := func(_ metav1.ListOptions) (watch.Interface, error) {
// Since the client does not have Watch privileges, do not
// actually watch anything. Use a watch.FakeWatcher here to
// implement watch.Interface but not send any events.
return watch.NewFake(), nil
}
return &cache.ListWatch{ListFunc: listFunc, WatchFunc: watchFunc}
}
// MultiNamespaceListerWatcher takes allowed and denied namespaces and a
// cache.ListerWatcher generator func and returns a single cache.ListerWatcher
// capable of operating on multiple namespaces.