From 193df99eb0faa3a6ed4600a11066824ddd871716 Mon Sep 17 00:00:00 2001 From: Kjeld Schouten Date: Sun, 24 Dec 2023 22:45:22 +0100 Subject: [PATCH] fix(common): ensure no loadbalancer reservation is made and ingress is not connected to ingresscontroller with Stop-All set (#652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Description** Currently ingress and loadbalancer reservations are still being made for stopped charts. With this change we set services to clusterip, to prevent external connections. We also set ingress to a special `stopped` ingressClass, this ensures we don't nuke things like certificates when stopping **โš™๏ธ Type of change** - [x] โš™๏ธ Feature/App addition - [x] ๐Ÿช› Bugfix - [ ] โš ๏ธ Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] ๐Ÿ”ƒ Refactor of current code **๐Ÿงช How Has This Been Tested?** **๐Ÿ“ƒ Notes:** **โœ”๏ธ Checklist:** - [ ] โš–๏ธ My code follows the style guidelines of this project - [ ] ๐Ÿ‘€ I have performed a self-review of my own code - [ ] #๏ธโƒฃ I have commented my code, particularly in hard-to-understand areas - [ ] ๐Ÿ“„ I have made corresponding changes to the documentation - [ ] โš ๏ธ My changes generate no new warnings - [ ] ๐Ÿงช I have added tests to this description that prove my fix is effective or that my feature works - [ ] โฌ†๏ธ I increased versions for any altered app according to semantic versioning **โž• App addition** If this PR is an app addition please make sure you have done the following. - [ ] ๐Ÿชž I have opened a PR on [truecharts/containers](https://github.com/truecharts/containers) adding the container to TrueCharts mirror repo. - [ ] ๐Ÿ–ผ๏ธ I have added an icon in the Chart's root directory called `icon.png` --- _Please don't blindly check all the boxes. Read them and only check those that apply. Those checkboxes are there for the reviewer to see what is this all about and the status of this PR with a quick glance._ --------- Co-authored-by: Stavros kois --- .../common-test/tests/ingress/stop_test.yaml | 93 ++++++++++++++ .../tests/ingress/validation_test.yaml | 14 ++ .../common-test/tests/service/stop_test.yaml | 120 ++++++++++++++++++ library/common/Chart.yaml | 2 +- library/common/templates/class/_ingress.tpl | 17 ++- library/common/templates/class/_service.tpl | 6 +- .../templates/lib/ingress/_validation.tpl | 7 + 7 files changed, 254 insertions(+), 5 deletions(-) create mode 100644 library/common-test/tests/ingress/stop_test.yaml create mode 100644 library/common-test/tests/service/stop_test.yaml diff --git a/library/common-test/tests/ingress/stop_test.yaml b/library/common-test/tests/ingress/stop_test.yaml new file mode 100644 index 00000000..63715d18 --- /dev/null +++ b/library/common-test/tests/ingress/stop_test.yaml @@ -0,0 +1,93 @@ +suite: ingress - stop test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with stopAll + set: + operator: &operator + verify: + enabled: false + global: + stopAll: true + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: &ingress + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + integrations: + traefik: + enabled: false + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: spec.ingressClassName + value: tc-stopped + + - it: should pass with ixChartContext - isStopped (true) + set: + operator: *operator + global: + namespace: ix-something + ixChartContext: + storageClassName: some-storage-class + isStopped: true + service: *service + ingress: *ingress + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: spec.ingressClassName + value: tc-stopped + + - it: should pass with ixChartContext - isStopped (false) + set: + operator: *operator + global: + namespace: ix-something + ixChartContext: + storageClassName: some-storage-class + isStopped: false + service: *service + ingress: *ingress + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isNull: + path: spec.ingressClassName diff --git a/library/common-test/tests/ingress/validation_test.yaml b/library/common-test/tests/ingress/validation_test.yaml index 192fbbff..72a8aaa2 100644 --- a/library/common-test/tests/ingress/validation_test.yaml +++ b/library/common-test/tests/ingress/validation_test.yaml @@ -610,3 +610,17 @@ tests: asserts: - failedTemplate: errorMessage: Ingress - [tls.scaleCert] can only be used in TrueNAS SCALE + + - it: should fail with ingressClassName set to tc-stopped + set: + operator: *operator + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + ingressClassName: tc-stopped + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [ingressClassName] to not be [stopped], this is reserved for internal use diff --git a/library/common-test/tests/service/stop_test.yaml b/library/common-test/tests/service/stop_test.yaml new file mode 100644 index 00000000..8b9487e0 --- /dev/null +++ b/library/common-test/tests/service/stop_test.yaml @@ -0,0 +1,120 @@ +suite: service stop test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with stopAll + set: + global: + stopAll: true + service: &service + my-service1: + enabled: true + primary: true + type: LoadBalancer + ports: + port-name: + enabled: true + primary: true + port: 12344 + workload: &workload + my-workload: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &serviceDoc 1 + isKind: + of: Service + - documentIndex: *serviceDoc + isAPIVersion: + of: v1 + - documentIndex: *serviceDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *serviceDoc + equal: + path: spec.type + value: ClusterIP + + - it: should pass with isStopped (true) + set: + global: + namespace: ix-something + ixChartContext: + storageClassName: some-storage-class + isStopped: true + service: &service + my-service1: + enabled: true + primary: true + type: LoadBalancer + ports: + port-name: + enabled: true + primary: true + port: 12344 + workload: &workload + my-workload: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &serviceDoc 1 + isKind: + of: Service + - documentIndex: *serviceDoc + isAPIVersion: + of: v1 + - documentIndex: *serviceDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *serviceDoc + equal: + path: spec.type + value: ClusterIP + + - it: should pass with isStopped (false) + set: + global: + namespace: ix-something + ixChartContext: + storageClassName: some-storage-class + isStopped: false + service: &service + my-service1: + enabled: true + primary: true + type: LoadBalancer + ports: + port-name: + enabled: true + primary: true + port: 12344 + workload: &workload + my-workload: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &serviceDoc 1 + isKind: + of: Service + - documentIndex: *serviceDoc + isAPIVersion: + of: v1 + - documentIndex: *serviceDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *serviceDoc + equal: + path: spec.type + value: LoadBalancer diff --git a/library/common/Chart.yaml b/library/common/Chart.yaml index 7d2849b6..72f3beba 100644 --- a/library/common/Chart.yaml +++ b/library/common/Chart.yaml @@ -15,4 +15,4 @@ maintainers: name: common sources: null type: library -version: 16.2.21 +version: 16.2.22 diff --git a/library/common/templates/class/_ingress.tpl b/library/common/templates/class/_ingress.tpl index 4c465f00..ea3f9a11 100644 --- a/library/common/templates/class/_ingress.tpl +++ b/library/common/templates/class/_ingress.tpl @@ -23,7 +23,18 @@ objectData: The object data to be used to render the Ingress. {{- include "tc.v1.common.lib.ingress.integration.certManager" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} {{- include "tc.v1.common.lib.ingress.integration.traefik" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} - {{- include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) }} + {{- include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} + + {{- $ingressClassName := "" -}} + {{- if $objectData.ingressClassName -}} + {{- $ingressClassName = (tpl $objectData.ingressClassName $rootCtx) -}} + {{- end -}} + + {{/* When Stop All is set, force ingressClass "stopped" + to yeet ingress from the ingresscontroller */}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $ingressClassName = "tc-stopped" -}} + {{- end }} --- apiVersion: networking.k8s.io/v1 kind: Ingress @@ -41,8 +52,8 @@ metadata: {{- . | nindent 4 }} {{- end }} spec: - {{- if $objectData.ingressClassName }} - ingressClassName: {{ tpl $objectData.ingressClassName $rootCtx }} + {{- if $ingressClassName }} + ingressClassName: {{ $ingressClassName }} {{- end }} rules: {{- range $h := $objectData.hosts }} diff --git a/library/common/templates/class/_service.tpl b/library/common/templates/class/_service.tpl index bd03ec37..d1068478 100644 --- a/library/common/templates/class/_service.tpl +++ b/library/common/templates/class/_service.tpl @@ -51,8 +51,12 @@ objectData: The service data, that will be used to render the Service object. {{- $svcType = "ClusterIP" -}} {{- end -}} {{- end -}} - {{- $_ := set $objectData "type" $svcType }} + {{/* When Stop All is set, force ClusterIP as well */}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $svcType = "ClusterIP" -}} + {{- end -}} + {{- $_ := set $objectData "type" $svcType }} --- apiVersion: v1 kind: Service diff --git a/library/common/templates/lib/ingress/_validation.tpl b/library/common/templates/lib/ingress/_validation.tpl index cee39de0..60dc898c 100644 --- a/library/common/templates/lib/ingress/_validation.tpl +++ b/library/common/templates/lib/ingress/_validation.tpl @@ -31,6 +31,13 @@ objectData: {{- end -}} {{- end -}} + {{- if $objectData.ingressClassName -}} + {{- $icn := tpl $objectData.ingressClassName $rootCtx -}} + {{- if eq $icn "tc-stopped" -}} + {{- fail "Ingress - Expected [ingressClassName] to not be [stopped], this is reserved for internal use" -}} + {{- end -}} + {{- end -}} + {{- if not $objectData.hosts -}} {{- fail "Ingress - Expected non-empty [hosts]" -}} {{- end -}}