Skip to content

Commit 73e8354

Browse files
Wei WengWei Weng
authored andcommitted
add chart validation and webhook tests
Signed-off-by: Wei Weng <Wei.Weng@microsoft.com>
1 parent c7cb9b4 commit 73e8354

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

charts/hub-agent/templates/deployment.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
{{- if and (not .Values.useCertManager) (gt (.Values.replicaCount | int) 1) }}
2+
{{- fail "ERROR: replicaCount > 1 requires useCertManager=true (self-signed certificates cannot be shared across replicas)" }}
3+
{{- end }}
14
apiVersion: apps/v1
25
kind: Deployment
36
metadata:
@@ -86,7 +89,7 @@ spec:
8689
- name: webhook-cert
8790
secret:
8891
secretName: fleet-webhook-server-cert
89-
defaultMode: 0644
92+
defaultMode: 0400
9093
{{- end }}
9194
{{- with .Values.affinity }}
9295
affinity:

pkg/webhook/webhook.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func NewWebhookConfig(mgr manager.Manager, webhookServiceName string, port int32
200200
// Use self-signed certificate generation (original flow)
201201
caPEM, err = w.genCertificate(certDir)
202202
if err != nil {
203-
return nil, err
203+
return nil, fmt.Errorf("failed to generate self-signed certificate: %w", err)
204204
}
205205
}
206206

@@ -694,7 +694,7 @@ func (w *Config) genCertificate(certDir string) ([]byte, error) {
694694

695695
// loadCertManagerCA loads the CA certificate from the mounted cert-manager Secret.
696696
// When using cert-manager, Kubernetes mounts the Secret as files in the certDir.
697-
// cert-manager creates: ca.crt, tls.crt, and tls.key
697+
// cert-manager creates: ca.crt, tls.crt, and tls.key.
698698
// The tls.crt and tls.key are automatically used by the webhook server.
699699
// We only need to read ca.crt for the webhook configuration's CABundle.
700700
func (w *Config) loadCertManagerCA(certDir string) ([]byte, error) {

pkg/webhook/webhook_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package webhook
33
import (
44
"os"
55
"path/filepath"
6+
"strings"
67
"testing"
78

89
"github.com/google/go-cmp/cmp"
@@ -215,3 +216,93 @@ func TestNewWebhookConfig(t *testing.T) {
215216
})
216217
}
217218
}
219+
func TestLoadCertManagerCA_NotFound(t *testing.T) {
220+
config := &Config{}
221+
_, err := config.loadCertManagerCA("/nonexistent/path")
222+
if err == nil {
223+
t.Error("Expected error when certificate files don't exist")
224+
}
225+
}
226+
227+
func TestLoadCertManagerCA_EmptyFile(t *testing.T) {
228+
dir := t.TempDir()
229+
// Create empty files
230+
if err := os.WriteFile(filepath.Join(dir, "tls.crt"), []byte{}, 0600); err != nil {
231+
t.Fatalf("failed to create empty tls.crt: %v", err)
232+
}
233+
if err := os.WriteFile(filepath.Join(dir, "ca.crt"), []byte{}, 0600); err != nil {
234+
t.Fatalf("failed to create empty ca.crt: %v", err)
235+
}
236+
237+
config := &Config{}
238+
_, err := config.loadCertManagerCA(dir)
239+
if err == nil {
240+
t.Error("Expected error for empty certificate files")
241+
}
242+
if !strings.Contains(err.Error(), "empty") {
243+
t.Errorf("Expected error message to contain 'empty', got: %v", err)
244+
}
245+
}
246+
247+
func TestLoadCertManagerCA_Success(t *testing.T) {
248+
t.Run("loads ca.crt successfully", func(t *testing.T) {
249+
dir := t.TempDir()
250+
caContent := []byte("test-ca-content")
251+
if err := os.WriteFile(filepath.Join(dir, "ca.crt"), caContent, 0600); err != nil {
252+
t.Fatalf("failed to create ca.crt: %v", err)
253+
}
254+
255+
config := &Config{}
256+
result, err := config.loadCertManagerCA(dir)
257+
if err != nil {
258+
t.Errorf("Unexpected error: %v", err)
259+
}
260+
if string(result) != string(caContent) {
261+
t.Errorf("Expected %s, got %s", caContent, result)
262+
}
263+
})
264+
}
265+
266+
func TestNewWebhookConfig_CertManagerNotMounted(t *testing.T) {
267+
t.Setenv("POD_NAMESPACE", "test-namespace")
268+
269+
dir := t.TempDir()
270+
// Don't create any certificate files to simulate cert-manager not ready
271+
272+
_, err := NewWebhookConfig(nil, "test-webhook", 8080, nil, dir, true, true, false, true)
273+
if err == nil {
274+
t.Error("Expected error when cert-manager certificates not mounted")
275+
}
276+
if !strings.Contains(err.Error(), "failed to load cert-manager CA certificate") {
277+
t.Errorf("Expected error about loading cert-manager CA, got: %v", err)
278+
}
279+
}
280+
281+
func TestNewWebhookConfig_SelfSignedCertError(t *testing.T) {
282+
t.Setenv("POD_NAMESPACE", "test-namespace")
283+
284+
// Use an invalid certDir (read-only location) to force genCertificate to fail
285+
invalidCertDir := "/proc/invalid-cert-dir"
286+
287+
clientConnectionType := options.Service
288+
_, err := NewWebhookConfig(
289+
nil,
290+
"test-service",
291+
443,
292+
&clientConnectionType,
293+
invalidCertDir,
294+
false, // enableGuardRail
295+
false, // denyModifyMemberClusterLabels
296+
false, // enableWorkload
297+
false, // useCertManager = false to trigger self-signed path
298+
)
299+
300+
if err == nil {
301+
t.Fatal("Expected error when genCertificate fails, got nil")
302+
}
303+
304+
expectedErrMsg := "failed to generate self-signed certificate"
305+
if !strings.Contains(err.Error(), expectedErrMsg) {
306+
t.Errorf("Expected error to contain '%s', got: %v", expectedErrMsg, err)
307+
}
308+
}

0 commit comments

Comments
 (0)