From e5ff694855820e8bf5b7f17680c3dc6586241bdd Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Fri, 26 Mar 2021 10:54:26 +0100 Subject: play kube: support optional/mandatory env var from config map In K8S the pod creation fails if an env var reference a non existing config map key. It can be marked as optional, but per default it is mandatory. Podman on the other hand always treat such references as optional. Rework envVarsFrom() and envVarValue() to additionaly return an error and add support for the optional attribute in configMapRef and configMapKeyRef. Signed-off-by: Alban Bedel --- pkg/specgen/generate/kube/kube.go | 43 +++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'pkg/specgen/generate/kube/kube.go') diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 6adbef2dc..f31f5e711 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -210,12 +210,18 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener } for _, env := range opts.Container.Env { - value := envVarValue(env, opts) + value, err := envVarValue(env, opts) + if err != nil { + return nil, err + } envs[env.Name] = value } for _, envFrom := range opts.Container.EnvFrom { - cmEnvs := envVarsFrom(envFrom, opts) + cmEnvs, err := envVarsFrom(envFrom, opts) + if err != nil { + return nil, err + } for k, v := range cmEnvs { envs[k] = v @@ -326,39 +332,54 @@ func quantityToInt64(quantity *resource.Quantity) (int64, error) { } // envVarsFrom returns all key-value pairs as env vars from a configMap that matches the envFrom setting of a container -func envVarsFrom(envFrom v1.EnvFromSource, opts *CtrSpecGenOptions) map[string]string { +func envVarsFrom(envFrom v1.EnvFromSource, opts *CtrSpecGenOptions) (map[string]string, error) { envs := map[string]string{} if envFrom.ConfigMapRef != nil { - cmName := envFrom.ConfigMapRef.Name + cmRef := envFrom.ConfigMapRef + err := errors.Errorf("Configmap %v not found", cmRef.Name) for _, c := range opts.ConfigMaps { - if cmName == c.Name { + if cmRef.Name == c.Name { envs = c.Data + err = nil break } } + + if err != nil && (cmRef.Optional == nil || !*cmRef.Optional) { + return nil, err + } } - return envs + return envs, nil } // envVarValue returns the environment variable value configured within the container's env setting. // It gets the value from a configMap if specified, otherwise returns env.Value -func envVarValue(env v1.EnvVar, opts *CtrSpecGenOptions) string { +func envVarValue(env v1.EnvVar, opts *CtrSpecGenOptions) (string, error) { if env.ValueFrom != nil { if env.ValueFrom.ConfigMapKeyRef != nil { + cmKeyRef := env.ValueFrom.ConfigMapKeyRef + err := errors.Errorf("Cannot set env %v: configmap %v not found", env.Name, cmKeyRef.Name) + for _, c := range opts.ConfigMaps { - if env.ValueFrom.ConfigMapKeyRef.Name == c.Name { - if value, ok := c.Data[env.ValueFrom.ConfigMapKeyRef.Key]; ok { - return value + if cmKeyRef.Name == c.Name { + if value, ok := c.Data[cmKeyRef.Key]; ok { + return value, nil } + err = errors.Errorf("Cannot set env %v: key %s not found in configmap %v", env.Name, cmKeyRef.Key, cmKeyRef.Name) + break } } + if cmKeyRef.Optional == nil || !*cmKeyRef.Optional { + return "", err + } + return "", nil } } - return env.Value + return env.Value, nil } // getPodPorts converts a slice of kube container descriptions to an -- cgit v1.2.3-54-g00ecf