package edgeinjector import ( "context" "fmt" "strings" "github.com/google/uuid" corev1 "k8s.io/api/core/v1" "edge-infra.dev/pkg/edge/api/utils" "edge-infra.dev/pkg/lib/fog" ) func InjectSecret(ctx context.Context, pod *corev1.Pod, secretType SecretType, env ...map[string]string) { log := fog.FromContext(ctx) log.Info("handling secret label for pod") secretName := fmt.Sprintf("%s-%s", secretType, uuid.NewString()) InjectLabels(pod, map[string]string{SecretLabel(secretType): secretName}) log.Info("injected secret label unto pod", "secretName", secretName) switch InjectionType(pod) { case DirectType: if len(env) > 0 { InjectEnvVar(pod, secretName, env[0], true) } else { InjectEnvFrom(pod, secretName) } log.Info("injected secret name env unto pod", "secretName", secretName, "injection type", "direct") default: // refSecretName couchdb-secret ==> COUCHDB_SECRET refSecretName := strings.ReplaceAll(strings.ToUpper(string(secretType)), "-", "_") InjectEnvVar(pod, secretName, map[string]string{refSecretName: secretName}, false) log.Info("injected secret ref unto pod", "secretName", secretName, "injection type", "reference") } } func InjectLabels(pod *corev1.Pod, labels map[string]string) { if len(pod.Labels) == 0 { pod.Labels = map[string]string{} } for k, v := range labels { pod.Labels[k] = v } } // InjectEnvFrom inject `container.envFrom.SecretRef` func InjectEnvFrom(pod *corev1.Pod, secret string) { containers := Containers(pod) for i := range pod.Spec.InitContainers { if len(containers) > 0 && !utils.Contains(containers, pod.Spec.InitContainers[i].Name) { continue } if !envFromSecretExists(pod.Spec.InitContainers[i].EnvFrom, secret) { pod.Spec.InitContainers[i].EnvFrom = append(pod.Spec.InitContainers[i].EnvFrom, corev1.EnvFromSource{ SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: secret, }, }, }) } } for i := range pod.Spec.Containers { if len(containers) > 0 && !utils.Contains(containers, pod.Spec.Containers[i].Name) { continue } if !envFromSecretExists(pod.Spec.Containers[i].EnvFrom, secret) { pod.Spec.Containers[i].EnvFrom = append(pod.Spec.Containers[i].EnvFrom, corev1.EnvFromSource{ SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: secret, }, }, }) } } } // InjectEnvVar inject `container.env.valueFrom.secretKeyRef[name,key]` func InjectEnvVar(pod *corev1.Pod, secret string, envs map[string]string, direct bool) { containers := Containers(pod) for i := range pod.Spec.InitContainers { if len(containers) > 0 && !utils.Contains(containers, pod.Spec.InitContainers[i].Name) { continue } for envName, secretKey := range envs { if !envVarExists(pod.Spec.InitContainers[i].Env, envName) { pod.Spec.InitContainers[i].Env = append(pod.Spec.InitContainers[i].Env, buildEnvVar(secret, envName, secretKey, direct)) } } } for i := range pod.Spec.Containers { if len(containers) > 0 && !utils.Contains(containers, pod.Spec.Containers[i].Name) { continue } for envName, secretKey := range envs { if !envVarExists(pod.Spec.Containers[i].Env, envName) { pod.Spec.Containers[i].Env = append(pod.Spec.Containers[i].Env, buildEnvVar(secret, envName, secretKey, direct)) } } } } func buildEnvVar(secret, envName, secretValueOrKey string, direct bool) corev1.EnvVar { f := false env := corev1.EnvVar{Name: envName} if direct { env.ValueFrom = &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: secret, }, Key: secretValueOrKey, Optional: &f, }, } return env } env.Value = secretValueOrKey return env } func envVarExists(envs []corev1.EnvVar, name string) bool { for _, env := range envs { if env.Name == name { return true } } return false } func envFromSecretExists(envs []corev1.EnvFromSource, name string) bool { for _, env := range envs { if env.SecretRef != nil && env.SecretRef.Name == name { return true } } return false }