mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Added rest client metrics for client TTL and rot. (#84382)
* Added rest client metrics for client TTL and rot. * Fixed foo bar comment, added nil checks * Moved rotation observation inside of old cert nil check block * Fixed rotation age logic. * fixed BUILD for exec plugin package * fixed null pointer dereference in exec.go * Updated metric name, bucket, used oldest cert.
This commit is contained in:
parent
143f9dd7cc
commit
9dcb3bfcff
@ -2,7 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
|||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["exec.go"],
|
srcs = [
|
||||||
|
"exec.go",
|
||||||
|
"metrics.go",
|
||||||
|
],
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec",
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec",
|
||||||
importpath = "k8s.io/client-go/plugin/pkg/client/auth/exec",
|
importpath = "k8s.io/client-go/plugin/pkg/client/auth/exec",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
@ -16,6 +19,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1:go_default_library",
|
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1:go_default_library",
|
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/tools/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/util/connrotation:go_default_library",
|
"//staging/src/k8s.io/client-go/util/connrotation:go_default_library",
|
||||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||||
@ -26,7 +30,10 @@ go_library(
|
|||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["exec_test.go"],
|
srcs = [
|
||||||
|
"exec_test.go",
|
||||||
|
"metrics_test.go",
|
||||||
|
],
|
||||||
data = glob(["testdata/**"]),
|
data = glob(["testdata/**"]),
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
@ -34,6 +41,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication:go_default_library",
|
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/tools/metrics:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -42,6 +43,7 @@ import (
|
|||||||
"k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
|
"k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
|
||||||
"k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
"k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
|
||||||
"k8s.io/client-go/tools/clientcmd/api"
|
"k8s.io/client-go/tools/clientcmd/api"
|
||||||
|
"k8s.io/client-go/tools/metrics"
|
||||||
"k8s.io/client-go/transport"
|
"k8s.io/client-go/transport"
|
||||||
"k8s.io/client-go/util/connrotation"
|
"k8s.io/client-go/util/connrotation"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
@ -260,6 +262,8 @@ func (a *Authenticator) cert() (*tls.Certificate, error) {
|
|||||||
func (a *Authenticator) getCreds() (*credentials, error) {
|
func (a *Authenticator) getCreds() (*credentials, error) {
|
||||||
a.mu.Lock()
|
a.mu.Lock()
|
||||||
defer a.mu.Unlock()
|
defer a.mu.Unlock()
|
||||||
|
defer expirationMetrics.report(time.Now)
|
||||||
|
|
||||||
if a.cachedCreds != nil && !a.credsExpired() {
|
if a.cachedCreds != nil && !a.credsExpired() {
|
||||||
return a.cachedCreds, nil
|
return a.cachedCreds, nil
|
||||||
}
|
}
|
||||||
@ -267,6 +271,7 @@ func (a *Authenticator) getCreds() (*credentials, error) {
|
|||||||
if err := a.refreshCredsLocked(nil); err != nil {
|
if err := a.refreshCredsLocked(nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.cachedCreds, nil
|
return a.cachedCreds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,6 +360,17 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed parsing client key/certificate: %v", err)
|
return fmt.Errorf("failed parsing client key/certificate: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leaf is initialized to be nil:
|
||||||
|
// https://golang.org/pkg/crypto/tls/#X509KeyPair
|
||||||
|
// Leaf certificate is the first certificate:
|
||||||
|
// https://golang.org/pkg/crypto/tls/#Certificate
|
||||||
|
// Populating leaf is useful for quickly accessing the underlying x509
|
||||||
|
// certificate values.
|
||||||
|
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed parsing client leaf certificate: %v", err)
|
||||||
|
}
|
||||||
newCreds.cert = &cert
|
newCreds.cert = &cert
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,10 +378,20 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
|||||||
a.cachedCreds = newCreds
|
a.cachedCreds = newCreds
|
||||||
// Only close all connections when TLS cert rotates. Token rotation doesn't
|
// Only close all connections when TLS cert rotates. Token rotation doesn't
|
||||||
// need the extra noise.
|
// need the extra noise.
|
||||||
if len(a.onRotateList) > 0 && oldCreds != nil && !reflect.DeepEqual(oldCreds.cert, a.cachedCreds.cert) {
|
if oldCreds != nil && !reflect.DeepEqual(oldCreds.cert, a.cachedCreds.cert) {
|
||||||
|
// Can be nil if the exec auth plugin only returned token auth.
|
||||||
|
if oldCreds.cert != nil && oldCreds.cert.Leaf != nil {
|
||||||
|
metrics.ClientCertRotationAge.Observe(time.Now().Sub(oldCreds.cert.Leaf.NotBefore))
|
||||||
|
}
|
||||||
for _, onRotate := range a.onRotateList {
|
for _, onRotate := range a.onRotateList {
|
||||||
onRotate()
|
onRotate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expiry := time.Time{}
|
||||||
|
if a.cachedCreds.cert != nil && a.cachedCreds.cert.Leaf != nil {
|
||||||
|
expiry = a.cachedCreds.cert.Leaf.NotAfter
|
||||||
|
}
|
||||||
|
expirationMetrics.set(a, expiry)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,10 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
validCert = &cert
|
validCert = &cert
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,7 +764,7 @@ func TestConcurrentUpdateTransportConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// genClientCert generates an x509 certificate for testing. Certificate and key
|
// genClientCert generates an x509 certificate for testing. Certificate and key
|
||||||
// are returned in PEM encoding.
|
// are returned in PEM encoding. The generated cert expires in 24 hours.
|
||||||
func genClientCert(t *testing.T) ([]byte, []byte) {
|
func genClientCert(t *testing.T) ([]byte, []byte) {
|
||||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 exec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/tools/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
type certificateExpirationTracker struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
m map[*Authenticator]time.Time
|
||||||
|
earliest time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var expirationMetrics = &certificateExpirationTracker{m: map[*Authenticator]time.Time{}}
|
||||||
|
|
||||||
|
// set stores the given expiration time and updates the updates earliest.
|
||||||
|
func (c *certificateExpirationTracker) set(a *Authenticator, t time.Time) {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
c.m[a] = t
|
||||||
|
|
||||||
|
// update earliest
|
||||||
|
earliest := time.Time{}
|
||||||
|
for _, t := range c.m {
|
||||||
|
if t.IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if earliest.IsZero() || earliest.After(t) {
|
||||||
|
earliest = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.earliest = earliest
|
||||||
|
}
|
||||||
|
|
||||||
|
// report reports the ttl to the earliest reported expiration time.
|
||||||
|
// If no Authenticators have reported a certificate expiration, this reports nil.
|
||||||
|
func (c *certificateExpirationTracker) report(now func() time.Time) {
|
||||||
|
c.mu.RLock()
|
||||||
|
defer c.mu.RUnlock()
|
||||||
|
if c.earliest.IsZero() {
|
||||||
|
metrics.ClientCertTTL.Set(nil)
|
||||||
|
} else {
|
||||||
|
ttl := c.earliest.Sub(now())
|
||||||
|
metrics.ClientCertTTL.Set(&ttl)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 exec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/tools/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockTTLGauge struct {
|
||||||
|
v *time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockTTLGauge) Set(d *time.Duration) {
|
||||||
|
m.v = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptr(d time.Duration) *time.Duration {
|
||||||
|
return &d
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCertificateExpirationTracker(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
nowFn := func() time.Time { return now }
|
||||||
|
mockMetric := &mockTTLGauge{}
|
||||||
|
realMetric := metrics.ClientCertTTL
|
||||||
|
metrics.ClientCertTTL = mockMetric
|
||||||
|
defer func() {
|
||||||
|
metrics.ClientCertTTL = realMetric
|
||||||
|
}()
|
||||||
|
|
||||||
|
tracker := &certificateExpirationTracker{m: map[*Authenticator]time.Time{}}
|
||||||
|
tracker.report(nowFn)
|
||||||
|
if mockMetric.v != nil {
|
||||||
|
t.Error("empty tracker should record nil value")
|
||||||
|
}
|
||||||
|
|
||||||
|
firstAuthenticator := &Authenticator{}
|
||||||
|
secondAuthenticator := &Authenticator{}
|
||||||
|
for _, tc := range []struct {
|
||||||
|
desc string
|
||||||
|
auth *Authenticator
|
||||||
|
time time.Time
|
||||||
|
want *time.Duration
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "ttl for one authenticator",
|
||||||
|
auth: firstAuthenticator,
|
||||||
|
time: now.Add(time.Minute * 10),
|
||||||
|
want: ptr(time.Minute * 10),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "second authenticator shorter ttl",
|
||||||
|
auth: secondAuthenticator,
|
||||||
|
time: now.Add(time.Minute * 5),
|
||||||
|
want: ptr(time.Minute * 5),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "update shorter to be longer",
|
||||||
|
auth: secondAuthenticator,
|
||||||
|
time: now.Add(time.Minute * 15),
|
||||||
|
want: ptr(time.Minute * 10),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "update shorter to be zero time",
|
||||||
|
auth: firstAuthenticator,
|
||||||
|
time: time.Time{},
|
||||||
|
want: ptr(time.Minute * 15),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "update last to be zero time records nil",
|
||||||
|
auth: secondAuthenticator,
|
||||||
|
time: time.Time{},
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
// Must run in series as the tests build off each other.
|
||||||
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
tracker.set(tc.auth, tc.time)
|
||||||
|
tracker.report(nowFn)
|
||||||
|
if mockMetric.v != nil && tc.want != nil {
|
||||||
|
if mockMetric.v.Seconds() != tc.want.Seconds() {
|
||||||
|
t.Errorf("got: %v; want: %v", mockMetric.v, tc.want)
|
||||||
|
}
|
||||||
|
} else if mockMetric.v != tc.want {
|
||||||
|
t.Errorf("got: %v; want: %v", mockMetric.v, tc.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,16 @@ import (
|
|||||||
|
|
||||||
var registerMetrics sync.Once
|
var registerMetrics sync.Once
|
||||||
|
|
||||||
|
// DurationMetric is a measurement of some amount of time.
|
||||||
|
type DurationMetric interface {
|
||||||
|
Observe(duration time.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TTLMetric sets the time to live of something.
|
||||||
|
type TTLMetric interface {
|
||||||
|
Set(ttl *time.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
// LatencyMetric observes client latency partitioned by verb and url.
|
// LatencyMetric observes client latency partitioned by verb and url.
|
||||||
type LatencyMetric interface {
|
type LatencyMetric interface {
|
||||||
Observe(verb string, u url.URL, latency time.Duration)
|
Observe(verb string, u url.URL, latency time.Duration)
|
||||||
@ -37,21 +47,51 @@ type ResultMetric interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// ClientCertTTL is the time to live of a client certificate
|
||||||
|
ClientCertTTL TTLMetric = noopTTL{}
|
||||||
|
// ClientCertRotationAge is the age of a certificate that has just been rotated.
|
||||||
|
ClientCertRotationAge DurationMetric = noopDuration{}
|
||||||
// RequestLatency is the latency metric that rest clients will update.
|
// RequestLatency is the latency metric that rest clients will update.
|
||||||
RequestLatency LatencyMetric = noopLatency{}
|
RequestLatency LatencyMetric = noopLatency{}
|
||||||
// RequestResult is the result metric that rest clients will update.
|
// RequestResult is the result metric that rest clients will update.
|
||||||
RequestResult ResultMetric = noopResult{}
|
RequestResult ResultMetric = noopResult{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RegisterOpts contains all the metrics to register. Metrics may be nil.
|
||||||
|
type RegisterOpts struct {
|
||||||
|
ClientCertTTL TTLMetric
|
||||||
|
ClientCertRotationAge DurationMetric
|
||||||
|
RequestLatency LatencyMetric
|
||||||
|
RequestResult ResultMetric
|
||||||
|
}
|
||||||
|
|
||||||
// Register registers metrics for the rest client to use. This can
|
// Register registers metrics for the rest client to use. This can
|
||||||
// only be called once.
|
// only be called once.
|
||||||
func Register(lm LatencyMetric, rm ResultMetric) {
|
func Register(opts RegisterOpts) {
|
||||||
registerMetrics.Do(func() {
|
registerMetrics.Do(func() {
|
||||||
RequestLatency = lm
|
if opts.ClientCertTTL != nil {
|
||||||
RequestResult = rm
|
ClientCertTTL = opts.ClientCertTTL
|
||||||
|
}
|
||||||
|
if opts.ClientCertRotationAge != nil {
|
||||||
|
ClientCertRotationAge = opts.ClientCertRotationAge
|
||||||
|
}
|
||||||
|
if opts.RequestLatency != nil {
|
||||||
|
RequestLatency = opts.RequestLatency
|
||||||
|
}
|
||||||
|
if opts.RequestResult != nil {
|
||||||
|
RequestResult = opts.RequestResult
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type noopDuration struct{}
|
||||||
|
|
||||||
|
func (noopDuration) Observe(time.Duration) {}
|
||||||
|
|
||||||
|
type noopTTL struct{}
|
||||||
|
|
||||||
|
func (noopTTL) Set(*time.Duration) {}
|
||||||
|
|
||||||
type noopLatency struct{}
|
type noopLatency struct{}
|
||||||
|
|
||||||
func (noopLatency) Observe(string, url.URL, time.Duration) {}
|
func (noopLatency) Observe(string, url.URL, time.Duration) {}
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package restclient
|
package restclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -55,13 +56,62 @@ var (
|
|||||||
},
|
},
|
||||||
[]string{"code", "method", "host"},
|
[]string{"code", "method", "host"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
execPluginCertTTL = k8smetrics.NewGauge(
|
||||||
|
&k8smetrics.GaugeOpts{
|
||||||
|
Name: "rest_client_exec_plugin_ttl_seconds",
|
||||||
|
Help: "Gauge of the shortest TTL (time-to-live) of the client " +
|
||||||
|
"certificate(s) managed by the auth exec plugin. The value " +
|
||||||
|
"is in seconds until certificate expiry. If auth exec " +
|
||||||
|
"plugins are unused or manage no TLS certificates, the " +
|
||||||
|
"value will be +INF.",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
execPluginCertRotation = k8smetrics.NewHistogram(
|
||||||
|
&k8smetrics.HistogramOpts{
|
||||||
|
Name: "rest_client_exec_plugin_certificate_rotation_age",
|
||||||
|
Help: "Histogram of the number of seconds the last auth exec " +
|
||||||
|
"plugin client certificate lived before being rotated. " +
|
||||||
|
"If auth exec plugin client certificates are unused, " +
|
||||||
|
"histogram will contain no data.",
|
||||||
|
// There are three sets of ranges these buckets intend to capture:
|
||||||
|
// - 10-60 minutes: captures a rotation cadence which is
|
||||||
|
// happening too quickly.
|
||||||
|
// - 4 hours - 1 month: captures an ideal rotation cadence.
|
||||||
|
// - 3 months - 4 years: captures a rotation cadence which is
|
||||||
|
// is probably too slow or much too slow.
|
||||||
|
Buckets: []float64{
|
||||||
|
600, // 10 minutes
|
||||||
|
1800, // 30 minutes
|
||||||
|
3600, // 1 hour
|
||||||
|
14400, // 4 hours
|
||||||
|
86400, // 1 day
|
||||||
|
604800, // 1 week
|
||||||
|
2592000, // 1 month
|
||||||
|
7776000, // 3 months
|
||||||
|
15552000, // 6 months
|
||||||
|
31104000, // 1 year
|
||||||
|
124416000, // 4 years
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
execPluginCertTTL.Set(math.Inf(1)) // Initialize TTL to +INF
|
||||||
|
|
||||||
legacyregistry.MustRegister(requestLatency)
|
legacyregistry.MustRegister(requestLatency)
|
||||||
legacyregistry.MustRegister(deprecatedRequestLatency)
|
legacyregistry.MustRegister(deprecatedRequestLatency)
|
||||||
legacyregistry.MustRegister(requestResult)
|
legacyregistry.MustRegister(requestResult)
|
||||||
metrics.Register(&latencyAdapter{m: requestLatency, dm: deprecatedRequestLatency}, &resultAdapter{requestResult})
|
legacyregistry.MustRegister(execPluginCertTTL)
|
||||||
|
legacyregistry.MustRegister(execPluginCertRotation)
|
||||||
|
metrics.Register(metrics.RegisterOpts{
|
||||||
|
ClientCertTTL: &ttlAdapter{m: execPluginCertTTL},
|
||||||
|
ClientCertRotationAge: &rotationAdapter{m: execPluginCertRotation},
|
||||||
|
RequestLatency: &latencyAdapter{m: requestLatency, dm: deprecatedRequestLatency},
|
||||||
|
RequestResult: &resultAdapter{requestResult},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type latencyAdapter struct {
|
type latencyAdapter struct {
|
||||||
@ -81,3 +131,23 @@ type resultAdapter struct {
|
|||||||
func (r *resultAdapter) Increment(code, method, host string) {
|
func (r *resultAdapter) Increment(code, method, host string) {
|
||||||
r.m.WithLabelValues(code, method, host).Inc()
|
r.m.WithLabelValues(code, method, host).Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ttlAdapter struct {
|
||||||
|
m *k8smetrics.Gauge
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ttlAdapter) Set(ttl *time.Duration) {
|
||||||
|
if ttl == nil {
|
||||||
|
e.m.Set(math.Inf(1))
|
||||||
|
} else {
|
||||||
|
e.m.Set(float64(ttl.Seconds()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type rotationAdapter struct {
|
||||||
|
m *k8smetrics.Histogram
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rotationAdapter) Observe(d time.Duration) {
|
||||||
|
r.m.Observe(d.Seconds())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user