@@ -32,12 +32,6 @@ import (
32
32
"k8s.io/apimachinery/pkg/api/meta"
33
33
"k8s.io/apimachinery/pkg/runtime"
34
34
kerrors "k8s.io/apimachinery/pkg/util/errors"
35
- "k8s.io/apiserver/pkg/authentication/authenticatorfactory"
36
- "k8s.io/apiserver/pkg/authorization/authorizer"
37
- "k8s.io/apiserver/pkg/authorization/authorizerfactory"
38
- "k8s.io/apiserver/pkg/server/options"
39
- authenticationv1 "k8s.io/client-go/kubernetes/typed/authentication/v1"
40
- authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
41
35
"k8s.io/client-go/rest"
42
36
"k8s.io/client-go/tools/leaderelection"
43
37
"k8s.io/client-go/tools/leaderelection/resourcelock"
@@ -93,19 +87,14 @@ type controllerManager struct {
93
87
// metricsListener is used to serve prometheus metrics
94
88
metricsListener net.Listener
95
89
96
- // metricsSecureServing enables secure metrics serving.
97
- // This means metrics will be served via https and with authentication and authorization.
98
- metricsSecureServing bool
90
+ // metricsFilter is a func that is added before the metrics handler on the metrics server.
91
+ // This can be e.g. used to enforce authentication and authorization on the metrics
92
+ // endpoint.
93
+ metricsFilter metrics.Filter
99
94
100
95
// metricsExtraHandlers contains extra handlers to register on http server that serves metrics.
101
96
metricsExtraHandlers map [string ]http.Handler
102
97
103
- // metricsAuthenticationClient is the client used to authenticate requests to the metrics endpoint.
104
- metricsAuthenticationClient authenticationv1.AuthenticationV1Interface
105
-
106
- // metricsAuthorizationClient is the client used to authorize requests to the metrics endpoint.
107
- metricsAuthorizationClient authorizationv1.AuthorizationV1Interface
108
-
109
98
// healthProbeListener is used to serve liveness probe
110
99
healthProbeListener net.Listener
111
100
@@ -322,11 +311,11 @@ func (cm *controllerManager) addMetricsServer() error {
322
311
323
312
log := cm .logger .WithValues ("path" , defaultMetricsEndpoint )
324
313
325
- if cm .metricsSecureServing {
314
+ if cm .metricsFilter != nil {
326
315
var err error
327
- handler , err = withAuthenticationAndAuthorization ( log , cm .metricsAuthenticationClient , cm . metricsAuthorizationClient , handler )
316
+ handler , err = cm .metricsFilter ( log , handler )
328
317
if err != nil {
329
- return fmt .Errorf ("failed to add metrics server: %w" , err )
318
+ return fmt .Errorf ("failed to add metrics server: failed to add metrics filter %w" , err )
330
319
}
331
320
}
332
321
@@ -344,74 +333,6 @@ func (cm *controllerManager) addMetricsServer() error {
344
333
})
345
334
}
346
335
347
- func withAuthenticationAndAuthorization (log logr.Logger , authenticationClient authenticationv1.AuthenticationV1Interface , authorizationClient authorizationv1.AuthorizationV1Interface , handler http.Handler ) (http.Handler , error ) {
348
- authenticatorConfig := authenticatorfactory.DelegatingAuthenticatorConfig {
349
- Anonymous : false , // Require authentication.
350
- CacheTTL : 1 * time .Minute ,
351
- TokenAccessReviewClient : authenticationClient ,
352
- TokenAccessReviewTimeout : 10 * time .Second ,
353
- WebhookRetryBackoff : options .DefaultAuthWebhookRetryBackoff (),
354
- }
355
- delegatingAuthenticator , _ , err := authenticatorConfig .New ()
356
- if err != nil {
357
- return nil , fmt .Errorf ("failed to create authenticator: %w" , err )
358
- }
359
-
360
- authorizerConfig := authorizerfactory.DelegatingAuthorizerConfig {
361
- SubjectAccessReviewClient : authorizationClient ,
362
- AllowCacheTTL : 5 * time .Minute ,
363
- DenyCacheTTL : 30 * time .Second ,
364
- WebhookRetryBackoff : options .DefaultAuthWebhookRetryBackoff (),
365
- }
366
- delegatingAuthorizer , err := authorizerConfig .New ()
367
- if err != nil {
368
- return nil , fmt .Errorf ("failed to create authorizer: %w" , err )
369
- }
370
-
371
- return http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
372
- if req .Method != http .MethodGet {
373
- http .Error (w , "Method Not Allowed" , http .StatusMethodNotAllowed )
374
- return
375
- }
376
-
377
- ctx := req .Context ()
378
-
379
- res , ok , err := delegatingAuthenticator .AuthenticateRequest (req )
380
- if err != nil {
381
- log .Error (err , "Authentication failed" , err )
382
- http .Error (w , "Authentication failed" , http .StatusInternalServerError )
383
- return
384
- }
385
- if ! ok {
386
- log .V (4 ).Info ("Authentication failed" )
387
- http .Error (w , "Unauthorized" , http .StatusUnauthorized )
388
- return
389
- }
390
-
391
- attributes := authorizer.AttributesRecord {
392
- User : res .User ,
393
- Verb : "get" ,
394
- Path : req .URL .Path ,
395
- }
396
-
397
- authorized , reason , err := delegatingAuthorizer .Authorize (ctx , attributes )
398
- if err != nil {
399
- msg := fmt .Sprintf ("Authorization for user %s failed" , attributes .User .GetName ())
400
- log .Error (err , msg )
401
- http .Error (w , msg , http .StatusInternalServerError )
402
- return
403
- }
404
- if authorized != authorizer .DecisionAllow {
405
- msg := fmt .Sprintf ("Authorization denied for user %s" , attributes .User .GetName ())
406
- log .V (4 ).Info (fmt .Sprintf ("%s: %s" , msg , reason ))
407
- http .Error (w , msg , http .StatusForbidden )
408
- return
409
- }
410
-
411
- handler .ServeHTTP (w , req )
412
- }), nil
413
- }
414
-
415
336
func (cm * controllerManager ) serveHealthProbes () {
416
337
mux := http .NewServeMux ()
417
338
server := httpserver .New (mux )
0 commit comments