Skip to content

Commit fde47c4

Browse files
committed
3 methods done
Signed-off-by: kangclzjc <[email protected]>
1 parent db152ff commit fde47c4

File tree

6 files changed

+59
-14
lines changed

6 files changed

+59
-14
lines changed

operator/api/config/v1alpha1/defaults.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ func SetDefaults_ServerConfiguration(serverConfig *ServerConfiguration) {
8585
if serverConfig.Webhooks.CertManagement.CertManagerEnabled == nil {
8686
serverConfig.Webhooks.CertManagement.CertManagerEnabled = ptr.To(false)
8787
}
88+
if serverConfig.Webhooks.CertManagement.AutoProvision == nil {
89+
serverConfig.Webhooks.CertManagement.AutoProvision = ptr.To(true)
90+
}
8891
if serverConfig.Webhooks.CertManagement.SecretName == "" {
8992
serverConfig.Webhooks.CertManagement.SecretName = "grove-webhook-server-cert"
9093
}

operator/api/config/v1alpha1/types.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,18 @@ type WebhookCertManagement struct {
148148
SecretName string `json:"secretName,omitempty"`
149149
// CertManagerEnabled indicates whether to use cert-manager for certificate management.
150150
// When true, the operator waits for cert-manager to provide certificates.
151-
// When false, the operator checks if certificates exist and auto-generates them if not.
151+
// When false, behavior depends on AutoProvision.
152152
// This requires cert-manager to be installed in the cluster when set to true.
153153
// Default: false
154154
// +optional
155155
CertManagerEnabled *bool `json:"certManagerEnabled,omitempty"`
156+
// AutoProvision indicates whether to use cert-controller for automatic certificate generation.
157+
// When true, cert-controller generates and manages certificates automatically.
158+
// When false, certificates are expected to be provided externally (e.g., via Helm chart or manual Secret creation).
159+
// This field is ignored when CertManagerEnabled is true.
160+
// Default: true
161+
// +optional
162+
AutoProvision *bool `json:"autoProvision,omitempty"`
156163
}
157164

158165
// Server contains information for HTTP(S) server configuration.

operator/charts/templates/_helpers.tpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ config.yaml: |
1616
server:
1717
webhooks:
1818
port: {{ .Values.config.server.webhooks.port }}
19-
serverCertDir: {{ .Values.config.server.webhooks.certDir }}
19+
serverCertDir: {{ .Values.config.server.webhooks.serverCertDir }}
2020
certManagement:
2121
secretName: {{ .Values.config.server.webhooks.certManagement.secretName }}
2222
certManagerEnabled: {{ .Values.config.server.webhooks.certManagement.certManagerEnabled }}
23+
autoProvision: {{ if or .Values.config.server.webhooks.certManagement.certManagerEnabled .Values.config.server.webhooks.certManagement.certFilesPath }}false{{ else }}true{{ end }}
2324
healthProbes:
2425
port: {{ .Values.config.server.healthProbes.port }}
2526
metrics:

operator/charts/templates/deployment.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ spec:
9191
configMap:
9292
name: {{ include "operator.config.name" . }}
9393
- name: grove-webhook-server-cert
94+
# Always mount the Secret volume (cert-controller manages it in auto-provision mode)
9495
secret:
9596
secretName: {{ .Values.config.server.webhooks.certManagement.secretName }}
9697
defaultMode: 420

operator/cmd/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func main() {
6969
certMgmt.SecretName,
7070
operatorCfg.Authorizer.Enabled,
7171
*certMgmt.CertManagerEnabled,
72+
*certMgmt.AutoProvision,
7273
webhookCertsReadyCh,
7374
); err != nil {
7475
logger.Error(err, "failed to setup certificate management")

operator/internal/controller/cert/cert.go

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package cert
1818

1919
import (
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
139147
func 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

Comments
 (0)