Skip to content

Commit b0454ca

Browse files
committed
pkg: Introduce options to disable granularly authn/authz for metrics
In HyperShift, the CVO currently needs to have disabled both authorization and authentication. Ensure the aspects are disabled so as not break HyperShift. However, in the future, the authentication will be enabled using mTLS and a mounted CA bundle file. Thus, authentication needs to be configurable. Authorization needs to be configurable, as well as HyperShift allows a custom monitoring stack to scrape hosted control plane components. In the future in HyperShift, authentication of the metrics endpoint of the CVO will be enforced; however, the authorization will be disabled. This commit prepares the code for these changes.
1 parent 5143969 commit b0454ca

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

pkg/cvo/metrics.go

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,19 @@ func handleServerResult(result asyncResult, lastLoopError error) error {
193193
return lastError
194194
}
195195

196+
type MetricsOptions struct {
197+
DisableAuthentication bool
198+
DisableAuthorization bool
199+
}
200+
196201
// RunMetrics launches a server bound to listenAddress serving
197202
// Prometheus metrics at /metrics over HTTPS. Continues serving
198203
// until runContext.Done() and then attempts a clean shutdown
199204
// limited by shutdownContext.Done(). Assumes runContext.Done()
200205
// occurs before or simultaneously with shutdownContext.Done().
201206
// The TLS configuration automatically reloads certificates when
202207
// they change on disk using dynamiccertificates.
203-
func RunMetrics(runContext context.Context, shutdownContext context.Context, listenAddress, certFile, keyFile string, restConfig *rest.Config, disableMetricsAuth bool) error {
208+
func RunMetrics(runContext context.Context, shutdownContext context.Context, listenAddress, certFile, keyFile string, restConfig *rest.Config, metricsOptions MetricsOptions) error {
204209
if listenAddress == "" {
205210
return errors.New("TLS configuration is required to serve metrics")
206211
}
@@ -217,34 +222,45 @@ func RunMetrics(runContext context.Context, shutdownContext context.Context, lis
217222
// Start the serving cert controller to begin watching the cert and key files
218223
go servingContentController.Run(runContext, 1)
219224

220-
// Create a dynamic CA controller to watch for client CA changes from a ConfigMap.
221-
kubeClient, err := kubernetes.NewForConfig(restConfig)
222-
if err != nil {
223-
return fmt.Errorf("failed to create kube client: %w", err)
224-
}
225+
var clientCA dynamiccertificates.CAContentProvider
226+
var clientCAController *dynamiccertificates.ConfigMapCAController
227+
if !metricsOptions.DisableAuthentication {
228+
// Create a dynamic CA controller to watch for client CA changes from a ConfigMap.
229+
kubeClient, err := kubernetes.NewForConfig(restConfig)
230+
if err != nil {
231+
return fmt.Errorf("failed to create kube client: %w", err)
232+
}
225233

226-
clientCAController, err := dynamiccertificates.NewDynamicCAFromConfigMapController(
227-
"metrics-client-ca",
228-
"kube-system",
229-
"extension-apiserver-authentication",
230-
"client-ca-file",
231-
kubeClient)
232-
if err != nil {
233-
return fmt.Errorf("failed to create client CA controller: %w", err)
234-
}
234+
clientCAController, err = dynamiccertificates.NewDynamicCAFromConfigMapController(
235+
"metrics-client-ca",
236+
"kube-system",
237+
"extension-apiserver-authentication",
238+
"client-ca-file",
239+
kubeClient)
240+
if err != nil {
241+
return fmt.Errorf("failed to create client CA controller: %w", err)
242+
}
243+
244+
if err := clientCAController.RunOnce(runContext); err != nil {
245+
return fmt.Errorf("failed to initialize client CA controller: %w", err)
246+
}
235247

236-
if err := clientCAController.RunOnce(runContext); err != nil {
237-
return fmt.Errorf("failed to initialize client CA controller: %w", err)
248+
// Start the client CA controller to begin watching the ConfigMap
249+
go clientCAController.Run(runContext, 1)
250+
251+
// Assign to interface variable to ensure proper nil handling
252+
clientCA = clientCAController
238253
}
239254

240-
// Start the client CA controller to begin watching the ConfigMap
241-
go clientCAController.Run(runContext, 1)
255+
clientAuth := tls.NoClientCert
256+
if !metricsOptions.DisableAuthentication {
257+
clientAuth = tls.RequireAndVerifyClientCert
258+
}
242259

260+
baseTlSConfig := crypto.SecureTLSConfig(&tls.Config{ClientAuth: clientAuth})
243261
servingCertController := dynamiccertificates.NewDynamicServingCertificateController(
244-
crypto.SecureTLSConfig(&tls.Config{
245-
ClientAuth: tls.RequireAndVerifyClientCert,
246-
}),
247-
clientCAController,
262+
baseTlSConfig,
263+
clientCA,
248264
servingContentController,
249265
nil,
250266
nil,
@@ -253,12 +269,14 @@ func RunMetrics(runContext context.Context, shutdownContext context.Context, lis
253269
return fmt.Errorf("failed to initialize serving certificate controller: %w", err)
254270
}
255271

256-
clientCAController.AddListener(servingCertController)
272+
if clientCAController != nil {
273+
clientCAController.AddListener(servingCertController)
274+
}
257275
servingContentController.AddListener(servingCertController)
258276

259277
go servingCertController.Run(1, runContext.Done())
260278

261-
server := createHttpServer(disableMetricsAuth)
279+
server := createHttpServer(metricsOptions.DisableAuthorization)
262280

263281
resultChannel := make(chan asyncResult, 1)
264282
resultChannelCount := 1
@@ -267,7 +285,7 @@ func RunMetrics(runContext context.Context, shutdownContext context.Context, lis
267285
// If authentication is enabled, ClientAuth is set to ensure connections are rejected rather than
268286
// fall back to unauthenticated mode if the callback fails to provide a valid config.
269287
tlsConfig := crypto.SecureTLSConfig(&tls.Config{
270-
ClientAuth: tls.RequireAndVerifyClientCert,
288+
ClientAuth: clientAuth,
271289
GetConfigForClient: servingCertController.GetConfigForClient,
272290
})
273291
go startListening(server, tlsConfig, listenAddress, resultChannel)

pkg/start/start.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,11 @@ func (o *Options) run(ctx context.Context, controllerCtx *Context, lock resource
350350
resultChannelCount++
351351
go func() {
352352
defer utilruntime.HandleCrash()
353-
disableMetricsAuth := o.HyperShift
354-
err := cvo.RunMetrics(postMainContext, shutdownContext, o.ListenAddr, o.ServingCertFile, o.ServingKeyFile, restConfig, disableMetricsAuth)
353+
options := cvo.MetricsOptions{
354+
DisableAuthentication: o.HyperShift,
355+
DisableAuthorization: o.HyperShift,
356+
}
357+
err := cvo.RunMetrics(postMainContext, shutdownContext, o.ListenAddr, o.ServingCertFile, o.ServingKeyFile, restConfig, options)
355358
resultChannel <- asyncResult{name: "metrics server", error: err}
356359
}()
357360
}

0 commit comments

Comments
 (0)