@@ -18,8 +18,10 @@ package main
1818
1919import (
2020 "context"
21+ "crypto/tls"
2122 "flag"
2223 "fmt"
24+ "log"
2325 "net/http"
2426 "os"
2527 "path/filepath"
@@ -41,6 +43,7 @@ import (
4143 "k8s.io/klog/v2/textlogger"
4244 ctrl "sigs.k8s.io/controller-runtime"
4345 crcache "sigs.k8s.io/controller-runtime/pkg/cache"
46+ "sigs.k8s.io/controller-runtime/pkg/certwatcher"
4447 "sigs.k8s.io/controller-runtime/pkg/client"
4548 crfinalizer "sigs.k8s.io/controller-runtime/pkg/finalizer"
4649 "sigs.k8s.io/controller-runtime/pkg/healthz"
@@ -71,6 +74,7 @@ import (
7174var (
7275 setupLog = ctrl .Log .WithName ("setup" )
7376 defaultSystemNamespace = "olmv1-system"
77+ certWatcher * certwatcher.CertWatcher
7478)
7579
7680const authFilePrefix = "operator-controller-global-pull-secrets"
@@ -93,6 +97,7 @@ func main() {
9397 certFile string
9498 keyFile string
9599 enableLeaderElection bool
100+ secureMetrics bool
96101 probeAddr string
97102 cachePath string
98103 operatorControllerVersion bool
@@ -103,6 +108,8 @@ func main() {
103108 flag .StringVar (& metricsAddr , "metrics-bind-address" , ":8443" , "The address the metric endpoint binds to." )
104109 flag .StringVar (& probeAddr , "health-probe-bind-address" , ":8081" , "The address the probe endpoint binds to." )
105110 flag .StringVar (& caCertDir , "ca-certs-dir" , "" , "The directory of TLS certificate to use for verifying HTTPS connections to the Catalogd and docker-registry web servers." )
111+ flag .BoolVar (& secureMetrics , "metrics-secure" , true ,
112+ "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead." )
106113 flag .StringVar (& certFile , "tls-cert" , "" , "The certificate file used for serving catalog contents over HTTPS. Requires tls-key." )
107114 flag .StringVar (& keyFile , "tls-key" , "" , "The key file used for serving catalog contents over HTTPS. Requires tls-cert." )
108115 flag .BoolVar (& enableLeaderElection , "leader-elect" , false ,
@@ -174,15 +181,29 @@ func main() {
174181
175182 metricsServerOptions := server.Options {
176183 BindAddress : metricsAddr ,
177- SecureServing : true ,
184+ SecureServing : secureMetrics ,
185+ }
178186
187+ if secureMetrics {
179188 // FilterProvider is used to protect the metrics endpoint with authn/authz.
180189 // These configurations ensure that only authorized users and service accounts
181190 // can access the metrics endpoint.
182- FilterProvider : filters .WithAuthenticationAndAuthorization ,
183- CertDir : caCertDir ,
184- CertName : certFile ,
185- KeyName : keyFile ,
191+ metricsServerOptions .FilterProvider = filters .WithAuthenticationAndAuthorization
192+
193+ // If the certificate files are provided, the metrics server will use them to serve the metrics endpoint.
194+ // Otherwise, the metrics server will use the default certificate provided by the controller-runtime which
195+ // is not recommended for production use.
196+ if len (certFile ) > 0 && len (keyFile ) > 0 {
197+ // If the certificate files change, the watcher will reload them.
198+ var err error
199+ certWatcher , err = certwatcher .New (certFile , keyFile )
200+ if err != nil {
201+ log .Fatalf ("Failed to initialize certificate watcher: %v" , err )
202+ }
203+ metricsServerOptions .TLSOpts = append (metricsServerOptions .TLSOpts , func (config * tls.Config ) {
204+ config .GetCertificate = certWatcher .GetCertificate
205+ })
206+ }
186207 }
187208
188209 mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {
@@ -361,6 +382,14 @@ func main() {
361382
362383 //+kubebuilder:scaffold:builder
363384
385+ if secureMetrics && certWatcher != nil {
386+ setupLog .Info ("Adding certificate watcher to manager" )
387+ if err := mgr .Add (certWatcher ); err != nil {
388+ setupLog .Error (err , "unable to add certificate watcher to manager" )
389+ os .Exit (1 )
390+ }
391+ }
392+
364393 if err := mgr .AddHealthzCheck ("healthz" , healthz .Ping ); err != nil {
365394 setupLog .Error (err , "unable to set up health check" )
366395 os .Exit (1 )
0 commit comments