diff --git a/charts/library/common-test/tests/container/ports_test.yaml b/charts/library/common-test/tests/container/ports_test.yaml index 896ffb418f703..98007ac10323b 100644 --- a/charts/library/common-test/tests/container/ports_test.yaml +++ b/charts/library/common-test/tests/container/ports_test.yaml @@ -303,3 +303,100 @@ tests: containerPort: 1234 hostPort: null protocol: UDP + + - it: should fail if there are duplicate ports but they are not adjacent + set: + service: + my-service1: + enabled: true + primary: true + targetSelector: workload-name1 + ports: + my-port: + enabled: true + primary: true + port: 1234 + protocol: tcp + targetSelector: container-name1 + my-port2: + enabled: true + port: 1235 + protocol: tcp + targetSelector: container-name1 + my-port3: + enabled: true + port: 1234 + protocol: udp + targetSelector: container-name1 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: "Port number [1234] is used by multiple ports [my-port, my-port3] in the service [my-service1] but their names are not adjacent when sorted alphabetically (Other ports in this container sorted: [my-port, my-port2, my-port3]). This can cause issues with Kubernetes port updates." + + - it: should pass if there are duplicate ports but they are adjacent + set: + service: + my-service1: + enabled: true + primary: true + targetSelector: workload-name1 + ports: + my-port: + enabled: true + primary: true + port: 1234 + protocol: tcp + targetSelector: container-name1 + my-port2: + enabled: true + port: 1234 + protocol: udp + targetSelector: container-name1 + my-port3: + enabled: true + port: 1235 + protocol: udp + targetSelector: container-name1 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.containers[0].ports + value: + - name: my-port + containerPort: 1234 + protocol: TCP + hostPort: null + - name: my-port2 + containerPort: 1234 + protocol: UDP + hostPort: null + - name: my-port3 + containerPort: 1235 + protocol: UDP + hostPort: null diff --git a/charts/library/common/Chart.yaml b/charts/library/common/Chart.yaml index fe236e51acecc..b63a10e9d6ba4 100644 --- a/charts/library/common/Chart.yaml +++ b/charts/library/common/Chart.yaml @@ -19,7 +19,7 @@ keywords: - truecharts - library-chart - common -kubeVersion: '>=1.24.0-0' +kubeVersion: ">=1.24.0-0" maintainers: - name: TrueCharts email: info@truecharts.org @@ -48,4 +48,4 @@ sources: - https://hub.docker.com/r/mikefarah/yq - https://hub.docker.com/r/traefik/whoami type: library -version: 25.1.6 +version: 25.1.7 diff --git a/charts/library/common/templates/lib/container/_ports.tpl b/charts/library/common/templates/lib/container/_ports.tpl index 451b8e2d2e7ab..932fe27ef5a05 100644 --- a/charts/library/common/templates/lib/container/_ports.tpl +++ b/charts/library/common/templates/lib/container/_ports.tpl @@ -8,6 +8,8 @@ objectData: The object data to be used to render the container. {{- $rootCtx := .rootCtx -}} {{- $objectData := .objectData -}} + {{- $portsByName := dict -}} + {{- range $serviceName, $serviceValues := $rootCtx.Values.service -}} {{- $podSelected := false -}} {{/* If service is enabled... */}} @@ -73,15 +75,58 @@ objectData: The object data to be used to render the container. {{- else }} hostPort: null {{- end -}} + {{- $_ := set $portsByName $portName (dict "containerPort" (toString $containerPort) "serviceName" $serviceName) -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} + {{- include "tc.v1.common.lib.container.ports.detectSortingIssues" (dict "portsByName" $portsByName "rootCtx" $rootCtx) -}} + {{- end -}} {{/* Turning hostNetwork on, it creates hostPort automatically and turning it back off does not remove them. Setting hostPort explicitly to null will remove them. There are still cases that hostPort is not removed, for example, if you have a TCP and UDP port with the same number. Only the TCPs hostPort will be removed. Also note that setting hostPort to null always, it will NOT affect hostNetwork, as it will still create the hostPorts. It only helps to remove them when hostNetwork is turned off. */}} + + +{{- define "tc.v1.common.lib.container.ports.detectSortingIssues" -}} + {{- $rootCtx := .rootCtx -}} + {{- $portsByName := .portsByName -}} + + {{- $portCounts := dict -}} + {{- range $name, $portValues := $portsByName -}} + {{- $count := 1 -}} + {{- $port := (get $portValues "containerPort") -}} + {{- if hasKey $portCounts $port -}} + {{- $count = add1 (get $portCounts $port) -}} + {{- end -}} + {{- $_ := set $portCounts $port $count -}} + {{- end -}} + + {{- $sorted := keys $portsByName | sortAlpha -}} + {{- range $idx, $name := $sorted -}} + {{- $portValues := (get $portsByName $name) -}} + {{- $port := $portValues.containerPort -}} + {{- if eq (get $portCounts $port) 1 -}} + {{- continue -}} + {{- end -}} + + {{- if lt $idx (sub (len $sorted) 1) -}} + {{- $nextPort := (get $portsByName (index $sorted (add1 $idx))).containerPort -}} + {{- if ne $port $nextPort -}} + {{- $portNamesUsingNum := list -}} + {{- range $name, $p := $portsByName -}} + {{- if eq $p.containerPort $port -}} + {{- $portNamesUsingNum = mustAppend $portNamesUsingNum $name -}} + {{- end -}} + {{- end -}} + {{- fail (printf "Port number [%s] is used by multiple ports [%s] in the service [%s] but their names are not adjacent when sorted alphabetically (Other ports in this container sorted: [%s]). This can cause issues with Kubernetes port updates." $port (join ", " $portNamesUsingNum) $portValues.serviceName (join ", " (keys $portsByName | sortAlpha))) -}} + {{- end -}} + {{- $_ := set $portCounts $port 1 -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/charts/library/common/templates/lib/container/_resources.tpl b/charts/library/common/templates/lib/container/_resources.tpl index 7f802062182c7..0cdb76d49573c 100644 --- a/charts/library/common/templates/lib/container/_resources.tpl +++ b/charts/library/common/templates/lib/container/_resources.tpl @@ -38,7 +38,7 @@ limits: {{- if not $objectData.resources.excludeExtra -}} {{- range $k, $v := (omit $resources.limits "cpu" "memory") }} {{/* Omit cpu and memory, as they are handled above */}} {{- if or (not $v) (eq (toString $v) "0") -}} - {{ continue }} + {{- continue -}} {{- end }} {{ $k }}: {{ $v }} {{- end -}}