From b1b286f54398ab0c43aeed5c7b3d0b5a9223cb12 Mon Sep 17 00:00:00 2001 From: diyliv Date: Mon, 20 Jul 2026 11:29:10 +0300 Subject: [PATCH] warn not error on missing certificate secret Signed-off-by: diyliv --- common-hooks/copy-custom-certificate/hook.go | 9 +- .../copy-custom-certificate/hook_test.go | 157 ++++++++++++++++++ 2 files changed, 162 insertions(+), 4 deletions(-) diff --git a/common-hooks/copy-custom-certificate/hook.go b/common-hooks/copy-custom-certificate/hook.go index 9abdb17c..02ac1a8c 100644 --- a/common-hooks/copy-custom-certificate/hook.go +++ b/common-hooks/copy-custom-certificate/hook.go @@ -18,7 +18,6 @@ package copycustomcertificate import ( "context" - "errors" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -66,10 +65,10 @@ func RegisterHook(moduleName string) bool { JqFilter: JQFilterCustomCertificate, }, }, - }, copyCustomCertificatesHandler(moduleName)) + }, CopyCustomCertificatesHandler(moduleName)) } -func copyCustomCertificatesHandler(moduleName string) func(ctx context.Context, input *pkg.HookInput) error { +func CopyCustomCertificatesHandler(moduleName string) func(ctx context.Context, input *pkg.HookInput) error { return func(_ context.Context, input *pkg.HookInput) error { certs, err := objectpatch.UnmarshalToStruct[certificate.Certificate](input.Snapshots, snapshotKey) if err != nil { @@ -109,7 +108,9 @@ func copyCustomCertificatesHandler(moduleName string) func(ctx context.Context, cert, ok := customCertificates[secretName] if !ok { - return errors.New("custom certificate secret name is configured, but secret with this name '" + secretName + "' doesn't exist") + input.Logger.Warn("custom certificate secret name is configured, but secret with this name doesn't exist", "secret_name", secretName) + input.Values.Set(valuesPath, certValues{CA: "", TLSKey: "", TLSCert: ""}) + return nil } input.Values.Set(valuesPath, certValues{ diff --git a/common-hooks/copy-custom-certificate/hook_test.go b/common-hooks/copy-custom-certificate/hook_test.go index 105b2fa6..1d2cd73a 100644 --- a/common-hooks/copy-custom-certificate/hook_test.go +++ b/common-hooks/copy-custom-certificate/hook_test.go @@ -22,10 +22,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" copycustomcertificate "github.com/deckhouse/module-sdk/common-hooks/copy-custom-certificate" tlscertificate "github.com/deckhouse/module-sdk/common-hooks/tls-certificate" + "github.com/deckhouse/module-sdk/pkg" "github.com/deckhouse/module-sdk/pkg/certificate" + "github.com/deckhouse/module-sdk/testing/framework" "github.com/deckhouse/module-sdk/testing/helpers" ) @@ -92,3 +95,157 @@ func TestJQFilterApplyCertificateSecret_ParsesClientCertificate(t *testing.T) { assert.Equal(t, "some-key", string(auth.Key)) assert.Equal(t, "some-crt", string(auth.Cert)) } + +func TestHandler_SecretNotFound_ReturnsWarningNotError(t *testing.T) { + cfg := &pkg.HookConfig{ + OnBeforeHelm: &pkg.OrderedConfig{Order: 10}, + Kubernetes: []pkg.KubernetesConfig{ + { + Name: "custom_certificates", + APIVersion: "v1", + Kind: "Secret", + NamespaceSelector: &pkg.NamespaceSelector{ + NameSelector: &pkg.NameSelector{ + MatchNames: []string{"d8-system"}, + }, + }, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "owner", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"helm"}, + }, + }, + }, + JqFilter: copycustomcertificate.JQFilterCustomCertificate, + }, + }, + } + + handler := copycustomcertificate.CopyCustomCertificatesHandler("testmodule") + hec := framework.HookExecutionConfigInit(t, cfg, handler, `{}`, `{}`) + + hec.KubeStateSet(` +--- +apiVersion: v1 +kind: Secret +metadata: + name: other-cert + namespace: d8-system + labels: + owner: deckhouse +data: + tls.crt: Q1JUQ1JUQ1JU + tls.key: S0VZS0VZS0VZ +type: kubernetes.io/tls +`) + + hec.ValuesSet("testmodule.https.mode", "CustomCertificate") + hec.ValuesSet("testmodule.https.customCertificate.secretName", "missing-cert") + + hec.RunHook() + + require.NoError(t, hec.HookError()) + + assert.Equal(t, "", hec.ValuesGet("testmodule.internal.customCertificateData.ca\\.crt").String()) + assert.Equal(t, "", hec.ValuesGet("testmodule.internal.customCertificateData.tls\\.key").String()) + assert.Equal(t, "", hec.ValuesGet("testmodule.internal.customCertificateData.tls\\.crt").String()) +} + +func TestHandler_SecretExists_SetsValues(t *testing.T) { + cfg := &pkg.HookConfig{ + OnBeforeHelm: &pkg.OrderedConfig{Order: 10}, + Kubernetes: []pkg.KubernetesConfig{ + { + Name: "custom_certificates", + APIVersion: "v1", + Kind: "Secret", + NamespaceSelector: &pkg.NamespaceSelector{ + NameSelector: &pkg.NameSelector{ + MatchNames: []string{"d8-system"}, + }, + }, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "owner", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"helm"}, + }, + }, + }, + JqFilter: copycustomcertificate.JQFilterCustomCertificate, + }, + }, + } + + handler := copycustomcertificate.CopyCustomCertificatesHandler("testmodule") + hec := framework.HookExecutionConfigInit(t, cfg, handler, `{}`, `{}`) + + hec.KubeStateSet(` +--- +apiVersion: v1 +kind: Secret +metadata: + name: my-cert + namespace: d8-system + labels: + owner: deckhouse +data: + tls.crt: Q1JUQ1JUQ1JU + tls.key: S0VZS0VZS0VZ + ca.crt: Q0FDQUNBQ0E= +type: kubernetes.io/tls +`) + + hec.ValuesSet("testmodule.https.mode", "CustomCertificate") + hec.ValuesSet("testmodule.https.customCertificate.secretName", "my-cert") + + hec.RunHook() + + require.NoError(t, hec.HookError()) + + assert.Equal(t, "CACACACA", hec.ValuesGet("testmodule.internal.customCertificateData.ca\\.crt").String()) + assert.Equal(t, "KEYKEYKEY", hec.ValuesGet("testmodule.internal.customCertificateData.tls\\.key").String()) + assert.Equal(t, "CRTCRTCRT", hec.ValuesGet("testmodule.internal.customCertificateData.tls\\.crt").String()) +} + +func TestHandler_NonCustomCertificateMode_RemovesValues(t *testing.T) { + cfg := &pkg.HookConfig{ + OnBeforeHelm: &pkg.OrderedConfig{Order: 10}, + Kubernetes: []pkg.KubernetesConfig{ + { + Name: "custom_certificates", + APIVersion: "v1", + Kind: "Secret", + NamespaceSelector: &pkg.NamespaceSelector{ + NameSelector: &pkg.NameSelector{ + MatchNames: []string{"d8-system"}, + }, + }, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "owner", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"helm"}, + }, + }, + }, + JqFilter: copycustomcertificate.JQFilterCustomCertificate, + }, + }, + } + + handler := copycustomcertificate.CopyCustomCertificatesHandler("testmodule") + hec := framework.HookExecutionConfigInit(t, cfg, handler, `{}`, `{}`) + + hec.KubeStateSet(``) + hec.ValuesSet("testmodule.https.mode", "CertManager") + + hec.RunHook() + + require.NoError(t, hec.HookError()) + assert.False(t, hec.ValuesGet("testmodule.internal.customCertificateData").Exists()) +}