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  }