1
0
mirror of https://github.com/rancher/types.git synced 2025-09-09 00:48:56 +00:00

Move mappers

This commit is contained in:
Darren Shepherd
2017-11-29 14:37:09 -07:00
parent bf0a2b9e43
commit e76df53327
12 changed files with 0 additions and 0 deletions

View File

@@ -1,47 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
m "github.com/rancher/norman/types/mapper"
)
type DeploymentStrategyMapper struct {
}
func (d DeploymentStrategyMapper) FromInternal(data map[string]interface{}) {
if m.GetValueN(data, "strategy", "type") != "Recreate" {
m.PutValue(data, "Parallel", "deploymentStrategy", "kind")
maxUnavailable := m.GetValueN(data, "strategy", "rollingUpdate", "maxUnavailable")
maxSurge := m.GetValueN(data, "strategy", "rollingUpdate", "maxSurge")
if !convert.IsEmpty(maxSurge) {
m.PutValue(data, true, "deploymentStrategy", "parallelConfig", "startFirst")
m.PutValue(data, convert.ToString(maxSurge), "batchSize")
} else if !convert.IsEmpty(maxUnavailable) {
m.PutValue(data, convert.ToString(maxUnavailable), "batchSize")
}
}
}
func (d DeploymentStrategyMapper) ToInternal(data map[string]interface{}) {
batchSize := m.GetValueN(data, "batchSize")
if convert.IsEmpty(batchSize) {
batchSize = 1
}
batchSize, _ = convert.ToNumber(batchSize)
kind, _ := m.GetValueN(data, "deploymentStrategy", "kind").(string)
if kind == "" || kind == "Parallel" {
startFirst, _ := m.GetValueN(data, "deploymentStrategy", "startFirst").(bool)
if startFirst {
m.PutValue(data, batchSize, "strategy", "rollingUpdate", "maxSurge")
} else {
m.PutValue(data, batchSize, "strategy", "rollingUpdate", "maxUnavailable")
}
}
}
func (d DeploymentStrategyMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@@ -1,190 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"k8s.io/api/core/v1"
)
type EnvironmentMapper struct {
}
func (e EnvironmentMapper) FromInternal(data map[string]interface{}) {
env := []v1.EnvVar{}
envFrom := []v1.EnvFromSource{}
envMap := map[string]interface{}{}
envFromMaps := []map[string]interface{}{}
if err := convert.ToObj(data["env"], &env); err == nil {
for _, envVar := range env {
if envVar.ValueFrom == nil {
envMap[envVar.Name] = envVar.Value
continue
}
if envVar.ValueFrom.FieldRef != nil {
envFromMaps = append(envFromMaps, 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,
})
}
if envVar.ValueFrom.ConfigMapKeyRef != nil {
envFromMaps = append(envFromMaps, map[string]interface{}{
"source": "configMap",
"sourceName": envVar.ValueFrom.ConfigMapKeyRef.Name,
"sourceKey": envVar.ValueFrom.ConfigMapKeyRef.Key,
"optional": 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": 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{}{
"source": "secret",
"sourceName": envVar.SecretRef.Name,
"prefix": envVar.Prefix,
"optional": envVar.SecretRef.Optional,
})
}
if envVar.ConfigMapRef != nil {
envFromMaps = append(envFromMaps, map[string]interface{}{
"source": "configMap",
"sourceName": envVar.ConfigMapRef.Name,
"prefix": envVar.Prefix,
"optional": envVar.ConfigMapRef.Optional,
})
}
}
}
delete(data, "env")
delete(data, "envFrom")
if len(envMap) > 0 {
data["environment"] = envMap
}
if len(envFromMaps) > 0 {
data["environmentFrom"] = envFromMaps
}
}
func (e EnvironmentMapper) ToInternal(data map[string]interface{}) {
envVar := []map[string]interface{}{}
envVarFrom := []map[string]interface{}{}
for key, value := range convert.ToMapInterface(data["environment"]) {
envVar = append(envVar, map[string]interface{}{
"name": key,
"value": value,
})
}
for _, value := range convert.ToMapSlice(data["environmentFrom"]) {
source := convert.ToString(value["source"])
if source == "" {
continue
}
targetKey := convert.ToString(value["targetKey"])
if targetKey == "" {
switch source {
case "secret":
envVarFrom = append(envVarFrom, map[string]interface{}{
"prefix": value["prefix"],
"secretRef": map[string]interface{}{
"name": value["sourceName"],
"optional": value["optional"],
},
})
case "configMap":
envVarFrom = append(envVarFrom, map[string]interface{}{
"prefix": value["prefix"],
"configMapRef": map[string]interface{}{
"name": value["sourceName"],
"optional": value["optional"],
},
})
}
} else {
switch source {
case "field":
envVar = append(envVarFrom, map[string]interface{}{
"name": targetKey,
"valueFrom": map[string]interface{}{
"fieldRef": map[string]interface{}{
"fieldPath": value["sourceName"],
},
},
})
case "resource":
envVar = append(envVarFrom, 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(envVarFrom, 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(envVarFrom, map[string]interface{}{
"name": targetKey,
"valueFrom": map[string]interface{}{
"secretKeyRef": map[string]interface{}{
"name": value["sourceName"],
"key": value["sourceKey"],
"optional": value["optional"],
},
},
})
}
}
}
delete(data, "environment")
delete(data, "environmentFrom")
data["env"] = envVar
data["envFrom"] = envVarFrom
}
func (e EnvironmentMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
delete(schema.ResourceFields, "env")
delete(schema.ResourceFields, "envFrom")
return nil
}

View File

@@ -1,49 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
type InitContainerMapper struct {
}
func (e InitContainerMapper) FromInternal(data map[string]interface{}) {
containers, _ := data["containers"].([]interface{})
for _, initContainer := range convert.ToMapSlice(data["initContainers"]) {
if initContainer == nil {
continue
}
initContainer["initContainer"] = true
containers = append(containers, initContainer)
}
if data != nil {
data["containers"] = containers
}
}
func (e InitContainerMapper) ToInternal(data map[string]interface{}) {
newContainers := []interface{}{}
newInitContainers := []interface{}{}
for _, container := range convert.ToMapSlice(data["containers"]) {
if convert.ToBool(container["initContainer"]) {
newInitContainers = append(newInitContainers, container)
} else {
newContainers = append(newContainers, container)
}
delete(container, "initContainer")
}
if data != nil {
data["containers"] = newContainers
data["initContainers"] = newInitContainers
}
}
func (e InitContainerMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
delete(schema.ResourceFields, "initContainers")
return nil
}

View File

@@ -1,39 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/mapper"
)
type NamespaceIDMapper struct {
Move *mapper.Move
}
func (n *NamespaceIDMapper) FromInternal(data map[string]interface{}) {
if n.Move != nil {
n.Move.FromInternal(data)
}
}
func (n *NamespaceIDMapper) ToInternal(data map[string]interface{}) {
if n.Move != nil {
n.Move.ToInternal(data)
}
}
func (n *NamespaceIDMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
field, ok := schema.ResourceFields["namespace"]
if !ok {
return nil
}
field.Type = "reference[namespace]"
schema.ResourceFields["namespace"] = field
n.Move = &mapper.Move{
From: "namespace",
To: "namespaceId",
}
return n.Move.ModifySchema(schema, schemas)
}

View File

@@ -1,44 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
var namespaceMapping = map[string]string{
"hostNetwork": "net",
"hostIPC": "ipc",
"hostPID": "pid",
}
type NamespaceMapper struct {
}
func (e NamespaceMapper) FromInternal(data map[string]interface{}) {
for name, friendlyName := range namespaceMapping {
value := convert.ToBool(data[name])
if value {
data[friendlyName] = "host"
}
delete(data, name)
}
}
func (e NamespaceMapper) ToInternal(data map[string]interface{}) {
for name, friendlyName := range namespaceMapping {
value := convert.ToString(data[friendlyName])
if value == "host" {
data[name] = true
} else {
data[name] = false
}
delete(data, friendlyName)
}
}
func (e NamespaceMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
delete(schema.ResourceFields, "hostNetwork")
delete(schema.ResourceFields, "hostPID")
delete(schema.ResourceFields, "hostIPC")
return nil
}

View File

@@ -1,29 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/mapper"
)
type NodeAddressMapper struct {
}
func (n NodeAddressMapper) FromInternal(data map[string]interface{}) {
addresses, _ := mapper.GetSlice(data, "addresses")
for _, address := range addresses {
t := address["type"]
a := address["address"]
if t == "InternalIP" {
data["IpAddress"] = a
} else if t == "Hostname" {
data["hostname"] = a
}
}
}
func (n NodeAddressMapper) ToInternal(data map[string]interface{}) {
}
func (n NodeAddressMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@@ -1,49 +0,0 @@
package mapper
import (
"strings"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/mapper"
)
type OSInfo struct {
}
func (o OSInfo) FromInternal(data map[string]interface{}) {
cpuInfo := map[string]interface{}{
"count": mapper.GetValueN(data, "capacity", "cpu"),
}
kib := strings.TrimSuffix(convert.ToString(mapper.GetValueN(data, "capacity", "memory")), "Ki")
memoryInfo := map[string]interface{}{}
kibNum, err := convert.ToNumber(kib)
if err == nil {
memoryInfo["memTotalKiB"] = kibNum
}
osInfo := map[string]interface{}{
"dockerVersion": strings.TrimPrefix(convert.ToString(mapper.GetValueN(data, "nodeInfo", "containerRuntimeVersion")), "docker://"),
"kernelVersion": mapper.GetValueN(data, "nodeInfo", "kernelVersion"),
"operatingSystem": mapper.GetValueN(data, "nodeInfo", "osImage"),
}
data["info"] = map[string]interface{}{
"cpu": cpuInfo,
"memory": memoryInfo,
"os": osInfo,
"kubernetes": map[string]interface{}{
"kubeletVersion": mapper.GetValueN(data, "nodeInfo", "kubeletVersion"),
"kubeProxyVersion": mapper.GetValueN(data, "nodeInfo", "kubeletVersion"),
},
}
}
func (o OSInfo) ToInternal(data map[string]interface{}) {
}
func (o OSInfo) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@@ -1,52 +0,0 @@
package mapper
import (
"strings"
"github.com/rancher/norman/types"
m "github.com/rancher/norman/types/mapper"
)
type PivotMapper struct {
Plural bool
}
func (r PivotMapper) FromInternal(data map[string]interface{}) {
for key, value := range data {
mapValue, ok := value.(map[string]interface{})
if !ok {
continue
}
for subKey, subValue := range mapValue {
if r.Plural {
m.PutValue(data, subValue, subKey, strings.TrimSuffix(key, "s"))
} else {
m.PutValue(data, subValue, subKey, key)
}
}
delete(data, key)
}
}
func (r PivotMapper) ToInternal(data map[string]interface{}) {
for key, value := range data {
mapValue, ok := value.(map[string]interface{})
if !ok {
continue
}
for subKey, subValue := range mapValue {
if r.Plural {
m.PutValue(data, subValue, subKey, key+"s")
} else {
m.PutValue(data, subValue, subKey, key)
}
}
delete(data, key)
}
}
func (r PivotMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@@ -1,261 +0,0 @@
package mapper
import (
"fmt"
"sort"
"strings"
"regexp"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/mapper"
"k8s.io/api/core/v1"
)
var (
exprRegexp = regexp.MustCompile("^(.*)(=|!=|<|>| in | notin )(.*)$")
)
type SchedulingMapper struct {
}
func (s SchedulingMapper) FromInternal(data map[string]interface{}) {
defer func() {
delete(data, "nodeSelector")
delete(data, "affinity")
}()
requireAll := []string{}
for key, value := range convert.ToMapInterface(data["nodeSelector"]) {
if value == "" {
requireAll = append(requireAll, key)
} else {
requireAll = append(requireAll, fmt.Sprintf("%s = %s", key, value))
}
}
if len(requireAll) > 0 {
mapper.PutValue(data, requireAll, "scheduling", "node", "requireAll")
}
v, ok := data["affinity"]
if !ok || v == nil {
return
}
affinity := &v1.Affinity{}
if err := convert.ToObj(v, affinity); err != nil {
return
}
if affinity.NodeAffinity != nil {
s.nodeAffinity(data, affinity.NodeAffinity)
}
}
func (s SchedulingMapper) nodeAffinity(data map[string]interface{}, nodeAffinity *v1.NodeAffinity) {
requireAll := []string{}
requireAny := []string{}
preferred := []string{}
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil {
for _, term := range nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms {
exprs := NodeSelectorTermToStrings(term)
if len(exprs) == 0 {
continue
}
if len(requireAny) > 0 {
// Once any is set all new terms go to any
requireAny = append(requireAny, strings.Join(exprs, " && "))
} else if len(requireAll) > 0 {
// If all is already set, we actually need to move everything to any
requireAny = append(requireAny, strings.Join(requireAll, " && "))
requireAny = append(requireAny, strings.Join(exprs, " && "))
requireAll = []string{}
} else {
// The first term is considered all
requireAll = exprs
}
}
}
if nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution != nil {
sortPreferred(nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution)
for _, term := range nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution {
exprs := NodeSelectorTermToStrings(term.Preference)
preferred = append(preferred, strings.Join(exprs, " && "))
}
}
if len(requireAll) > 0 {
mapper.PutValue(data, requireAll, "scheduling", "node", "requireAll")
}
if len(requireAny) > 0 {
mapper.PutValue(data, requireAny, "scheduling", "node", "requireAny")
}
if len(preferred) > 0 {
mapper.PutValue(data, requireAny, "scheduling", "node", "preferred")
}
}
func sortPreferred(terms []v1.PreferredSchedulingTerm) {
sort.Slice(terms, func(i, j int) bool {
return terms[i].Weight > terms[j].Weight
})
}
func NodeSelectorTermToStrings(term v1.NodeSelectorTerm) []string {
exprs := []string{}
for _, expr := range term.MatchExpressions {
nextExpr := ""
switch expr.Operator {
case v1.NodeSelectorOpIn:
if len(expr.Values) > 1 {
nextExpr = fmt.Sprintf("%s in (%s)", expr.Key, strings.Join(expr.Values, ", "))
} else if len(expr.Values) == 1 {
nextExpr = fmt.Sprintf("%s = %s", expr.Key, expr.Values[0])
}
case v1.NodeSelectorOpNotIn:
if len(expr.Values) > 1 {
nextExpr = fmt.Sprintf("%s notin (%s)", expr.Key, strings.Join(expr.Values, ", "))
} else if len(expr.Values) == 1 {
nextExpr = fmt.Sprintf("%s != %s", expr.Key, expr.Values[0])
}
case v1.NodeSelectorOpExists:
nextExpr = expr.Key
case v1.NodeSelectorOpDoesNotExist:
nextExpr = "!" + expr.Key
case v1.NodeSelectorOpGt:
if len(expr.Values) == 1 {
nextExpr = fmt.Sprintf("%s > %s", expr.Key, expr.Values[0])
}
case v1.NodeSelectorOpLt:
if len(expr.Values) == 1 {
nextExpr = fmt.Sprintf("%s < %s", expr.Key, expr.Values[0])
}
}
if nextExpr != "" {
exprs = append(exprs, nextExpr)
}
}
return exprs
}
func StringsToNodeSelectorTerm(exprs []string) []v1.NodeSelectorTerm {
result := []v1.NodeSelectorTerm{}
for _, inter := range exprs {
term := v1.NodeSelectorTerm{}
for _, expr := range strings.Split(inter, "&&") {
groups := exprRegexp.FindStringSubmatch(expr)
selectorRequirement := v1.NodeSelectorRequirement{}
if groups == nil {
if strings.HasPrefix(expr, "!") {
selectorRequirement.Key = strings.TrimSpace(expr[1:])
selectorRequirement.Operator = v1.NodeSelectorOpDoesNotExist
} else {
selectorRequirement.Key = strings.TrimSpace(expr)
selectorRequirement.Operator = v1.NodeSelectorOpExists
}
} else {
selectorRequirement.Key = strings.TrimSpace(groups[1])
selectorRequirement.Values = convert.ToValuesSlice(groups[3])
op := strings.TrimSpace(groups[2])
switch op {
case "=":
selectorRequirement.Operator = v1.NodeSelectorOpIn
case "!=":
selectorRequirement.Operator = v1.NodeSelectorOpNotIn
case "notin":
selectorRequirement.Operator = v1.NodeSelectorOpNotIn
case "in":
selectorRequirement.Operator = v1.NodeSelectorOpIn
case "<":
selectorRequirement.Operator = v1.NodeSelectorOpLt
case ">":
selectorRequirement.Operator = v1.NodeSelectorOpGt
}
}
term.MatchExpressions = append(term.MatchExpressions, selectorRequirement)
}
result = append(result, term)
}
return result
}
func (s SchedulingMapper) ToInternal(data map[string]interface{}) {
defer func() {
delete(data, "scheduling")
}()
nodeName := convert.ToString(mapper.GetValueN(data, "scheduling", "node", "name"))
if nodeName != "" {
data["nodeName"] = nodeName
}
requireAll := convert.ToStringSlice(mapper.GetValueN(data, "scheduling", "node", "requireAll"))
requireAny := convert.ToStringSlice(mapper.GetValueN(data, "scheduling", "node", "requireAny"))
preferred := convert.ToStringSlice(mapper.GetValueN(data, "scheduling", "node", "preferred"))
if len(requireAll) == 0 && len(requireAny) == 0 && len(preferred) == 0 {
return
}
nodeAffinity := v1.NodeAffinity{}
if len(requireAll) > 0 {
nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = &v1.NodeSelector{
NodeSelectorTerms: []v1.NodeSelectorTerm{
AggregateTerms(StringsToNodeSelectorTerm(requireAll)),
},
}
}
if len(requireAny) > 0 {
if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil {
nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = &v1.NodeSelector{}
}
nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = StringsToNodeSelectorTerm(requireAny)
}
if len(preferred) > 0 {
count := int32(100)
for _, term := range StringsToNodeSelectorTerm(preferred) {
nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append(
nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution, v1.PreferredSchedulingTerm{
Weight: count,
Preference: term,
})
count--
}
}
affinity, _ := convert.EncodeToMap(&v1.Affinity{
NodeAffinity: &nodeAffinity,
})
data["affinity"] = affinity
}
func AggregateTerms(terms []v1.NodeSelectorTerm) v1.NodeSelectorTerm {
result := v1.NodeSelectorTerm{}
for _, term := range terms {
result.MatchExpressions = append(result.MatchExpressions, term.MatchExpressions...)
}
return result
}
func (s SchedulingMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
delete(schema.ResourceFields, "nodeSelector")
delete(schema.ResourceFields, "affinity")
return nil
}

View File

@@ -1,18 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
)
type StatefulSetSpecMapper struct {
}
func (s StatefulSetSpecMapper) FromInternal(data map[string]interface{}) {
}
func (s StatefulSetSpecMapper) ToInternal(data map[string]interface{}) {
}
func (s StatefulSetSpecMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@@ -1,37 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/types/status"
)
type Status struct {
}
func (s Status) FromInternal(data map[string]interface{}) {
status.Set(data)
}
func (s Status) ToInternal(data map[string]interface{}) {
}
func (s Status) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
schema.ResourceFields["state"] = types.Field{
CodeName: "State",
Type: "string",
}
schema.ResourceFields["transitioning"] = types.Field{
CodeName: "Transitioning",
Type: "enum",
Options: []string{
"yes",
"no",
"error",
},
}
schema.ResourceFields["transitioningMessage"] = types.Field{
CodeName: "TransitioningMessage",
Type: "string",
}
return nil
}

View File

@@ -1,17 +0,0 @@
package mapper
import (
"github.com/rancher/norman/types"
m "github.com/rancher/norman/types/mapper"
)
func NewWorkloadTypeMapper() types.Mapper {
return &types.Mappers{
&m.Move{From: "labels", To: "workloadLabels"},
&m.Move{From: "annotations", To: "workloadAnnotations"},
&m.Move{From: "metadata/labels", To: "labels", NoDeleteFromField: true},
&m.Move{From: "metadata/annotations", To: "annotations", NoDeleteFromField: true},
&m.Drop{Field: "metadata"},
&NamespaceIDMapper{},
}
}