diff --git a/charts/library/common-test/tests/container/ports_test.yaml b/charts/library/common-test/tests/container/ports_test.yaml index 896ffb418f7..98007ac1032 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 fe236e51ace..b63a10e9d6b 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 451b8e2d2e7..932fe27ef5a 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 7f802062182..0cdb76d4957 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 -}}