diff --git a/keptn-cert-manager/eventfilter/eventfilter_test.go b/keptn-cert-manager/eventfilter/eventfilter_test.go index 9264487c5e0..cc01baec0d8 100644 --- a/keptn-cert-manager/eventfilter/eventfilter_test.go +++ b/keptn-cert-manager/eventfilter/eventfilter_test.go @@ -7,6 +7,7 @@ import ( v1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/controller-runtime/pkg/event" ) const ( @@ -106,3 +107,73 @@ func Test_matchesLabels(t *testing.T) { assert.False(t, matchesLabels(deploymentNoLabels, firstSelector)) } + +func TestForLabelsAndNamespace(t *testing.T) { + deployment := &v1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: testName1, + Namespace: testNamespace1, + Labels: map[string]string{ + "app": "test", + "env": "dev", + }, + }, + } + + selector := labels.SelectorFromSet(labels.Set{ + "app": "test", + "env": "dev", + }) + + // when the deployments matched with labels and is present in the required namespace. + assert.True(t, ForLabelsAndNamespace(selector, testNamespace1).Generic(event.GenericEvent{Object: deployment})) + + // when the namespace doesn't match. + assert.False(t, ForLabelsAndNamespace(selector, "another-namespace").Generic(event.GenericEvent{Object: deployment})) + + // when the labels don't match. + deploymentNoLabels := &v1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: testName1, + Namespace: testNamespace1, + }, + } + assert.False(t, ForLabelsAndNamespace(selector, testNamespace1).Generic(event.GenericEvent{Object: deploymentNoLabels})) +} + +func TestForNamesAndNamespace(t *testing.T) { + deployment1 := &v1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-1", + Namespace: "test-namespace-1", + }, + } + + deployment2 := &v1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment-2", + Namespace: "test-namespace-2", + }, + } + + names := []string{"deployment-1", "deployment-2"} + namespace := "test-namespace-1" + + // Test deployments in the same namespace and with matching names + pred := ForNamesAndNamespace(names, namespace) + assert.True(t, pred.Generic(event.GenericEvent{Object: deployment1})) + assert.False(t, pred.Generic(event.GenericEvent{Object: deployment2})) + + // Test deployments in different namespace + namespace = "test-namespace-2" + pred = ForNamesAndNamespace(names, namespace) + assert.False(t, pred.Generic(event.GenericEvent{Object: deployment1})) + assert.True(t, pred.Generic(event.GenericEvent{Object: deployment2})) + + // Test deployments with mismatched names + names = []string{"deployment-3", "deployment-4"} + namespace = "test-namespace-1" + pred = ForNamesAndNamespace(names, namespace) + assert.False(t, pred.Generic(event.GenericEvent{Object: deployment1})) + assert.False(t, pred.Generic(event.GenericEvent{Object: deployment2})) +} diff --git a/keptn-cert-manager/kubeutils/certificates_test.go b/keptn-cert-manager/kubeutils/certificates_test.go new file mode 100644 index 00000000000..feef50388ad --- /dev/null +++ b/keptn-cert-manager/kubeutils/certificates_test.go @@ -0,0 +1,77 @@ +package kubeutils + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "math/big" + "testing" + "time" +) + +func TestValidateCertificateExpiration(t *testing.T) { + certTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(1), + NotBefore: time.Now(), + NotAfter: time.Now().Add(24 * time.Hour), + } + + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("Failed to generate private key: %v", err) + } + + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, &privateKey.PublicKey, privateKey) + if err != nil { + t.Fatalf("Failed to create certificate: %v", err) + } + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes}) + + testCases := []struct { + name string + certData []byte + renewalThreshold time.Duration + now time.Time + expectedValid bool + expectedErrorNil bool + }{ + { + name: "Valid certificate", + certData: certPEM, + renewalThreshold: 2 * time.Hour, + now: time.Now().Add(21 * time.Hour), // Certificate is still valids + expectedValid: true, + expectedErrorNil: true, + }, + { + name: "Expired certificate", + certData: certPEM, + renewalThreshold: 2 * time.Hour, + now: time.Now().Add(25 * time.Hour), // Certificate has expired + expectedValid: false, + expectedErrorNil: true, + }, + { + name: "Invalid PEM data", + certData: []byte("invalid PEM data"), + renewalThreshold: 2 * time.Hour, + now: time.Now(), + expectedValid: false, + expectedErrorNil: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + valid, err := ValidateCertificateExpiration(tc.certData, tc.renewalThreshold, tc.now) + if valid != tc.expectedValid { + t.Errorf("Expected valid=%v, got %v", tc.expectedValid, valid) + } + if (err == nil) != tc.expectedErrorNil { + t.Errorf("Expected error nil=%v, got error=%v", tc.expectedErrorNil, err) + } + }) + } +} diff --git a/keptn-cert-manager/kubeutils/secret_test.go b/keptn-cert-manager/kubeutils/secret_test.go index 4335a24d931..a4fa8a43640 100644 --- a/keptn-cert-manager/kubeutils/secret_test.go +++ b/keptn-cert-manager/kubeutils/secret_test.go @@ -23,7 +23,7 @@ func TestSecretQuery(t *testing.T) { t.Run(`Update secret when data has changed`, testUpdateSecretWhenDataChanged) t.Run(`Update secret when labels have changed`, testUpdateSecretWhenLabelsChanged) t.Run(`Create secret in target namespace`, testCreateSecretInTargetNamespace) - t.Run(`New Secret`, TestNewSecret) + t.Run(`New Secret`, testNewSecretwithmutiplekeys) } func testGetSecret(t *testing.T) { @@ -261,7 +261,7 @@ func createTestSecret(labels map[string]string, data map[string][]byte) *corev1. return secret } -func TestNewSecret(t *testing.T) { +func testNewSecretwithmutiplekeys(t *testing.T) { testCases := []struct { name string