...

Source file src/edge-infra.dev/pkg/edge/webhooks/edge-injector/pod_injector.go

Documentation: edge-infra.dev/pkg/edge/webhooks/edge-injector

     1  package edgeinjector
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/google/uuid"
     9  	corev1 "k8s.io/api/core/v1"
    10  
    11  	"edge-infra.dev/pkg/edge/api/utils"
    12  	"edge-infra.dev/pkg/lib/fog"
    13  )
    14  
    15  func InjectSecret(ctx context.Context, pod *corev1.Pod, secretType SecretType, env ...map[string]string) {
    16  	log := fog.FromContext(ctx)
    17  	log.Info("handling secret label for pod")
    18  
    19  	secretName := fmt.Sprintf("%s-%s", secretType, uuid.NewString())
    20  	InjectLabels(pod, map[string]string{SecretLabel(secretType): secretName})
    21  
    22  	log.Info("injected secret label unto pod", "secretName", secretName)
    23  
    24  	switch InjectionType(pod) {
    25  	case DirectType:
    26  		if len(env) > 0 {
    27  			InjectEnvVar(pod, secretName, env[0], true)
    28  		} else {
    29  			InjectEnvFrom(pod, secretName)
    30  		}
    31  		log.Info("injected secret name env unto pod", "secretName", secretName, "injection type", "direct")
    32  	default:
    33  		// refSecretName couchdb-secret ==> COUCHDB_SECRET
    34  		refSecretName := strings.ReplaceAll(strings.ToUpper(string(secretType)), "-", "_")
    35  		InjectEnvVar(pod, secretName, map[string]string{refSecretName: secretName}, false)
    36  		log.Info("injected secret ref unto pod", "secretName", secretName, "injection type", "reference")
    37  	}
    38  }
    39  
    40  func InjectLabels(pod *corev1.Pod, labels map[string]string) {
    41  	if len(pod.Labels) == 0 {
    42  		pod.Labels = map[string]string{}
    43  	}
    44  	for k, v := range labels {
    45  		pod.Labels[k] = v
    46  	}
    47  }
    48  
    49  // InjectEnvFrom inject `container.envFrom.SecretRef`
    50  func InjectEnvFrom(pod *corev1.Pod, secret string) {
    51  	containers := Containers(pod)
    52  	for i := range pod.Spec.InitContainers {
    53  		if len(containers) > 0 && !utils.Contains(containers, pod.Spec.InitContainers[i].Name) {
    54  			continue
    55  		}
    56  		if !envFromSecretExists(pod.Spec.InitContainers[i].EnvFrom, secret) {
    57  			pod.Spec.InitContainers[i].EnvFrom = append(pod.Spec.InitContainers[i].EnvFrom, corev1.EnvFromSource{
    58  				SecretRef: &corev1.SecretEnvSource{
    59  					LocalObjectReference: corev1.LocalObjectReference{
    60  						Name: secret,
    61  					},
    62  				},
    63  			})
    64  		}
    65  	}
    66  	for i := range pod.Spec.Containers {
    67  		if len(containers) > 0 && !utils.Contains(containers, pod.Spec.Containers[i].Name) {
    68  			continue
    69  		}
    70  		if !envFromSecretExists(pod.Spec.Containers[i].EnvFrom, secret) {
    71  			pod.Spec.Containers[i].EnvFrom = append(pod.Spec.Containers[i].EnvFrom, corev1.EnvFromSource{
    72  				SecretRef: &corev1.SecretEnvSource{
    73  					LocalObjectReference: corev1.LocalObjectReference{
    74  						Name: secret,
    75  					},
    76  				},
    77  			})
    78  		}
    79  	}
    80  }
    81  
    82  // InjectEnvVar inject `container.env.valueFrom.secretKeyRef[name,key]`
    83  func InjectEnvVar(pod *corev1.Pod, secret string, envs map[string]string, direct bool) {
    84  	containers := Containers(pod)
    85  	for i := range pod.Spec.InitContainers {
    86  		if len(containers) > 0 && !utils.Contains(containers, pod.Spec.InitContainers[i].Name) {
    87  			continue
    88  		}
    89  		for envName, secretKey := range envs {
    90  			if !envVarExists(pod.Spec.InitContainers[i].Env, envName) {
    91  				pod.Spec.InitContainers[i].Env = append(pod.Spec.InitContainers[i].Env, buildEnvVar(secret, envName, secretKey, direct))
    92  			}
    93  		}
    94  	}
    95  	for i := range pod.Spec.Containers {
    96  		if len(containers) > 0 && !utils.Contains(containers, pod.Spec.Containers[i].Name) {
    97  			continue
    98  		}
    99  		for envName, secretKey := range envs {
   100  			if !envVarExists(pod.Spec.Containers[i].Env, envName) {
   101  				pod.Spec.Containers[i].Env = append(pod.Spec.Containers[i].Env, buildEnvVar(secret, envName, secretKey, direct))
   102  			}
   103  		}
   104  	}
   105  }
   106  
   107  func buildEnvVar(secret, envName, secretValueOrKey string, direct bool) corev1.EnvVar {
   108  	f := false
   109  	env := corev1.EnvVar{Name: envName}
   110  	if direct {
   111  		env.ValueFrom = &corev1.EnvVarSource{
   112  			SecretKeyRef: &corev1.SecretKeySelector{
   113  				LocalObjectReference: corev1.LocalObjectReference{
   114  					Name: secret,
   115  				},
   116  				Key:      secretValueOrKey,
   117  				Optional: &f,
   118  			},
   119  		}
   120  		return env
   121  	}
   122  	env.Value = secretValueOrKey
   123  	return env
   124  }
   125  
   126  func envVarExists(envs []corev1.EnvVar, name string) bool {
   127  	for _, env := range envs {
   128  		if env.Name == name {
   129  			return true
   130  		}
   131  	}
   132  	return false
   133  }
   134  
   135  func envFromSecretExists(envs []corev1.EnvFromSource, name string) bool {
   136  	for _, env := range envs {
   137  		if env.SecretRef != nil && env.SecretRef.Name == name {
   138  			return true
   139  		}
   140  	}
   141  	return false
   142  }
   143  

View as plain text