@@ -17,10 +17,13 @@ limitations under the License.
1717package main
1818
1919import (
20+ "crypto/tls"
2021 "flag"
21- "os"
22-
2322 "github.com/redhat-cop/operator-utils/pkg/util"
23+ "os"
24+ "path/filepath"
25+ "sigs.k8s.io/controller-runtime/pkg/certwatcher"
26+ "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
2427
2528 // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2629 // to ensure that exec-entrypoint and run can make use of them.
@@ -55,11 +58,23 @@ func main() {
5558 var metricsAddr string
5659 var enableLeaderElection bool
5760 var probeAddr string
58- flag .StringVar (& metricsAddr , "metrics-bind-address" , ":8080" , "The address the metric endpoint binds to." )
61+ var secureMetrics bool
62+ var metricsCertPath , metricsCertName , metricsCertKey string
63+ var tlsOpts []func (* tls.Config )
64+
65+ flag .StringVar (& metricsAddr , "metrics-bind-address" , "0" , "The address the metrics endpoint binds to. " +
66+ "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service." )
5967 flag .StringVar (& probeAddr , "health-probe-bind-address" , ":8081" , "The address the probe endpoint binds to." )
60- flag .BoolVar (& enableLeaderElection , "leader-elect" , false ,
68+ flag .BoolVar (& enableLeaderElection , "leader-elect" , true ,
6169 "Enable leader election for controller manager. " +
6270 "Enabling this will ensure there is only one active controller manager." )
71+ flag .BoolVar (& secureMetrics , "metrics-secure" , true ,
72+ "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead." )
73+ flag .StringVar (& metricsCertPath , "metrics-cert-path" , "" ,
74+ "The directory that contains the metrics server certificate." )
75+ flag .StringVar (& metricsCertName , "metrics-cert-name" , "tls.crt" , "The name of the metrics server certificate file." )
76+ flag .StringVar (& metricsCertKey , "metrics-cert-key" , "tls.key" , "The name of the metrics server key file." )
77+
6378 opts := zap.Options {
6479 Development : true ,
6580 }
@@ -68,11 +83,57 @@ func main() {
6883
6984 ctrl .SetLogger (zap .New (zap .UseFlagOptions (& opts )))
7085
86+ // Create watchers for metrics and webhooks certificates
87+ var metricsCertWatcher * certwatcher.CertWatcher
88+
89+ // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
90+ // More info:
91+ // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server
92+ // - https://book.kubebuilder.io/reference/metrics.html
93+ metricsServerOptions := metricsserver.Options {
94+ BindAddress : metricsAddr ,
95+ SecureServing : secureMetrics ,
96+ TLSOpts : tlsOpts ,
97+ }
98+
99+ if secureMetrics {
100+ // FilterProvider is used to protect the metrics endpoint with authn/authz.
101+ // These configurations ensure that only authorized users and service accounts
102+ // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
103+ // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
104+ metricsServerOptions .FilterProvider = filters .WithAuthenticationAndAuthorization
105+ }
106+
107+ // If the certificate is not specified, controller-runtime will automatically
108+ // generate self-signed certificates for the metrics server. While convenient for development and testing,
109+ // this setup is not recommended for production.
110+ //
111+ // TODO(user): If you enable certManager, uncomment the following lines:
112+ // - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
113+ // managed by cert-manager for the metrics server.
114+ // - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
115+ if len (metricsCertPath ) > 0 {
116+ setupLog .Info ("Initializing metrics certificate watcher using provided certificates" ,
117+ "metrics-cert-path" , metricsCertPath , "metrics-cert-name" , metricsCertName , "metrics-cert-key" , metricsCertKey )
118+
119+ var err error
120+ metricsCertWatcher , err = certwatcher .New (
121+ filepath .Join (metricsCertPath , metricsCertName ),
122+ filepath .Join (metricsCertPath , metricsCertKey ),
123+ )
124+ if err != nil {
125+ setupLog .Error (err , "to initialize metrics certificate watcher" , "error" , err )
126+ os .Exit (1 )
127+ }
128+
129+ metricsServerOptions .TLSOpts = append (metricsServerOptions .TLSOpts , func (config * tls.Config ) {
130+ config .GetCertificate = metricsCertWatcher .GetCertificate
131+ })
132+ }
133+
71134 mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {
72- Scheme : scheme ,
73- Metrics : metricsserver.Options {
74- BindAddress : metricsAddr ,
75- },
135+ Scheme : scheme ,
136+ Metrics : metricsServerOptions ,
76137 HealthProbeBindAddress : probeAddr ,
77138 LeaderElection : enableLeaderElection ,
78139 LeaderElectionID : "9b29b064.davidkarlsen.com" ,
@@ -93,6 +154,16 @@ func main() {
93154 os .Exit (1 )
94155 }
95156
157+ // +kubebuilder:scaffold:builder
158+
159+ if metricsCertWatcher != nil {
160+ setupLog .Info ("Adding metrics certificate watcher to manager" )
161+ if err := mgr .Add (metricsCertWatcher ); err != nil {
162+ setupLog .Error (err , "unable to add metrics certificate watcher to manager" )
163+ os .Exit (1 )
164+ }
165+ }
166+
96167 if err = (& controller.MigrationReconciler {
97168 ReconcilerBase : util .NewFromManager (mgr , mgr .GetEventRecorderFor ("Migration" )),
98169 Client : mgr .GetClient (),
0 commit comments