diff --git a/apis/project.cattle.io/v3/schema/schema.go b/apis/project.cattle.io/v3/schema/schema.go index 98d16d3a..1f882540 100644 --- a/apis/project.cattle.io/v3/schema/schema.go +++ b/apis/project.cattle.io/v3/schema/schema.go @@ -582,7 +582,7 @@ func podTypes(schemas *types.Schemas) *types.Schemas { MustImport(&Version, v1.Handler{}, handlerOverride{}). MustImport(&Version, v1.Probe{}, handlerOverride{}). MustImport(&Version, v1.Container{}, struct { - Environment map[string]string + Environment []EnvironmentVar EnvironmentFrom []EnvironmentFrom InitContainer bool State string diff --git a/apis/project.cattle.io/v3/schema/types.go b/apis/project.cattle.io/v3/schema/types.go index 7c57c94f..598c95a2 100644 --- a/apis/project.cattle.io/v3/schema/types.go +++ b/apis/project.cattle.io/v3/schema/types.go @@ -37,6 +37,12 @@ type handlerOverride struct { TCP bool } +type EnvironmentVar struct { + Name string + Value string + ValueFrom *EnvironmentFrom +} + type EnvironmentFrom struct { Source string `norman:"type=enum,options=field|resource|configMap|secret"` SourceName string diff --git a/client/project/v3/zz_generated_container.go b/client/project/v3/zz_generated_container.go index d5ed5490..0793f118 100644 --- a/client/project/v3/zz_generated_container.go +++ b/client/project/v3/zz_generated_container.go @@ -48,7 +48,7 @@ type Container struct { CapDrop []string `json:"capDrop,omitempty" yaml:"capDrop,omitempty"` Command []string `json:"command,omitempty" yaml:"command,omitempty"` Entrypoint []string `json:"entrypoint,omitempty" yaml:"entrypoint,omitempty"` - Environment map[string]string `json:"environment,omitempty" yaml:"environment,omitempty"` + Environment []EnvironmentVar `json:"environment,omitempty" yaml:"environment,omitempty"` EnvironmentFrom []EnvironmentFrom `json:"environmentFrom,omitempty" yaml:"environmentFrom,omitempty"` ExitCode *int64 `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` Image string `json:"image,omitempty" yaml:"image,omitempty"` diff --git a/client/project/v3/zz_generated_environment_var.go b/client/project/v3/zz_generated_environment_var.go new file mode 100644 index 00000000..b1323626 --- /dev/null +++ b/client/project/v3/zz_generated_environment_var.go @@ -0,0 +1,14 @@ +package client + +const ( + EnvironmentVarType = "environmentVar" + EnvironmentVarFieldName = "name" + EnvironmentVarFieldValue = "value" + EnvironmentVarFieldValueFrom = "valueFrom" +) + +type EnvironmentVar struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` + ValueFrom *EnvironmentFrom `json:"valueFrom,omitempty" yaml:"valueFrom,omitempty"` +} diff --git a/mapper/env.go b/mapper/env.go index bd80532e..336295c9 100644 --- a/mapper/env.go +++ b/mapper/env.go @@ -1,11 +1,9 @@ package mapper import ( - "sort" - "github.com/rancher/norman/types" "github.com/rancher/norman/types/convert" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" ) type EnvironmentMapper struct { @@ -14,71 +12,82 @@ type EnvironmentMapper struct { func (e EnvironmentMapper) FromInternal(data map[string]interface{}) { var env []v1.EnvVar var envFrom []v1.EnvFromSource - - envMap := map[string]interface{}{} - var envFromMaps []interface{} + var environment, environmentFrom []interface{} if err := convert.ToObj(data["env"], &env); err == nil { for _, envVar := range env { if envVar.ValueFrom == nil { - envMap[envVar.Name] = envVar.Value + environment = append(environment, map[string]interface{}{ + "name": envVar.Name, + "value": envVar.Value, + }) continue } - if envVar.ValueFrom.FieldRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ - "source": "field", - "sourceName": envVar.ValueFrom.FieldRef.FieldPath, - "targetKey": envVar.Name, + environment = append(environment, map[string]interface{}{ + "name": envVar.Name, + "valueFrom": map[string]interface{}{ + "source": "field", + "sourceName": envVar.ValueFrom.FieldRef.FieldPath, + "targetKey": envVar.Name, + }, }) } if envVar.ValueFrom.ResourceFieldRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ - "source": "resource", - "sourceName": envVar.ValueFrom.ResourceFieldRef.ContainerName, - "sourceKey": envVar.ValueFrom.ResourceFieldRef.Resource, - "divisor": envVar.ValueFrom.ResourceFieldRef.Divisor, - "targetKey": envVar.Name, + environment = append(environment, map[string]interface{}{ + "name": envVar.Name, + "valueFrom": map[string]interface{}{ + "source": "resource", + "sourceName": envVar.ValueFrom.ResourceFieldRef.ContainerName, + "sourceKey": envVar.ValueFrom.ResourceFieldRef.Resource, + "divisor": envVar.ValueFrom.ResourceFieldRef.Divisor, + "targetKey": envVar.Name, + }, }) } if envVar.ValueFrom.ConfigMapKeyRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ - "source": "configMap", - "sourceName": envVar.ValueFrom.ConfigMapKeyRef.Name, - "sourceKey": envVar.ValueFrom.ConfigMapKeyRef.Key, - "optional": getValue(envVar.ValueFrom.ConfigMapKeyRef.Optional), - "targetKey": envVar.Name, + environment = append(environment, map[string]interface{}{ + "name": envVar.Name, + "valueFrom": map[string]interface{}{ + "source": "configMap", + "sourceName": envVar.ValueFrom.ConfigMapKeyRef.Name, + "sourceKey": envVar.ValueFrom.ConfigMapKeyRef.Key, + "optional": getValue(envVar.ValueFrom.ConfigMapKeyRef.Optional), + "targetKey": envVar.Name, + }, }) } if envVar.ValueFrom.SecretKeyRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ - "source": "secret", - "sourceName": envVar.ValueFrom.SecretKeyRef.Name, - "sourceKey": envVar.ValueFrom.SecretKeyRef.Key, - "optional": getValue(envVar.ValueFrom.SecretKeyRef.Optional), - "targetKey": envVar.Name, + environment = append(environment, map[string]interface{}{ + "name": envVar.Name, + "valueFrom": map[string]interface{}{ + "source": "secret", + "sourceName": envVar.ValueFrom.SecretKeyRef.Name, + "sourceKey": envVar.ValueFrom.SecretKeyRef.Key, + "optional": getValue(envVar.ValueFrom.SecretKeyRef.Optional), + "targetKey": envVar.Name, + }, }) } } } - if err := convert.ToObj(data["envFrom"], &envFrom); err == nil { - for _, envVar := range envFrom { - if envVar.SecretRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ + for _, envFromSource := range envFrom { + if envFromSource.SecretRef != nil { + environmentFrom = append(environmentFrom, map[string]interface{}{ "source": "secret", - "sourceName": envVar.SecretRef.Name, - "prefix": envVar.Prefix, - "optional": getValue(envVar.SecretRef.Optional), + "sourceName": envFromSource.SecretRef.Name, + "prefix": envFromSource.Prefix, + "optional": getValue(envFromSource.SecretRef.Optional), "type": "/v3/project/schemas/environmentFrom", }) } - if envVar.ConfigMapRef != nil { - envFromMaps = append(envFromMaps, map[string]interface{}{ + if envFromSource.ConfigMapRef != nil { + environmentFrom = append(environmentFrom, map[string]interface{}{ "source": "configMap", - "sourceName": envVar.ConfigMapRef.Name, - "prefix": envVar.Prefix, - "optional": getValue(envVar.ConfigMapRef.Optional), + "sourceName": envFromSource.ConfigMapRef.Name, + "prefix": envFromSource.Prefix, + "optional": getValue(envFromSource.ConfigMapRef.Optional), "type": "/v3/project/schemas/environmentFrom", }) } @@ -88,103 +97,107 @@ func (e EnvironmentMapper) FromInternal(data map[string]interface{}) { delete(data, "env") delete(data, "envFrom") - if len(envMap) > 0 { - data["environment"] = envMap + if len(environment) > 0 { + data["environment"] = environment } - if len(envFromMaps) > 0 { - data["environmentFrom"] = envFromMaps + if len(environmentFrom) > 0 { + data["environmentFrom"] = environmentFrom } } func (e EnvironmentMapper) ToInternal(data map[string]interface{}) error { - var envVar []map[string]interface{} - var envVarFrom []map[string]interface{} + var environment, env, envFrom []map[string]interface{} + var valueFrom map[string]interface{} - var orderedKeys []string - environment := convert.ToMapInterface(data["environment"]) - for k := range environment { - orderedKeys = append(orderedKeys, k) + if err := convert.ToObj(data["environment"], &environment); err == nil { + for _, environmentVar := range environment { + if convert.ToString(environmentVar["value"]) != "" { + env = append(env, map[string]interface{}{ + "name": environmentVar["name"], + "value": environmentVar["value"], + }) + continue + } + if err = convert.ToObj(environmentVar["valueFrom"], &valueFrom); err == nil { + source := convert.ToString(valueFrom["source"]) + if source == "" { + continue + } + targetKey := convert.ToString(valueFrom["targetKey"]) + sourceKey := convert.ToString(valueFrom["sourceKey"]) + if targetKey == "" { + targetKey = sourceKey + } + switch source { + case "field": + env = append(env, map[string]interface{}{ + "name": targetKey, + "valueFrom": map[string]interface{}{ + "fieldRef": map[string]interface{}{ + "fieldPath": valueFrom["sourceName"], + }, + }, + }) + case "resource": + env = append(env, map[string]interface{}{ + "name": targetKey, + "valueFrom": map[string]interface{}{ + "resourceFieldRef": map[string]interface{}{ + "containerName": valueFrom["sourceName"], + "resource": valueFrom["sourceKey"], + "divisor": valueFrom["divisor"], + }, + }, + }) + case "configMap": + env = append(env, map[string]interface{}{ + "name": targetKey, + "valueFrom": map[string]interface{}{ + "configMapKeyRef": map[string]interface{}{ + "name": valueFrom["sourceName"], + "key": valueFrom["sourceKey"], + "optional": valueFrom["optional"], + }, + }, + }) + case "secret": + env = append(env, map[string]interface{}{ + "name": targetKey, + "valueFrom": map[string]interface{}{ + "secretKeyRef": map[string]interface{}{ + "name": valueFrom["sourceName"], + "key": valueFrom["sourceKey"], + "optional": valueFrom["optional"], + }, + }, + }) + } + } + } } - sort.Strings(orderedKeys) - for _, key := range orderedKeys { - envVar = append(envVar, map[string]interface{}{ - "name": key, - "value": environment[key], - }) - } - - for _, value := range convert.ToMapSlice(data["environmentFrom"]) { - source := convert.ToString(value["source"]) + for _, environmentFrom := range convert.ToMapSlice(data["environmentFrom"]) { + source := convert.ToString(environmentFrom["source"]) if source == "" { continue } - - targetKey := convert.ToString(value["targetKey"]) - sourceKey := convert.ToString(value["sourceKey"]) + targetKey := convert.ToString(environmentFrom["targetKey"]) + sourceKey := convert.ToString(environmentFrom["sourceKey"]) if targetKey == "" && sourceKey == "" { switch source { case "secret": - envVarFrom = append(envVarFrom, map[string]interface{}{ - "prefix": value["prefix"], + envFrom = append(envFrom, map[string]interface{}{ + "prefix": environmentFrom["prefix"], "secretRef": map[string]interface{}{ - "name": value["sourceName"], - "optional": value["optional"], + "name": environmentFrom["sourceName"], + "optional": environmentFrom["optional"], }, }) case "configMap": - envVarFrom = append(envVarFrom, map[string]interface{}{ - "prefix": value["prefix"], + envFrom = append(envFrom, map[string]interface{}{ + "prefix": environmentFrom["prefix"], "configMapRef": map[string]interface{}{ - "name": value["sourceName"], - "optional": value["optional"], - }, - }) - } - } else { - if targetKey == "" { - targetKey = sourceKey - } - switch source { - case "field": - envVar = append(envVar, map[string]interface{}{ - "name": targetKey, - "valueFrom": map[string]interface{}{ - "fieldRef": map[string]interface{}{ - "fieldPath": value["sourceName"], - }, - }, - }) - case "resource": - envVar = append(envVar, map[string]interface{}{ - "name": targetKey, - "valueFrom": map[string]interface{}{ - "resourceFieldRef": map[string]interface{}{ - "containerName": value["sourceName"], - "resource": value["sourceKey"], - "divisor": value["divisor"], - }, - }, - }) - case "configMap": - envVar = append(envVar, map[string]interface{}{ - "name": targetKey, - "valueFrom": map[string]interface{}{ - "configMapKeyRef": map[string]interface{}{ - "name": value["sourceName"], - "key": value["sourceKey"], - "optional": value["optional"], - }, - }, - }) - case "secret": - envVar = append(envVar, map[string]interface{}{ - "name": targetKey, - "valueFrom": map[string]interface{}{ - "secretKeyRef": map[string]interface{}{ - "name": value["sourceName"], - "key": value["sourceKey"], - "optional": value["optional"], - }, + "name": environmentFrom["sourceName"], + "optional": environmentFrom["optional"], }, }) } @@ -193,8 +206,8 @@ func (e EnvironmentMapper) ToInternal(data map[string]interface{}) error { delete(data, "environment") delete(data, "environmentFrom") - data["env"] = envVar - data["envFrom"] = envVarFrom + data["env"] = env + data["envFrom"] = envFrom return nil }