diff --git a/apis/project.cattle.io/v3/schema/schema.go b/apis/project.cattle.io/v3/schema/schema.go index be9f2ff4..ad179ed0 100644 --- a/apis/project.cattle.io/v3/schema/schema.go +++ b/apis/project.cattle.io/v3/schema/schema.go @@ -514,6 +514,7 @@ func podTypes(schemas *types.Schemas) *types.Schemas { ). AddMapperForType(&Version, v1.ContainerPort{}, m.Move{From: "hostIP", To: "hostIp"}, + m.Copy{From: "hostPort", To: "sourcePort"}, m.Drop{Field: "hostPort"}, ). AddMapperForType(&Version, v1.Handler{}, diff --git a/mapper/container_ports.go b/mapper/container_ports.go index 464eef41..e5aba17d 100644 --- a/mapper/container_ports.go +++ b/mapper/container_ports.go @@ -6,6 +6,7 @@ import ( "github.com/rancher/norman/types" "github.com/rancher/norman/types/convert" "github.com/rancher/norman/types/mapper" + "github.com/rancher/norman/types/values" "github.com/sirupsen/logrus" ) @@ -20,13 +21,15 @@ func (n ContainerPorts) FromInternal(data map[string]interface{}) { field.FromInternal(data) containers := convert.ToInterfaceSlice(data["containers"]) - ports := convert.ToInterfaceSlice(data["ports"]) + annotationPorts := convert.ToInterfaceSlice(data["ports"]) + annotationsPortsMap := map[string]map[string]interface{}{} - for i := 0; i < len(ports) && i < len(containers); i++ { + // process fields defined via annotations + for i := 0; i < len(annotationPorts) && i < len(containers); i++ { container := convert.ToMapInterface(containers[i]) if container != nil { - portsSlice := convert.ToInterfaceSlice(ports[i]) - var containerPorts []interface{} + portsSlice := convert.ToInterfaceSlice(annotationPorts[i]) + portMap := map[string]interface{}{} for _, port := range portsSlice { asMap, err := convert.EncodeToMap(port) if err != nil { @@ -34,12 +37,49 @@ func (n ContainerPorts) FromInternal(data map[string]interface{}) { continue } asMap["type"] = "/v3/project/schemas/containerPort" - containerPorts = append(containerPorts, asMap) + name, _ := values.GetValue(asMap, "name") + portMap[convert.ToString(name)] = asMap } - - container["ports"] = containerPorts + containerName, _ := values.GetValue(container, "name") + annotationsPortsMap[convert.ToString(containerName)] = portMap } } + + for _, container := range containers { + // iterate over container ports and see if some of them are not defined via annotation + // set kind to hostport if source port is set, and clusterip if it is not + containerMap := convert.ToMapInterface(container) + containerName, _ := values.GetValue(containerMap, "name") + portMap := annotationsPortsMap[convert.ToString(containerName)] + if portMap == nil { + portMap = map[string]interface{}{} + } + var containerPorts []interface{} + containerPortSlice := convert.ToInterfaceSlice(containerMap["ports"]) + for _, port := range containerPortSlice { + asMap, err := convert.EncodeToMap(port) + if err != nil { + logrus.Warnf("Failed to convert container port to map %v", err) + continue + } + portName, _ := values.GetValue(asMap, "name") + if annotationPort, ok := portMap[convert.ToString(portName)]; ok { + containerPorts = append(containerPorts, annotationPort) + } else { + hostPort, _ := values.GetValue(asMap, "sourcePort") + if hostPort == nil { + asMap["kind"] = "ClusterIP" + } else { + asMap["sourcePort"] = hostPort + asMap["kind"] = "HostPort" + } + delete(asMap, "hostPort") + containerPorts = append(containerPorts, asMap) + } + } + containerMap["ports"] = containerPorts + } + } func (n ContainerPorts) ToInternal(data map[string]interface{}) error { @@ -63,6 +103,8 @@ func (n ContainerPorts) ToInternal(data map[string]interface{}) error { mapped["hostPort"] = mapped["sourcePort"] } } + // delete the source port so it doesn't get converted to the host port by default mapper + delete(mapped, "sourcePort") } ports = append(ports, l) }