@@ -20,6 +20,7 @@ import (
2020	"crypto/tls" 
2121	"flag" 
2222	"os" 
23+ 	"path/filepath" 
2324	"strconv" 
2425
2526	"github.com/securesign/operator/internal/images" 
@@ -46,7 +47,9 @@ import (
4647	utilruntime "k8s.io/apimachinery/pkg/util/runtime" 
4748	clientgoscheme "k8s.io/client-go/kubernetes/scheme" 
4849	ctrl "sigs.k8s.io/controller-runtime" 
50+ 	"sigs.k8s.io/controller-runtime/pkg/certwatcher" 
4951	"sigs.k8s.io/controller-runtime/pkg/healthz" 
52+ 	"sigs.k8s.io/controller-runtime/pkg/metrics/filters" 
5053	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" 
5154	"sigs.k8s.io/controller-runtime/pkg/webhook" 
5255
@@ -79,26 +82,43 @@ func init() {
7982	//+kubebuilder:scaffold:scheme 
8083}
8184
85+ // nolint:gocyclo 
8286func  main () {
8387	var  (
8488		metricsAddr           string 
89+ 		metricsCertPath       string 
90+ 		metricsCertName       string 
91+ 		metricsCertKey        string 
92+ 		webhookCertPath       string 
93+ 		webhookCertName       string 
94+ 		webhookCertKey        string 
8595		enableLeaderElection  bool 
8696		probeAddr             string 
8797		pprofAddr             string 
8898		secureMetrics         bool 
8999		enableHTTP2           bool 
100+ 		tlsOpts               []func (* tls.Config )
90101	)
91102
92103	flag .StringVar (& pprofAddr , "pprof-address" , "" , "The address to expose the pprof server. Default is empty string which disables the pprof server." )
93- 	flag .StringVar (& metricsAddr , "metrics-bind-address" , ":8080" , "The address the metric endpoint binds to." )
104+ 	flag .StringVar (& metricsAddr , "metrics-bind-address" , ":8080" , "The address the metrics endpoint binds to. " + 
105+ 		"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service." )
94106	flag .StringVar (& probeAddr , "health-probe-bind-address" , ":8081" , "The address the probe endpoint binds to." )
95107	flag .BoolVar (& enableLeaderElection , "leader-elect" , false ,
96108		"Enable leader election for controller manager. " + 
97109			"Enabling this will ensure there is only one active controller manager." )
98- 	flag .BoolVar (& secureMetrics , "metrics-secure" , false ,
99- 		"If set the metrics endpoint is served securely" )
110+ 	flag .BoolVar (& secureMetrics , "metrics-secure" , true ,
111+ 		"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead." )
112+ 	flag .StringVar (& webhookCertPath , "webhook-cert-path" , "" , "The directory that contains the webhook certificate." )
113+ 	flag .StringVar (& webhookCertName , "webhook-cert-name" , "tls.crt" , "The name of the webhook certificate file." )
114+ 	flag .StringVar (& webhookCertKey , "webhook-cert-key" , "tls.key" , "The name of the webhook key file." )
115+ 	flag .StringVar (& metricsCertPath , "metrics-cert-path" , "" ,
116+ 		"The directory that contains the metrics server certificate." )
117+ 	flag .StringVar (& metricsCertName , "metrics-cert-name" , "tls.crt" , "The name of the metrics server certificate file." )
118+ 	flag .StringVar (& metricsCertKey , "metrics-cert-key" , "tls.key" , "The name of the metrics server key file." )
100119	flag .BoolVar (& enableHTTP2 , "enable-http2" , false ,
101120		"If set, HTTP/2 will be enabled for the metrics and webhook servers" )
121+ 
102122	flag .Int64Var (& constants .CreateTreeDeadline , "create-tree-deadline" , constants .CreateTreeDeadline , "The time allowance (in seconds) for the create tree job to run before failing." )
103123	utils .BoolFlagOrEnv (& constants .Openshift , "openshift" , "OPENSHIFT" , false , "Enable to ensures the operator applies OpenShift specific configurations." )
104124	utils .RelatedImageFlag ("trillian-log-signer-image" , images .TrillianLogSigner , "The image used for trillian log signer." )
@@ -135,22 +155,87 @@ func main() {
135155		c .NextProtos  =  []string {"http/1.1" }
136156	}
137157
138- 	tlsOpts  :=  []func (* tls.Config ){}
139158	if  ! enableHTTP2  {
140159		tlsOpts  =  append (tlsOpts , disableHTTP2 )
141160	}
142161
162+ 	// Create watchers for metrics and webhooks certificates 
163+ 	var  metricsCertWatcher , webhookCertWatcher  * certwatcher.CertWatcher 
164+ 
165+ 	// Initial webhook TLS options 
166+ 	webhookTLSOpts  :=  tlsOpts 
167+ 
168+ 	if  len (webhookCertPath ) >  0  {
169+ 		setupLog .Info ("Initializing webhook certificate watcher using provided certificates" ,
170+ 			"webhook-cert-path" , webhookCertPath , "webhook-cert-name" , webhookCertName , "webhook-cert-key" , webhookCertKey )
171+ 
172+ 		var  err  error 
173+ 		webhookCertWatcher , err  =  certwatcher .New (
174+ 			filepath .Join (webhookCertPath , webhookCertName ),
175+ 			filepath .Join (webhookCertPath , webhookCertKey ),
176+ 		)
177+ 		if  err  !=  nil  {
178+ 			setupLog .Error (err , "Failed to initialize webhook certificate watcher" )
179+ 			os .Exit (1 )
180+ 		}
181+ 
182+ 		webhookTLSOpts  =  append (webhookTLSOpts , func (config  * tls.Config ) {
183+ 			config .GetCertificate  =  webhookCertWatcher .GetCertificate 
184+ 		})
185+ 	}
186+ 
143187	webhookServer  :=  webhook .NewServer (webhook.Options {
144- 		TLSOpts : tlsOpts ,
188+ 		TLSOpts : webhookTLSOpts ,
145189	})
146190
191+ 	// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. 
192+ 	// More info: 
193+ 	// - https://pkg.go.dev/sigs.k8s.io/[email protected] /pkg/metrics/server  194+ 	// - https://book.kubebuilder.io/reference/metrics.html 
195+ 	metricsServerOptions  :=  metricsserver.Options {
196+ 		BindAddress :   metricsAddr ,
197+ 		SecureServing : secureMetrics ,
198+ 		TLSOpts :       tlsOpts ,
199+ 	}
200+ 
201+ 	if  secureMetrics  {
202+ 		// FilterProvider is used to protect the metrics endpoint with authn/authz. 
203+ 		// These configurations ensure that only authorized users and service accounts 
204+ 		// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: 
205+ 		// https://pkg.go.dev/sigs.k8s.io/[email protected] /pkg/metrics/filters#WithAuthenticationAndAuthorization  206+ 		metricsServerOptions .FilterProvider  =  filters .WithAuthenticationAndAuthorization 
207+ 	}
208+ 
209+ 	// If the certificate is not specified, controller-runtime will automatically 
210+ 	// generate self-signed certificates for the metrics server. While convenient for development and testing, 
211+ 	// this setup is not recommended for production. 
212+ 	// 
213+ 	// TODO(user): If you enable certManager, uncomment the following lines: 
214+ 	// - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates 
215+ 	// managed by cert-manager for the metrics server. 
216+ 	// - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification. 
217+ 	if  len (metricsCertPath ) >  0  {
218+ 		setupLog .Info ("Initializing metrics certificate watcher using provided certificates" ,
219+ 			"metrics-cert-path" , metricsCertPath , "metrics-cert-name" , metricsCertName , "metrics-cert-key" , metricsCertKey )
220+ 
221+ 		var  err  error 
222+ 		metricsCertWatcher , err  =  certwatcher .New (
223+ 			filepath .Join (metricsCertPath , metricsCertName ),
224+ 			filepath .Join (metricsCertPath , metricsCertKey ),
225+ 		)
226+ 		if  err  !=  nil  {
227+ 			setupLog .Error (err , "to initialize metrics certificate watcher" , "error" , err )
228+ 			os .Exit (1 )
229+ 		}
230+ 
231+ 		metricsServerOptions .TLSOpts  =  append (metricsServerOptions .TLSOpts , func (config  * tls.Config ) {
232+ 			config .GetCertificate  =  metricsCertWatcher .GetCertificate 
233+ 		})
234+ 	}
235+ 
147236	mgr , err  :=  ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {
148- 		Scheme : scheme ,
149- 		Metrics : metricsserver.Options {
150- 			BindAddress :   metricsAddr ,
151- 			SecureServing : secureMetrics ,
152- 			TLSOpts :       tlsOpts ,
153- 		},
237+ 		Scheme :                 scheme ,
238+ 		Metrics :                metricsServerOptions ,
154239		WebhookServer :          webhookServer ,
155240		HealthProbeBindAddress : probeAddr ,
156241		PprofBindAddress :       pprofAddr ,
@@ -233,6 +318,22 @@ func main() {
233318	}
234319	//+kubebuilder:scaffold:builder 
235320
321+ 	if  metricsCertWatcher  !=  nil  {
322+ 		setupLog .Info ("Adding metrics certificate watcher to manager" )
323+ 		if  err  :=  mgr .Add (metricsCertWatcher ); err  !=  nil  {
324+ 			setupLog .Error (err , "unable to add metrics certificate watcher to manager" )
325+ 			os .Exit (1 )
326+ 		}
327+ 	}
328+ 
329+ 	if  webhookCertWatcher  !=  nil  {
330+ 		setupLog .Info ("Adding webhook certificate watcher to manager" )
331+ 		if  err  :=  mgr .Add (webhookCertWatcher ); err  !=  nil  {
332+ 			setupLog .Error (err , "unable to add webhook certificate watcher to manager" )
333+ 			os .Exit (1 )
334+ 		}
335+ 	}
336+ 
236337	if  err  :=  mgr .AddHealthzCheck ("healthz" , healthz .Ping ); err  !=  nil  {
237338		setupLog .Error (err , "unable to set up health check" )
238339		os .Exit (1 )
0 commit comments