From 0d6a4577b7845fc4fcba7f55593dd59d003e21fe Mon Sep 17 00:00:00 2001 From: Aliaksandr Shamchonak Date: Tue, 28 May 2024 17:05:52 +0400 Subject: [PATCH] Validate Kubernetes secret type spec.output.secret.type --- .../controller/secret.go | 29 ++++++- .../controller/secret_test.go | 78 +++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 cmd/azure-keyvault-controller/controller/secret_test.go diff --git a/cmd/azure-keyvault-controller/controller/secret.go b/cmd/azure-keyvault-controller/controller/secret.go index 7f02a166..e785773b 100644 --- a/cmd/azure-keyvault-controller/controller/secret.go +++ b/cmd/azure-keyvault-controller/controller/secret.go @@ -195,8 +195,8 @@ func createNewSecretFromExisting(akvs *akv.AzureKeyVaultSecret, values map[strin secretName := determineSecretName(akvs) secretType := determineSecretType(akvs) - // if existing secret is not opaque and owned by a different akvs, - // we cannot update this secret, as none opaque secrets cannot have multiple owners, + // if existing secret is not Opaque and owned by a different akvs, + // we cannot update this secret, as none Opaque secrets cannot have multiple owners, // because they would overrite each others keys if existingSecret.Type != corev1.SecretTypeOpaque { if !isOwnedBy(existingSecret, akvs) { @@ -293,11 +293,18 @@ func determineSecretName(azureKeyVaultSecret *akv.AzureKeyVaultSecret) string { return name } +// determineSecretType determines the secret type based on the provided Azure Key Vault secret. +// If the secret type is not specified, it defaults to corev1.SecretTypeOpaque. +// It returns the determined secret type and an error if the secret type is invalid. func determineSecretType(azureKeyVaultSecret *akv.AzureKeyVaultSecret) corev1.SecretType { if azureKeyVaultSecret.Spec.Output.Secret.Type == "" { return corev1.SecretTypeOpaque } + if !ValidateSecretType(string(azureKeyVaultSecret.Spec.Output.Secret.Type)) { + fmt.Errorf("invalid secret type: %s", azureKeyVaultSecret.Spec.Output.Secret.Type) + } + return azureKeyVaultSecret.Spec.Output.Secret.Type } @@ -355,3 +362,21 @@ func sortByteValueKeys(values map[string][]byte) []string { // } // return false // } + +// validateSecretType validates the given secret type. +// It checks if the secret type is one of the supported types and returns true if it is, false otherwise. +func ValidateSecretType(secretType string) bool { + switch secretType { + case string(corev1.SecretTypeOpaque), + string(corev1.SecretTypeServiceAccountToken), + string(corev1.SecretTypeBootstrapToken), + string(corev1.SecretTypeDockercfg), + string(corev1.SecretTypeDockerConfigJson), + string(corev1.SecretTypeBasicAuth), + string(corev1.SecretTypeSSHAuth), + string(corev1.SecretTypeTLS): + return true + default: + return false + } +} diff --git a/cmd/azure-keyvault-controller/controller/secret_test.go b/cmd/azure-keyvault-controller/controller/secret_test.go new file mode 100644 index 00000000..35ece8d7 --- /dev/null +++ b/cmd/azure-keyvault-controller/controller/secret_test.go @@ -0,0 +1,78 @@ +/* +Copyright Sparebanken Vest + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" +) + +func TestValidateSecretType(t *testing.T) { + tests := []struct { + secretType string + expected bool + }{ + { + secretType: string(corev1.SecretTypeOpaque), + expected: true, + }, + { + secretType: string(corev1.SecretTypeServiceAccountToken), + expected: true, + }, + { + secretType: string(corev1.SecretTypeBootstrapToken), + expected: true, + }, + { + secretType: string(corev1.SecretTypeDockercfg), + expected: true, + }, + { + secretType: string(corev1.SecretTypeDockerConfigJson), + expected: true, + }, + { + secretType: string(corev1.SecretTypeBasicAuth), + expected: true, + }, + { + secretType: string(corev1.SecretTypeSSHAuth), + expected: true, + }, + { + secretType: string(corev1.SecretTypeTLS), + expected: true, + }, + { + secretType: "opaque", + expected: false, + }, + { + secretType: "invalid", + expected: false, + }, + } + + for _, test := range tests { + result := ValidateSecretType(test.secretType) + if result != test.expected { + t.Errorf("Expected ValidateSecretType(%s) to be %v, but got %v", test.secretType, test.expected, result) + } + } +}