Browse Source

Validator (#3003)

* feat: add validator for duplicates keys

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>

* feat: retain mode on duplicate keys

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>

* feat: add new test

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>

* chore: rebase the test

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>

* fix: test cases for duplicate keys

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>

---------

Signed-off-by: Mehrbod Akhlaghpour <m9.akhlaghpoor@gmail.com>
Amirhossein Akhlaghpour 2 years ago
parent
commit
1bd07fd90e

+ 15 - 0
apis/externalsecrets/v1beta1/externalsecret_validator.go

@@ -63,5 +63,20 @@ func validateExternalSecret(obj runtime.Object) (admission.Warnings, error) {
 		}
 	}
 
+	errs = validateDuplicateKeys(es, errs)
 	return nil, errs
 }
+
+func validateDuplicateKeys(es *ExternalSecret, errs error) error {
+	if es.Spec.Target.DeletionPolicy == DeletionPolicyRetain {
+		seenKeys := make(map[string]struct{})
+		for _, data := range es.Spec.Data {
+			secretKey := data.SecretKey
+			if _, exists := seenKeys[secretKey]; exists {
+				errs = errors.Join(errs, fmt.Errorf("duplicate secretKey found: %s", secretKey))
+			}
+			seenKeys[secretKey] = struct{}{}
+		}
+	}
+	return errs
+}

+ 33 - 0
apis/externalsecrets/v1beta1/externalsecret_validator_test.go

@@ -122,6 +122,39 @@ either data or dataFrom should be specified`,
 				},
 			},
 		},
+		{
+			name: "duplicate secretKeys",
+			obj: &ExternalSecret{
+				Spec: ExternalSecretSpec{
+					Target: ExternalSecretTarget{
+						DeletionPolicy: DeletionPolicyRetain,
+					},
+					Data: []ExternalSecretData{
+						{SecretKey: "SERVICE_NAME"},
+						{SecretKey: "SERVICE_NAME"},
+						{SecretKey: "SERVICE_NAME-2"},
+						{SecretKey: "SERVICE_NAME-2"},
+						{SecretKey: "NOT_DUPLICATE"},
+					},
+				},
+			},
+			expectedErr: "duplicate secretKey found: SERVICE_NAME\nduplicate secretKey found: SERVICE_NAME-2",
+		},
+		{
+			name: "duplicate secretKey",
+			obj: &ExternalSecret{
+				Spec: ExternalSecretSpec{
+					Target: ExternalSecretTarget{
+						DeletionPolicy: DeletionPolicyRetain,
+					},
+					Data: []ExternalSecretData{
+						{SecretKey: "SERVICE_NAME"},
+						{SecretKey: "SERVICE_NAME"},
+					},
+				},
+			},
+			expectedErr: "duplicate secretKey found: SERVICE_NAME",
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {