diff --git a/apis/project.cattle.io/v3/schema/schema.go b/apis/project.cattle.io/v3/schema/schema.go index 1f882540..98d16d3a 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 []EnvironmentVar + Environment map[string]string 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 598c95a2..7c57c94f 100644 --- a/apis/project.cattle.io/v3/schema/types.go +++ b/apis/project.cattle.io/v3/schema/types.go @@ -37,12 +37,6 @@ 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 0793f118..d5ed5490 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 []EnvironmentVar `json:"environment,omitempty" yaml:"environment,omitempty"` + Environment map[string]string `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 deleted file mode 100644 index b1323626..00000000 --- a/client/project/v3/zz_generated_environment_var.go +++ /dev/null @@ -1,14 +0,0 @@ -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 336295c9..bd80532e 100644 --- a/mapper/env.go +++ b/mapper/env.go @@ -1,9 +1,11 @@ package mapper import ( + "sort" + "github.com/rancher/norman/types" "github.com/rancher/norman/types/convert" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" ) type EnvironmentMapper struct { @@ -12,82 +14,71 @@ type EnvironmentMapper struct { func (e EnvironmentMapper) FromInternal(data map[string]interface{}) { var env []v1.EnvVar var envFrom []v1.EnvFromSource - var environment, environmentFrom []interface{} + + envMap := map[string]interface{}{} + var envFromMaps []interface{} if err := convert.ToObj(data["env"], &env); err == nil { for _, envVar := range env { if envVar.ValueFrom == nil { - environment = append(environment, map[string]interface{}{ - "name": envVar.Name, - "value": envVar.Value, - }) + envMap[envVar.Name] = envVar.Value continue } + if envVar.ValueFrom.FieldRef != nil { - environment = append(environment, map[string]interface{}{ - "name": envVar.Name, - "valueFrom": map[string]interface{}{ - "source": "field", - "sourceName": envVar.ValueFrom.FieldRef.FieldPath, - "targetKey": envVar.Name, - }, + envFromMaps = append(envFromMaps, map[string]interface{}{ + "source": "field", + "sourceName": envVar.ValueFrom.FieldRef.FieldPath, + "targetKey": envVar.Name, }) } if envVar.ValueFrom.ResourceFieldRef != nil { - 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, - }, + 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, }) } if envVar.ValueFrom.ConfigMapKeyRef != nil { - 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, - }, + 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, }) } if envVar.ValueFrom.SecretKeyRef != nil { - 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, - }, + 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, }) } } } + if err := convert.ToObj(data["envFrom"], &envFrom); err == nil { - for _, envFromSource := range envFrom { - if envFromSource.SecretRef != nil { - environmentFrom = append(environmentFrom, map[string]interface{}{ + for _, envVar := range envFrom { + if envVar.SecretRef != nil { + envFromMaps = append(envFromMaps, map[string]interface{}{ "source": "secret", - "sourceName": envFromSource.SecretRef.Name, - "prefix": envFromSource.Prefix, - "optional": getValue(envFromSource.SecretRef.Optional), + "sourceName": envVar.SecretRef.Name, + "prefix": envVar.Prefix, + "optional": getValue(envVar.SecretRef.Optional), "type": "/v3/project/schemas/environmentFrom", }) } - if envFromSource.ConfigMapRef != nil { - environmentFrom = append(environmentFrom, map[string]interface{}{ + if envVar.ConfigMapRef != nil { + envFromMaps = append(envFromMaps, map[string]interface{}{ "source": "configMap", - "sourceName": envFromSource.ConfigMapRef.Name, - "prefix": envFromSource.Prefix, - "optional": getValue(envFromSource.ConfigMapRef.Optional), + "sourceName": envVar.ConfigMapRef.Name, + "prefix": envVar.Prefix, + "optional": getValue(envVar.ConfigMapRef.Optional), "type": "/v3/project/schemas/environmentFrom", }) } @@ -97,107 +88,103 @@ func (e EnvironmentMapper) FromInternal(data map[string]interface{}) { delete(data, "env") delete(data, "envFrom") - if len(environment) > 0 { - data["environment"] = environment + if len(envMap) > 0 { + data["environment"] = envMap } - if len(environmentFrom) > 0 { - data["environmentFrom"] = environmentFrom + if len(envFromMaps) > 0 { + data["environmentFrom"] = envFromMaps } } func (e EnvironmentMapper) ToInternal(data map[string]interface{}) error { - var environment, env, envFrom []map[string]interface{} - var valueFrom map[string]interface{} + var envVar []map[string]interface{} + var envVarFrom []map[string]interface{} - 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"], - }, - }, - }) - } - } - } + var orderedKeys []string + environment := convert.ToMapInterface(data["environment"]) + for k := range environment { + orderedKeys = append(orderedKeys, k) } - for _, environmentFrom := range convert.ToMapSlice(data["environmentFrom"]) { - source := convert.ToString(environmentFrom["source"]) + 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"]) if source == "" { continue } - targetKey := convert.ToString(environmentFrom["targetKey"]) - sourceKey := convert.ToString(environmentFrom["sourceKey"]) + + targetKey := convert.ToString(value["targetKey"]) + sourceKey := convert.ToString(value["sourceKey"]) if targetKey == "" && sourceKey == "" { switch source { case "secret": - envFrom = append(envFrom, map[string]interface{}{ - "prefix": environmentFrom["prefix"], + envVarFrom = append(envVarFrom, map[string]interface{}{ + "prefix": value["prefix"], "secretRef": map[string]interface{}{ - "name": environmentFrom["sourceName"], - "optional": environmentFrom["optional"], + "name": value["sourceName"], + "optional": value["optional"], }, }) case "configMap": - envFrom = append(envFrom, map[string]interface{}{ - "prefix": environmentFrom["prefix"], + envVarFrom = append(envVarFrom, map[string]interface{}{ + "prefix": value["prefix"], "configMapRef": map[string]interface{}{ - "name": environmentFrom["sourceName"], - "optional": environmentFrom["optional"], + "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"], + }, }, }) } @@ -206,8 +193,8 @@ func (e EnvironmentMapper) ToInternal(data map[string]interface{}) error { delete(data, "environment") delete(data, "environmentFrom") - data["env"] = env - data["envFrom"] = envFrom + data["env"] = envVar + data["envFrom"] = envVarFrom return nil }