From 9d3b156eaa5be2b0fbfb47167b42b3213151f114 Mon Sep 17 00:00:00 2001 From: Geert Pingen Date: Sat, 1 Jul 2023 11:11:45 +0200 Subject: [PATCH 1/5] Updates Secret to use env_name field as environment variable name on injection if exists Signed-off-by: Geert Pingen --- go.mod | 2 ++ pkg/webhook/k8s_secrets.go | 1 + pkg/webhook/utils.go | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 532f4a996..6c84e663b 100644 --- a/go.mod +++ b/go.mod @@ -147,3 +147,5 @@ require ( ) replace github.com/aws/amazon-sagemaker-operator-for-k8s => github.com/aws/amazon-sagemaker-operator-for-k8s v1.0.1-0.20210303003444-0fb33b1fd49d + +replace github.com/flyteorg/flyteidl => /home/geert/git/flyte/flyteidl diff --git a/pkg/webhook/k8s_secrets.go b/pkg/webhook/k8s_secrets.go index f207da362..bd77c0d84 100644 --- a/pkg/webhook/k8s_secrets.go +++ b/pkg/webhook/k8s_secrets.go @@ -77,6 +77,7 @@ func (i K8sSecretInjector) Inject(ctx context.Context, secret *core.Secret, p *c p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) case core.Secret_ENV_VAR: envVar := CreateEnvVarForSecret(secret) + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, envVar) p.Spec.Containers = AppendEnvVars(p.Spec.Containers, envVar) diff --git a/pkg/webhook/utils.go b/pkg/webhook/utils.go index 2dd0bb991..19fd90213 100644 --- a/pkg/webhook/utils.go +++ b/pkg/webhook/utils.go @@ -26,8 +26,12 @@ func hasEnvVar(envVars []corev1.EnvVar, envVarKey string) bool { func CreateEnvVarForSecret(secret *core.Secret) corev1.EnvVar { optional := true + secretName := strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key) + if len(secret.EnvName) != 0 { + secretName = secret.EnvName + } return corev1.EnvVar{ - Name: strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key), + Name: secretName, ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ From 196fb96c4ce2ac9b6fe412ce1bcd54d9de3285d5 Mon Sep 17 00:00:00 2001 From: Geert Pingen Date: Sat, 1 Jul 2023 11:23:38 +0200 Subject: [PATCH 2/5] Removes local go.mod replace Signed-off-by: Geert Pingen --- go.mod | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.mod b/go.mod index 6c84e663b..532f4a996 100644 --- a/go.mod +++ b/go.mod @@ -147,5 +147,3 @@ require ( ) replace github.com/aws/amazon-sagemaker-operator-for-k8s => github.com/aws/amazon-sagemaker-operator-for-k8s v1.0.1-0.20210303003444-0fb33b1fd49d - -replace github.com/flyteorg/flyteidl => /home/geert/git/flyte/flyteidl From 6d83c4206596c2fc7f375f0fb12053b0aa325f0d Mon Sep 17 00:00:00 2001 From: Geert Pingen Date: Fri, 7 Jul 2023 21:19:33 +0200 Subject: [PATCH 3/5] First draft to add oneof Signed-off-by: Geert Pingen --- go.mod | 2 + ...zation.use_secrets.secret_task_1_task.yaml | 3 +- ...ion.use_secrets.user_info_task_1_task.yaml | 6 +- ...n.use_secrets.secret_file_task_1_task.yaml | 3 +- ...zation.use_secrets.secret_task_1_task.yaml | 3 +- ...ion.use_secrets.user_info_task_1_task.yaml | 6 +- ...n.use_secrets.secret_file_task_1_task.yaml | 3 +- ...n.use_secrets.my_secret_workflow_2_wf.yaml | 12 +- pkg/webhook/global_secrets.go | 1 + pkg/webhook/k8s_secrets.go | 124 +++++++++++------- pkg/webhook/utils.go | 29 +++- 11 files changed, 131 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index 532f4a996..6c84e663b 100644 --- a/go.mod +++ b/go.mod @@ -147,3 +147,5 @@ require ( ) replace github.com/aws/amazon-sagemaker-operator-for-k8s => github.com/aws/amazon-sagemaker-operator-for-k8s v1.0.1-0.20210303003444-0fb33b1fd49d + +replace github.com/flyteorg/flyteidl => /home/geert/git/flyte/flyteidl diff --git a/pkg/compiler/test/testdata/snacks-core/012_core.containerization.use_secrets.secret_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/012_core.containerization.use_secrets.secret_task_1_task.yaml index 370bebdc1..2911fee01 100755 --- a/pkg/compiler/test/testdata/snacks-core/012_core.containerization.use_secrets.secret_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/012_core.containerization.use_secrets.secret_task_1_task.yaml @@ -43,6 +43,7 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/013_core.containerization.use_secrets.user_info_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/013_core.containerization.use_secrets.user_info_task_1_task.yaml index eb509172f..6e7ce998d 100755 --- a/pkg/compiler/test/testdata/snacks-core/013_core.containerization.use_secrets.user_info_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/013_core.containerization.use_secrets.user_info_task_1_task.yaml @@ -48,8 +48,10 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: username - - group: user-info + - MountTarget: null + group: user-info key: password type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/014_core.containerization.use_secrets.secret_file_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/014_core.containerization.use_secrets.secret_file_task_1_task.yaml index 417db4725..c65cce698 100755 --- a/pkg/compiler/test/testdata/snacks-core/014_core.containerization.use_secrets.secret_file_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/014_core.containerization.use_secrets.secret_file_task_1_task.yaml @@ -48,7 +48,8 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret mount_requirement: 1 type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/compiled/012_core.containerization.use_secrets.secret_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/compiled/012_core.containerization.use_secrets.secret_task_1_task.yaml index 8ffeba716..80f27cad9 100755 --- a/pkg/compiler/test/testdata/snacks-core/compiled/012_core.containerization.use_secrets.secret_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/compiled/012_core.containerization.use_secrets.secret_task_1_task.yaml @@ -50,6 +50,7 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/compiled/013_core.containerization.use_secrets.user_info_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/compiled/013_core.containerization.use_secrets.user_info_task_1_task.yaml index b341ea9aa..827591ed2 100755 --- a/pkg/compiler/test/testdata/snacks-core/compiled/013_core.containerization.use_secrets.user_info_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/compiled/013_core.containerization.use_secrets.user_info_task_1_task.yaml @@ -55,8 +55,10 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: username - - group: user-info + - MountTarget: null + group: user-info key: password type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/compiled/014_core.containerization.use_secrets.secret_file_task_1_task.yaml b/pkg/compiler/test/testdata/snacks-core/compiled/014_core.containerization.use_secrets.secret_file_task_1_task.yaml index 4a0fb267a..f7fe3d98a 100755 --- a/pkg/compiler/test/testdata/snacks-core/compiled/014_core.containerization.use_secrets.secret_file_task_1_task.yaml +++ b/pkg/compiler/test/testdata/snacks-core/compiled/014_core.containerization.use_secrets.secret_file_task_1_task.yaml @@ -55,7 +55,8 @@ template: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret mount_requirement: 1 type: python-task diff --git a/pkg/compiler/test/testdata/snacks-core/compiled/015_core.containerization.use_secrets.my_secret_workflow_2_wf.yaml b/pkg/compiler/test/testdata/snacks-core/compiled/015_core.containerization.use_secrets.my_secret_workflow_2_wf.yaml index 65ecd563a..9075c94b1 100755 --- a/pkg/compiler/test/testdata/snacks-core/compiled/015_core.containerization.use_secrets.my_secret_workflow_2_wf.yaml +++ b/pkg/compiler/test/testdata/snacks-core/compiled/015_core.containerization.use_secrets.my_secret_workflow_2_wf.yaml @@ -226,7 +226,8 @@ tasks: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret mount_requirement: 1 type: python-task @@ -282,7 +283,8 @@ tasks: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: user_secret type: python-task - template: @@ -342,8 +344,10 @@ tasks: version: 0.32.6 security_context: secrets: - - group: user-info + - MountTarget: null + group: user-info key: username - - group: user-info + - MountTarget: null + group: user-info key: password type: python-task diff --git a/pkg/webhook/global_secrets.go b/pkg/webhook/global_secrets.go index 42c8869d5..e883ae3d7 100644 --- a/pkg/webhook/global_secrets.go +++ b/pkg/webhook/global_secrets.go @@ -30,6 +30,7 @@ func (g GlobalSecrets) Type() config.SecretManagerType { } func (g GlobalSecrets) Inject(ctx context.Context, secret *coreIdl.Secret, p *corev1.Pod) (newP *corev1.Pod, injected bool, err error) { + v, err := g.envSecretManager.GetForSecret(ctx, secret) if err != nil { return p, false, err diff --git a/pkg/webhook/k8s_secrets.go b/pkg/webhook/k8s_secrets.go index bd77c0d84..3207dffb2 100644 --- a/pkg/webhook/k8s_secrets.go +++ b/pkg/webhook/k8s_secrets.go @@ -38,65 +38,99 @@ func (i K8sSecretInjector) Type() config.SecretManagerType { } func (i K8sSecretInjector) Inject(ctx context.Context, secret *core.Secret, p *corev1.Pod) (newP *corev1.Pod, injected bool, err error) { + if len(secret.Group) == 0 || len(secret.Key) == 0 { return nil, false, fmt.Errorf("k8s Secrets Webhook require both key and group to be set. "+ "Secret: [%v]", secret) } - switch secret.MountRequirement { - case core.Secret_ANY: - fallthrough - case core.Secret_FILE: - // Inject a Volume that to the pod and all of its containers and init containers that mounts the secret into a - // file. - - volume := CreateVolumeForSecret(secret) - p.Spec.Volumes = AppendVolume(p.Spec.Volumes, volume) - - // Mount the secret to all containers in the given pod. - mount := CreateVolumeMountForSecret(volume.Name, secret) - p.Spec.InitContainers = AppendVolumeMounts(p.Spec.InitContainers, mount) - p.Spec.Containers = AppendVolumeMounts(p.Spec.Containers, mount) - - // Set environment variable to let the container know where to find the mounted files. - defaultDirEnvVar := corev1.EnvVar{ - Name: SecretPathDefaultDirEnvVar, - Value: filepath.Join(K8sSecretPathPrefix...), + // Check for new MountTarget field. If MountTarget doesn't exist, fall back to old MountRequirement field. + if secret.MountTarget != nil { + switch secret.MountTarget.(type) { + case *core.Secret_EnvVar: + target, ok := secret.GetMountTarget().(*core.Secret_EnvVar) + if ok { + injectSecretAsEnvVar(p, secret, &target.EnvVar.Name) + } + case *core.Secret_File: + target, ok := secret.GetMountTarget().(*core.Secret_File) + if ok { + injectSecretAsFile(p, secret, &target.File.Path) + } + default: + err := fmt.Errorf("unrecognized mount target [%v] for secret [%v]", secret.GetMountTarget(), secret.Key) + logger.Error(ctx, err) + return p, false, err + } + } else { + switch secret.MountRequirement { + case core.Secret_ANY: + fallthrough + case core.Secret_FILE: + injectSecretAsFile(p, secret, nil) + case core.Secret_ENV_VAR: + injectSecretAsEnvVar(p, secret, nil) + default: + err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) + logger.Error(ctx, err) + return p, false, err } + } - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, defaultDirEnvVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, defaultDirEnvVar) + return p, true, nil +} - // Sets an empty prefix to let the containers know the file names will match the secret keys as-is. - prefixEnvVar := corev1.EnvVar{ - Name: SecretPathFilePrefixEnvVar, - Value: "", - } +func NewK8sSecretsInjector() K8sSecretInjector { + return K8sSecretInjector{} +} - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) - case core.Secret_ENV_VAR: - envVar := CreateEnvVarForSecret(secret) +func injectSecretAsFile(p *corev1.Pod, secret *core.Secret, mountPath *string) { + // Inject a Volume that to the pod and all of its containers and init containers that mounts the secret into a + // file. + volume := CreateVolumeForSecret(secret) + p.Spec.Volumes = AppendVolume(p.Spec.Volumes, volume) - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, envVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, envVar) + // Mount the secret to all containers in the given pod. + mount := CreateVolumeMountForSecret(volume.Name, secret) + if mountPath != nil { + mount = CreateVolumeMountForSecretWithMountPath(volume.Name, secret, *mountPath) + } + p.Spec.InitContainers = AppendVolumeMounts(p.Spec.InitContainers, mount) + p.Spec.Containers = AppendVolumeMounts(p.Spec.Containers, mount) - prefixEnvVar := corev1.EnvVar{ - Name: SecretEnvVarPrefix, - Value: K8sDefaultEnvVarPrefix, - } + // Set environment variable to let the container know where to find the mounted files. + defaultDirEnvVar := corev1.EnvVar{ + Name: SecretPathDefaultDirEnvVar, + Value: filepath.Join(K8sSecretPathPrefix...), + } + + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, defaultDirEnvVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, defaultDirEnvVar) - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) - default: - err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) - logger.Error(ctx, err) - return p, false, err + // Sets an empty prefix to let the containers know the file names will match the secret keys as-is. + prefixEnvVar := corev1.EnvVar{ + Name: SecretPathFilePrefixEnvVar, + Value: "", } - return p, true, nil + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) } -func NewK8sSecretsInjector() K8sSecretInjector { - return K8sSecretInjector{} +func injectSecretAsEnvVar(p *corev1.Pod, secret *core.Secret, envVarName *string) { + envVar := CreateEnvVarForSecret(secret) + if envVarName != nil { + envVar = CreateNamedEnvVarForSecret(secret, *envVarName) + } + + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, envVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, envVar) + + prefixEnvVar := corev1.EnvVar{ + Name: SecretEnvVarPrefix, + Value: K8sDefaultEnvVarPrefix, + } + + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) } diff --git a/pkg/webhook/utils.go b/pkg/webhook/utils.go index 19fd90213..fb77c3996 100644 --- a/pkg/webhook/utils.go +++ b/pkg/webhook/utils.go @@ -26,12 +26,25 @@ func hasEnvVar(envVars []corev1.EnvVar, envVarKey string) bool { func CreateEnvVarForSecret(secret *core.Secret) corev1.EnvVar { optional := true - secretName := strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key) - if len(secret.EnvName) != 0 { - secretName = secret.EnvName + envVarName := strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key) + return corev1.EnvVar{ + Name: envVarName, + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secret.Group, + }, + Key: secret.Key, + Optional: &optional, + }, + }, } +} + +func CreateNamedEnvVarForSecret(secret *core.Secret, envVarName string) corev1.EnvVar { + optional := true return corev1.EnvVar{ - Name: secretName, + Name: envVarName, ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ @@ -72,6 +85,14 @@ func CreateVolumeMountForSecret(volumeName string, secret *core.Secret) corev1.V } } +func CreateVolumeMountForSecretWithMountPath(volumeName string, secret *core.Secret, mountPath string) corev1.VolumeMount { + return corev1.VolumeMount{ + Name: volumeName, + ReadOnly: true, + MountPath: mountPath, + } +} + func AppendVolumeMounts(containers []corev1.Container, mount corev1.VolumeMount) []corev1.Container { res := make([]corev1.Container, 0, len(containers)) for _, c := range containers { From 12b438ffb91ce6441e75e801c1b74b5c1c6e0dd7 Mon Sep 17 00:00:00 2001 From: Geert Pingen Date: Sat, 8 Jul 2023 12:12:16 +0200 Subject: [PATCH 4/5] Updates k8s_secrets Signed-off-by: Geert Pingen --- pkg/webhook/global_secrets.go | 84 +++++++++++++++++++++++------------ pkg/webhook/k8s_secrets.go | 12 ++--- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/pkg/webhook/global_secrets.go b/pkg/webhook/global_secrets.go index e883ae3d7..a796f3122 100644 --- a/pkg/webhook/global_secrets.go +++ b/pkg/webhook/global_secrets.go @@ -36,37 +36,40 @@ func (g GlobalSecrets) Inject(ctx context.Context, secret *coreIdl.Secret, p *co return p, false, err } - switch secret.MountRequirement { - case coreIdl.Secret_FILE: - return nil, false, fmt.Errorf("global secrets can only be injected as environment "+ - "variables [%v/%v]", secret.Group, secret.Key) - case coreIdl.Secret_ANY: - fallthrough - case coreIdl.Secret_ENV_VAR: - if len(secret.Group) == 0 { - return nil, false, fmt.Errorf("mounting a secret to env var requires selecting the "+ - "secret and a single key within. Key [%v]", secret.Key) + if secret.MountTarget != nil { + switch secret.MountTarget.(type) { + case *coreIdl.Secret_EnvVar: + target, ok := secret.GetMountTarget().(*coreIdl.Secret_EnvVar) + if ok { + InjectEnvVar(p, secret, &target.EnvVar.Name, v) + } + case *coreIdl.Secret_File: + return nil, false, fmt.Errorf("global secrets can only be injected as environment "+ + "variables [%v/%v]", secret.Group, secret.Key) + default: + err := fmt.Errorf("unrecognized mount target [%v] for secret [%v]", secret.GetMountTarget(), secret.Key) + logger.Error(ctx, err) + return p, false, err } - - envVar := corev1.EnvVar{ - Name: strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key), - Value: v, - } - - prefixEnvVar := corev1.EnvVar{ - Name: SecretEnvVarPrefix, - Value: K8sDefaultEnvVarPrefix, + } else { + switch secret.MountRequirement { + case coreIdl.Secret_FILE: + return nil, false, fmt.Errorf("global secrets can only be injected as environment "+ + "variables [%v/%v]", secret.Group, secret.Key) + case coreIdl.Secret_ANY: + fallthrough + case coreIdl.Secret_ENV_VAR: + if len(secret.Group) == 0 { + return nil, false, fmt.Errorf("mounting a secret to env var requires selecting the "+ + "secret and a single key within. Key [%v]", secret.Key) + } + + InjectEnvVar(p, secret, nil, v) + default: + err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) + logger.Error(ctx, err) + return p, false, err } - - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) - - p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, envVar) - p.Spec.Containers = AppendEnvVars(p.Spec.Containers, envVar) - default: - err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) - logger.Error(ctx, err) - return p, false, err } return p, true, nil @@ -77,3 +80,26 @@ func NewGlobalSecrets(provider GlobalSecretProvider) GlobalSecrets { envSecretManager: provider, } } + +func InjectEnvVar(p *corev1.Pod, secret *coreIdl.Secret, envVarName *string, value string) { + _envVarName := strings.ToUpper(K8sDefaultEnvVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key) + if envVarName != nil { + _envVarName = *envVarName + } + + envVar := corev1.EnvVar{ + Name: _envVarName, + Value: value, + } + + prefixEnvVar := corev1.EnvVar{ + Name: SecretEnvVarPrefix, + Value: K8sDefaultEnvVarPrefix, + } + + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, prefixEnvVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) + + p.Spec.InitContainers = AppendEnvVars(p.Spec.InitContainers, envVar) + p.Spec.Containers = AppendEnvVars(p.Spec.Containers, envVar) +} diff --git a/pkg/webhook/k8s_secrets.go b/pkg/webhook/k8s_secrets.go index 3207dffb2..a9d8f341c 100644 --- a/pkg/webhook/k8s_secrets.go +++ b/pkg/webhook/k8s_secrets.go @@ -50,12 +50,12 @@ func (i K8sSecretInjector) Inject(ctx context.Context, secret *core.Secret, p *c case *core.Secret_EnvVar: target, ok := secret.GetMountTarget().(*core.Secret_EnvVar) if ok { - injectSecretAsEnvVar(p, secret, &target.EnvVar.Name) + InjectSecretAsEnvVar(p, secret, &target.EnvVar.Name) } case *core.Secret_File: target, ok := secret.GetMountTarget().(*core.Secret_File) if ok { - injectSecretAsFile(p, secret, &target.File.Path) + InjectSecretAsFile(p, secret, &target.File.Path) } default: err := fmt.Errorf("unrecognized mount target [%v] for secret [%v]", secret.GetMountTarget(), secret.Key) @@ -67,9 +67,9 @@ func (i K8sSecretInjector) Inject(ctx context.Context, secret *core.Secret, p *c case core.Secret_ANY: fallthrough case core.Secret_FILE: - injectSecretAsFile(p, secret, nil) + InjectSecretAsFile(p, secret, nil) case core.Secret_ENV_VAR: - injectSecretAsEnvVar(p, secret, nil) + InjectSecretAsEnvVar(p, secret, nil) default: err := fmt.Errorf("unrecognized mount requirement [%v] for secret [%v]", secret.MountRequirement.String(), secret.Key) logger.Error(ctx, err) @@ -84,7 +84,7 @@ func NewK8sSecretsInjector() K8sSecretInjector { return K8sSecretInjector{} } -func injectSecretAsFile(p *corev1.Pod, secret *core.Secret, mountPath *string) { +func InjectSecretAsFile(p *corev1.Pod, secret *core.Secret, mountPath *string) { // Inject a Volume that to the pod and all of its containers and init containers that mounts the secret into a // file. volume := CreateVolumeForSecret(secret) @@ -117,7 +117,7 @@ func injectSecretAsFile(p *corev1.Pod, secret *core.Secret, mountPath *string) { p.Spec.Containers = AppendEnvVars(p.Spec.Containers, prefixEnvVar) } -func injectSecretAsEnvVar(p *corev1.Pod, secret *core.Secret, envVarName *string) { +func InjectSecretAsEnvVar(p *corev1.Pod, secret *core.Secret, envVarName *string) { envVar := CreateEnvVarForSecret(secret) if envVarName != nil { envVar = CreateNamedEnvVarForSecret(secret, *envVarName) From 8724259ee4c1ce25ce9d22bc0b89b6c2ad97797f Mon Sep 17 00:00:00 2001 From: Geert Pingen Date: Sat, 8 Jul 2023 17:29:02 +0200 Subject: [PATCH 5/5] Adds test cases Signed-off-by: Geert Pingen --- pkg/webhook/k8s_secrets_test.go | 132 +++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/pkg/webhook/k8s_secrets_test.go b/pkg/webhook/k8s_secrets_test.go index 500da6f44..6bd2b54e7 100644 --- a/pkg/webhook/k8s_secrets_test.go +++ b/pkg/webhook/k8s_secrets_test.go @@ -52,6 +52,35 @@ func TestK8sSecretInjector_Inject(t *testing.T) { }, } + successPodEnvWithName := corev1.Pod{ + Spec: corev1.PodSpec{ + InitContainers: []corev1.Container{}, + Containers: []corev1.Container{ + { + Name: "container1", + Env: []corev1.EnvVar{ + { + Name: "foo", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "HELLO", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "grOUP", + }, + Optional: &optional, + }, + }, + }, + { + Name: "FLYTE_SECRETS_ENV_PREFIX", + Value: "_FSEC_", + }, + }, + }, + }, + }, + } + successPodFile := corev1.Pod{ Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ @@ -96,6 +125,50 @@ func TestK8sSecretInjector_Inject(t *testing.T) { }, } + successPodFileWithPath := corev1.Pod{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "m4ze5vkql3", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "grOUP", + Items: []corev1.KeyToPath{ + { + Key: "HELLO", + Path: "hello", + }, + }, + Optional: &optional, + }, + }, + }, + }, + InitContainers: []corev1.Container{}, + Containers: []corev1.Container{ + { + Name: "container1", + VolumeMounts: []corev1.VolumeMount{ + { + Name: "m4ze5vkql3", + MountPath: "/foo", + ReadOnly: true, + }, + }, + Env: []corev1.EnvVar{ + { + Name: "FLYTE_SECRETS_DEFAULT_DIR", + Value: "/etc/flyte/secrets", + }, + { + Name: "FLYTE_SECRETS_FILE_PREFIX", + }, + }, + }, + }, + }, + } + successPodMultiFiles := corev1.Pod{ Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ @@ -144,6 +217,54 @@ func TestK8sSecretInjector_Inject(t *testing.T) { }, } + successPodMultiFilesWithPath := corev1.Pod{ + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "m4ze5vkql3", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "grOUP", + Items: []corev1.KeyToPath{ + { + Key: "HELLO", + Path: "hello", + }, + { + Key: "world", + Path: "world", + }, + }, + Optional: &optional, + }, + }, + }, + }, + InitContainers: []corev1.Container{}, + Containers: []corev1.Container{ + { + Name: "container1", + VolumeMounts: []corev1.VolumeMount{ + { + Name: "m4ze5vkql3", + MountPath: "/foo", + ReadOnly: true, + }, + }, + Env: []corev1.EnvVar{ + { + Name: "FLYTE_SECRETS_DEFAULT_DIR", + Value: "/etc/flyte/secrets", + }, + { + Name: "FLYTE_SECRETS_FILE_PREFIX", + }, + }, + }, + }, + }, + } + successPodFileAllKeys := corev1.Pod{ Spec: corev1.PodSpec{ Volumes: []corev1.Volume{ @@ -200,9 +321,18 @@ func TestK8sSecretInjector_Inject(t *testing.T) { {name: "require file single", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "HELLO", MountRequirement: coreIdl.Secret_FILE}, p: inputPod.DeepCopy()}, want: &successPodFile, wantErr: false}, - {name: "require file multiple from same secret group", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "world", MountRequirement: coreIdl.Secret_FILE}, + {name: "require multiple file from same secret group", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "world", MountRequirement: coreIdl.Secret_FILE}, p: successPodFile.DeepCopy()}, want: &successPodMultiFiles, wantErr: false}, + {name: "require env var with name", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "HELLO", MountTarget: &coreIdl.Secret_EnvVar{EnvVar: &coreIdl.Secret_MountEnvVar{Name: "foo"}}}, + p: inputPod.DeepCopy()}, + want: &successPodEnvWithName, wantErr: false}, + {name: "require single file with mount path", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "HELLO", MountTarget: &coreIdl.Secret_File{File: &coreIdl.Secret_MountFile{Path: "/foo"}}}, + p: inputPod.DeepCopy()}, + want: &successPodFileWithPath, wantErr: false}, + {name: "require multiple file from same secret group with mount path", args: args{secret: &coreIdl.Secret{Group: "grOUP", Key: "world", MountTarget: &coreIdl.Secret_File{File: &coreIdl.Secret_MountFile{Path: "/foo"}}}, + p: successPodFileWithPath.DeepCopy()}, + want: &successPodMultiFilesWithPath, wantErr: false}, {name: "require file all keys", args: args{secret: &coreIdl.Secret{Key: "hello", MountRequirement: coreIdl.Secret_FILE}, p: inputPod.DeepCopy()}, want: &successPodFileAllKeys, wantErr: true},