1717package cert
1818
1919import (
20+ "crypto/x509"
21+ "encoding/pem"
2022 "fmt"
2123 "os"
2224 "strings"
@@ -40,10 +42,11 @@ const (
4042)
4143
4244// ManageWebhookCerts registers the cert-controller with the manager which will be used to manage
43- // webhook certificates. The behavior depends on certManagerEnabled :
45+ // webhook certificates. The behavior depends on the configuration :
4446// - If certManagerEnabled=true: waits for cert-manager to provide certificates
45- // - If certManagerEnabled=false: checks if certificates exist, auto-generates if not
46- func ManageWebhookCerts (mgr ctrl.Manager , certDir string , secretName string , authorizerEnabled bool , certManagerEnabled bool , certsReadyCh chan struct {}) error {
47+ // - If autoProvision=true: uses cert-controller for automatic certificate generation and management
48+ // - If autoProvision=false: waits for externally provided certificates (e.g., from Helm chart)
49+ func ManageWebhookCerts (mgr ctrl.Manager , certDir string , secretName string , authorizerEnabled bool , certManagerEnabled bool , autoProvision bool , certsReadyCh chan struct {}) error {
4750 namespace , err := getOperatorNamespace ()
4851 if err != nil {
4952 return err
@@ -59,16 +62,21 @@ func ManageWebhookCerts(mgr ctrl.Manager, certDir string, secretName string, aut
5962 return nil
6063 }
6164
62- // Check if certificates already exist (from Helm certFilesPath or manual creation)
63- if certsExist ( certDir ) {
64- logger .Info ("Using existing certificates" ,
65- "certDir" , certDir )
66- close ( certsReadyCh )
65+ // If auto-provision is disabled, wait for externally provided certificates
66+ if ! autoProvision {
67+ logger .Info ("Using externally provided certificates" ,
68+ "certDir" , certDir , "secretName" , secretName )
69+ go waitForExternalCerts ( logger , certDir , certsReadyCh )
6770 return nil
6871 }
6972
70- // Auto-generate certificates using cert-controller
71- logger .Info ("Auto-generating certificates using cert-controller" ,
73+ // Auto-provision mode: Use cert-controller for certificate management
74+ // cert-controller handles:
75+ // - Generating certificates if they don't exist
76+ // - Rotating certificates before expiry
77+ // - Injecting CA bundle into webhook configurations
78+ // - Monitoring certificate files and Secret for changes
79+ logger .Info ("Auto-provisioning certificates using cert-controller" ,
7280 "secretName" , secretName , "certDir" , certDir )
7381 rotator := & cert.CertRotator {
7482 SecretKey : types.NamespacedName {
@@ -135,11 +143,11 @@ func getOperatorNamespace() (string, error) {
135143 return namespace , nil
136144}
137145
138- // certsExist checks if both certificate and key files exist in the specified directory
146+ // certsExist checks if both certificate and key files exist and have content in the specified directory
139147func certsExist (certDir string ) bool {
140148 certPath := fmt .Sprintf ("%s/tls.crt" , certDir )
141149 keyPath := fmt .Sprintf ("%s/tls.key" , certDir )
142- return fileExists (certPath ) && fileExists (keyPath )
150+ return fileExistsWithContent (certPath ) && fileExistsWithContent (keyPath )
143151}
144152
145153// waitForExternalCerts waits for externally managed certificates to be available
@@ -189,3 +197,27 @@ func fileExists(path string) bool {
189197 }
190198 return ! info .IsDir ()
191199}
200+
201+ // fileExistsWithContent checks if a file exists and contains valid PEM data
202+ func fileExistsWithContent (path string ) bool {
203+ data , err := os .ReadFile (path )
204+ if err != nil || len (data ) == 0 {
205+ return false
206+ }
207+
208+ // Try to decode PEM block to verify it's valid
209+ block , _ := pem .Decode (data )
210+ if block == nil || len (block .Bytes ) == 0 {
211+ return false
212+ }
213+
214+ // For certificate files, try to parse as X.509
215+ // For key files, just having valid PEM is enough
216+ if strings .Contains (path , "tls.crt" ) || strings .Contains (path , "ca.crt" ) {
217+ _ , err := x509 .ParseCertificate (block .Bytes )
218+ return err == nil
219+ }
220+
221+ // For key files (tls.key), valid PEM block is sufficient
222+ return true
223+ }
0 commit comments