@@ -17,10 +17,13 @@ limitations under the License.
17
17
package main
18
18
19
19
import (
20
+ "crypto/tls"
20
21
"flag"
21
- "os"
22
-
23
22
"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"
24
27
25
28
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
26
29
// to ensure that exec-entrypoint and run can make use of them.
@@ -55,11 +58,23 @@ func main() {
55
58
var metricsAddr string
56
59
var enableLeaderElection bool
57
60
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." )
59
67
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 ,
61
69
"Enable leader election for controller manager. " +
62
70
"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
+
63
78
opts := zap.Options {
64
79
Development : true ,
65
80
}
@@ -68,11 +83,57 @@ func main() {
68
83
69
84
ctrl .SetLogger (zap .New (zap .UseFlagOptions (& opts )))
70
85
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/[email protected] /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/[email protected] /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
+
71
134
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 ,
76
137
HealthProbeBindAddress : probeAddr ,
77
138
LeaderElection : enableLeaderElection ,
78
139
LeaderElectionID : "9b29b064.davidkarlsen.com" ,
@@ -93,6 +154,16 @@ func main() {
93
154
os .Exit (1 )
94
155
}
95
156
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
+
96
167
if err = (& controller.MigrationReconciler {
97
168
ReconcilerBase : util .NewFromManager (mgr , mgr .GetEventRecorderFor ("Migration" )),
98
169
Client : mgr .GetClient (),
0 commit comments