mirror of
https://github.com/kubernetes/client-go.git
synced 2026-06-29 05:25:11 +00:00
defer metric registration to runtime entry point via constructors
Signed-off-by: Richa Banker <richabanker@google.com> Kubernetes-commit: 8721c830cf013a92a805b46eb163736f97aba2aa
This commit is contained in:
committed by
Kubernetes Publisher
parent
68262a1cf9
commit
1d2651da7d
@@ -159,6 +159,7 @@ func (s *sometimes) Do(f func()) {
|
||||
|
||||
// GetAuthenticator returns an exec-based plugin for providing client credentials.
|
||||
func GetAuthenticator(config *api.ExecConfig, cluster *clientauthentication.Cluster) (*Authenticator, error) {
|
||||
metrics.EnsureRegistered()
|
||||
return newAuthenticator(globalCache, term.IsTerminal, config, cluster)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
clientfeatures "k8s.io/client-go/features"
|
||||
"k8s.io/client-go/tools/metrics"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
@@ -110,6 +111,8 @@ type RESTClient struct {
|
||||
// NewRESTClient creates a new RESTClient. This client performs generic REST functions
|
||||
// such as Get, Put, Post, and Delete on specified paths.
|
||||
func NewRESTClient(baseURL *url.URL, versionedAPIPath string, config ClientContentConfig, rateLimiter flowcontrol.RateLimiter, client *http.Client) (*RESTClient, error) {
|
||||
metrics.EnsureRegistered()
|
||||
|
||||
base := *baseURL
|
||||
if !strings.HasSuffix(base.Path, "/") {
|
||||
base.Path += "/"
|
||||
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
"k8s.io/client-go/features"
|
||||
"k8s.io/client-go/pkg/version"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/client-go/tools/metrics"
|
||||
"k8s.io/client-go/transport"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
@@ -355,6 +356,8 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
|
||||
// Note that the http client takes precedence over the transport values configured.
|
||||
// The http client defaults to the `http.DefaultClient` if nil.
|
||||
func RESTClientForConfigAndClient(config *Config, httpClient *http.Client) (*RESTClient, error) {
|
||||
metrics.EnsureRegistered()
|
||||
|
||||
if config.GroupVersion == nil {
|
||||
return nil, fmt.Errorf("GroupVersion is required when initializing a RESTClient")
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"k8s.io/client-go/pkg/apis/clientauthentication"
|
||||
"k8s.io/client-go/plugin/pkg/client/auth/exec"
|
||||
"k8s.io/client-go/tools/metrics"
|
||||
"k8s.io/client-go/transport"
|
||||
)
|
||||
|
||||
@@ -82,6 +83,7 @@ func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTrip
|
||||
|
||||
// TransportConfig converts a client config to an appropriate transport config.
|
||||
func (c *Config) TransportConfig() (*transport.Config, error) {
|
||||
metrics.EnsureRegistered()
|
||||
conf := &transport.Config{
|
||||
UserAgent: c.UserAgent,
|
||||
Transport: c.Transport,
|
||||
|
||||
@@ -25,7 +25,37 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var registerMetrics sync.Once
|
||||
var (
|
||||
registerMetrics sync.Once
|
||||
ensureRegisteredOnce sync.Once
|
||||
// ensureRegisteredFn, if set via RegisterOpts.RegisterFn, is invoked
|
||||
// exactly once before any rest client is constructed. Adapter packages
|
||||
// (e.g. k8s.io/component-base/metrics/prometheus/restclient) install
|
||||
// this callback in their init() so that the actual registration with
|
||||
// legacyregistry — and the metric Create() that reads
|
||||
// feature-gate-derived options like NativeHistograms — happens at
|
||||
// runtime rather than at init() time. See EnsureRegistered for the
|
||||
// caller-side contract.
|
||||
ensureRegisteredFn func()
|
||||
)
|
||||
|
||||
// EnsureRegistered invokes the callback installed via RegisterOpts.RegisterFn (if
|
||||
// any) exactly once. Callers should treat it as idempotent; subsequent calls are
|
||||
// effectively free.
|
||||
//
|
||||
// New public constructors or entry points for packages in client-go that create
|
||||
// a REST client, HTTP transport, or credential provider should invoke EnsureRegistered()
|
||||
// at the very beginning of the function. Adapter Observe methods
|
||||
// also call EnsureRegistered(), so no observations are lost if a constructor
|
||||
// forgets to invoke it, but if invoked, the entrypoint call shifts registration from
|
||||
// "first-observation" to "first client construction", meaning the metric
|
||||
// series is visible to Promteheus scrapes from process startup rather than
|
||||
// appearing only after the first request.
|
||||
func EnsureRegistered() {
|
||||
if ensureRegisteredFn != nil {
|
||||
ensureRegisteredOnce.Do(ensureRegisteredFn)
|
||||
}
|
||||
}
|
||||
|
||||
// DurationMetric is a measurement of some amount of time.
|
||||
type DurationMetric interface {
|
||||
@@ -163,6 +193,12 @@ type RegisterOpts struct {
|
||||
TransportCAReloads TransportCAReloadsMetric
|
||||
TransportCertRotationGCCalls TransportCertRotationGCCallsMetric
|
||||
TransportCacheGCCalls TransportCacheGCCallsMetric
|
||||
|
||||
// RegisterFn, if non-nil, is invoked exactly once by EnsureRegistered().
|
||||
// before the first rest client is constructed. Adapters use this to defer
|
||||
// registrations that depend on runtime state (eg., feature gates read my metric
|
||||
// Create() without changing the import side contract of the adapter package.)
|
||||
RegisterFn func()
|
||||
}
|
||||
|
||||
// Register registers metrics for the rest client to use. This can
|
||||
@@ -217,6 +253,9 @@ func Register(opts RegisterOpts) {
|
||||
if opts.TransportCacheGCCalls != nil {
|
||||
TransportCacheGCCalls = opts.TransportCacheGCCalls
|
||||
}
|
||||
if opts.RegisterFn != nil {
|
||||
ensureRegisteredFn = opts.RegisterFn
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,14 @@ import (
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
clientgofeaturegate "k8s.io/client-go/features"
|
||||
"k8s.io/client-go/tools/metrics"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// New returns an http.RoundTripper that will provide the authentication
|
||||
// or transport level security defined by the provided Config.
|
||||
func New(config *Config) (http.RoundTripper, error) {
|
||||
metrics.EnsureRegistered()
|
||||
// Set transport level security
|
||||
if config.Transport != nil && (config.HasCA() || config.HasCertAuth() || config.HasCertCallback() || config.TLS.Insecure) {
|
||||
return nil, fmt.Errorf("using a custom transport with TLS certificate options or the insecure flag is not allowed")
|
||||
|
||||
Reference in New Issue
Block a user