github.com/rancher/types@v0.0.0-20220328215343-4370ff10ecd5/mapper/container_ports.go (about) 1 package mapper 2 3 import ( 4 "strings" 5 6 "github.com/rancher/norman/types" 7 "github.com/rancher/norman/types/convert" 8 "github.com/rancher/norman/types/mapper" 9 "github.com/rancher/norman/types/values" 10 "github.com/sirupsen/logrus" 11 ) 12 13 type ContainerPorts struct { 14 } 15 16 func (n ContainerPorts) FromInternal(data map[string]interface{}) { 17 field := mapper.AnnotationField{ 18 Field: "ports", 19 List: true, 20 } 21 field.FromInternal(data) 22 23 containers := convert.ToInterfaceSlice(data["containers"]) 24 annotationPorts := convert.ToInterfaceSlice(data["ports"]) 25 annotationsPortsMap := map[string]map[string]interface{}{} 26 27 // process fields defined via annotations 28 for i := 0; i < len(annotationPorts) && i < len(containers); i++ { 29 container := convert.ToMapInterface(containers[i]) 30 if container != nil { 31 portsSlice := convert.ToInterfaceSlice(annotationPorts[i]) 32 portMap := map[string]interface{}{} 33 for _, port := range portsSlice { 34 asMap, err := convert.EncodeToMap(port) 35 if err != nil { 36 logrus.Warnf("Failed to convert container port to map %v", err) 37 continue 38 } 39 asMap["type"] = "/v3/project/schemas/containerPort" 40 name, _ := values.GetValue(asMap, "name") 41 portMap[convert.ToString(name)] = asMap 42 } 43 containerName, _ := values.GetValue(container, "name") 44 annotationsPortsMap[convert.ToString(containerName)] = portMap 45 } 46 } 47 48 for _, container := range containers { 49 // iterate over container ports and see if some of them are not defined via annotation 50 // set kind to hostport if source port is set, and clusterip if it is not 51 containerMap := convert.ToMapInterface(container) 52 containerName, _ := values.GetValue(containerMap, "name") 53 portMap := annotationsPortsMap[convert.ToString(containerName)] 54 if portMap == nil { 55 portMap = map[string]interface{}{} 56 } 57 var containerPorts []interface{} 58 containerPortSlice := convert.ToInterfaceSlice(containerMap["ports"]) 59 for _, port := range containerPortSlice { 60 asMap, err := convert.EncodeToMap(port) 61 if err != nil { 62 logrus.Warnf("Failed to convert container port to map %v", err) 63 continue 64 } 65 portName, _ := values.GetValue(asMap, "name") 66 if annotationPort, ok := portMap[convert.ToString(portName)]; ok { 67 containerPorts = append(containerPorts, annotationPort) 68 } else { 69 hostPort, _ := values.GetValue(asMap, "hostPort") 70 if hostPort == nil { 71 asMap["kind"] = "ClusterIP" 72 } else { 73 asMap["sourcePort"] = hostPort 74 asMap["kind"] = "HostPort" 75 } 76 containerPorts = append(containerPorts, asMap) 77 } 78 } 79 containerMap["ports"] = containerPorts 80 } 81 82 } 83 84 func (n ContainerPorts) ToInternal(data map[string]interface{}) error { 85 field := mapper.AnnotationField{ 86 Field: "ports", 87 List: true, 88 } 89 90 var ports []interface{} 91 path := []string{"containers", "{ARRAY}", "ports"} 92 convert.Transform(data, path, func(obj interface{}) interface{} { 93 if l, ok := obj.([]interface{}); ok { 94 for _, p := range l { 95 mapped, err := convert.EncodeToMap(p) 96 if err != nil { 97 logrus.Warnf("Failed to encode port: %v", err) 98 return obj 99 } 100 if strings.EqualFold(convert.ToString(mapped["kind"]), "HostPort") { 101 mapped["hostPort"] = mapped["sourcePort"] 102 } 103 } 104 ports = append(ports, l) 105 } 106 return obj 107 }) 108 109 if len(ports) != 0 { 110 data["ports"] = ports 111 return field.ToInternal(data) 112 } 113 114 return nil 115 } 116 117 func (n ContainerPorts) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { 118 return nil 119 }