diff --git a/charts/library/common-test/Chart.yaml b/charts/library/common-test/Chart.yaml new file mode 100644 index 00000000000..0689fa77b04 --- /dev/null +++ b/charts/library/common-test/Chart.yaml @@ -0,0 +1,27 @@ +apiVersion: v2 +appVersion: "" +dependencies: +- name: common + repository: file://../common + version: ~25.0.0 +deprecated: false +description: Helper chart to test different use cases of the common library +home: https://github.com/truecharts/apps/tree/master/charts/library/common-test +icon: https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png +keywords: +- common-test +- truecharts +- common +- test +kubeVersion: '>=1.24.0-0' +maintainers: +- email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: common-test +sources: +- https://github.com/truecharts/apps/tree/master/charts/library/common-test +type: application +version: 1.0.0 +annotations: + truecharts.org/min_helm_version: "3.11" diff --git a/charts/library/common-test/LICENSE b/charts/library/common-test/LICENSE new file mode 100644 index 00000000000..30e1322aea9 --- /dev/null +++ b/charts/library/common-test/LICENSE @@ -0,0 +1,106 @@ +Business Source License 1.1 + +Parameters + +Licensor: The TrueCharts Project, it's owner and it's contributors +Licensed Work: The TrueCharts "Common-Test" Helm Chart +Additional Use Grant: You may use the licensed work in production, as long + as it is directly sourced from a TrueCharts provided + official repository, catalog or source. You may also make private + modification to the directly sourced licenced work, + when used in production. + + The following cases are, due to their nature, also + defined as 'production use' and explicitly prohibited: + - Bundling, including or displaying the licensed work + with(in) another work intended for production use, + with the apparent intend of facilitating and/or + promoting production use by third parties in + violation of this license. + +Change Date: 2050-01-01 + +Change License: 3-clause BSD license + +For information about alternative licensing arrangements for the Software, +please contact: legal@truecharts.org + +Notice + +The Business Source License (this document, or the “License”) is not an Open +Source license. However, the Licensed Work will eventually be made available +under an Open Source License, as stated in this License. + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +“Business Source License” is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Business Source License 1.1 + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative +works, redistribute, and make non-production use of the Licensed Work. The +Licensor may make an Additional Use Grant, above, permitting limited +production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly +available distribution of a specific version of the Licensed Work under this +License, whichever comes first, the Licensor hereby grants you rights under +the terms of the Change License, and the rights granted in the paragraph +above terminate. + +If your use of the Licensed Work does not comply with the requirements +currently in effect as described in this License, you must purchase a +commercial license from the Licensor, its affiliated entities, or authorized +resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works +of the Licensed Work, are subject to this License. This License applies +separately for each version of the Licensed Work and the Change Date may vary +for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy +of the Licensed Work. If you receive the Licensed Work in original or +modified form from a third party, the terms and conditions set forth in this +License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically +terminate your rights under this License for the current and all other +versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of +Licensor or its affiliates (provided that you may use a trademark or logo of +Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON +AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND +TITLE. + +MariaDB hereby grants you permission to use this License’s text to license +your works, and to refer to it using the trademark “Business Source License”, +as long as you comply with the Covenants of Licensor below. + +Covenants of Licensor + +In consideration of the right to use this License’s text and the “Business +Source License” name and trademark, Licensor covenants to MariaDB, and to all +other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, + or a license that is compatible with GPL Version 2.0 or a later version, + where “compatible” means that software provided under the Change License can + be included in a program with software provided under GPL Version 2.0 or a + later version. Licensor may specify additional Change Licenses without + limitation. + +2. To either: (a) specify an additional grant of rights to use that does not + impose any additional restriction on the right granted in this License, as + the Additional Use Grant; or (b) insert the text “None”. + +3. To specify a Change Date. + +4. Not to modify this License in any other way. diff --git a/charts/library/common-test/README.md b/charts/library/common-test/README.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/charts/library/common-test/ci/autopermissions-values.yaml b/charts/library/common-test/ci/autopermissions-values.yaml new file mode 100644 index 00000000000..7aa1aa52001 --- /dev/null +++ b/charts/library/common-test/ci/autopermissions-values.yaml @@ -0,0 +1,48 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +persistence: + autopermissions: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chown: true + chmod: 775 + hostPath: /usr + mountPath: /hptest + hostPathType: "" diff --git a/charts/library/common-test/ci/basic-values.yaml b/charts/library/common-test/ci/basic-values.yaml new file mode 100644 index 00000000000..d7fe2666394 --- /dev/null +++ b/charts/library/common-test/ci/basic-values.yaml @@ -0,0 +1,37 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" diff --git a/charts/library/common-test/ci/clickhouse-values.yaml b/charts/library/common-test/ci/clickhouse-values.yaml new file mode 100644 index 00000000000..c96212434b8 --- /dev/null +++ b/charts/library/common-test/ci/clickhouse-values.yaml @@ -0,0 +1,28 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +clickhouse: + enabled: true diff --git a/charts/library/common-test/ci/cnpg-multi-values.yaml b/charts/library/common-test/ci/cnpg-multi-values.yaml new file mode 100644 index 00000000000..da2e4dd6c1c --- /dev/null +++ b/charts/library/common-test/ci/cnpg-multi-values.yaml @@ -0,0 +1,107 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +cnpg: + main: + enabled: true + # -- number of instances for both postgres and pgbouncer + instances: 2 + database: "app" + user: "app" + password: test-password + # -- change to supervised to disable unsupervised updates + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # -- storage size for the two pvc's per instance + storage: + size: "256Gi" + walsize: "256Gi" + pooler: + # -- enable to create extra pgbouncer for readonly access + createRO: false + instances: 2 + # -- set to enable prometheus metrics + monitoring: + enablePodMonitor: false + # -- contains credentials and urls output by generator + creds: {} + ro: + enabled: true + # -- number of instances for both postgres and pgbouncer + instances: 2 + database: "app2" + user: "app2" + password: test-password + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # -- storage size for the two pvc's per instance + storage: + size: "256Gi" + walsize: "256Gi" + pooler: + # -- enable to create extra pgbouncer for readonly access + createRO: true + instances: 2 + # -- set to enable prometheus metrics + monitoring: + enablePodMonitor: false + # -- contains credentials and urls output by generator + creds: {} + mon: + enabled: true + # -- number of instances for both postgres and pgbouncer + instances: 2 + database: "app2" + user: "app2" + password: test-password + # -- change to supervised to disable unsupervised updates + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # -- storage size for the two pvc's per instance + storage: + size: "256Gi" + walsize: "256Gi" + pooler: + # -- enable to create extra pgbouncer for readonly access + createRO: true + instances: 2 + # -- set to enable prometheus metrics + monitoring: + enablePodMonitor: true + # -- contains credentials and urls output by generator + creds: {} diff --git a/charts/library/common-test/ci/cnpg-values.yaml b/charts/library/common-test/ci/cnpg-values.yaml new file mode 100644 index 00000000000..95a10a80bea --- /dev/null +++ b/charts/library/common-test/ci/cnpg-values.yaml @@ -0,0 +1,54 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +cnpg: + main: + enabled: true + # -- number of instances for both postgres and pgbouncer + instances: 2 + database: "app" + user: "app" + password: test-password + # -- change to supervised to disable unsupervised updates + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # -- storage size for the two pvc's per instance + storage: + size: "256Gi" + walsize: "256Gi" + pooler: + # -- enable to create extra pgbouncer for readonly access + createRO: false + instances: 2 + # -- set to enable prometheus metrics + monitoring: + enablePodMonitor: false + # -- contains credentials and urls output by generator + creds: {} diff --git a/charts/library/common-test/ci/codeserver-values.yaml b/charts/library/common-test/ci/codeserver-values.yaml new file mode 100644 index 00000000000..6241ab64c1b --- /dev/null +++ b/charts/library/common-test/ci/codeserver-values.yaml @@ -0,0 +1,57 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + + +args: + - --port + - '8080' + +persistence: + testpvc: + enabled: true + type: pvc + mountPath: /testpvc + +addons: + codeserver: + enabled: true + service: + type: LoadBalancer + ports: + codeserver: + nodePort: 30067 diff --git a/charts/library/common-test/ci/configmap-values.yaml b/charts/library/common-test/ci/configmap-values.yaml new file mode 100644 index 00000000000..8c770183e68 --- /dev/null +++ b/charts/library/common-test/ci/configmap-values.yaml @@ -0,0 +1,72 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + + +key1: value1 +key2: 80 +key3: pair +key4: value2 +key5: 81 +key6: false + +envFrom: + - configMapRef: + name: kv-test + +configmap: + kv-test: + enabled: true + data: + key: "{{ .Values.key1 }}" + key1: "{{ .Values.key4 }}" + key2: "{{ .Values.key5 }}" + key3: "{{ .Values.key6 }}" + + file-test: + enabled: true + data: + nginx.conf2: | + alias {{ .Values.key3 }} + listen {{ .Values.key2 }} + function { + # some json + "key": { + "key2": "value", + "key3": "value2" + } + } diff --git a/charts/library/common-test/ci/credentials-values.yaml b/charts/library/common-test/ci/credentials-values.yaml new file mode 100644 index 00000000000..dafba3f3644 --- /dev/null +++ b/charts/library/common-test/ci/credentials-values.yaml @@ -0,0 +1,46 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +credentials: + mys3: + type: s3 + url: "test" + bucket: "test" + accessKey: "test" + secretKey: "test" + encrKey: "test" diff --git a/charts/library/common-test/ci/credentialsList-values.yaml b/charts/library/common-test/ci/credentialsList-values.yaml new file mode 100644 index 00000000000..193af6e93cc --- /dev/null +++ b/charts/library/common-test/ci/credentialsList-values.yaml @@ -0,0 +1,46 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +credentialsList: + - name: mys3 + type: s3 + url: "test" + bucket: "test" + accessKey: "test" + secretKey: "test" + encrKey: "test" diff --git a/charts/library/common-test/ci/cron-values.yaml b/charts/library/common-test/ci/cron-values.yaml new file mode 100644 index 00000000000..b793b87f89c --- /dev/null +++ b/charts/library/common-test/ci/cron-values.yaml @@ -0,0 +1,39 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: CronJob + schedule: "*/1 * * * *" + podSpec: + restartPolicy: OnFailure + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" diff --git a/charts/library/common-test/ci/daemonset-values.yaml b/charts/library/common-test/ci/daemonset-values.yaml new file mode 100644 index 00000000000..4be16579a60 --- /dev/null +++ b/charts/library/common-test/ci/daemonset-values.yaml @@ -0,0 +1,37 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: DaemonSet + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" diff --git a/charts/library/common-test/ci/extra-containers-values.yaml b/charts/library/common-test/ci/extra-containers-values.yaml new file mode 100644 index 00000000000..1569b5a88e5 --- /dev/null +++ b/charts/library/common-test/ci/extra-containers-values.yaml @@ -0,0 +1,49 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +additionalContainers: + some-name: + imageSelector: image + args: + - --port + - "8081" + probes: + liveness: + enabled: true + port: 8081 + type: http + path: / + readiness: + enabled: true + port: 8081 + type: http + path: / + startup: + enabled: true + port: 8081 + type: http + path: / diff --git a/charts/library/common-test/ci/imagePullSecret-values.yaml b/charts/library/common-test/ci/imagePullSecret-values.yaml new file mode 100644 index 00000000000..6a994da9327 --- /dev/null +++ b/charts/library/common-test/ci/imagePullSecret-values.yaml @@ -0,0 +1,53 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +registry: quay.io +user: user +pass: secret_pass +email: mail@example.com + +imagePullSecret: + image-secret-name: + enabled: true + labels: {} + annotations: {} + data: + registry: "{{ .Values.registry }}" + username: "{{ .Values.user }}" + password: "{{ .Values.pass }}" + email: "{{ .Values.email }}" diff --git a/charts/library/common-test/ci/ingress-values.yaml b/charts/library/common-test/ci/ingress-values.yaml new file mode 100644 index 00000000000..5cae3b5fee2 --- /dev/null +++ b/charts/library/common-test/ci/ingress-values.yaml @@ -0,0 +1,120 @@ +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + protocol: http + autolink: + enabled: true + ports: + autolink: + enabled: true + protocol: http + port: 8081 + +# -- Configure the ingresses for the chart here. +# Additional ingresses can be added by adding a dictionary key similar to the 'main' ingress. +# @default -- See below +ingress: + main: + enabled: true + hosts: + - host: chart-example.local + paths: + - path: / + pathType: Prefix + tls: [] + + certificateissuer: + enabled: true + certificateIssuer: someissuer + hosts: + - host: ci.chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: + - hosts: + - ci.chart-example.local + + tlscertificateissuer: + enabled: true + hosts: + - host: citls.chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: + - certificateIssuer: sometlsissuer + hosts: + - citls.chart-example.local + + label: + enabled: true + fixedMiddlewares: + - chain-basic + labels: + labelexample1: labelvalue2 + hosts: + - host: label.chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: [] + + autolink: + enabled: true + fixedMiddlewares: + - chain-basic + hosts: + - host: label.chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: [] + autoLink: true + + notls: + enabled: true + fixedMiddlewares: + - chain-basic + hosts: + - host: notls.chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: diff --git a/charts/library/common-test/ci/init-values.yaml b/charts/library/common-test/ci/init-values.yaml new file mode 100644 index 00000000000..6745f3473be --- /dev/null +++ b/charts/library/common-test/ci/init-values.yaml @@ -0,0 +1,52 @@ +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + initContainers: + init-cont: + enabled: true + type: init + imageSelector: alpineImage + args: + - echo + - "Hello World" + install-cont: + enabled: true + type: install + imageSelector: alpineImage + args: + - echo + - "Hello World" + +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 diff --git a/charts/library/common-test/ci/job-values.yaml b/charts/library/common-test/ci/job-values.yaml new file mode 100644 index 00000000000..412883170e0 --- /dev/null +++ b/charts/library/common-test/ci/job-values.yaml @@ -0,0 +1,38 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Job + podSpec: + restartPolicy: Never + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" diff --git a/charts/library/common-test/ci/mariadb-values.yaml b/charts/library/common-test/ci/mariadb-values.yaml new file mode 100644 index 00000000000..65b6c95c694 --- /dev/null +++ b/charts/library/common-test/ci/mariadb-values.yaml @@ -0,0 +1,28 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +mariadb: + enabled: true diff --git a/charts/library/common-test/ci/metrics-values.yaml b/charts/library/common-test/ci/metrics-values.yaml new file mode 100644 index 00000000000..f615c5e588a --- /dev/null +++ b/charts/library/common-test/ci/metrics-values.yaml @@ -0,0 +1,66 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +metrics: + main: + enabled: true + type: "servicemonitor" + matchLabels: "" + endpoints: + - port: "8080" + interval: "10s" + scrapeTimeout: "10s" + path: / + honorLabels: false + prometheusRule: + enabled: false + podmon: + enabled: true + type: "podmonitor" + matchLabels: "" + endpoints: + - port: "8080" + interval: "10s" + scrapeTimeout: "10s" + path: / + honorLabels: false + prometheusRule: + enabled: false + promrule: + enabled: true + type: "servicemonitor" + matchLabels: "" + endpoints: + - port: "8080" + interval: "10s" + scrapeTimeout: "10s" + path: / + honorLabels: false + prometheusRule: + enabled: true + groups: + somegroup: + rules: [] diff --git a/charts/library/common-test/ci/mongodb-values.yaml b/charts/library/common-test/ci/mongodb-values.yaml new file mode 100644 index 00000000000..06c6588c2c8 --- /dev/null +++ b/charts/library/common-test/ci/mongodb-values.yaml @@ -0,0 +1,28 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +mongodb: + enabled: true diff --git a/charts/library/common-test/ci/netshoot-values.yaml b/charts/library/common-test/ci/netshoot-values.yaml new file mode 100644 index 00000000000..ea09a9bd3d2 --- /dev/null +++ b/charts/library/common-test/ci/netshoot-values.yaml @@ -0,0 +1,49 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +addons: + netshoot: + enabled: true + + # -- select pods to bind vpn addon to + targetSelector: + - main diff --git a/charts/library/common-test/ci/networkPolicy-values.yaml b/charts/library/common-test/ci/networkPolicy-values.yaml new file mode 100644 index 00000000000..c7cca36a80a --- /dev/null +++ b/charts/library/common-test/ci/networkPolicy-values.yaml @@ -0,0 +1,72 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +networkPolicy: + main: + enabled: true + + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: myproject + - podSelector: + matchLabels: + role: frontend + - namespaceSelector: + matchLabels: + project: myproject2 + podSelector: + matchLabels: + role: frontend2 + ports: + - protocol: TCP + port: 6379 + egress: + - to: + - ipBlock: + cidr: 172.17.2.0/16 + except: + - 172.17.2.0/24 + - namespaceSelector: + matchLabels: + project: myproject3 + - podSelector: + matchLabels: + role: frontend3 + - namespaceSelector: + matchLabels: + project: myproject4 + podSelector: + matchLabels: + role: frontend4 + ports: + - protocol: TCP + port: 5978 diff --git a/charts/library/common-test/ci/persistence-values.yaml b/charts/library/common-test/ci/persistence-values.yaml new file mode 100644 index 00000000000..f4582d6df47 --- /dev/null +++ b/charts/library/common-test/ci/persistence-values.yaml @@ -0,0 +1,99 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +persistence: + pvc-stock: + enabled: true + type: pvc + mountPath: /pvcstock + + pvc-size: + enabled: true + type: pvc + mountPath: /pvcsize + size: 1Gi + + pvc-readonly: + enabled: true + type: pvc + mountPath: /pvcro + readOnly: true + + pvc-labeled: + enabled: true + labels: + labelexample1: labelvalue2 + type: pvc + mountPath: /pvclabeled + + pvc-sc-empty: + enabled: true + type: pvc + mountPath: /pvcscempty + readOnly: false + storageClass: "" + + emptydir: + enabled: true + type: emptyDir + mountPath: /emptydir + + emptydir-mem: + enabled: true + type: emptyDir + mountPath: /emptydirmem + medium: Memory + + emptydir-size: + enabled: true + type: emptyDir + mountPath: /emptydirsize + size: 1Gi + + emptydir-memsize: + enabled: true + type: emptyDir + mountPath: /emptydirmemsize + medium: Memory + size: 1Gi + + hostpath-stock: + enabled: true + type: hostPath + hostPath: /usr + mountPath: /hptest + hostPathType: "" diff --git a/charts/library/common-test/ci/portal-ingress-values.yaml b/charts/library/common-test/ci/portal-ingress-values.yaml new file mode 100644 index 00000000000..780217d2124 --- /dev/null +++ b/charts/library/common-test/ci/portal-ingress-values.yaml @@ -0,0 +1,94 @@ +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + protocol: http + test: + enabled: true + ports: + test: + enabled: true + protocol: http + port: 8081 + +# -- Configure the ingresses for the chart here. +# Additional ingresses can be added by adding a dictionary key similar to the 'main' ingress. +# @default -- See below +ingress: + main: + enabled: true + hosts: + - host: chart-example.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: [] + test: + enabled: true + hosts: + - host: chart-test.local + paths: + - path: / + pathType: Prefix + service: + name: + port: + tls: [] + +portal: + open: + enabled: true + override: + protocol: + host: + port: + path: "" + path: + enabled: true + path: "somepath" + explicit: + enabled: true + targetSelector: + ingress: "test" + service: "test" + port: "" + override: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "666" + override-explicit: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "666" + targetSelector: + ingress: "test" + service: "test" + port: "" diff --git a/charts/library/common-test/ci/portal-svc-values.yaml b/charts/library/common-test/ci/portal-svc-values.yaml new file mode 100644 index 00000000000..e26bafefc63 --- /dev/null +++ b/charts/library/common-test/ci/portal-svc-values.yaml @@ -0,0 +1,67 @@ +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + protocol: http + test: + enabled: true + ports: + test: + enabled: true + protocol: http + port: 8081 + +portal: + open: + enabled: true + override: + protocol: + host: + port: + path: "" + path: + enabled: true + path: "somepath" + explicit: + enabled: true + targetSelector: + ingress: "test" + service: "test" + port: "" + override: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "666" + override-explicit: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "666" + targetSelector: + ingress: "test" + service: "test" + port: "" diff --git a/charts/library/common-test/ci/priorityclass-values.yaml b/charts/library/common-test/ci/priorityclass-values.yaml new file mode 100644 index 00000000000..308066148e9 --- /dev/null +++ b/charts/library/common-test/ci/priorityclass-values.yaml @@ -0,0 +1,47 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +# -- create storageClasses on demand +priorityClass: + example: + provisioner: some.provisioner.io + enabled: true + value: 1000000 + preemptionPolicy: PreemptLowerPriority + globalDefault: false + description: "some description" diff --git a/charts/library/common-test/ci/rbac-values.yaml b/charts/library/common-test/ci/rbac-values.yaml new file mode 100644 index 00000000000..65ce60e4047 --- /dev/null +++ b/charts/library/common-test/ci/rbac-values.yaml @@ -0,0 +1,109 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + workload2: + enabled: true + primary: false + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +rbac: + main: + enabled: true + primary: true + clusterWide: true + allServiceAccounts: true + labels: + key: value + key1: value1 + annotations: + key: value + key1: value1 + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + +serviceAccount: + sa-name: + enabled: true + primary: true + labels: + key: value + key2: value + annotations: + key: value + key2: value + other-sa-name: + enabled: true + targetSelector: + - workload2 diff --git a/charts/library/common-test/ci/redis-values.yaml b/charts/library/common-test/ci/redis-values.yaml new file mode 100644 index 00000000000..0c5534ac6df --- /dev/null +++ b/charts/library/common-test/ci/redis-values.yaml @@ -0,0 +1,28 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +redis: + enabled: true diff --git a/charts/library/common-test/ci/register-operator-values.yaml b/charts/library/common-test/ci/register-operator-values.yaml new file mode 100644 index 00000000000..035f0bb8232 --- /dev/null +++ b/charts/library/common-test/ci/register-operator-values.yaml @@ -0,0 +1,44 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +operator: + register: true diff --git a/charts/library/common-test/ci/route-values.yaml b/charts/library/common-test/ci/route-values.yaml new file mode 100644 index 00000000000..8ad3acea3c8 --- /dev/null +++ b/charts/library/common-test/ci/route-values.yaml @@ -0,0 +1,48 @@ +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + protocol: http + autolink: + enabled: true + ports: + autolink: + enabled: true + protocol: http + port: 8081 + +route: + main: + enabled: true + hostnames: + - chart-example.local + parentRefs: + # Group of the referent resource. + - group: gateway.networking.k8s.io + # Kind of the referent resource. + kind: Gateway + # Name of the referent resources + name: test + # Namespace of the referent resource + namespace: test diff --git a/charts/library/common-test/ci/schedule-values.yaml b/charts/library/common-test/ci/schedule-values.yaml new file mode 100644 index 00000000000..36a590d64d5 --- /dev/null +++ b/charts/library/common-test/ci/schedule-values.yaml @@ -0,0 +1,61 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +schedules: + test: + enabled: true + schedule: "0 0 * * *" + test2: + enabled: true + labels: + myenv: foo + annotations: + myenv: foo + schedule: "0 0 * * *" + useOwnerReferencesInBackup: false + template: + ttl: "240h" + storageLocation: default + test3: + enabled: true + schedule: "0 0 * * *" + template: + ttl: "240h" + storageLocation: default + includedNamespaces: + - foo diff --git a/charts/library/common-test/ci/secrets-values.yaml b/charts/library/common-test/ci/secrets-values.yaml new file mode 100644 index 00000000000..fa5270a988b --- /dev/null +++ b/charts/library/common-test/ci/secrets-values.yaml @@ -0,0 +1,72 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + + +key1: value1 +key2: 80 +key3: pair +key4: value2 +key5: 81 +key6: false + +envFrom: + - secretRef: + name: kv-test + +secret: + kv-test: + enabled: true + data: + key: "{{ .Values.key1 }}" + key1: "{{ .Values.key4 }}" + key2: "{{ .Values.key5 }}" + key3: "{{ .Values.key6 }}" + + file-test: + enabled: true + data: + nginx.conf2: | + alias {{ .Values.key3 }} + listen {{ .Values.key2 }} + function { + # some json + "key": { + "key2": "value", + "key3": "value2" + } + } diff --git a/charts/library/common-test/ci/solr-values.yaml b/charts/library/common-test/ci/solr-values.yaml new file mode 100644 index 00000000000..be25f2b0222 --- /dev/null +++ b/charts/library/common-test/ci/solr-values.yaml @@ -0,0 +1,28 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +solr: + enabled: true diff --git a/charts/library/common-test/ci/statefulset-values.yaml b/charts/library/common-test/ci/statefulset-values.yaml new file mode 100644 index 00000000000..5f2cdfc1c56 --- /dev/null +++ b/charts/library/common-test/ci/statefulset-values.yaml @@ -0,0 +1,45 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +persistence: + data: + enabled: true + mountPath: /data + type: vct + accessMode: "ReadWriteOnce" + size: 1Gi diff --git a/charts/library/common-test/ci/storageclass-values.yaml b/charts/library/common-test/ci/storageclass-values.yaml new file mode 100644 index 00000000000..a8683758dc3 --- /dev/null +++ b/charts/library/common-test/ci/storageclass-values.yaml @@ -0,0 +1,62 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +# -- create storageClasses on demand +storageClass: + example1: + enabled: true + provisioner: some.provisioner.io + example2: + enabled: true + provisioner: some.provisioner.io + reclaimPolicy: retain + allowVolumeExpansion: true + volumeBindingMode: Immediate + example3: + enabled: true + provisioner: some.provisioner.io + parameters: {} + mountOptions: [] + example4: + enabled: true + provisioner: some.provisioner.io + parameters: {} + reclaimPolicy: retain + allowVolumeExpansion: true + volumeBindingMode: Immediate + mountOptions: [] diff --git a/charts/library/common-test/ci/volsync-dest-values.yaml b/charts/library/common-test/ci/volsync-dest-values.yaml new file mode 100644 index 00000000000..498cf38aa7b --- /dev/null +++ b/charts/library/common-test/ci/volsync-dest-values.yaml @@ -0,0 +1,60 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +persistence: + destbackup: + enabled: true + type: pvc + mountPath: /backedup + targetSelectAll: true + volsync: + - name: mybackup + type: restic + credentials: mys3 + dest: + enabled: true + src: + enabled: false + +credentials: + mys3: + type: s3 + url: "test" + bucket: "test" + accessKey: "test" + secretKey: "test" + encrKey: "test" diff --git a/charts/library/common-test/ci/volsync-src-values.yaml b/charts/library/common-test/ci/volsync-src-values.yaml new file mode 100644 index 00000000000..b5293c33ea3 --- /dev/null +++ b/charts/library/common-test/ci/volsync-src-values.yaml @@ -0,0 +1,60 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +persistence: + srcbackup: + enabled: true + type: pvc + mountPath: /backedup + targetSelectAll: true + volsync: + - name: mybackup + type: restic + credentials: mys3 + dest: + enabled: false + src: + enabled: true + +credentials: + mys3: + type: s3 + url: "test" + bucket: "test" + accessKey: "test" + secretKey: "test" + encrKey: "test" diff --git a/charts/library/common-test/ci/volumesnapshotlocation-values.yaml b/charts/library/common-test/ci/volumesnapshotlocation-values.yaml new file mode 100644 index 00000000000..6eed1b745d5 --- /dev/null +++ b/charts/library/common-test/ci/volumesnapshotlocation-values.yaml @@ -0,0 +1,53 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +# Parameters for the VolumeSnapshotLocation(s). Configure multiple by adding other element(s) to the volumeSnapshotLocation slice. +# See https://velero.io/docs/v1.6/api-types/volumesnapshotlocation/ +volumeSnapshotLocation: + test: + enabled: true + # provider is the name for the volume snapshot provider. + provider: aws + credential: + # AWS/s3 credentials to be put into secret (mandatory if provider == aws/s3) + aws: + id: fdgsdfghsdfgh + key: dfgdfhsdfgh + # Additional provider-specific configuration. See link above + # for details of required/optional fields for your provider. + config: {} diff --git a/charts/library/common-test/ci/vpn-gluetun-values.yaml b/charts/library/common-test/ci/vpn-gluetun-values.yaml new file mode 100644 index 00000000000..c5e59646ea9 --- /dev/null +++ b/charts/library/common-test/ci/vpn-gluetun-values.yaml @@ -0,0 +1,73 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#wireguard-vpn) + # @default -- See values.yaml + vpn: + # -- Specify the VPN type. Valid options are disabled, gluetun or tailscale + type: gluetun + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: + something: UTC + + + # -- you can directly specify the config file here + config: "fdgdfsg" + + scripts: + # -- you can directly specify the upscript here + up: "sffds" + # some script + + # -- you can directly specify the downscript here + down: "fsdfds" + # some script + + # -- select pods to bind vpn addon to + targetSelector: + - main diff --git a/charts/library/common-test/ci/vpn-openvpn-values.yaml b/charts/library/common-test/ci/vpn-openvpn-values.yaml new file mode 100644 index 00000000000..c7cf11447f4 --- /dev/null +++ b/charts/library/common-test/ci/vpn-openvpn-values.yaml @@ -0,0 +1,81 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#wireguard-vpn) + # @default -- See values.yaml + vpn: + # -- Specify the VPN type. Valid options are disabled, gluetun or tailscale + type: openvpn + + # -- OpenVPN specific configuration + # @default -- See below + openvpn: + # -- Credentials to connect to the VPN Service (used with -a) + # Only using password is enough + username: "testuser" + password: "testpass" + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: + something: UTC + + + # -- you can directly specify the config file here + config: "fdgdfsg" + + scripts: + # -- you can directly specify the upscript here + up: "sffds" + # some script + + # -- you can directly specify the downscript here + down: "fsdfds" + # some script + + # -- select pods to bind vpn addon to + targetSelector: + - main diff --git a/charts/library/common-test/ci/vpn-tailscale-values.yaml b/charts/library/common-test/ci/vpn-tailscale-values.yaml new file mode 100644 index 00000000000..19aee245e3d --- /dev/null +++ b/charts/library/common-test/ci/vpn-tailscale-values.yaml @@ -0,0 +1,60 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#wireguard-vpn) + # @default -- See values.yaml + vpn: + # -- Specify the VPN type. Valid options are disabled, gluetun or tailscale + type: tailscale + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: + something: UTC + + # -- select pods to bind vpn addon to + targetSelector: + - main diff --git a/charts/library/common-test/ci/vpn-wireguard-values.yaml b/charts/library/common-test/ci/vpn-wireguard-values.yaml new file mode 100644 index 00000000000..2f060c31727 --- /dev/null +++ b/charts/library/common-test/ci/vpn-wireguard-values.yaml @@ -0,0 +1,73 @@ +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + port: 8080 + +workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: http + port: "{{ .Values.service.main.ports.main.port }}" + +args: + - --port + - '8080' + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#wireguard-vpn) + # @default -- See values.yaml + vpn: + # -- Specify the VPN type. Valid options are disabled, gluetun or tailscale + type: wireguard + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: + something: UTC + + + # -- you can directly specify the config file here + config: "fdgdfsg" + + scripts: + # -- you can directly specify the upscript here + up: "sffds" + # some script + + # -- you can directly specify the downscript here + down: "fsdfds" + # some script + + # -- select pods to bind vpn addon to + targetSelector: + - main diff --git a/charts/library/common-test/default-values.yaml b/charts/library/common-test/default-values.yaml new file mode 100644 index 00000000000..65ef08337a7 --- /dev/null +++ b/charts/library/common-test/default-values.yaml @@ -0,0 +1,15 @@ +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + +service: + main: + enabled: true + ports: + main: + enabled: true + port: 80 diff --git a/charts/library/common-test/templates/NOTES.txt b/charts/library/common-test/templates/NOTES.txt new file mode 100644 index 00000000000..efcb74cb772 --- /dev/null +++ b/charts/library/common-test/templates/NOTES.txt @@ -0,0 +1 @@ +{{- include "tc.v1.common.lib.chart.notes" $ -}} diff --git a/charts/library/common-test/templates/common.yaml b/charts/library/common-test/templates/common.yaml new file mode 100644 index 00000000000..038688831db --- /dev/null +++ b/charts/library/common-test/templates/common.yaml @@ -0,0 +1 @@ +{{- include "tc.v1.common.loader.all" . -}} diff --git a/charts/library/common-test/tests/addons/autoperms_test.yaml b/charts/library/common-test/tests/addons/autoperms_test.yaml new file mode 100644 index 00000000000..fb115275e78 --- /dev/null +++ b/charts/library/common-test/tests/addons/autoperms_test.yaml @@ -0,0 +1,428 @@ +suite: auto perms test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should render permissions job + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + persistence: + test1: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chown: true + chmod: 770 + recursive: true + mountPath: /test1 + hostPath: /testhost1 + test2: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chown: true + chmod: 770 + recursive: false + mountPath: /test2 + hostPath: /testhost2 + test3: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chmod: 770 + mountPath: /test3 + hostPath: /testhost3 + test4: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chown: true + mountPath: /test4 + hostPath: /testhost4 + # Should not appear + test5: + enabled: true + type: hostPath + mountPath: /test5 + hostPath: /testhost5 + test6: + enabled: true + type: hostPath + targetSelectAll: true + mountPath: /test6 + hostPath: /testhost6 + autoPermissions: + enabled: true + chown: true + chmod: 770 + recursive: true + user: 1000 + group: 1000 + test7: + enabled: true + type: emptyDir + autoPermissions: + enabled: true + chown: true + chmod: 770 + recursive: true + mountPath: /test7 + test9: + enabled: true + type: nfs + server: 1.1.1.1 + path: /share + autoPermissions: + enabled: true + chown: true + mountPath: /test9 + # Should not show up + test10: + enabled: false + type: hostPath + hostPath: /testhost10 + autoPermissions: + enabled: true + chown: true + mountPath: /test10 + + asserts: + - documentIndex: &jobDoc 0 + isKind: + of: Job + - documentIndex: *jobDoc + equal: + path: spec.template.spec.containers[0].securityContext + value: + runAsUser: 0 + runAsGroup: 568 + runAsNonRoot: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test1 + hostPath: + path: /testhost1 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test2 + hostPath: + path: /testhost2 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test3 + hostPath: + path: /testhost3 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test4 + hostPath: + path: /testhost4 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test6 + hostPath: + path: /testhost6 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test7 + emptyDir: {} + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: test9 + nfs: + server: 1.1.1.1 + path: /share + - documentIndex: *jobDoc + contains: + path: spec.template.spec.volumes + content: + name: tmp + emptyDir: + medium: Memory + sizeLimit: 8Gi + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test1 + mountPath: /mounts/test1 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test2 + mountPath: /mounts/test2 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test3 + mountPath: /mounts/test3 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test4 + mountPath: /mounts/test4 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test6 + mountPath: /mounts/test6 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test7 + mountPath: /mounts/test7 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test9 + mountPath: /mounts/test9 + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: tmp + mountPath: /tmp + readOnly: false + - documentIndex: *jobDoc + equal: + path: spec.template.spec.containers[0].command + value: + - /bin/sh + - -c + - documentIndex: *jobDoc + equal: + path: spec.template.spec.containers[0].args + value: + - |- + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + echo "Automatically correcting permissions for /mounts/test1..." + before=$(stat -c "%a" /mounts/test1) + chmod -R 770 /mounts/test1 || echo "Failed setting permissions using chmod..." + echo "Permissions before: [$before]" + echo "Permissions after: [$(stat -c "%a" /mounts/test1)]" + echo "" + echo "Automatically correcting ownership for /mounts/test1..." + before=$(stat -c "%u:%g" /mounts/test1) + chown -R -f :568 /mounts/test1 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test1)]" + echo "" + echo "Automatically correcting permissions for /mounts/test2..." + before=$(stat -c "%a" /mounts/test2) + chmod 770 /mounts/test2 || echo "Failed setting permissions using chmod..." + echo "Permissions before: [$before]" + echo "Permissions after: [$(stat -c "%a" /mounts/test2)]" + echo "" + echo "Automatically correcting ownership for /mounts/test2..." + before=$(stat -c "%u:%g" /mounts/test2) + chown -f :568 /mounts/test2 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test2)]" + echo "" + echo "Automatically correcting permissions for /mounts/test3..." + before=$(stat -c "%a" /mounts/test3) + chmod 770 /mounts/test3 || echo "Failed setting permissions using chmod..." + echo "Permissions before: [$before]" + echo "Permissions after: [$(stat -c "%a" /mounts/test3)]" + echo "" + echo "Automatically correcting ownership for /mounts/test4..." + before=$(stat -c "%u:%g" /mounts/test4) + chown -f :568 /mounts/test4 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test4)]" + echo "" + echo "Automatically correcting permissions for /mounts/test6..." + before=$(stat -c "%a" /mounts/test6) + chmod -R 770 /mounts/test6 || echo "Failed setting permissions using chmod..." + echo "Permissions before: [$before]" + echo "Permissions after: [$(stat -c "%a" /mounts/test6)]" + echo "" + echo "Automatically correcting ownership for /mounts/test6..." + before=$(stat -c "%u:%g" /mounts/test6) + chown -R -f 1000:1000 /mounts/test6 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test6)]" + echo "" + echo "Automatically correcting permissions for /mounts/test7..." + before=$(stat -c "%a" /mounts/test7) + chmod -R 770 /mounts/test7 || echo "Failed setting permissions using chmod..." + echo "Permissions before: [$before]" + echo "Permissions after: [$(stat -c "%a" /mounts/test7)]" + echo "" + echo "Automatically correcting ownership for /mounts/test7..." + before=$(stat -c "%u:%g" /mounts/test7) + chown -R -f :568 /mounts/test7 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test7)]" + echo "" + echo "Automatically correcting ownership for /mounts/test9..." + before=$(stat -c "%u:%g" /mounts/test9) + chown -f :568 /mounts/test9 || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/test9)]" + echo "" + echo "Finished auto permissions job..." + + + - it: should have different resources + set: + resources: + limits: + nvidia.com/gpu: 1 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name: + enabled: true + primary: true + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + persistence: + test1: + enabled: true + type: hostPath + autoPermissions: + enabled: true + chown: true + chmod: 770 + recursive: true + mountPath: /test1 + hostPath: /testhost1 + asserts: + - documentIndex: &jobDoc 0 + isKind: + of: Job + - documentIndex: &deploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.containers[0].resources + value: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + - documentIndex: *jobDoc + equal: + path: spec.template.spec.containers[0].resources + value: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 2000m + memory: 2Gi + + # Failures + - it: should fail trying to set ownership on non hostPath + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + persistence: + test: + enabled: true + type: device + hostPath: /test + autoPermissions: + enabled: true + chown: true + asserts: + - failedTemplate: + errorMessage: Auto Permissions - Allowed persistent types for auto permissions are [hostPath, emptyDir, nfs], but got [device] on [test] + + - it: should fail trying to set permissions on readOnly + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + persistence: + test: + enabled: true + type: hostPath + hostPath: /test + readOnly: true + autoPermissions: + enabled: true + chmod: 770 + asserts: + - failedTemplate: + errorMessage: Auto Permissions - You cannot change permissions/ownership automatically on [test] with readOnly enabled diff --git a/charts/library/common-test/tests/addons/codeserver_test.yaml b/charts/library/common-test/tests/addons/codeserver_test.yaml new file mode 100644 index 00000000000..743f4c354b3 --- /dev/null +++ b/charts/library/common-test/tests/addons/codeserver_test.yaml @@ -0,0 +1,316 @@ +suite: addon codeserver +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: addon enabled should pass + set: + workload: &workload + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + addons: + codeserver: + enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: &AddonServiceDocument 1 + isKind: + of: Service + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test-codeserver + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test + - documentIndex: *ServiceDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *AddonServiceDocument + equal: + path: metadata.name + value: test-release-name-common-test-codeserver + + - it: addon enabled should pass without other service + set: + workload: *workload + resources: + limits: + nvidia.com/gpu: 1 + service: + main: + enabled: false + addons: + codeserver: + enabled: true + service: + enabled: true + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: &AddonServiceDocument 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test-codeserver + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *AddonServiceDocument + equal: + path: metadata.name + value: test-release-name-common-test + + - it: addon enabled should pass and mount volume with targetSelector on other container only + set: + workload: *workload + persistence: + data: + enabled: true + type: emptyDir + targetSelector: + main: + main: + mountPath: /data + readOnly: true + data2: + enabled: true + type: emptyDir + mountPath: /some/path + targetSelector: + main: + main: + readOnly: false + addons: + codeserver: + enabled: true + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test-codeserver + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /data + name: data + readOnly: true + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /some/path + name: data2 + readOnly: false + + - it: should apply ingress settings without primary + set: + workload: *workload + addons: + codeserver: + enabled: true + service: + enabled: true + type: LoadBalancer + ports: + codeserver: + port: 30067 + ingress: + enabled: true + hosts: + - host: code.chart-example.local + paths: + - path: / + integrations: + traefik: + enabled: false + asserts: + - documentIndex: &serviceDocument 1 + isKind: + of: Service + - documentIndex: *serviceDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *serviceDocument + equal: + path: spec.ports[0].port + value: 30067 + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].host + value: code.chart-example.local + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].path + value: / + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend.service.name + value: test-release-name-common-test + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend.service.port.number + value: 30067 + + - it: should apply ingress settings with primary + set: + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + ingress: + my-ing: + enabled: true + primary: true + hosts: + - host: chart-example.local + paths: + - path: / + integrations: + traefik: + enabled: false + addons: + codeserver: + enabled: true + service: + enabled: true + type: LoadBalancer + ports: + codeserver: + port: 30067 + ingress: + enabled: true + hosts: + - host: code.chart-example.local + paths: + - path: / + integrations: + traefik: + enabled: false + asserts: + - documentIndex: &serviceDocument 1 + isKind: + of: Service + - documentIndex: *serviceDocument + equal: + path: metadata.name + value: test-release-name-common-test-codeserver + - documentIndex: *serviceDocument + equal: + path: spec.ports[0].port + value: 30067 + - documentIndex: &IngressDocument 3 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: metadata.name + value: test-release-name-common-test-codeserver + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].host + value: code.chart-example.local + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].path + value: / + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend.service.name + value: test-release-name-common-test-codeserver + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend.service.port.number + value: 30067 diff --git a/charts/library/common-test/tests/addons/netshoot_test.yaml b/charts/library/common-test/tests/addons/netshoot_test.yaml new file mode 100644 index 00000000000..c2df2c686a7 --- /dev/null +++ b/charts/library/common-test/tests/addons/netshoot_test.yaml @@ -0,0 +1,82 @@ +suite: addon netshoot +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: addon enabled should pass + set: + resources: + limits: + nvidia.com/gpu: 1 + workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + addons: + netshoot: + enabled: true + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-netshoot + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *ServiceDocument + equal: + path: metadata.name + value: test-release-name-common-test diff --git a/charts/library/common-test/tests/addons/vpn_test.yaml b/charts/library/common-test/tests/addons/vpn_test.yaml new file mode 100644 index 00000000000..5d28880b79d --- /dev/null +++ b/charts/library/common-test/tests/addons/vpn_test.yaml @@ -0,0 +1,964 @@ +suite: addon vpn +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: addon vpn gluetun enabled with config and env should pass + set: + resources: + limits: + nvidia.com/gpu: 1 + addons: + vpn: + type: gluetun + config: | + some vpn config + with multiple lines + env: + key: value + key1: value1 + envList: + - name: key2 + value: value2 + - name: key3 + value: value3 + workload: &workload + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 3 + - documentIndex: &SecretDocument 0 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *SecretDocument + equal: + path: metadata.name + value: test-release-name-common-test-vpnconfig + - documentIndex: *SecretDocument + equal: + path: stringData + value: + vpn.conf: |- + some vpn config + with multiple lines + - documentIndex: *DeploymentDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *ServiceDocument + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].env + content: + name: key + value: value + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].env + content: + name: key1 + value: value1 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key + value: value + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key1 + value: value1 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key2 + value: value2 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key3 + value: value3 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + secret: + secretName: test-release-name-common-test-vpnconfig + defaultMode: 0777 + optional: false + items: + - key: vpn.conf + path: vpn.conf + + - it: addon vpn gluetun enabled with scripts added + set: + addons: + vpn: + type: gluetun + config: | + some vpn config + with multiple lines + scripts: + up: | + echo "up" + echo "done" + down: | + echo "down" + echo "done" + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 4 + - documentIndex: &ConfigMapDocument 0 + isKind: + of: ConfigMap + - documentIndex: &SecretDocument 1 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 2 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 3 + isKind: + of: Service + - documentIndex: *SecretDocument + equal: + path: metadata.name + value: test-release-name-common-test-vpnconfig + - documentIndex: *ConfigMapDocument + equal: + path: metadata.name + value: test-release-name-common-test-vpnscripts + - documentIndex: *ConfigMapDocument + equal: + path: data + value: + up.sh: |- + echo "up" + echo "done" + down.sh: |- + echo "down" + echo "done" + - documentIndex: *SecretDocument + equal: + path: stringData + value: + vpn.conf: |- + some vpn config + with multiple lines + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnscripts + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnscripts + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + secret: + secretName: test-release-name-common-test-vpnconfig + defaultMode: 0777 + optional: false + items: + - key: vpn.conf + path: vpn.conf + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnscripts + configMap: + name: vpnscripts + defaultMode: 0777 + optional: false + items: + - key: up.sh + path: up.sh + - key: down.sh + path: down.sh + + - it: addon vpn gluetun enabled with existing secret + set: + addons: + vpn: + type: gluetun + existingSecret: existing-secret + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + secret: + secretName: existing-secret + defaultMode: 0777 + optional: false + items: + - key: vpn.conf + path: vpn.conf + + - it: addon vpn gluetun enabled with configFile + set: + addons: + vpn: + type: gluetun + configFile: /path/to/file + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 3 + - documentIndex: &JobDocument 0 + isKind: + of: Job + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *JobDocument + equal: + path: metadata.name + value: test-release-name-common-test-autopermissions + - documentIndex: *JobDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File + - documentIndex: *JobDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /mounts/vpnconfig + readOnly: false + - documentIndex: *JobDocument + equal: + path: spec.template.spec.containers[0].args + value: + - |- + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + echo "Automatically correcting ownership for /mounts/vpnconfig..." + before=$(stat -c "%u:%g" /mounts/vpnconfig) + chown -f 568:568 /mounts/vpnconfig || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/vpnconfig)]" + echo "" + echo "Finished auto permissions job..." + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /gluetun/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File + + - it: addon vpn gluetun enabled with configFolder + set: + addons: + vpn: + type: gluetun + configFolder: /path/to/folder + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 3 + - documentIndex: &JobDocument 0 + isKind: + of: Job + - documentIndex: *JobDocument + equal: + path: metadata.name + value: test-release-name-common-test-autopermissions + - documentIndex: *JobDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnfolder + hostPath: + path: /path/to/folder + - documentIndex: *JobDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnfolder + mountPath: /mounts/vpnfolder + readOnly: false + - documentIndex: *JobDocument + equal: + path: spec.template.spec.containers[0].args + value: + - |- + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + echo "Automatically correcting ownership for /mounts/vpnfolder..." + before=$(stat -c "%u:%g" /mounts/vpnfolder) + chown -f 568:568 /mounts/vpnfolder || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/vpnfolder)]" + echo "" + echo "Finished auto permissions job..." + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnfolder + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnfolder + mountPath: /gluetun + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnfolder + hostPath: + path: /path/to/folder + + - it: tailscale addon enabled with authkey should pass + set: + resources: + limits: + nvidia.com/gpu: 1 + addons: + vpn: + type: tailscale + tailscale: + authkey: something + userspace: true + env: + key: value + key1: value1 + workload: *workload + asserts: + - hasDocuments: + count: 1 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.automountServiceAccountToken + value: true + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-tailscale + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_KUBE_SECRET + value: "" + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_SOCKET + value: /var/run/tailscale/tailscaled.sock + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_STATE_DIR + value: /var/lib/tailscale/state + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_AUTH_ONCE + value: "true" + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_USERSPACE + value: "true" + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_ACCEPT_DNS + value: "false" + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: TS_AUTH_KEY + value: something + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].env + content: + name: key + value: value + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].env + content: + name: key1 + value: value1 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key + value: value + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].env + content: + name: key1 + value: value1 + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: tailscalestate + mountPath: /var/lib/tailscale + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: tailscalestate + mountPath: /var/lib/tailscale + readOnly: false + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: tailscalestate + emptyDir: {} + + - it: tailscale addon enabled with authkey without userspace should pass + set: + addons: + vpn: + type: tailscale + tailscale: + authkey: something + userspace: false + key1: value1 + workload: *workload + asserts: + - hasDocuments: + count: 1 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-tailscale + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1].securityContext + content: + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: false + runAsUser: 0 + runAsGroup: 0 + + - it: addon vpn openvpn enabled with configFile + set: + resources: + limits: + nvidia.com/gpu: 1 + addons: + vpn: + type: openvpn + configFile: /path/to/file + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 3 + - documentIndex: &JobDocument 0 + isKind: + of: Job + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *JobDocument + equal: + path: metadata.name + value: test-release-name-common-test-autopermissions + - documentIndex: *JobDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File + - documentIndex: *JobDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /mounts/vpnconfig + readOnly: false + - documentIndex: *JobDocument + equal: + path: spec.template.spec.containers[0].args + value: + - |- + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + echo "Automatically correcting ownership for /mounts/vpnconfig..." + before=$(stat -c "%u:%g" /mounts/vpnconfig) + chown -f 568:568 /mounts/vpnconfig || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/vpnconfig)]" + echo "" + echo "Finished auto permissions job..." + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /vpn/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /vpn/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File + + - it: addon vpn wireguard enabled with configFile + set: + resources: + limits: + nvidia.com/gpu: 1 + addons: + vpn: + type: wireguard + configFile: /path/to/file + workload: *workload + service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 8080 + asserts: + - hasDocuments: + count: 3 + - documentIndex: &JobDocument 0 + isKind: + of: Job + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &ServiceDocument 2 + isKind: + of: Service + - documentIndex: *JobDocument + equal: + path: metadata.name + value: test-release-name-common-test-autopermissions + - documentIndex: *JobDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File + - documentIndex: *JobDocument + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /mounts/vpnconfig + readOnly: false + - documentIndex: *JobDocument + equal: + path: spec.template.spec.containers[0].args + value: + - |- + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + echo "Automatically correcting ownership for /mounts/vpnconfig..." + before=$(stat -c "%u:%g" /mounts/vpnconfig) + chown -f 568:568 /mounts/vpnconfig || echo "Failed setting ownership using chown..." + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" /mounts/vpnconfig)]" + echo "" + echo "Finished auto permissions job..." + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[0].name + value: test-release-name-common-test + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: vpnconfig + mountPath: /etc/wireguard/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: vpnconfig + mountPath: /etc/wireguard/vpn.conf + readOnly: false + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: test-release-name-common-test-vpn + - documentIndex: *DeploymentDocument + isSubset: + path: spec.template.spec.containers[1] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /path/to/file + type: File diff --git a/charts/library/common-test/tests/certificate/data_test.yaml b/charts/library/common-test/tests/certificate/data_test.yaml new file mode 100644 index 00000000000..2768ed31c81 --- /dev/null +++ b/charts/library/common-test/tests/certificate/data_test.yaml @@ -0,0 +1,107 @@ +suite: certificate data test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with certificate created + set: + issuer: some-issuer + host: host1 + certificate: + my-certificate1: + enabled: true + hosts: + - "{{ .Values.host }}" + certificateIssuer: "{{ .Values.issuer }}" + my-certificate2: + enabled: true + hosts: + - host2 + - "*.host2.com" + certificateIssuer: some-other-issuer + certificateSecretTemplate: + labels: + label1: label1 + label2: label2 + annotations: + annotation1: annotation1 + annotation2: annotation2 + asserts: + - documentIndex: &certDoc 0 + isKind: + of: Certificate + - documentIndex: *certDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *certDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-certificate1 + - documentIndex: *certDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *certDoc + equal: + path: spec + value: + secretName: test-release-name-common-test-my-certificate1 + dnsNames: + - host1 + issuerRef: + name: some-issuer + kind: ClusterIssuer + group: cert-manager.io + privateKey: + algorithm: ECDSA + size: 256 + rotationPolicy: Always + - documentIndex: &otherCertDoc 1 + isKind: + of: Certificate + - documentIndex: *otherCertDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *otherCertDoc + equal: + path: spec + value: + secretName: certificate-issuer-my-certificate2 + dnsNames: + - host2 + - "*.host2.com" + issuerRef: + name: some-other-issuer + kind: ClusterIssuer + group: cert-manager.io + privateKey: + algorithm: ECDSA + size: 256 + rotationPolicy: Always + secretTemplate: + labels: + label1: label1 + label2: label2 + app: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: v9.9.9 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: test-release-name + annotations: + annotation1: annotation1 + annotation2: annotation2 + - documentIndex: *otherCertDoc + equal: + path: metadata.name + value: certificate-issuer-my-certificate2 + - documentIndex: *otherCertDoc + equal: + path: metadata.namespace + value: test-release-namespace diff --git a/charts/library/common-test/tests/certificate/metadata_test.yaml b/charts/library/common-test/tests/certificate/metadata_test.yaml new file mode 100644 index 00000000000..b7c4e18ae4a --- /dev/null +++ b/charts/library/common-test/tests/certificate/metadata_test.yaml @@ -0,0 +1,215 @@ +suite: certificate metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with certificate created with labels and annotations + set: + label1: label1 + label2: global_label2 + label3: label3 + annotation1: annotation1 + annotation2: global_annotation2 + annotation3: annotation3 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + certificate: + my-certificate1: + enabled: true + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + hosts: + - host1 + certificateIssuer: some-issuer + my-certificate2: + enabled: true + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + hosts: + - host1 + certificateIssuer: some-issuer + certificateSecretTemplate: + labels: + label3: "{{ .Values.label3 }}" + label4: label4 + annotations: + annotation3: "{{ .Values.annotation3 }}" + annotation4: annotation4 + asserts: + - documentIndex: &certDoc 0 + isKind: + of: Certificate + - documentIndex: *certDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *certDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *certDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *certDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-certificate1 + - documentIndex: *certDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - documentIndex: &otherCertDoc 1 + isKind: + of: Certificate + - documentIndex: *otherCertDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *otherCertDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + - documentIndex: *otherCertDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + - documentIndex: *otherCertDoc + equal: + path: metadata.name + value: certificate-issuer-my-certificate2 + - documentIndex: *otherCertDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *otherCertDoc + equal: + path: spec.secretTemplate.annotations + value: + annotation3: annotation3 + annotation4: annotation4 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + - documentIndex: *otherCertDoc + equal: + path: spec.secretTemplate.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label3: label3 + label4: label4 + + - it: should pass with certificate created with namespace from tpl + set: + key: some-namespace + certificate: + my-cert1: + enabled: true + namespace: "{{ .Values.key }}" + hosts: + - host1 + certificateIssuer: some-issuer + asserts: + - documentIndex: *certDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with certificate created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + certificate: + my-cert1: + enabled: true + hosts: + - host1 + certificateIssuer: some-issuer + asserts: + - documentIndex: *certDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with certificate created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + certificate: + my-cert1: + enabled: true + hosts: + - host1 + certificateIssuer: some-issuer + asserts: + - documentIndex: *certDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/certificate/name_test.yaml b/charts/library/common-test/tests/certificate/name_test.yaml new file mode 100644 index 00000000000..31ff78c37b6 --- /dev/null +++ b/charts/library/common-test/tests/certificate/name_test.yaml @@ -0,0 +1,46 @@ +suite: certificate name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + certificate: + my-cert1: + enabled: true + hosts: + - host1 + certificateIssuer: some-issuer + my-cert2: + enabled: true + hosts: + - host1 + certificateIssuer: some-issuer + certificateSecretTemplate: + labels: + some-label: my-cert2 + annotations: + some-annotation: my-cert2 + asserts: + - documentIndex: &certDoc 0 + isKind: + of: Certificate + - documentIndex: *certDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *certDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-cert1 + - documentIndex: &otherCertDoc 1 + isKind: + of: Certificate + - documentIndex: *otherCertDoc + isAPIVersion: + of: cert-manager.io/v1 + - documentIndex: *otherCertDoc + equal: + path: metadata.name + value: certificate-issuer-my-cert2 diff --git a/charts/library/common-test/tests/certificate/validation_test.yaml b/charts/library/common-test/tests/certificate/validation_test.yaml new file mode 100644 index 00000000000..b923af14874 --- /dev/null +++ b/charts/library/common-test/tests/certificate/validation_test.yaml @@ -0,0 +1,187 @@ +suite: certificate validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with name longer than 253 characters + set: + certificate: + my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-long-long-long-long-long-long-long-name: + enabled: true + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-name-that-is-longer-than-253-characters-my-certificate-super-long-long-long-long-long-long-long-long-name] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with name starting with underscore + set: + certificate: + _my-cert: + enabled: true + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-_my-cert] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with namespace longer than 63 characters + set: + certificate: + my-certificate: + enabled: true + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + certificateIssuer: some-issuer + hosts: + - test-host + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. + + - it: should fail with labels not a dict + set: + certificate: + my-cert: + enabled: true + labels: "not a dict" + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected [labels] to be a dictionary, but got [string] + + - it: should fail with annotations not a dict + set: + certificate: + my-certificate: + enabled: true + annotations: "not a dict" + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected [annotations] to be a dictionary, but got [string] + + - it: should fail with empty enabled + set: + certificate: + my-certificate: + enabled: + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected the defined key [enabled] in [certificate.my-certificate] to not be empty + + - it: should fail if certificateIssuer is missing + set: + certificate: + my-cert: + enabled: true + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected non-empty [certificateIssuer] + + - it: should fail if hosts are empty + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: [] + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected non-empty [hosts] + + - it: should fail if hosts is not slice + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: not-a-slice + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected [hosts] to be a [slice], but got [string] + + - it: should fail if hosts entry is empty + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - "" + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected non-empty entry in [hosts] + + - it: should fail if hosts entry starts with https:// + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - https://test-host + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected entry in [hosts] to not start with [https://], but got [https://test-host] + + - it: should fail if hosts entry starts with http:// + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - http://test-host + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected entry in [hosts] to not start with [http://], but got [http://test-host] + + - it: should fail if hosts entry contains ":" + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - test-host:123 + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected entry in [hosts] to not contain [:], but got [test-host:123] + + - it: should fail if certificateSecretTemplate missing both labels and annotations + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - test-host + certificateSecretTemplate: + some-key: some-value + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate - Expected [certificateSecretTemplate] to have at least one of [labels, annotations] + + - it: should fail if certificateSecretTemplate labels are not a map + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - test-host + certificateSecretTemplate: + labels: "not a map" + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate (certificateSecretTemplate) - Expected [labels] to be a dictionary, but got [string] + + - it: should fail if certificateSecretTemplate annotations are not a map + set: + certificate: + my-cert: + enabled: true + certificateIssuer: some-issuer + hosts: + - test-host + certificateSecretTemplate: + annotations: "not a map" + asserts: + - failedTemplate: + errorMessage: Cert Manager Certificate (certificateSecretTemplate) - Expected [annotations] to be a dictionary, but got [string] diff --git a/charts/library/common-test/tests/chartContext/data_test.yaml b/charts/library/common-test/tests/chartContext/data_test.yaml new file mode 100644 index 00000000000..b6d271a0274 --- /dev/null +++ b/charts/library/common-test/tests/chartContext/data_test.yaml @@ -0,0 +1,323 @@ +suite: chart context data test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with service default values + set: + createChartContextConfigmap: true + enabled: true + port: 12345 + service: + my-service: + enabled: "{{ .Values.enabled }}" + primary: true + ports: + my-port: + enabled: "{{ .Values.enabled }}" + primary: true + port: "{{ .Values.port }}" + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: http://127.0.0.1:12345 + appUrlWithPortAndPath: http://127.0.0.1:12345/ + appHost: "127.0.0.1" + appPort: "12345" + appPath: / + appProtocol: http + + - it: should pass with service loadBalancer values + set: + createChartContextConfigmap: true + ip: 1.2.3.4 + service: + my-service: + enabled: true + primary: true + type: LoadBalancer + loadBalancerIP: "{{ .Values.ip }}" + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: http://1.2.3.4:12345 + appUrlWithPortAndPath: http://1.2.3.4:12345/ + appHost: "1.2.3.4" + appPort: "12345" + appPath: / + appProtocol: http + + - it: should pass with ingress + set: + createChartContextConfigmap: true + enabled: true + host: example.com + path: /some-path + ingress: + my-ingress: + enabled: "{{ .Values.enabled }}" + primary: true + integrations: + traefik: + enabled: false + hosts: + - host: "{{ .Values.host }}" + paths: + - path: "{{ .Values.path }}" + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: https://example.com + appUrlWithPortAndPath: https://example.com:443/some-path + appHost: "example.com" + appPort: "443" + appPath: /some-path + appProtocol: https + + - it: should pass with ingress and traefik integration + set: + createChartContextConfigmap: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: http://example.com + appUrlWithPortAndPath: http://example.com:80/some-path + appHost: "example.com" + appPort: "80" + appPath: /some-path + appProtocol: http + + - it: should pass with ingress and tls and traefik integration + set: + createChartContextConfigmap: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + tls: + - hosts: + - example.com + secretName: example-tls + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: https://example.com + appUrlWithPortAndPath: https://example.com:443/some-path + appHost: "example.com" + appPort: "443" + appPath: /some-path + appProtocol: https + + - it: should pass with ingress and tls and traefik integration + set: + createChartContextConfigmap: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + tls: + - hosts: + - example.com + secretName: example-tls + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: https://example.com + appUrlWithPortAndPath: https://example.com:443/some-path + appHost: "example.com" + appPort: "443" + appPath: /some-path + appProtocol: https + + - it: should pass with ingress and certManager integration and traefik integration + set: + createChartContextConfigmap: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: some-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-chart-context + - documentIndex: *configMapDoc + equal: + path: data + value: + podCIDR: 172.16.0.0/16 + svcCIDR: 172.17.0.0/16 + appUrl: https://example.com + appUrlWithPortAndPath: https://example.com:443/some-path + appHost: "example.com" + appPort: "443" + appPath: /some-path + appProtocol: https diff --git a/charts/library/common-test/tests/chartContext/portal_test.yaml b/charts/library/common-test/tests/chartContext/portal_test.yaml new file mode 100644 index 00000000000..b5d5aaf6cc4 --- /dev/null +++ b/charts/library/common-test/tests/chartContext/portal_test.yaml @@ -0,0 +1,731 @@ +suite: portal test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with service default values + set: + global: &global + namespace: ix-ns + enabled: true + port: 12345 + service: + my-service: + enabled: "{{ .Values.enabled }}" + primary: true + ports: + my-port: + enabled: "{{ .Values.enabled }}" + primary: true + port: "{{ .Values.port }}" + portal: + main: + enabled: "{{ .Values.enabled }}" + asserts: + - documentIndex: &configMapDoc 1 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: / + port: "12345" + protocol: http + url: http://127.0.0.1:12345/ + + - it: should pass with service loadBalancer values + set: + global: *global + ip: 1.2.3.4 + service: + my-service: + enabled: true + primary: true + type: LoadBalancer + loadBalancerIP: "{{ .Values.ip }}" + ports: + my-port: + enabled: true + primary: true + port: 12345 + portal: + main: + enabled: true + asserts: + - documentIndex: &configMapDoc 1 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 1.2.3.4 + path: / + port: "12345" + protocol: http + url: http://1.2.3.4:12345/ + + - it: should pass with ingress + set: + global: *global + portal: + main: + enabled: true + enabled: true + host: example.com + path: /some-path + ingress: + my-ingress: + enabled: "{{ .Values.enabled }}" + primary: true + integrations: + traefik: + enabled: false + hosts: + - host: "{{ .Values.host }}" + paths: + - path: "{{ .Values.path }}" + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "443" + protocol: https + url: https://example.com:443/some-path + + - it: should pass with ingress and traefik integration + set: + global: *global + portal: + main: + enabled: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "80" + protocol: http + url: http://example.com:80/some-path + + - it: should pass with ingress and tls and traefik integration + set: + global: *global + portal: + main: + enabled: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + tls: + - hosts: + - example.com + secretName: example-tls + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "443" + protocol: https + url: https://example.com:443/some-path + + - it: should pass with ingress and tls and traefik integration + set: + global: *global + portal: + main: + enabled: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + tls: + - hosts: + - example.com + secretName: example-tls + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "443" + protocol: https + url: https://example.com:443/some-path + + - it: should pass with ingress and certManager integration and traefik integration + set: + global: *global + portal: + main: + enabled: true + ingress: + my-ingress: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: some-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "443" + protocol: https + url: https://example.com:443/some-path + + - it: should pass with overrides + set: + global: *global + portal: + main: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "123" + ingress: + my-ingress: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: some-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: test.example.com + path: /some-path + port: "123" + protocol: http + url: http://test.example.com:123/some-path + + - it: should pass with overrides and multiple portals + set: + global: *global + portal: + main: + enabled: true + override: + protocol: "http" + host: "test.example.com" + port: "123" + other: + enabled: true + path: /some-other-path + override: + protocol: "http" + host: "test123.example.com" + port: "456" + ingress: + my-ingress: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: some-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: test.example.com + path: /some-path + port: "123" + protocol: http + url: http://test.example.com:123/some-path + - documentIndex: &configMapDoc 3 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-other + - documentIndex: *configMapDoc + equal: + path: data + value: + host: test123.example.com + path: /some-other-path + port: "456" + protocol: http + url: http://test123.example.com:456/some-other-path + + - it: should pass with targetSelector ingress and multiple portals + set: + global: *global + portal: + main: + enabled: true + other: + enabled: true + path: /some-other-path + targetSelector: + ingress: my-other-ingress + ingress: + my-ingress: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: some-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: example.com + paths: + - path: /some-path + my-other-ingress: + enabled: true + integrations: + certManager: + enabled: true + certificateIssuer: some-other-issuer + traefik: + enabled: true + entrypoints: + - web + enableFixedMiddlewares: false + hosts: + - host: some.other.example.com + paths: + - path: /some-other-path + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + asserts: + - documentIndex: &configMapDoc 3 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: example.com + path: /some-path + port: "443" + protocol: https + url: https://example.com:443/some-path + - documentIndex: &configMapDoc 4 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-other + - documentIndex: *configMapDoc + equal: + path: data + value: + host: some.other.example.com + path: /some-other-path + port: "443" + protocol: https + url: https://some.other.example.com:443/some-other-path + + - it: should pass with targetSelector service and multiple portals + set: + global: *global + portal: + main: + enabled: true + other: + enabled: true + path: /some-other-path + targetSelector: + service: my-other-service + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + my-other-service: + enabled: true + ports: + my-port: + enabled: true + primary: true + port: 123457 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: / + port: "12345" + protocol: http + url: http://127.0.0.1:12345/ + - documentIndex: &configMapDoc 3 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-other + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: /some-other-path + port: "123457" + protocol: http + url: http://127.0.0.1:123457/some-other-path + + - it: should pass with targetSelector service and port and multiple portals + set: + global: *global + portal: + main: + enabled: true + other: + enabled: true + path: /some-other-path + targetSelector: + service: my-other-service + port: my-other-port + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + my-other-service: + enabled: true + ports: + my-port: + enabled: true + primary: true + port: 123457 + my-other-port: + enabled: true + port: 123458 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: / + port: "12345" + protocol: http + url: http://127.0.0.1:12345/ + - documentIndex: &configMapDoc 3 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-other + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: /some-other-path + port: "123458" + protocol: http + url: http://127.0.0.1:123458/some-other-path + + - it: should pass with targetSelector service and multiple portals + set: + global: *global + portal: + main: + enabled: true + other: + enabled: true + path: /some-other-path + targetSelector: + service: my-other-service + port: "" + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: true + primary: true + port: 12345 + my-other-service: + enabled: true + ports: + my-port1: + enabled: true + port: 123457 + my-port2: + enabled: true + port: 123458 + asserts: + - documentIndex: &configMapDoc 2 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-main + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: / + port: "12345" + protocol: http + url: http://127.0.0.1:12345/ + - documentIndex: &configMapDoc 3 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.name + value: test-release-name-common-test-tcportal-other + - documentIndex: *configMapDoc + equal: + path: data + value: + host: 127.0.0.1 + path: /some-other-path + port: "123457" + protocol: http + url: http://127.0.0.1:123457/some-other-path diff --git a/charts/library/common-test/tests/cnpg/backup_metadata_test.yaml b/charts/library/common-test/tests/cnpg/backup_metadata_test.yaml new file mode 100644 index 00000000000..f7585be2c59 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/backup_metadata_test.yaml @@ -0,0 +1,215 @@ +suite: cnpg backup metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with cnpg manualBackups backup created with labels and annotations + set: + credentials: + test: &test + type: s3 + url: some-url + bucket: some-bucket + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + label1: label1 + label2: global_label2 + label3: label3 + annotation1: annotation1 + annotation2: global_annotation2 + annotation3: annotation3 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + labels: + label5: label5 + annotations: + annotation5: annotation5 + manualBackups: + - name: today + labels: + label3: "{{ .Values.label3 }}" + label4: label4 + annotations: + annotation3: "{{ .Values.annotation3 }}" + annotation4: annotation4 + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: Backup + - documentIndex: *backupDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + annotation3: annotation3 + annotation4: annotation4 + annotation5: annotation5 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *backupDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + cnpg.io/cluster: test-release-name-common-test-cnpg-my-pg + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + label3: label3 + label4: label4 + label5: label5 + some-label: some-value + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with cnpg manualBackups backup created with namespace + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: some-namespace + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg manualBackups backup created with object namespace from tpl + set: + credentials: + test: *test + key: some-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: "{{ .Values.key }}" + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg manualBackups backup created with namespace from global with tpl + set: + credentials: + test: *test + key: global-namespace + global: + namespace: "{{ .Values.key }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with cnpg manualBackups backup created with namespace from root with tpl + set: + credentials: + test: *test + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/cnpg/backup_name_test.yaml b/charts/library/common-test/tests/cnpg/backup_name_test.yaml new file mode 100644 index 00000000000..4a89028d9d6 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/backup_name_test.yaml @@ -0,0 +1,65 @@ +suite: cnpg backup name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + credentials: + test: + type: s3 + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + url: some-url + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + my-pg2: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: other + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: Backup + - documentIndex: *backupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *backupDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-backup-today + - documentIndex: &otherbackupDoc 2 + isKind: + of: Backup + - documentIndex: *otherbackupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherbackupDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-backup-other diff --git a/charts/library/common-test/tests/cnpg/backup_provider_secret_spec_test.yaml b/charts/library/common-test/tests/cnpg/backup_provider_secret_spec_test.yaml new file mode 100644 index 00000000000..0829d118e3b --- /dev/null +++ b/charts/library/common-test/tests/cnpg/backup_provider_secret_spec_test.yaml @@ -0,0 +1,48 @@ +suite: cnpg backup provider secret spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create secret for s3 provider + set: + credentials: + test: + type: s3 + url: some-url + encrKey: some-encr-key + bucket: some-bucket + secretKey: some-secret-key + accessKey: some-access-key + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + asserts: + - documentIndex: &secretDoc 2 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_SECRET_KEY: some-secret-key + ACCESS_KEY_ID: some-access-key diff --git a/charts/library/common-test/tests/cnpg/backup_spec_test.yaml b/charts/library/common-test/tests/cnpg/backup_spec_test.yaml new file mode 100644 index 00000000000..e73bbecd89d --- /dev/null +++ b/charts/library/common-test/tests/cnpg/backup_spec_test.yaml @@ -0,0 +1,65 @@ +suite: cnpg backup spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec + set: + credentials: + test: + type: s3 + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + encrKey: some-encr-key + url: some-url + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + manualBackups: + - name: today + - name: before-upgrade + asserts: + - documentIndex: &cnpgDoc 0 + isKind: + of: Backup + - documentIndex: *cnpgDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *cnpgDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-backup-today + - documentIndex: *cnpgDoc + equal: + path: spec + value: + cluster: + name: test-release-name-common-test-cnpg-my-pg + - documentIndex: &otherCnpgDoc 1 + isKind: + of: Backup + - documentIndex: *otherCnpgDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherCnpgDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-backup-before-upgrade + - documentIndex: *otherCnpgDoc + equal: + path: spec + value: + cluster: + name: test-release-name-common-test-cnpg-my-pg diff --git a/charts/library/common-test/tests/cnpg/backup_validation_test.yaml b/charts/library/common-test/tests/cnpg/backup_validation_test.yaml new file mode 100644 index 00000000000..2bb1b803d60 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/backup_validation_test.yaml @@ -0,0 +1,42 @@ +suite: cnpg backup validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail without name in manualBackups backup + set: + credentials: + test: + type: azure + connectionString: some-connection-string + cnpg: + my-pg: + enabled: true + backups: + enabled: true + credentials: test + manualBackups: + - name: + asserts: + - failedTemplate: + errorMessage: CNPG Backup - Expected non-empty [name] in [backups.manualBackups] entry + + - it: should fail with invalid name in manualBackups backup + set: + credentials: + test: + type: azure + connectionString: some-connection-string + cnpg: + my-pg: + enabled: true + backups: + enabled: true + credentials: test + manualBackups: + - name: _invalid + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-cnpg-my-pg-backup-_invalid] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. diff --git a/charts/library/common-test/tests/cnpg/cluster_backup_spec_test.yaml b/charts/library/common-test/tests/cnpg/cluster_backup_spec_test.yaml new file mode 100644 index 00000000000..d97e784cdcc --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_backup_spec_test.yaml @@ -0,0 +1,343 @@ +suite: cnpg cluster backup spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec with backups (s3) + set: + credentials: + test: &test + type: s3 + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + encrKey: some-encr-key + url: some-url + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + asserts: + - documentIndex: &secretDoc 1 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + backup: + barmanObjectStore: + data: + jobs: 2 + destinationPath: some-path + endpointURL: some-url + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + serverName: test-release-name-common-test-cnpg-my-pg + retentionPolicy: 10d + target: primary + + - it: should use the revision when set in server name + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + revision: some-revision + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + backup: + barmanObjectStore: + data: + jobs: 2 + destinationPath: some-path + endpointURL: some-url + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + serverName: test-release-name-common-test-cnpg-my-pg-rsome-revision + retentionPolicy: 10d + target: primary + + - it: should override serverName when set + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + serverName: some-server-name + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + backup: + barmanObjectStore: + data: + jobs: 2 + destinationPath: some-path + endpointURL: some-url + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + serverName: some-server-name + retentionPolicy: 10d + target: primary + + - it: should override serverName when set (and also take account revision) + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + serverName: some-server-name + revision: "1" + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + backup: + barmanObjectStore: + data: + jobs: 2 + destinationPath: some-path + endpointURL: some-url + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + serverName: some-server-name-r1 + retentionPolicy: 10d + target: primary + + - it: should enable encryption when set + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + encryption: + enabled: true + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + backup: + barmanObjectStore: + data: + compression: gzip + encryption: AES256 + jobs: 2 + destinationPath: some-path + endpointURL: some-url + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-backup-s3-creds + serverName: test-release-name-common-test-cnpg-my-pg + wal: + compression: gzip + encryption: AES256 + retentionPolicy: 10d + target: primary diff --git a/charts/library/common-test/tests/cnpg/cluster_metadata_test.yaml b/charts/library/common-test/tests/cnpg/cluster_metadata_test.yaml new file mode 100644 index 00000000000..9ef0027c7de --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_metadata_test.yaml @@ -0,0 +1,155 @@ +suite: cnpg cluster metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with cnpg created with labels and annotations + set: + label1: label1 + label2: global_label2 + label3: label3 + annotation1: annotation1 + annotation2: global_annotation2 + annotation3: annotation3 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + cluster: + labels: + label3: "{{ .Values.label3 }}" + annotations: + annotation3: "{{ .Values.annotation3 }}" + asserts: + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: metadata.annotations + content: + annotation1: annotation1 + annotation2: annotation2 + annotation3: annotation3 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + cnpg.io/hibernation: "off" + some-annotation: some-value + - documentIndex: *clusterDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *clusterDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + cnpg.io/reload: "on" + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + label3: label3 + some-label: some-value + - documentIndex: *clusterDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with cnpg created with namespace + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: some-namespace + asserts: + - documentIndex: *clusterDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg created with object namespace from tpl + set: + key: some-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: "{{ .Values.key }}" + asserts: + - documentIndex: *clusterDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg created with namespace from global with tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: *clusterDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with cnpg created with namespace from root with tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: *clusterDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/cnpg/cluster_name_test.yaml b/charts/library/common-test/tests/cnpg/cluster_name_test.yaml new file mode 100644 index 00000000000..a648bceaf1d --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_name_test.yaml @@ -0,0 +1,41 @@ +suite: cnpg cluster name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + my-pg2: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: &otherclusterDoc 1 + isKind: + of: Cluster + - documentIndex: *otherclusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherclusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2 diff --git a/charts/library/common-test/tests/cnpg/cluster_recovery_spec_test.yaml b/charts/library/common-test/tests/cnpg/cluster_recovery_spec_test.yaml new file mode 100644 index 00000000000..d318a7bd451 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_recovery_spec_test.yaml @@ -0,0 +1,454 @@ +suite: cnpg cluster recovery spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec with recovery/backup + set: + postgres16Image: + repository: ghcr.io/cloudnative-pg/postgresql + tag: "16.3" + pullPolicy: IfNotPresent + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: backup + backupName: some-backup-name + asserts: + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + equal: + path: spec + value: + enableSuperuserAccess: true + imageName: ghcr.io/cloudnative-pg/postgresql:16.3 + primaryUpdateStrategy: unsupervised + primaryUpdateMethod: switchover + logLevel: info + instances: 2 + nodeMaintenanceWindow: + reusePVC: true + inProgress: false + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + storage: + pvcTemplate: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + walStorage: + pvcTemplate: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + backup: + name: some-backup-name + + - it: should generate correct spec with recovery/objectStore (s3) + set: + credentials: + test: &test + type: s3 + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + encrKey: some-encr-key + url: https://s3.some-region.amazonaws.com + path: some-path + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + credentials: test + asserts: + - documentIndex: &secretDoc 1 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + source: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + externalClusters: + - name: test-release-name-common-test-cnpg-my-pg + barmanObjectStore: + serverName: test-release-name-common-test-cnpg-my-pg + destinationPath: s3://some-bucket/some-path/test-release-name/cnpg + endpointURL: https://s3.some-region.amazonaws.com + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + + - it: should generate correct spec with recovery/objectStore (s3 - destinationPath/endpointURL) + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + credentials: test + destinationPath: s3://some-bucket + + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + source: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + externalClusters: + - name: test-release-name-common-test-cnpg-my-pg + barmanObjectStore: + serverName: test-release-name-common-test-cnpg-my-pg + destinationPath: s3://some-bucket + endpointURL: https://s3.some-region.amazonaws.com + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + + - it: should use revision in serverName when set + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + credentials: test + destinationPath: s3://some-bucket + revision: some-revision + pitrTarget: + time: "2021-01-01T00:00:00Z" + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + source: test-release-name-common-test-cnpg-my-pg-rsome-revision + recoveryTarget: + targetTime: "2021-01-01T00:00:00Z" + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + externalClusters: + - name: test-release-name-common-test-cnpg-my-pg-rsome-revision + barmanObjectStore: + serverName: test-release-name-common-test-cnpg-my-pg-rsome-revision + destinationPath: s3://some-bucket + endpointURL: https://s3.some-region.amazonaws.com + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + + - it: should override serverName when set + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + credentials: test + destinationPath: s3://some-bucket + serverName: some-server-name + pitrTarget: + time: "2021-01-01T00:00:00Z" + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + source: some-server-name + recoveryTarget: + targetTime: "2021-01-01T00:00:00Z" + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + externalClusters: + - name: some-server-name + barmanObjectStore: + serverName: some-server-name + destinationPath: s3://some-bucket + endpointURL: https://s3.some-region.amazonaws.com + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + + - it: should override serverName when set along with revision + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + credentials: test + destinationPath: s3://some-bucket + serverName: some-server-name + revision: "20" + pitrTarget: + time: "2021-01-01T00:00:00Z" + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + - documentIndex: *secretDoc + equal: + path: stringData + value: + ACCESS_KEY_ID: some-access-key + ACCESS_SECRET_KEY: some-secret-key + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + bootstrap: + recovery: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + owner: test-user + database: test-db + source: some-server-name-r20 + recoveryTarget: + targetTime: "2021-01-01T00:00:00Z" + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + externalClusters: + - name: some-server-name-r20 + barmanObjectStore: + serverName: some-server-name-r20 + destinationPath: s3://some-bucket + endpointURL: https://s3.some-region.amazonaws.com + s3Credentials: + accessKeyId: + key: ACCESS_KEY_ID + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds + secretAccessKey: + key: ACCESS_SECRET_KEY + name: test-release-name-common-test-cnpg-my-pg-provider-recovery-s3-creds diff --git a/charts/library/common-test/tests/cnpg/cluster_spec_test.yaml b/charts/library/common-test/tests/cnpg/cluster_spec_test.yaml new file mode 100644 index 00000000000..0138b6d471e --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_spec_test.yaml @@ -0,0 +1,579 @@ +suite: cnpg cluster spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec + set: + postgres16Image: + repository: ghcr.io/cloudnative-pg/postgresql + tag: "16.3" + pullPolicy: IfNotPresent + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + equal: + path: spec + value: + enableSuperuserAccess: true + imageName: ghcr.io/cloudnative-pg/postgresql:16.3 + primaryUpdateStrategy: unsupervised + primaryUpdateMethod: switchover + logLevel: info + instances: 2 + nodeMaintenanceWindow: + reusePVC: true + inProgress: false + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + storage: + pvcTemplate: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + walStorage: + pvcTemplate: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + bootstrap: + initdb: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + database: test-db + owner: test-user + dataChecksums: true + + - it: should respect changed fallbackDefaults + set: + postgres15Image: + repository: ghcr.io/cloudnative-pg/postgresql + tag: "15.6" + global: + fallbackDefaults: + pgVersion: 15 + vctAccessModes: + - ReadWriteMany + - ReadWriteOnce + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + imageName: ghcr.io/cloudnative-pg/postgresql:15.6 + storage: + pvcTemplate: + accessModes: + - ReadWriteMany + - ReadWriteOnce + resources: + requests: + storage: 100Gi + walStorage: + pvcTemplate: + accessModes: + - ReadWriteMany + - ReadWriteOnce + resources: + requests: + storage: 100Gi + + - it: should generate correct imageName with changed type and pgVersion + set: + postgresVectors15Image: + repository: ghcr.io/tensorchord/cloudnative-pgvecto.rs + tag: "15.6-v0.2.1" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pgVersion: 15 + type: vectors + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + equal: + path: spec.imageName + value: ghcr.io/tensorchord/cloudnative-pgvecto.rs:15.6-v0.2.1 + + - it: should generate correct imageName with changed pgVersion + set: + postgres15Image: + repository: ghcr.io/cloudnative-pg/postgresql + tag: "15.6" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pgVersion: 15 + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + equal: + path: spec.imageName + value: ghcr.io/cloudnative-pg/postgresql:15.6 + + - it: should override options + set: + ext1: some-extension + ext2: some-other-extension + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + enableSuperuserAccess: false + imageName: some-image + primaryUpdateStrategy: supervised + primaryUpdateMethod: restart + logLevel: debug + instances: 3 + initdb: + dataChecksums: false + encoding: some-encoding + localeCollate: some-locale + localeCtype: some-locale + walSegmentSize: 16 + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }}; + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }}; + postInitSQL: + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }}1; + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }}2; + postInitTemplateSQL: + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext1 }}1; + - CREATE EXTENSION IF NOT EXISTS {{ .Values.ext2 }}2; + nodeMaintenanceWindow: + reusePVC: false + inProgress: true + resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 20m + memory: 100Mi + storage: + size: 200Gi + accessModes: + - ReadWriteMany + walStorage: + size: 200Gi + accessModes: + - ReadWriteMany + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + equal: + path: spec + value: + enableSuperuserAccess: false + imageName: some-image + primaryUpdateStrategy: supervised + primaryUpdateMethod: restart + logLevel: debug + instances: 3 + nodeMaintenanceWindow: + reusePVC: false + inProgress: true + resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 20m + memory: 100Mi + storage: + pvcTemplate: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 200Gi + walStorage: + pvcTemplate: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 200Gi + bootstrap: + initdb: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + database: test-db + owner: test-user + dataChecksums: false + encoding: some-encoding + localeCollate: some-locale + localeCtype: some-locale + walSegmentSize: 16 + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension; + - CREATE EXTENSION IF NOT EXISTS some-other-extension; + postInitSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension1; + - CREATE EXTENSION IF NOT EXISTS some-other-extension2; + postInitTemplateSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension1; + - CREATE EXTENSION IF NOT EXISTS some-other-extension2; + + - it: should override resources from top level + set: + resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 20m + memory: 100Mi + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + resources: + limits: + cpu: 2000m + memory: 4Gi + requests: + cpu: 20m + memory: 100Mi + + - it: should pass with custom-conf + set: + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + cluster: + postgresql: + key1: value1 + key2: '{{ printf "test-tpl" }}' + preloadLibraries: + - pg_stat_statements + - pg_cron + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + postgresql: + parameters: + key1: value1 + key2: test-tpl + shared_preload_libraries: + - pg_stat_statements + - pg_cron + + - it: should pass with timescaledb + set: + postgresTimescaledb16Image: + repository: timescale/timescaledb + tag: "some-tag" + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + type: timescaledb + cluster: + initdb: + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension; + postgresql: + key1: value1 + key2: '{{ printf "test-tpl" }}' + preloadLibraries: + - pg_stat_statements + - pg_cron + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + postgresql: + parameters: + key1: value1 + key2: test-tpl + shared_preload_libraries: + - pg_stat_statements + - pg_cron + - timescaledb + bootstrap: + initdb: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + database: app + owner: app + dataChecksums: true + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS timescaledb; + - CREATE EXTENSION IF NOT EXISTS some-extension; + + - it: should pass with postgis + set: + postgresPostgis16Image: + repository: postgis/postgisdb + tag: "some-tag" + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + type: postgis + cluster: + initdb: + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension; + postgresql: + key1: value1 + key2: '{{ printf "test-tpl" }}' + preloadLibraries: + - pg_stat_statements + - pg_cron + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + postgresql: + parameters: + key1: value1 + key2: test-tpl + shared_preload_libraries: + - pg_stat_statements + - pg_cron + bootstrap: + initdb: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + database: app + owner: app + dataChecksums: true + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS postgis; + - CREATE EXTENSION IF NOT EXISTS postgis_topology; + - CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; + - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; + - CREATE EXTENSION IF NOT EXISTS some-extension; + + - it: should pass with vectors + set: + postgresVectors16Image: + repository: vectors/vectors + tag: "some-tag" + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + type: vectors + cluster: + initdb: + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS some-extension; + postgresql: + key1: value1 + key2: '{{ printf "test-tpl" }}' + preloadLibraries: + - pg_stat_statements + - pg_cron + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isSubset: + path: spec + content: + postgresql: + parameters: + key1: value1 + key2: test-tpl + shared_preload_libraries: + - pg_stat_statements + - pg_cron + - vectors.so + bootstrap: + initdb: + secret: + name: test-release-name-common-test-cnpg-my-pg-user + database: app + owner: app + dataChecksums: true + postInitApplicationSQL: + - CREATE EXTENSION IF NOT EXISTS vectors; + - CREATE EXTENSION IF NOT EXISTS some-extension; + + - it: should pass with enabled monitoring + set: + postgresTimescaledb16Image: + repository: timescale/timescaledb + tag: "some-tag" + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + type: timescaledb + monitoring: + enablePodMonitor: true + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + equal: + path: spec.monitoring + value: + enablePodMonitor: true + disableDefaultQueries: false + + - it: should pass with override monitoring + set: + postgresTimescaledb16Image: + repository: timescale/timescaledb + tag: "some-tag" + cnpg: + my-pg: + enabled: true + user: app + database: app + password: test-password + type: timescaledb + monitoring: + enablePodMonitor: true + disableDefaultQueries: true + customQueries: + - name: test-query + query: test-query + metrics: + - a-gauge: + usage: GAUGE + description: test-metric + - a-counter: + usage: COUNTER + description: test-metric + - name: test-query2 + query: test-query2 + metrics: + - a-gauge: + usage: GAUGE + description: test-metric + - a-counter: + usage: COUNTER + description: test-metric + - name: test-query3 + query: test-query3 + expandObjectName: false + key: test-key + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + equal: + path: spec.monitoring + value: + enablePodMonitor: true + disableDefaultQueries: true + customQueriesConfigMap: + - name: test-release-name-common-test-cnpg-my-pg-test-query + key: custom-queries + - name: test-release-name-common-test-cnpg-my-pg-test-query2 + key: custom-queries + - name: test-query3 + key: test-key diff --git a/charts/library/common-test/tests/cnpg/cluster_validation_test.yaml b/charts/library/common-test/tests/cnpg/cluster_validation_test.yaml new file mode 100644 index 00000000000..d0e87cbd22a --- /dev/null +++ b/charts/library/common-test/tests/cnpg/cluster_validation_test.yaml @@ -0,0 +1,298 @@ +suite: cnpg cluster validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail without user + set: + cnpg: + my-pg: + enabled: true + database: test-db + password: test-password + asserts: + - failedTemplate: + errorMessage: CNPG - Expected a non-empty [user] key + + - it: should fail without database + set: + cnpg: + my-pg: + enabled: true + user: test-user + password: test-password + asserts: + - failedTemplate: + errorMessage: CNPG - Expected a non-empty [database] key + + - it: should fail without password + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + asserts: + - failedTemplate: + errorMessage: CNPG - Expected a non-empty [password] key + + - it: should fail with invalid pgVersion + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pgVersion: invalid + asserts: + - failedTemplate: + errorMessage: CNPG - Expected [pgVersion] to be one of [15, 16], but got [invalid] + + - it: should fail with hibernate not a bool + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + hibernate: invalid + asserts: + - failedTemplate: + errorMessage: CNPG - Expected [hibernate] to be a boolean, but got [string] + + - it: should fail with invalid mode + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [mode] to be one of [standalone, replica, recovery], but got [invalid] + + - it: should fail with invalid type + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + type: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [type] to be one of [postgres, postgis, timescaledb, vectors], but got [invalid] + + - it: should fail with invalid log level + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + logLevel: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [cluster.logLevel] to be one of [error, warning, info, debug, trace], but got [invalid] + + - it: should fail with invalid primaryUpdateStrategy + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + primaryUpdateStrategy: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [cluster.primaryUpdateStrategy] to be one of [supervised, unsupervised], but got [invalid] + + - it: should fail with invalid primaryUpdateMethod + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + primaryUpdateMethod: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [cluster.primaryUpdateMethod] to be one of [switchover, restart], but got [invalid] + + - it: should fail with invalid walSegmentSize + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + initdb: + walSegmentSize: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be an integer, but got [string] + + - it: should fail with too large walSegmentSize + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + cluster: + initdb: + walSegmentSize: 1025 + asserts: + - failedTemplate: + errorMessage: CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be between 1 and 1024, but got [1025] + + - it: should fail without recovery object when mode is recovery + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + asserts: + - failedTemplate: + errorMessage: CNPG Recovery - Expected a non-empty [recovery] key + + - it: should fail with revision in recovery not a string + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: backup + backupName: some-backup-name + revision: 5 + asserts: + - failedTemplate: + errorMessage: CNPG Recovery - Expected [recovery.revision] to be a string, got [float64] + + - it: should fail with invalid recovery method + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Recovery - Expected [recovery.method] to be one of [backup, object_store, pg_basebackup], but got [invalid] + + - it: should fail without backupName on recovery method backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: backup + asserts: + - failedTemplate: + errorMessage: CNPG Recovery - Expected a non-empty [recovery.backupName] key + + - it: should fail with revision in backups not a string + set: + credentials: + test: &test + type: s3 + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + url: some-url + encrKey: some-encr-key + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + credentials: test + revision: 5 + target: primary + asserts: + - failedTemplate: + errorMessage: CNPG Backup - Expected [backups.revision] to be a string, got [float64] + + - it: should fail with invalid target when backups are enabled + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + credentials: test + target: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Backup - Expected [backups.target] to be one of [primary, prefer-standby], but got [invalid] + + - it: should fail with invalid retentionPolicy when backups are enabled + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + credentials: test + target: primary + retentionPolicy: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Backup - Expected [backups.retentionPolicy] to match regex [^[1-9][0-9]*[dwm]$], got [invalid] + + - it: should fail with instances less than 1 + set: + cnpg: + my-pg: + enabled: true + instances: 0 + user: test-user + database: test-db + password: test-password + asserts: + - failedTemplate: + errorMessage: CNPG - Expected [instances] to be greater than 0, but got [0] diff --git a/charts/library/common-test/tests/cnpg/credentials_test.yaml b/charts/library/common-test/tests/cnpg/credentials_test.yaml new file mode 100644 index 00000000000..e2614a7d23a --- /dev/null +++ b/charts/library/common-test/tests/cnpg/credentials_test.yaml @@ -0,0 +1,188 @@ +suite: cnpg credentials test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct secret + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: &secretDoc 2 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: type + value: kubernetes.io/basic-auth + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-user + - documentIndex: *secretDoc + equal: + path: stringData.username + value: test-user + - documentIndex: *secretDoc + equal: + path: stringData.password + value: test-password + + - documentIndex: &secretDoc 1 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-urls + - documentIndex: *secretDoc + isSubset: + path: stringData + content: + porthost: test-release-name-common-test-cnpg-my-pg-rw:5432 + host: test-release-name-common-test-cnpg-my-pg-rw + jdbc: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-rw:5432/test-db + std: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db + nossl: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-rw:5432/test-db?sslmode=disable + + - it: should generate correct secret with pooler, only rw + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: false + asserts: + - documentIndex: &secretDoc 2 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-urls + - documentIndex: *secretDoc + isSubset: + path: stringData + content: + porthost: test-release-name-common-test-cnpg-my-pg-pooler-rw:5432 + host: test-release-name-common-test-cnpg-my-pg-pooler-rw + jdbc: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db + std: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db + nossl: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db?sslmode=disable + + - it: should generate correct secret with pooler rw and ro + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: true + asserts: + - documentIndex: &secretDoc 3 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-urls + - documentIndex: *secretDoc + isSubset: + path: stringData + content: + porthost: test-release-name-common-test-cnpg-my-pg-pooler-rw:5432 + host: test-release-name-common-test-cnpg-my-pg-pooler-rw + jdbc: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db + hostRO: test-release-name-common-test-cnpg-my-pg-pooler-ro + jdbcRO: jdbc:postgresql://test-release-name-common-test-cnpg-my-pg-pooler-ro:5432/test-db + porthostRO: test-release-name-common-test-cnpg-my-pg-pooler-ro:5432 + std: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db + nossl: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-rw:5432/test-db?sslmode=disable + stdRO: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-ro:5432/test-db + nosslRO: postgresql://test-user:test-password@test-release-name-common-test-cnpg-my-pg-pooler-ro:5432/test-db?sslmode=disable + + - it: should generate correct secret with password set + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: &secretDoc 2 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: type + value: kubernetes.io/basic-auth + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-user + - documentIndex: *secretDoc + equal: + path: stringData.username + value: test-user + - documentIndex: *secretDoc + equal: + path: stringData.password + value: test-password + # Failures + - it: should fail with no credentials on recovery + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: recovery + recovery: + method: object_store + asserts: + - failedTemplate: + errorMessage: CNPG Recovery Provider Secret Spawner - Expected [recovery.credentials] to be defined on [recovery] mode + - it: should fail with no credentials on backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + mode: backup + backups: + enabled: true + asserts: + - failedTemplate: + errorMessage: CNPG Recovery Provider Secret Spawner - Expected [backups.credentials] to be defined on [backup] mode diff --git a/charts/library/common-test/tests/cnpg/db_wait_test.yaml b/charts/library/common-test/tests/cnpg/db_wait_test.yaml new file mode 100644 index 00000000000..8de83218ff6 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/db_wait_test.yaml @@ -0,0 +1,158 @@ +suite: cnpg db-wait test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct db-wait script + set: + workload: &workload + my-workload: + type: Deployment + enabled: true + primary: true + podSpec: + my-container: + enabled: true + primary: true + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + asserts: + - documentIndex: &deployDoc 3 + isKind: + of: Deployment + - documentIndex: *deployDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].name + value: test-release-name-common-test-system-cnpg-wait + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].command + value: + - /bin/sh + - -c + - |- + /bin/sh <<'EOF' + echo "Executing DB waits..." + echo "Testing Database availability on [CNPG RW]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-rw]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-rw + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-rw]" + echo "Done executing DB waits..." + EOF + + - it: should generate correct db-wait script with pooler, only rw + set: + workload: *workload + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: false + asserts: + - documentIndex: &deployDoc 4 + isKind: + of: Deployment + - documentIndex: *deployDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].name + value: test-release-name-common-test-system-cnpg-wait + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].command + value: + - /bin/sh + - -c + - |- + /bin/sh <<'EOF' + echo "Executing DB waits..." + echo "Testing Database availability on [CNPG RW]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-rw]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-rw + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-rw]" + echo "Testing Database availability on [CNPG Pooler RW]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-pooler-rw]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-pooler-rw + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-pooler-rw]" + echo "Done executing DB waits..." + EOF + + - it: should generate correct db-wait script with pooler rw and ro + set: + workload: *workload + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: true + asserts: + - documentIndex: &deployDoc 5 + isKind: + of: Deployment + - documentIndex: *deployDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].name + value: test-release-name-common-test-system-cnpg-wait + - documentIndex: *deployDoc + equal: + path: spec.template.spec.initContainers[0].command + value: + - /bin/sh + - -c + - |- + /bin/sh <<'EOF' + echo "Executing DB waits..." + echo "Testing Database availability on [CNPG RW]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-rw]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-rw + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-rw]" + echo "Testing Database availability on [CNPG Pooler RW]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-pooler-rw]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-pooler-rw + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-pooler-rw]" + echo "Testing Database availability on [CNPG Pooler RO]" + until + echo "Testing database on url: [test-release-name-common-test-cnpg-my-pg-pooler-ro]" + pg_isready -U test-user -d test-db -h test-release-name-common-test-cnpg-my-pg-pooler-ro + do sleep 5 + done + echo "Database available on url: [test-release-name-common-test-cnpg-my-pg-pooler-ro]" + echo "Done executing DB waits..." + EOF diff --git a/charts/library/common-test/tests/cnpg/pooler_metadata_test.yaml b/charts/library/common-test/tests/cnpg/pooler_metadata_test.yaml new file mode 100644 index 00000000000..541f976c324 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/pooler_metadata_test.yaml @@ -0,0 +1,163 @@ +suite: cnpg pooler metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with cnpg pooler created with labels and annotations + set: + label1: label1 + label2: global_label2 + label3: label3 + annotation1: annotation1 + annotation2: global_annotation2 + annotation3: annotation3 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + pooler: + enabled: true + labels: + label3: "{{ .Values.label3 }}" + annotations: + annotation3: "{{ .Values.annotation3 }}" + asserts: + - documentIndex: &poolerDoc 0 + isKind: + of: Pooler + - documentIndex: *poolerDoc + isSubset: + path: metadata.annotations + content: + annotation1: annotation1 + annotation2: annotation2 + annotation3: annotation3 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *poolerDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *poolerDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + cnpg.io/reload: "on" + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + label3: label3 + some-label: some-value + - documentIndex: *poolerDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with cnpg pooler created with namespace + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: some-namespace + pooler: + enabled: true + asserts: + - documentIndex: *poolerDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg pooler created with object namespace from tpl + set: + key: some-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: "{{ .Values.key }}" + pooler: + enabled: true + asserts: + - documentIndex: *poolerDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg pooler created with namespace from global with tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + asserts: + - documentIndex: *poolerDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with cnpg pooler created with namespace from root with tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + asserts: + - documentIndex: *poolerDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/cnpg/pooler_name_test.yaml b/charts/library/common-test/tests/cnpg/pooler_name_test.yaml new file mode 100644 index 00000000000..13db6198103 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/pooler_name_test.yaml @@ -0,0 +1,56 @@ +suite: cnpg pooler name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + my-pg2: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: true + asserts: + - documentIndex: &poolerDoc 0 + isKind: + of: Pooler + - documentIndex: *poolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *poolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-pooler-rw + - documentIndex: &otherpoolerDoc 2 + isKind: + of: Pooler + - documentIndex: *otherpoolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherpoolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-pooler-rw + - documentIndex: &otherpoolerDoc 3 + isKind: + of: Pooler + - documentIndex: *otherpoolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherpoolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-pooler-ro diff --git a/charts/library/common-test/tests/cnpg/pooler_spec_test.yaml b/charts/library/common-test/tests/cnpg/pooler_spec_test.yaml new file mode 100644 index 00000000000..905eb7658f9 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/pooler_spec_test.yaml @@ -0,0 +1,98 @@ +suite: cnpg pooler spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec + set: + param: someValue + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + my-pg2: + enabled: true + user: test-user + database: test-db + password: test-password + pooler: + enabled: true + createRO: true + poolMode: transaction + instances: 1 + parameters: + some: value + someOther: "{{ .Values.param }}" + asserts: + - documentIndex: &poolerDoc 0 + isKind: + of: Pooler + - documentIndex: *poolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *poolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-pooler-rw + - documentIndex: *poolerDoc + equal: + path: spec + value: + cluster: + name: test-release-name-common-test-cnpg-my-pg + instances: 2 + type: rw + pgbouncer: + poolMode: session + - documentIndex: &otherpoolerDoc 2 + isKind: + of: Pooler + - documentIndex: *otherpoolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherpoolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-pooler-rw + - documentIndex: *otherpoolerDoc + equal: + path: spec + value: + cluster: + name: test-release-name-common-test-cnpg-my-pg2 + instances: 1 + type: rw + pgbouncer: + poolMode: transaction + parameters: + some: value + someOther: someValue + - documentIndex: &otherpoolerDoc 3 + isKind: + of: Pooler + - documentIndex: *otherpoolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherpoolerDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-pooler-ro + - documentIndex: *otherpoolerDoc + equal: + path: spec + value: + cluster: + name: test-release-name-common-test-cnpg-my-pg2 + instances: 1 + type: ro + pgbouncer: + poolMode: transaction + parameters: + some: value + someOther: someValue diff --git a/charts/library/common-test/tests/cnpg/pooler_validation_test.yaml b/charts/library/common-test/tests/cnpg/pooler_validation_test.yaml new file mode 100644 index 00000000000..c47651d33e1 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/pooler_validation_test.yaml @@ -0,0 +1,34 @@ +suite: cnpg pooler validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with invalid poolMode + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + pooler: + enabled: true + poolMode: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Pooler - Expected [poolMode] to be one of [session, transaction], but got [invalid] + + - it: should fail with pooler instances less than 1 + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + pooler: + enabled: true + instances: 0 + asserts: + - failedTemplate: + errorMessage: CNPG Pooler - Expected [instances] to be greater than 0, but got [0] diff --git a/charts/library/common-test/tests/cnpg/scheduled_backup_metadata_test.yaml b/charts/library/common-test/tests/cnpg/scheduled_backup_metadata_test.yaml new file mode 100644 index 00000000000..562a7ab5cb3 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/scheduled_backup_metadata_test.yaml @@ -0,0 +1,225 @@ +suite: cnpg scheduled backup metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with cnpg scheduledBackup backup created with labels and annotations + set: + credentials: + test: &test + type: s3 + url: some-url + bucket: some-bucket + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + label1: label1 + label2: global_label2 + label3: label3 + annotation1: annotation1 + annotation2: global_annotation2 + annotation3: annotation3 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + labels: + label5: label5 + annotations: + annotation5: annotation5 + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + labels: + label3: "{{ .Values.label3 }}" + label4: label4 + annotations: + annotation3: "{{ .Values.annotation3 }}" + annotation4: annotation4 + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: ScheduledBackup + - documentIndex: *backupDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + annotation3: annotation3 + annotation4: annotation4 + annotation5: annotation5 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *backupDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + cnpg.io/cluster: test-release-name-common-test-cnpg-my-pg + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + label3: label3 + label4: label4 + label5: label5 + some-label: some-value + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with cnpg scheduledBackup backup created with namespace + set: + credentials: + test: *test + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: some-namespace + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg scheduledBackup backup created with object namespace from tpl + set: + credentials: + test: *test + key: some-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + namespace: "{{ .Values.key }}" + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with cnpg scheduledBackup backup created with namespace from global with tpl + set: + credentials: + test: *test + key: global-namespace + global: + namespace: "{{ .Values.key }}" + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with cnpg scheduledBackup backup created with namespace from root with tpl + set: + credentials: + test: *test + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + asserts: + - documentIndex: *backupDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/cnpg/scheduled_backup_name_test.yaml b/charts/library/common-test/tests/cnpg/scheduled_backup_name_test.yaml new file mode 100644 index 00000000000..176119d36fe --- /dev/null +++ b/charts/library/common-test/tests/cnpg/scheduled_backup_name_test.yaml @@ -0,0 +1,71 @@ +suite: cnpg scheduled backup name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + credentials: + test: + type: s3 + url: some-url + bucket: some-bucket + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: self + my-pg2: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + azure: + connectionString: some-connection-string + scheduledBackups: + - name: weekly + schedule: "0 0 * * 0" + backupOwnerReference: self + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: ScheduledBackup + - documentIndex: *backupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *backupDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-sched-backup-daily + - documentIndex: &otherbackupDoc 2 + isKind: + of: ScheduledBackup + - documentIndex: *otherbackupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherbackupDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg2-sched-backup-weekly diff --git a/charts/library/common-test/tests/cnpg/scheduled_backup_spec_test.yaml b/charts/library/common-test/tests/cnpg/scheduled_backup_spec_test.yaml new file mode 100644 index 00000000000..fef4a6c2f69 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/scheduled_backup_spec_test.yaml @@ -0,0 +1,78 @@ +suite: cnpg scheduled backup spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec + set: + credentials: + test: + type: s3 + url: some-url + bucket: some-bucket + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + suspend: true + - name: weekly + schedule: "0 0 * * 0" + immediate: true + backupOwnerReference: cluster + asserts: + - documentIndex: &cnpgDoc 0 + isKind: + of: ScheduledBackup + - documentIndex: *cnpgDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *cnpgDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-sched-backup-daily + - documentIndex: *cnpgDoc + equal: + path: spec + value: + schedule: "0 0 * * *" + backupOwnerReference: none + suspend: true + immediate: false + cluster: + name: test-release-name-common-test-cnpg-my-pg + - documentIndex: &otherCnpgDoc 1 + isKind: + of: ScheduledBackup + - documentIndex: *otherCnpgDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *otherCnpgDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg-sched-backup-weekly + - documentIndex: *otherCnpgDoc + equal: + path: spec + value: + schedule: "0 0 * * 0" + backupOwnerReference: cluster + suspend: false + immediate: true + cluster: + name: test-release-name-common-test-cnpg-my-pg diff --git a/charts/library/common-test/tests/cnpg/scheduled_backup_stop_test.yaml b/charts/library/common-test/tests/cnpg/scheduled_backup_stop_test.yaml new file mode 100644 index 00000000000..6d7b0e19548 --- /dev/null +++ b/charts/library/common-test/tests/cnpg/scheduled_backup_stop_test.yaml @@ -0,0 +1,82 @@ +suite: cnpg scheduled backup stop test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hibernate + set: + credentials: + test: &test + type: s3 + encrKey: some-encr-key + accessKey: some-access-key + secretKey: some-secret-key + bucket: some-bucket + url: some-url + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + hibernate: true + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + suspend: false + backupOwnerReference: self + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: ScheduledBackup + - documentIndex: *backupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *backupDoc + equal: + path: spec.suspend + value: true + + - it: should set suspend on stopAll + set: + credentials: + test: *test + global: + stopAll: true + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + hibernate: false + backups: + enabled: true + target: primary + retentionPolicy: 10d + credentials: test + destinationPath: some-path + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + suspend: false + backupOwnerReference: self + asserts: + - documentIndex: &backupDoc 0 + isKind: + of: ScheduledBackup + - documentIndex: *backupDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *backupDoc + equal: + path: spec.suspend + value: true diff --git a/charts/library/common-test/tests/cnpg/scheduled_backup_validation_test.yaml b/charts/library/common-test/tests/cnpg/scheduled_backup_validation_test.yaml new file mode 100644 index 00000000000..441f661f4ff --- /dev/null +++ b/charts/library/common-test/tests/cnpg/scheduled_backup_validation_test.yaml @@ -0,0 +1,127 @@ +suite: cnpg scheduled backup validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail without name in scheduledBackups backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: + asserts: + - failedTemplate: + errorMessage: CNPG Scheduled Backup - Expected non-empty [name] in [backups.scheduledBackups] entry + + - it: should fail without schedule in scheduledBackups backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: daily + asserts: + - failedTemplate: + errorMessage: CNPG Scheduled Backup - Expected non-empty [schedule] in [backups.scheduledBackups] entry + + - it: should fail with invalid backupOwnerReference in scheduledBackups backup + set: + operator: + verify: + enabled: false + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: daily + schedule: "0 0 * * *" + backupOwnerReference: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Scheduled Backup - Expected [backupOwnerReference] in [backups.scheduledBackups] entry to be one of [none, self, cluster], but got [invalid] + + - it: should fail with invalid name in scheduledBackups backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: _invalid + schedule: "0 0 * * *" + backupOwnerReference: self + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-cnpg-my-pg-sched-backup-_invalid] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with suspend not a bool in scheduledBackups backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: _invalid + schedule: "0 0 * * *" + backupOwnerReference: self + suspend: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Scheduled Backup - Expected [suspend] in [backups.scheduledBackups] entry to be a boolean, but got [string] + + - it: should fail with immediate not a bool in scheduledBackups backup + set: + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + backups: + enabled: true + provider: azure + azure: + connectionString: some-connection-string + scheduledBackups: + - name: _invalid + schedule: "0 0 * * *" + backupOwnerReference: self + immediate: invalid + asserts: + - failedTemplate: + errorMessage: CNPG Scheduled Backup - Expected [immediate] in [backups.scheduledBackups] entry to be a boolean, but got [string] diff --git a/charts/library/common-test/tests/cnpg/stop_test.yaml b/charts/library/common-test/tests/cnpg/stop_test.yaml new file mode 100644 index 00000000000..9bd36e25c8c --- /dev/null +++ b/charts/library/common-test/tests/cnpg/stop_test.yaml @@ -0,0 +1,80 @@ +suite: cnpg stop test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hibernate + set: + cnpg: + mypg: + enabled: true + user: app + database: app + password: test-password + instances: 2 + hibernate: true + pooler: + enabled: true + asserts: + - documentIndex: &clusterDoc 1 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + isSubset: + path: metadata.annotations + content: + cnpg.io/hibernation: "on" + - documentIndex: &poolerDoc 0 + isKind: + of: Pooler + - documentIndex: *poolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *poolerDoc + isSubset: + path: spec + content: + instances: 0 + + - it: should set hibernate and 0 instances on stopAll + set: + global: + stopAll: true + cnpg: + mypg: + enabled: true + user: app + database: app + password: test-password + hibernate: false + instances: 2 + pooler: + enabled: true + asserts: + - documentIndex: *clusterDoc + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + isSubset: + path: metadata.annotations + content: + cnpg.io/hibernation: "on" + - documentIndex: *poolerDoc + isKind: + of: Pooler + - documentIndex: *poolerDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *poolerDoc + isSubset: + path: spec + content: + instances: 0 diff --git a/charts/library/common-test/tests/configmap/data_test.yaml b/charts/library/common-test/tests/configmap/data_test.yaml new file mode 100644 index 00000000000..eda2f672d67 --- /dev/null +++ b/charts/library/common-test/tests/configmap/data_test.yaml @@ -0,0 +1,95 @@ +suite: configmap data test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with key-value data + set: + configmap: + my-configmap1: + enabled: true + data: + foo: bar + asserts: + - documentIndex: &configmapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configmapDoc + equal: + path: data + value: + foo: bar + + - it: should pass with key-value data from tpl + set: + data: bar + configmap: + my-configmap1: + enabled: true + data: + foo: "{{ .Values.data }}" + asserts: + - documentIndex: *configmapDoc + equal: + path: data + value: + foo: bar + + - it: should pass with scalar data + set: + configmap: + my-configmap1: + enabled: true + data: + foo: | + some multi line + string text + asserts: + - documentIndex: *configmapDoc + equal: + path: data + value: + foo: | + some multi line + string text + + - it: should pass with scalar data with tpl + set: + data: Some other text + configmap: + my-configmap: + enabled: true + data: + foo: | + file start + {{ .Values.data }} + asserts: + - documentIndex: *configmapDoc + equal: + path: data + value: + foo: | + file start + Some other text + + - it: should pass with scalar data from tpl + set: + data: | + Some other text + some_text + configmap: + my-configmap1: + enabled: true + data: + foo: | + {{- .Values.data | nindent 2 }} + asserts: + - documentIndex: *configmapDoc + equal: + path: data + value: + foo: | + Some other text + some_text diff --git a/charts/library/common-test/tests/configmap/metadata_test.yaml b/charts/library/common-test/tests/configmap/metadata_test.yaml new file mode 100644 index 00000000000..d146d0a2d47 --- /dev/null +++ b/charts/library/common-test/tests/configmap/metadata_test.yaml @@ -0,0 +1,135 @@ +suite: configmap metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with configmap created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + configmap: + my-configmap1: + enabled: true + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + data: + foo: bar + asserts: + - documentIndex: &configMapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configMapDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *configMapDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *configMapDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with configmap created with namespace + set: + configmap: + my-configmap1: + enabled: true + namespace: some-namespace + data: + foo: bar + asserts: + - documentIndex: *configMapDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with configmap created with object namespace from tpl + set: + key: some-namespace + configmap: + my-configmap1: + enabled: true + namespace: "{{ .Values.key }}" + data: + foo: bar + asserts: + - documentIndex: *configMapDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with configmap created with namespace from global with tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + configmap: + my-configmap1: + enabled: true + data: + foo: bar + asserts: + - documentIndex: *configMapDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with configmap created with namespace from root with tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + configmap: + my-configmap1: + enabled: true + data: + foo: bar + asserts: + - documentIndex: *configMapDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/configmap/name_test.yaml b/charts/library/common-test/tests/configmap/name_test.yaml new file mode 100644 index 00000000000..066e88f4099 --- /dev/null +++ b/charts/library/common-test/tests/configmap/name_test.yaml @@ -0,0 +1,39 @@ +suite: configmap name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + configmap: + my-configmap1: + enabled: true + data: + foo: bar + my-configmap2: + enabled: true + data: + foo: bar + asserts: + - documentIndex: &configmapDoc 0 + isKind: + of: ConfigMap + - documentIndex: *configmapDoc + isAPIVersion: + of: v1 + - documentIndex: *configmapDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-configmap1 + - documentIndex: &otherConfigmapDoc 1 + isKind: + of: ConfigMap + - documentIndex: *otherConfigmapDoc + isAPIVersion: + of: v1 + - documentIndex: *otherConfigmapDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-configmap2 diff --git a/charts/library/common-test/tests/configmap/validation_test.yaml b/charts/library/common-test/tests/configmap/validation_test.yaml new file mode 100644 index 00000000000..4dc9c0ec657 --- /dev/null +++ b/charts/library/common-test/tests/configmap/validation_test.yaml @@ -0,0 +1,95 @@ +suite: configmap validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with name longer than 253 characters + set: + configmap: + my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-long-long-long-long-long-long-long-name: + enabled: true + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-name-that-is-longer-than-253-characters-my-configmap-super-long-long-long-long-long-long-long-long-name] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with name starting with underscore + set: + configmap: + _my-configmap: + enabled: true + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-_my-configmap] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with namespace longer than 63 characters + set: + configmap: + my-configmap: + enabled: true + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: Configmap - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. + + - it: should fail with labels not a dict + set: + configmap: + my-configmap: + enabled: true + labels: "not a dict" + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: ConfigMap - Expected [labels] to be a dictionary, but got [string] + + - it: should fail with annotations not a dict + set: + configmap: + my-configmap: + enabled: true + annotations: "not a dict" + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: ConfigMap - Expected [annotations] to be a dictionary, but got [string] + + - it: should fail with data not a dict + set: + configmap: + my-configmap: + enabled: true + data: "not a dict" + asserts: + - failedTemplate: + errorMessage: ConfigMap - Expected [data] to be a dictionary, but got [string] + + - it: should fail with empty data + set: + configmap: + my-configmap: + enabled: true + data: {} + asserts: + - failedTemplate: + errorMessage: ConfigMap - Expected non-empty [data] + + - it: should fail with empty enabled + set: + configmap: + my-configmap: + enabled: + data: + foo: bar + asserts: + - failedTemplate: + errorMessage: ConfigMap - Expected the defined key [enabled] in [configmap.my-configmap] to not be empty diff --git a/charts/library/common-test/tests/container/arg_test.yaml b/charts/library/common-test/tests/container/arg_test.yaml new file mode 100644 index 00000000000..6f4f2a1589e --- /dev/null +++ b/charts/library/common-test/tests/container/arg_test.yaml @@ -0,0 +1,126 @@ +suite: container arg test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct multiple args + set: + some_port: 80 + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + args: + - --port + - "{{ .Values.some_port }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + args: + - --port + - "80" + + - it: should create the correct arg command + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + args: --accept-eula + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + args: + - --accept-eula + + - it: should create the correct multiple args and extraArgs + set: + some_path: /some/path + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + args: + - --port + - "80" + extraArgs: + - --accept-eula + - --path + - "{{ .Values.some_path }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + args: + - --port + - "80" + - --accept-eula + - --path + - /some/path diff --git a/charts/library/common-test/tests/container/command_test.yaml b/charts/library/common-test/tests/container/command_test.yaml new file mode 100644 index 00000000000..79bdbb6e9e8 --- /dev/null +++ b/charts/library/common-test/tests/container/command_test.yaml @@ -0,0 +1,121 @@ +suite: container command test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct command in scalar + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + command: + - /bin/sh + - -c + - | + echo "Using image {{ .Values.image.repository }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + command: + - /bin/sh + - -c + - | + echo "Using image nginx" + + - it: should create the correct single command + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + command: ./start.sh + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + command: + - ./start.sh + + - it: should create the correct multiple command + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + command: + - ./print.sh + - "{{ .Values.image.repository }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + command: + - ./print.sh + - nginx diff --git a/charts/library/common-test/tests/container/envFixed_test .yaml b/charts/library/common-test/tests/container/envFixed_test .yaml new file mode 100644 index 00000000000..8f2cf55cb29 --- /dev/null +++ b/charts/library/common-test/tests/container/envFixed_test .yaml @@ -0,0 +1,580 @@ +suite: container envFixed test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct fixed envs + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + TZ: Europe/London + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs when running as root + set: + image: *image + TZ: Europe/London + securityContext: + container: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + workload: + workload-name: + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: PUID + value: "568" + - name: USER_ID + value: "568" + - name: UID + value: "568" + - name: PGID + value: "568" + - name: GROUP_ID + value: "568" + - name: GID + value: "568" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs when running as root and changed fsGroup + set: + image: *image + TZ: Europe/London + securityContext: + container: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + securityContext: + fsGroup: 1000 + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: PUID + value: "568" + - name: USER_ID + value: "568" + - name: UID + value: "568" + - name: PGID + value: "1000" + - name: GROUP_ID + value: "1000" + - name: GID + value: "1000" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs when running as root and not readonly + set: + image: *image + TZ: Europe/London + securityContext: + container: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false + workload: + workload-name: + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: PUID + value: "568" + - name: USER_ID + value: "568" + - name: UID + value: "568" + - name: PGID + value: "568" + - name: GROUP_ID + value: "568" + - name: GID + value: "568" + + - it: should create the correct fixed envs with GPU + set: + image: *image + TZ: Europe/London + containerOptions: + NVIDIA_CAPS: + - compute + - video + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + nvidia.com/gpu: 1 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_DRIVER_CAPABILITIES + value: "compute,video" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs with GPU and overridden on container level + set: + image: *image + TZ: Europe/London + containerOptions: + NVIDIA_CAPS: + - compute + - video + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + nvidia.com/gpu: 1 + fixedEnv: + NVIDIA_CAPS: + - all + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: Europe/London + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_DRIVER_CAPABILITIES + value: "all" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs with PUID set to 0 on container level + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + fixedEnv: + PUID: 0 + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: UTC + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: PUID + value: "0" + - name: USER_ID + value: "0" + - name: UID + value: "0" + - name: PGID + value: "568" + - name: GROUP_ID + value: "568" + - name: GID + value: "568" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create the correct fixed envs with large int values + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + securityContext: + fsGroup: 100000514 + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + fixedEnv: + PUID: 200000514 + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: UTC + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: PUID + value: "200000514" + - name: USER_ID + value: "200000514" + - name: UID + value: "200000514" + - name: PGID + value: "100000514" + - name: GROUP_ID + value: "100000514" + - name: GID + value: "100000514" + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create correct fixEnvs with nvidia.com/gpu in top level resources + set: + image: *image + resources: + limits: + nvidia.com/gpu: 1 + workload: + workload-name: + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: UTC + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_DRIVER_CAPABILITIES + value: all + - name: S6_READ_ONLY_ROOT + value: "1" + + - it: should create correct fixEnvs with nvidia.com/gpu in container level resources + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + nvidia.com/gpu: 1 + container-name2: + enabled: true + imageSelector: image + probes: *probes + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + env: + - name: TZ + value: UTC + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_DRIVER_CAPABILITIES + value: all + - name: S6_READ_ONLY_ROOT + value: "1" + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[1] + content: + env: + - name: TZ + value: UTC + - name: UMASK + value: "0022" + - name: UMASK_SET + value: "0022" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: S6_READ_ONLY_ROOT + value: "1" + + # Failures + - it: it should fail with NVIDIA_CAPS having invalid values + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + fixedEnv: + NVIDIA_CAPS: + - invalid + - compute + asserts: + - failedTemplate: + errorMessage: Container - Expected [fixedEnv.NVIDIA_CAPS] entry to be one of [all, compute, utility, graphics, video], but got [invalid] + + - it: it should fail with NVIDIA_CAPS not having unique values + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + fixedEnv: + NVIDIA_CAPS: + - compute + - compute + asserts: + - failedTemplate: + errorMessage: Container - Expected [fixedEnv.NVIDIA_CAPS] to have only unique values, but got [compute, compute] diff --git a/charts/library/common-test/tests/container/envFrom_test.yaml b/charts/library/common-test/tests/container/envFrom_test.yaml new file mode 100644 index 00000000000..a9ab30694dc --- /dev/null +++ b/charts/library/common-test/tests/container/envFrom_test.yaml @@ -0,0 +1,285 @@ +suite: container envFrom test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct envFrom + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + configmap: + configmap-name: + enabled: true + data: + key1: value1 + key2: value2 + secret: + secret-name: + enabled: true + data: + key3: value3 + key4: value4 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + envFrom: + - configMapRef: + name: configmap-name + - secretRef: + name: secret-name + asserts: + - documentIndex: &deploymentDoc 2 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + envFrom: + - configMapRef: + name: test-release-name-common-test-configmap-name + - secretRef: + name: test-release-name-common-test-secret-name + + - it: should create the correct envFrom without expanding the name + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + some_config_name: configmap-name + some_secret_name: secret-name + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + envFrom: + - configMapRef: + name: "{{ .Values.some_config_name }}" + expandObjectName: false + - secretRef: + name: "{{ .Values.some_secret_name }}" + expandObjectName: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + envFrom: + - configMapRef: + name: configmap-name + - secretRef: + name: secret-name + + # Failures + - it: it should fail without a valid ref + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - invalidRef: + name: invalid-name + asserts: + - failedTemplate: + errorMessage: Container - Expected [envFrom] entry to have one of [configMapRef, secretRef] + + - it: it should fail with both refs in the same entry + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - configMapRef: + name: configmap-name + secretRef: + name: secret-name + asserts: + - failedTemplate: + errorMessage: Container - Expected [envFrom] entry to have only one of [configMapRef, secretRef], but got both + + - it: it should fail with empty name in configMapRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - configMapRef: + name: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [envFrom.configMapRef.name] + + - it: it should fail with empty name in secretRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - secretRef: + name: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [envFrom.secretRef.name] + + - it: it should fail without defined configmap + set: + image: *image + configmap: + configmap-name: + enabled: true + data: + key1: value1 + key2: value2 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - configMapRef: + name: configmap-other-name + asserts: + - failedTemplate: + errorMessage: Container - Expected ConfigMap [configmap-other-name] defined in [envFrom] to exist + + - it: it should fail without defined secret + set: + image: *image + secret: + secret-name: + enabled: true + data: + key1: value1 + key2: value2 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - secretRef: + name: secret-other-name + asserts: + - failedTemplate: + errorMessage: Container - Expected Secret [secret-other-name] defined in [envFrom] to exist + + + - it: it should fail empty expandObjectName + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - secretRef: + expandObjectName: + name: '{{ printf "secret-name" }}' + asserts: + - failedTemplate: + errorMessage: Container - Expected the defined key [expandObjectName] in [envFrom.secretRef] to not be empty diff --git a/charts/library/common-test/tests/container/envList_test.yaml b/charts/library/common-test/tests/container/envList_test.yaml new file mode 100644 index 00000000000..4ff971856af --- /dev/null +++ b/charts/library/common-test/tests/container/envList_test.yaml @@ -0,0 +1,120 @@ +suite: container envList test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct envList + set: + some_value: value1 + some_other_value: 2 + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + envList: + - name: env1 + value: "{{ .Values.some_value }}" + - name: env2 + value: "{{ .Values.some_other_value }}" + - name: env3 + value: "" + - name: env4 + value: 100000514 + - name: env5 + value: "100000514" + - name: env6 + value: 100text000514 + - name: env7 + value: "100.400" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env1 + value: value1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env2 + value: "2" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env3 + value: "" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env4 + value: "100000514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env5 + value: "100000514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env6 + value: "100text000514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: env7 + value: "100.400" + + # Failures + - it: it should fail with empty name + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envList: + - name: "" + value: some_value + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [envList.name] diff --git a/charts/library/common-test/tests/container/env_dupe_test.yaml b/charts/library/common-test/tests/container/env_dupe_test.yaml new file mode 100644 index 00000000000..07d6c4a22c5 --- /dev/null +++ b/charts/library/common-test/tests/container/env_dupe_test.yaml @@ -0,0 +1,255 @@ +suite: container env dupe test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: +# Failures + - it: should fail with dupe env in env and envList + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + env: + VAR1: some_value + envList: + - name: VAR1 + value: 123 + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [env] + + - it: should fail with dupe env in env and envFrom configmap + set: + image: *image + configmap: + configmap-name: + enabled: true + data: + VAR1: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR1: some_value + envFrom: + - configMapRef: + name: configmap-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [VAR1] in [env] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name] + + - it: should fail with dupe env in env and envFrom secret + set: + image: *image + secret: + secret-name: + enabled: true + data: + VAR1: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR1: some_value + envFrom: + - secretRef: + name: secret-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [VAR1] in [env] tried to override the Environment Variable that is already defined in [Secret - secret-name] + + - it: should fail with dupe env in envList and envFrom secret + set: + image: *image + secret: + secret-name: + enabled: true + data: + VAR1: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envList: + - name: VAR1 + value: some_value + envFrom: + - secretRef: + name: secret-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [Secret - secret-name] + + - it: should fail with dupe env in envList and envFrom configmap + set: + image: *image + configmap: + configmap-name: + enabled: true + data: + VAR1: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envList: + - name: VAR1 + value: some_value + envFrom: + - configMapRef: + name: configmap-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name] + + - it: should fail with dupe env in fixedEnv and env + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + TZ: some_value + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [TZ] in [env] tried to override the Environment Variable that is already defined in [fixedEnv] + + - it: should fail with dupe env in fixedEnv and envList + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envList: + - name: TZ + value: some_value + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [TZ] in [envList] tried to override the Environment Variable that is already defined in [fixedEnv] + + - it: should fail with dupe env in fixedEnv and envFrom configmap + set: + image: *image + configmap: + configmap-name: + enabled: true + data: + TZ: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - configMapRef: + name: configmap-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [TZ] in [fixedEnv] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name] + + - it: should fail with dupe env in fixedEnv and envFrom secret + set: + image: *image + secret: + secret-name: + enabled: true + data: + TZ: value + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + envFrom: + - secretRef: + name: secret-name + asserts: + - failedTemplate: + errorMessage: Container - Environment Variable [TZ] in [fixedEnv] tried to override the Environment Variable that is already defined in [Secret - secret-name] diff --git a/charts/library/common-test/tests/container/env_test.yaml b/charts/library/common-test/tests/container/env_test.yaml new file mode 100644 index 00000000000..477605d9dce --- /dev/null +++ b/charts/library/common-test/tests/container/env_test.yaml @@ -0,0 +1,472 @@ +suite: container env test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct env + set: + some_value: value1 + some_other_value: 2 + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + configmap: + configmap-name: + enabled: true + data: + key1: value1 + key2: value2 + secret: + secret-name: + enabled: true + data: + key1: value1 + key2: value2 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + env: + VAR1: "{{ .Values.some_value }}" + VAR2: some_value + VAR3: + configMapKeyRef: + name: configmap-name + key: key1 + VAR4: + secretKeyRef: + name: secret-name + key: key2 + VAR5: + configMapKeyRef: + expandObjectName: false + name: configmap-name + key: key3 + VAR6: + secretKeyRef: + expandObjectName: false + name: secret-name + key: key4 + VAR7: + fieldRef: + fieldPath: metadata.name + VAR8: "" + VAR9: false + VAR10: "100000514" + VAR11: 100000514 + VAR12: 1000text00514 + VAR13: "100.40" + asserts: + - documentIndex: &deploymentDoc 2 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR1 + value: value1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR2 + value: some_value + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR3 + valueFrom: + configMapKeyRef: + key: key1 + name: test-release-name-common-test-configmap-name + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR4 + valueFrom: + secretKeyRef: + key: key2 + name: test-release-name-common-test-secret-name + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR5 + valueFrom: + configMapKeyRef: + key: key3 + name: configmap-name + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR6 + valueFrom: + secretKeyRef: + key: key4 + name: secret-name + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR7 + valueFrom: + fieldRef: + fieldPath: metadata.name + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR8 + value: "" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR9 + value: "false" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR10 + value: "100000514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR11 + value: "100000514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR12 + value: "1000text00514" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].env + content: + name: VAR13 + value: "100.40" + + # Failures + - it: it should fail invalid ref + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + invalidKeyRef: {} + asserts: + - failedTemplate: + errorMessage: Container - Expected [env] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [invalidKeyRef] + + - it: it should fail with more than one ref + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + configMapKeyRef: {} + secretKeyRef: {} + asserts: + - failedTemplate: + errorMessage: Container - Expected [env] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [configMapKeyRef, secretKeyRef] + + - it: it should fail with empty name in configMapKeyRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + configMapKeyRef: + name: "" + key: key + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [env.configMapKeyRef.name] + + - it: it should fail with empty key in configMapKeyRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + configMapKeyRef: + name: name + key: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [env.configMapKeyRef.key] + + - it: it should fail with empty name in secretKeyRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + secretKeyRef: + name: "" + key: key + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [env.secretKeyRef.name] + + - it: it should fail with empty key in secretKeyRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + secretKeyRef: + name: name + key: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [env.secretKeyRef.key] + + - it: it should fail with referenced secret not defined + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + secretKeyRef: + name: secret-name + key: somekey + asserts: + - failedTemplate: + errorMessage: Container - Expected in [env] the referenced Secret [secret-name] to be defined + + - it: it should fail with referenced configmap not defined + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + configMapKeyRef: + name: configmap-name + key: somekey + asserts: + - failedTemplate: + errorMessage: Container - Expected in [env] the referenced Configmap [configmap-name] to be defined + + - it: it should fail with referenced key in configmap not defined + set: + image: *image + configmap: + configmap-name: + enabled: true + data: + key1: value1 + key2: value2 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + configMapKeyRef: + name: configmap-name + key: somekey + asserts: + - failedTemplate: + errorMessage: Container - Expected in [env] the referenced key [somekey] in Configmap [configmap-name] to be defined + + - it: it should fail with referenced key in secret not defined + set: + image: *image + secret: + secret-name: + enabled: true + data: + key1: value1 + key2: value2 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + secretKeyRef: + name: secret-name + key: somekey + asserts: + - failedTemplate: + errorMessage: Container - Expected in [env] the referenced key [somekey] in Secret [secret-name] to be defined + + - it: it should fail with empty fieldPath in fieldRef + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + VAR: + fieldRef: + fieldPath: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [env.fieldRef.fieldPath] + + - it: it should fail empty expandObjectName + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + env: + key1: + secretKeyRef: + expandObjectName: + name: '{{ printf "secret-name" }}' + key: secret-key + asserts: + - failedTemplate: + errorMessage: Container - Expected the defined key [expandObjectName] in [env.key1] to not be empty diff --git a/charts/library/common-test/tests/container/image_test.yaml b/charts/library/common-test/tests/container/image_test.yaml new file mode 100644 index 00000000000..eaa27b51c1f --- /dev/null +++ b/charts/library/common-test/tests/container/image_test.yaml @@ -0,0 +1,142 @@ +suite: container image test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct image + set: + imageDictToUse: image + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + imageGPU: + repository: some-gpu-image + tag: 5.20.0 + pullPolicy: Always + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: "{{ .Values.imageDictToUse }}" + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + container-name2: + enabled: true + primary: false + imageSelector: imageGPU + probes: *probes + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + image: nginx:1.19.0 + imagePullPolicy: IfNotPresent + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[1] + content: + image: some-gpu-image:5.20.0 + imagePullPolicy: Always + + # Failures + - it: should fail with imageSelector trying to access non-existent image + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image-dict-that-does-not-exist + asserts: + - failedTemplate: + errorMessage: Container - Expected [.Values.image-dict-that-does-not-exist] to exist + + - it: should fail with empty repository in selected image + set: + image: + repository: "" + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [.Values.image.repository] + + - it: should fail with empty tag in selected image + set: + image: + repository: nginx + tag: "" + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [.Values.image.tag] + + - it: should fail with invalid pullPolicy selected image + set: + image: + repository: nginx + tag: 1.19.0 + pullPolicy: invalid + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + asserts: + - failedTemplate: + errorMessage: Container - Expected [.Values.image.pullPolicy] to be one of [IfNotPresent, Always, Never], but got [invalid] diff --git a/charts/library/common-test/tests/container/lifecycle_test.yaml b/charts/library/common-test/tests/container/lifecycle_test.yaml new file mode 100644 index 00000000000..cad393b4d61 --- /dev/null +++ b/charts/library/common-test/tests/container/lifecycle_test.yaml @@ -0,0 +1,275 @@ +suite: container lifecycle test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with lifecycle + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + lifecycle: + postStart: + type: exec + command: + - echo + - hello + preStop: + type: http + port: 80 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + lifecycle: + postStart: + exec: + command: + - echo + - hello + preStop: + httpGet: + port: 80 + path: / + scheme: HTTP + + - it: should pass with lifecycle + set: + image: *image + some_command: ./some_command + some_port: 80 + some_host: some_host + some_path: /api/v1 + some_value: 123 + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + lifecycle: + postStart: + type: https + port: "{{ .Values.some_port }}" + host: "{{ .Values.some_host }}" + path: "{{ .Values.some_path }}" + httpHeaders: + key: "{{ .Values.some_value }}" + preStop: + type: exec + command: "{{ .Values.some_command }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + lifecycle: + postStart: + httpGet: + port: 80 + path: /api/v1 + scheme: HTTPS + host: some_host + httpHeaders: + - name: key + value: "123" + preStop: + exec: + command: + - ./some_command + + # Failures + - it: should fail with invalid lifecycle hook + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + probes: *probes + imageSelector: image + lifecycle: + invalid: {} + asserts: + - failedTemplate: + errorMessage: Container - Expected [lifecycle] [hook] to be one of [preStop, postStart], but got [invalid] + + - it: should fail with empty lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + command: [] + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [lifecycle] [type] + + - it: should fail with invalid lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + type: invalid + command: [] + asserts: + - failedTemplate: + errorMessage: Container - Expected [lifecycle] [type] to be one of [exec, http, https], but got [invalid] + + - it: should fail with empty command on exec lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + type: exec + command: [] + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [lifecycle] [command] on [exec] type + + - it: should fail with empty port on http lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + type: http + port: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [lifecycle] [port] on [http] type + + - it: should fail with path not starting with / on http lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + type: http + port: 80 + path: "api/v1" + asserts: + - failedTemplate: + errorMessage: Container - Expected [lifecycle] [path] to start with a forward slash [/] on [http] type + + - it: should fail with empty value on httpHeaders on http lifecycle type + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + lifecycle: + preStop: + type: http + port: 80 + httpHeaders: + key: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [value] on [httpHeaders] diff --git a/charts/library/common-test/tests/container/name_test.yaml b/charts/library/common-test/tests/container/name_test.yaml new file mode 100644 index 00000000000..4ec5d713421 --- /dev/null +++ b/charts/library/common-test/tests/container/name_test.yaml @@ -0,0 +1,53 @@ +suite: container name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct container name + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + name: test-release-name-common-test + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[1] + content: + name: test-release-name-common-test-container-name2 diff --git a/charts/library/common-test/tests/container/ports_test.yaml b/charts/library/common-test/tests/container/ports_test.yaml new file mode 100644 index 00000000000..896ffb418f7 --- /dev/null +++ b/charts/library/common-test/tests/container/ports_test.yaml @@ -0,0 +1,305 @@ +suite: container ports test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the correct ports without selector + set: + some_port: 80 + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + workload-name2: + enabled: true + primary: false + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + service: + my-service1: + enabled: true + primary: true + ports: + port-name: + enabled: true + primary: true + port: "{{ .Values.some_port }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 80 + hostPort: null + protocol: TCP + - documentIndex: &otherDeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *otherDeploymentDoc + isNull: + path: spec.template.spec.containers[0].ports + + - it: should create the correct ports with selector + set: + some_port: 53 + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + service: + my-service1: + enabled: true + primary: true + targetSelector: workload-name1 + ports: + port-name: + enabled: true + primary: true + targetSelector: container-name1 + port: 1234 + my-service2: + enabled: true + primary: false + targetSelector: workload-name2 + ports: + port-name: + enabled: true + primary: true + targetSelector: container-name1 + port: 54 + targetPort: "{{ .Values.some_port }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 1234 + hostPort: null + protocol: TCP + - documentIndex: *deploymentDoc + isNotSubset: + path: spec.template.spec.containers[0].securityContext.capabilities + content: + add: + - NET_BIND_SERVICE + + - documentIndex: &otherDeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *otherDeploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 53 + hostPort: null + protocol: TCP + - documentIndex: *otherDeploymentDoc + isSubset: + path: spec.template.spec.containers[0].securityContext.capabilities + content: + add: + - NET_BIND_SERVICE + + - it: should create the correct ports with hostPort + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + service: + my-service1: + enabled: true + primary: true + ports: + port-name: + enabled: true + primary: true + port: 1234 + targetPort: 5678 + hostPort: 20000 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 5678 + protocol: TCP + hostPort: 20000 + + - it: should create the correct protocol from tpl + set: + some_protocol: https + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + service: + my-service1: + enabled: true + primary: true + ports: + port-name: + enabled: true + primary: true + port: 1234 + protocol: "{{ .Values.some_protocol }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 1234 + hostPort: null + protocol: TCP + + - it: should create the correct protocol + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + service: + my-service1: + enabled: true + primary: true + ports: + port-name: + enabled: true + primary: true + port: 1234 + protocol: udp + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + ports: + - name: port-name + containerPort: 1234 + hostPort: null + protocol: UDP diff --git a/charts/library/common-test/tests/container/probes_test.yaml b/charts/library/common-test/tests/container/probes_test.yaml new file mode 100644 index 00000000000..1aeb593621d --- /dev/null +++ b/charts/library/common-test/tests/container/probes_test.yaml @@ -0,0 +1,788 @@ +suite: container probe test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the probes correctly + set: + some_port: 80 + some_path: /healthz + some_command: echo + probe_type: exec + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: true + type: http + port: "{{ .Values.some_port }}" + path: "{{ .Values.some_path }}" + readiness: + enabled: true + type: tcp + port: 123 + startup: + enabled: true + type: "{{ .Values.probe_type }}" + command: + - "{{ .Values.some_command }}" + - hello + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + livenessProbe: + httpGet: + path: /healthz + port: 80 + scheme: HTTP + failureThreshold: 5 + initialDelaySeconds: 12 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 123 + failureThreshold: 4 + initialDelaySeconds: 10 + periodSeconds: 12 + successThreshold: 2 + timeoutSeconds: 5 + startupProbe: + exec: + command: + - echo + - hello + failureThreshold: 60 + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 3 + + - it: should create https probe + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: true + type: https + port: 443 + spec: + initialDelaySeconds: 120 + timeoutSeconds: 10 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + readiness: + enabled: true + type: tcp + port: 443 + spec: + initialDelaySeconds: 50 + timeoutSeconds: 30 + periodSeconds: 8 + successThreshold: 5 + failureThreshold: 9 + startup: + enabled: true + type: tcp + port: 443 + spec: + initialDelaySeconds: 25 + timeoutSeconds: 40 + periodSeconds: 7 + successThreshold: 1 + failureThreshold: 12 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + livenessProbe: + httpGet: + path: / + port: 443 + scheme: HTTPS + failureThreshold: 3 + initialDelaySeconds: 120 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 10 + readinessProbe: + tcpSocket: + port: 443 + failureThreshold: 9 + initialDelaySeconds: 50 + periodSeconds: 8 + successThreshold: 5 + timeoutSeconds: 30 + startupProbe: + tcpSocket: + port: 443 + failureThreshold: 12 + initialDelaySeconds: 25 + periodSeconds: 7 + successThreshold: 1 + timeoutSeconds: 40 + + - it: should not create any probes with diagnostic mode + set: + image: *image + diagnosticMode: + enabled: true + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].livenessProbe + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].readinessProbe + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].startupProbe + + - it: should not create any probes with diagnostic mode from global + set: + image: *image + diagnosticMode: + enabled: false + global: + diagnosticMode: + enabled: true + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].livenessProbe + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].readinessProbe + - documentIndex: *deploymentDoc + notExists: + path: spec.template.spec.containers[0].startupProbe + + # Failures + - it: should fail with invalid probe + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + invalid: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected probe to be one of [liveness, readiness, startup], but got [invalid] + + - it: should fail without probes defined + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: {} + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [probes] + + - it: should fail without liveness defined + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes.liveness] to be defined + + - it: should fail without readiness defined + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes.readiness] to be defined + + - it: should fail without startup defined + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes.startup] to be defined + + - it: should fail with invalid type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected probe type to be one of [http, https, tcp, grpc, exec], but got [invalid] + + - it: should fail with successThreshold more than 1 on liveness + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + successThreshold: 2 + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [successThreshold] to be 1 on [liveness] probe + + - it: should fail with successThreshold more than 1 on startup + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + startup: + enabled: true + type: http + port: 8080 + spec: + successThreshold: 2 + readiness: + enabled: false + liveness: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [successThreshold] to be 1 on [startup] probe + + - it: should fail with initialDelaySeconds not a number + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + initialDelaySeconds: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [initialDelaySeconds] to be a number, but got [invalid] + + - it: should fail with failureThreshold not a number + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + failureThreshold: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [failureThreshold] to be a number, but got [invalid] + + - it: should fail with successThreshold not a number + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + successThreshold: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [successThreshold] to be a number, but got [invalid] + + - it: should fail with timeoutSeconds not a number + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + timeoutSeconds: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [timeoutSeconds] to be a number, but got [invalid] + + - it: should fail with periodSeconds not a number + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + spec: + periodSeconds: invalid + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [periodSeconds] to be a number, but got [invalid] + + - it: should fail with empty command on exec type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: exec + command: [] + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [probes] [command] on [exec] type + + - it: should fail with empty port on grpc type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: grpc + port: "" + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [probes] [port] on [grpc] type + + - it: should fail with empty port on tcp type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: tcp + port: "" + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [probes] [port] on [tcp] type + + - it: should fail with empty port on http type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: "" + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [probes] [port] on [http] type + + - it: should fail with invalid path on http type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: 8080 + path: not-starting-with-slash + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected [probes] [path] to start with a forward slash [/] on [http] type + + - it: should fail with empty value in http headers + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: http + port: not-starting-with-slash + httpHeaders: + key: + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [value] on [httpHeaders] + + - it: should fail with diagnosticMode not a map + set: + image: *image + diagnosticMode: not-a-map + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Diagnostic Mode - Expected [diagnosticMode] to be a map, but got [string] + + - it: should fail with diagnosticMode.enabled not a boolean + set: + image: *image + diagnosticMode: + enabled: not-a-boolean + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Diagnostic Mode - Expected [diagnosticMode.enabled] to be a bool, but got [string] diff --git a/charts/library/common-test/tests/container/resources_test.yaml b/charts/library/common-test/tests/container/resources_test.yaml new file mode 100644 index 00000000000..cdf415e70ec --- /dev/null +++ b/charts/library/common-test/tests/container/resources_test.yaml @@ -0,0 +1,729 @@ +suite: container resources test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the resources correctly + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + + - it: should override the default limits + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + cpu: 2000m + memory: 4Gi + nvidia.com/gpu: 1 + some-resource: 1 + some-other-resource: 0 + some-string-resource: "0" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 2000m + memory: 4Gi + nvidia.com/gpu: 1 + some-resource: 1 + requests: + cpu: 10m + memory: 50Mi + + - it: should override the default limits from top level + set: + image: *image + resources: + limits: + some-resource: 1 + some-other-resource: 0 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + cpu: 2000m + memory: 4Gi + some-resource: 0 + some-other-resource: 2 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 2000m + memory: 4Gi + some-other-resource: 2 + requests: + cpu: 10m + memory: 50Mi + + - it: should override the default limits.cpu + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + cpu: 2000m + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 2000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + + - it: should override the default limits.memory + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + memory: 4Gi + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 4Gi + requests: + cpu: 10m + memory: 50Mi + + - it: should not render limits.cpu + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + cpu: 0 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + + - it: should not render limits.memory + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + limits: + memory: 0 + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + requests: + cpu: 10m + memory: 50Mi + + - it: should override the default requests + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + requests: + cpu: 200m + memory: 1Gi + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 200m + memory: 1Gi + + - it: should override the default requests.cpu + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + requests: + cpu: 200m + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 200m + memory: 50Mi + + - it: should override the default requests.memory + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + resources: + requests: + memory: 1Gi + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 1Gi + + - it: should not add extra resources on "wait" containers and on excluded containers + set: + image: *image + redis: + enabled: true + mongodb: + enabled: true + mariadb: + enabled: true + clickhouse: + enabled: true + solr: + enabled: true + cnpg: + my-pg: + enabled: true + user: test-user + database: test-db + password: test-password + resources: + limits: + "nvidia.com/gpu": "1" + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + my-container: + enabled: true + imageSelector: image + probes: *probes + resources: + excludeExtra: true + asserts: + - documentIndex: &clusterDoc 0 + isKind: + of: Cluster + - documentIndex: *clusterDoc + isAPIVersion: + of: postgresql.cnpg.io/v1 + - documentIndex: *clusterDoc + equal: + path: metadata.name + value: test-release-name-common-test-cnpg-my-pg + - documentIndex: *clusterDoc + equal: + path: spec.resources + value: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: &deploymentDoc 8 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + name: test-release-name-common-test + resources: + limits: + cpu: 4000m + memory: 8Gi + nvidia.com/gpu: 1 + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[1] + content: + name: test-release-name-common-test-my-container + resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[0] + content: + name: test-release-name-common-test-system-clickhouse-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + name: test-release-name-common-test-system-cnpg-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[2] + content: + name: test-release-name-common-test-system-mariadb-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[3] + content: + name: test-release-name-common-test-system-mongodb-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[4] + content: + name: test-release-name-common-test-system-redis-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[5] + content: + name: test-release-name-common-test-system-solr-wait + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 10m + memory: 50Mi + + # Failures + - it: should fail with empty requests + set: + image: *image + resources: + requests: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [resources.requests] + + - it: should fail with empty requests.cpu + set: + image: *image + resources: + requests: + cpu: "" + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [resources.requests.cpu] + + - it: should fail with empty requests.memory + set: + image: *image + resources: + requests: + cpu: 10m + memory: "" + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [resources.requests.memory] + + - it: should fail with invalid format in requests.cpu + set: + image: *image + resources: + requests: + cpu: 10MB + memory: 50Mi + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [resources.requests.cpu] to have one of the following formats [(Plain Integer - eg. 1), (Float - eg. 0.5), (Milicpu - eg. 500m)], but got [10MB] + + - it: should fail with invalid format in limits.cpu + set: + image: *image + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 10MB + memory: 8Gi + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [resources.limits.cpu] to have one of the following formats [(Plain Integer - eg. 1), (Float - eg. 0.5), (Milicpu - eg. 500m)], but got [10MB] + + - it: should fail with invalid format in requests.memory + set: + image: *image + resources: + requests: + cpu: 10m + memory: 50MB + limits: + cpu: 4000m + memory: 8Gi + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [resources.requests.memory] to have one of the following formats [(Suffixed with E/P/T/G/M/K - eg. 1G), (Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi), (Plain Integer in bytes - eg. 1024), (Exponent - eg. 134e6)], but got [50MB] + + - it: should fail with invalid format in limits.memory + set: + image: *image + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8GB + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [resources.limits.memory] to have one of the following formats [(Suffixed with E/P/T/G/M/K - eg. 1G), (Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi), (Plain Integer in bytes - eg. 1024), (Exponent - eg. 134e6)], but got [8GB] diff --git a/charts/library/common-test/tests/container/securityContext_test.yaml b/charts/library/common-test/tests/container/securityContext_test.yaml new file mode 100644 index 00000000000..3dbe4fc74bd --- /dev/null +++ b/charts/library/common-test/tests/container/securityContext_test.yaml @@ -0,0 +1,1056 @@ +suite: container security context test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create the securityContext correctly + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext runAsUser and runAsNonRoot + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsUser: 0 + runAsNonRoot: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 0 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - CHOWN + - SETUID + - SETGID + - FOWNER + - DAC_OVERRIDE + drop: + - ALL + + - it: should override the securityContext runAsGroup and runAsNonRoot + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsGroup: 0 + runAsNonRoot: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 0 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext readOnlyRootFilesystem + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + readOnlyRootFilesystem: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: false + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext privileged + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + privileged: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: true + privileged: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext allowPrivilegeEscalation + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + allowPrivilegeEscalation: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: true + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext capabilities.add + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + add: + - NET_ADMIN + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - NET_ADMIN + drop: + - ALL + + - it: should override the securityContext capabilities.drop + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + drop: + - NET_ADMIN + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - NET_ADMIN + + - it: should override the securityContext seccompProfile.type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + seccompProfile: + type: Unconfined + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: Unconfined + capabilities: + add: [] + drop: + - ALL + + - it: should override the securityContext all + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: false + allowPrivilegeEscalation: true + privileged: true + capabilities: + add: + - NET_ADMIN + drop: + - NET_BIND_SERVICE + seccompProfile: + type: Localhost + profile: path/to/profile.json + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: false + allowPrivilegeEscalation: true + privileged: true + runAsNonRoot: true + seccompProfile: + type: Localhost + localhostProfile: path/to/profile.json + capabilities: + add: + - NET_ADMIN + drop: + - NET_BIND_SERVICE + + - it: should set allowPrivilegeEscalation to true automatically when privileged is true + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + allowPrivilegeEscalation: false + privileged: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: true + privileged: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should set to privileged with assigned device on primary + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + persistence: + dev01: + enabled: true + type: device + hostPath: /dev/sda + mountPath: /test + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: true + privileged: true + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - CHOWN + - SETUID + - SETGID + - FOWNER + - DAC_OVERRIDE + drop: + - ALL + + - it: should not include extra caps when disabled from global + set: + image: *image + securityContext: + container: + runAsNonRoot: false + runAsUser: 0 + runAsGroup: 0 + capabilities: + disableS6Caps: true + 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 + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should not include extra caps when disabled from container level + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsNonRoot: false + runAsUser: 0 + runAsGroup: 0 + capabilities: + disableS6Caps: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + + - it: should set to privileged with assigned device on selected container + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + dev01: + enabled: true + type: device + hostPath: /dev/sda + mountPath: /test + targetSelector: + workload-name1: + container-name2: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[1] + content: + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: true + privileged: true + runAsNonRoot: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: + - CHOWN + - SETUID + - SETGID + - FOWNER + - DAC_OVERRIDE + drop: + - ALL + + # Failures + - it: should fail with empty securityContext + set: + image: *image + securityContext: + container: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected non-empty [.Values.securityContext.container] + + - it: should fail with readOnlyRootFilesystem not a bool + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + readOnlyRootFilesystem: "true" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.readOnlyRootFilesystem] to be [bool], but got [true] of type [string] + + - it: should fail with allowPrivilegeEscalation not a bool + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + allowPrivilegeEscalation: "true" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.allowPrivilegeEscalation] to be [bool], but got [true] of type [string] + + - it: should fail with privileged not a bool + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + privileged: "true" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.privileged] to be [bool], but got [true] of type [string] + + - it: should fail with runAsUser not an int + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsUser: "568" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.runAsUser] to be [int], but got [568] of type [string] + + - it: should fail with runAsGroup not an int + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsGroup: "568" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.runAsGroup] to be [int], but got [568] of type [string] + + - it: should fail without seccompProfile + set: + image: *image + securityContext: + container: + seccompProfile: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.seccompProfile] to be defined + + - it: should fail with invalid seccompProfile + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + seccompProfile: + type: invalid + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.seccompProfile] to be one of [RuntimeDefault, Localhost, Unconfined], but got [invalid] + + - it: should fail without profile on seccompProfile Localhost + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + seccompProfile: + type: Localhost + profile: "" + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.seccompProfile.profile] to be defined on type [Localhost] + + - it: should fail without capabilities + set: + image: *image + securityContext: + container: + capabilities: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.capabilities] to be defined + + - it: should fail capabilities.add not a list + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + add: invalid + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.capabilities.add] to be [list], but got [string] + + - it: should fail capabilities.drop not a list + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + drop: invalid + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.capabilities.drop] to be [list], but got [string] + + - it: should fail capabilities.disableS6Caps not a bool + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + capabilities: + disableS6Caps: not-bool + asserts: + - failedTemplate: + errorMessage: Container - Expected [securityContext.capabilities.disableS6Caps] to be [bool], but got [not-bool] of type [string] + + - it: should fail with duplicate capabilities.add + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + add: + - CHOWN + - CHOWN + asserts: + - failedTemplate: + errorMessage: Container - Expected items of [securityContext.capabilities.add] to be unique, but got [CHOWN, CHOWN] + + - it: should fail with duplicate capabilities.drop + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + securityContext: + capabilities: + drop: + - CHOWN + - CHOWN + asserts: + - failedTemplate: + errorMessage: Container - Expected items of [securityContext.capabilities.drop] to be unique, but got [CHOWN, CHOWN] diff --git a/charts/library/common-test/tests/container/termination_test.yaml b/charts/library/common-test/tests/container/termination_test.yaml new file mode 100644 index 00000000000..31289d7f31d --- /dev/null +++ b/charts/library/common-test/tests/container/termination_test.yaml @@ -0,0 +1,146 @@ +suite: container termination test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with termination set + set: + some_path: /dev/termination-log + some_policy: File + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + termination: + messagePath: "{{ .Values.some_path }}" + messagePolicy: "{{ .Values.some_policy }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + + - it: should pass with termination path only + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + termination: + messagePath: /some/path + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + terminationMessagePath: /some/path + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.containers[0].terminationMessagePolicy + + - it: should pass with termination policy only + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + termination: + messagePolicy: File + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + terminationMessagePolicy: File + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.containers[0].terminationMessagePath + + # Failures + - it: should fail with invalid policy + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + termination: + messagePolicy: SomeInvalidPolicy + asserts: + - failedTemplate: + errorMessage: Container - Expected [termination.messagePolicy] to be one of [File, FallbackToLogsOnError], but got [SomeInvalidPolicy] diff --git a/charts/library/common-test/tests/container/tty_stdin_test.yaml b/charts/library/common-test/tests/container/tty_stdin_test.yaml new file mode 100644 index 00000000000..849f2bacb89 --- /dev/null +++ b/charts/library/common-test/tests/container/tty_stdin_test.yaml @@ -0,0 +1,75 @@ +suite: container tty and stdin test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass without tty and stdin + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + tty: false + stdin: false + + - it: should pass with tty and stdin enabled + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + tty: true + stdin: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + tty: true + stdin: true diff --git a/charts/library/common-test/tests/container/validation_test.yaml b/charts/library/common-test/tests/container/validation_test.yaml new file mode 100644 index 00000000000..344c483ad10 --- /dev/null +++ b/charts/library/common-test/tests/container/validation_test.yaml @@ -0,0 +1,44 @@ +suite: container validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with more than one primary container on a workload + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + container-name2: + enabled: true + primary: true + asserts: + - failedTemplate: + errorMessage: Container - Only one container can be primary per workload + + - it: should fail with no primary container on a workload + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: false + container-name2: + enabled: true + primary: false + asserts: + - failedTemplate: + errorMessage: Container - At least one enabled container must be primary per workload diff --git a/charts/library/common-test/tests/container/volumeMounts_test.yaml b/charts/library/common-test/tests/container/volumeMounts_test.yaml new file mode 100644 index 00000000000..524bdb41537 --- /dev/null +++ b/charts/library/common-test/tests/container/volumeMounts_test.yaml @@ -0,0 +1,837 @@ +suite: container volumeMounts test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with shared volume on multiple workloads and containers with targetSelectAll + set: + some_path: /some/path + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Job + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + shared-vol: + enabled: true + type: emptyDir + mountPath: "{{ .Values.some_path }}" + targetSelectAll: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: shared-vol + mountPath: /some/path + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: shared-vol + mountPath: /some/path + readOnly: false + - documentIndex: &jobDoc 1 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: shared-vol + mountPath: /some/path + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: shared-vol + mountPath: /some/path + readOnly: false + + - it: should pass with volume on primary workload and container + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Job + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: true + type: emptyDir + mountPath: /some/path + readOnly: true + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + - documentIndex: &jobDoc 1 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + + - it: should pass with volume with selected pod and container + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Job + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: true + type: emptyDir + mountPath: /some/path + readOnly: true + targetSelector: + workload-name: + container-name2: {} + workload-name2: + container-name1: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + - documentIndex: &jobDoc 1 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + + - it: should pass with volume with selected pod and multiple containers + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Job + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: true + type: emptyDir + mountPath: /some/path + readOnly: true + targetSelector: + workload-name: + container-name1: {} + container-name2: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + - documentIndex: &jobDoc 1 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /dev/shm + name: devshm + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /shared + name: shared + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /tmp + name: tmp + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/logs + name: varlogs + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /dev/shm + name: devshm + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /shared + name: shared + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /tmp + name: tmp + readOnly: false + - documentIndex: *jobDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /var/logs + name: varlogs + readOnly: false + + - it: should pass with volume with selected pod and containers and specific values + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: Job + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: true + type: emptyDir + mountPath: /some/path + readOnly: true + targetSelector: + workload-name: + container-name1: + mountPath: /some/other/path + readOnly: false + mountPropagation: None + subPath: /some/sub/path + container-name2: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: some-vol + mountPath: /some/other/path + readOnly: false + mountPropagation: None + subPath: /some/sub/path + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + - documentIndex: &jobDoc 1 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + + - it: should pass with volume with selected pod and containers and specific values from tpl + set: + some_path: /some/other/path + some_propagation: None + some_sub_path: /some/sub/path + image: *image + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + container-name2: + enabled: true + primary: false + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: true + type: emptyDir + mountPath: /some/path + readOnly: true + targetSelector: + workload-name: + container-name1: + mountPath: "{{ .Values.some_path }}" + readOnly: false + mountPropagation: "{{ .Values.some_propagation }}" + subPath: "{{ .Values.some_sub_path }}" + container-name2: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: some-vol + mountPath: /some/other/path + readOnly: false + mountPropagation: None + subPath: /some/sub/path + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + name: some-vol + mountPath: /some/path + readOnly: true + + - it: should pass with vct mounted + set: + image: *image + workload: + workload-name: + enabled: true + primary: true + type: StatefulSet + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + workload-name2: + enabled: true + primary: false + type: StatefulSet + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + persistence: + vct-vol: + enabled: true + type: vct + size: 50Gi + targetSelector: + workload-name: + container-name1: + mountPath: /some/path + asserts: + - documentIndex: &statefulSetDoc 0 + isKind: + of: StatefulSet + - documentIndex: *statefulSetDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *statefulSetDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: test-release-name-common-test-vct-vol + mountPath: /some/path + readOnly: false + - documentIndex: &otherStatefulSetDoc 1 + isKind: + of: StatefulSet + - documentIndex: *otherStatefulSetDoc + isAPIVersion: + of: apps/v1 + + - it: should default mountPath to hostPath on device type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + persistence: + dev01: + enabled: true + type: device + hostPath: /dev/sda + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: dev01 + mountPath: /dev/sda + readOnly: false + + - it: should use mountPath if given instead of hostPath on device type + set: + image: *image + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + persistence: + dev01: + enabled: true + type: device + hostPath: /dev/sda + mountPath: /dev/sdb + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: dev01 + mountPath: /dev/sdb + readOnly: false + + - it: should respect tpl in enabled + set: + image: *image + flag: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: *probes + persistence: + some-vol: + enabled: "{{ .Values.flag }}" + type: emptyDir + mountPath: /some/path + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.volumes + value: + - name: devshm + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: shared + emptyDir: {} + - name: tmp + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: varlogs + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: varrun + emptyDir: + medium: Memory + sizeLimit: 8Gi + + - documentIndex: *deploymentDoc + equal: + # some-vol should not be present + path: spec.template.spec.containers[0].volumeMounts + value: + - mountPath: /dev/shm + name: devshm + readOnly: false + - mountPath: /shared + name: shared + readOnly: false + - mountPath: /tmp + name: tmp + readOnly: false + - mountPath: /var/logs + name: varlogs + readOnly: false + - mountPath: /var/run + name: varrun + readOnly: false + + # Failures + - it: should fail with invalid mountPropagation + set: + image: *image + workload: + workload-name: &workload + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + persistence: + vol-name: + enabled: true + type: pvc + mountPath: /some/path + mountPropagation: HostToContainer + targetSelector: + workload-name: + container-name1: + mountPropagation: invalid + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [mountPropagation] to be one of [None, HostToContainer, Bidirectional], but got [invalid] + + - it: should fail with non-boolean readOnly + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + mountPath: /some/path + targetSelector: + workload-name: + container-name1: + readOnly: invalid + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [readOnly] to be [boolean], but got [string] + + - it: should fail with empty readOnly + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + mountPath: /some/path + targetSelector: + workload-name: + container-name1: + readOnly: + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [readOnly] to be [boolean], but got [invalid] + + - it: should fail with empty mountPath + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + mountPath: "" + targetSelector: + workload-name: + container-name1: {} + asserts: + - failedTemplate: + errorMessage: Persistence - Expected non-empty [mountPath] + + - it: should fail with mountPath not starting with / + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + targetSelector: + workload-name: + container-name1: + mountPath: some/path + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [mountPath] to start with a forward slash [/] + + - it: should fail with non-dict targetSelect.workloadName + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + targetSelector: + workload-name: string + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [targetSelector.workload-name] to be a [dict], but got [string] + + - it: should fail with empty targetSelect.workloadName + set: + image: *image + workload: + workload-name: *workload + persistence: + vol-name: + enabled: true + type: pvc + targetSelector: + workload-name: {} + asserts: + - failedTemplate: + errorMessage: Persistence - Expected non-empty [targetSelector.workload-name] diff --git a/charts/library/common-test/tests/cronjob/metadata_test.yaml b/charts/library/common-test/tests/cronjob/metadata_test.yaml new file mode 100644 index 00000000000..4e1e3cb1d6c --- /dev/null +++ b/charts/library/common-test/tests/cronjob/metadata_test.yaml @@ -0,0 +1,201 @@ +suite: cronjob metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with cronjob created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "*/1 * * * *" + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + podSpec: + labels: + pod-label1: pod-label1 + pod-label2: "{{ .Values.label2 }}" + annotations: + pod-annotation1: pod-annotation1 + pod-annotation2: "{{ .Values.annotation2 }}" + asserts: + - documentIndex: &cronJobDoc 0 + isKind: + of: CronJob + - documentIndex: *cronJobDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *cronJobDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *cronJobDoc + equal: + path: spec.jobTemplate.spec.template.metadata.labels + value: + pod.name: workload-name + pod.lifecycle: fleeting + app: common-test-1.0.0 + release: test-release-name + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: v9.9.9 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + g_label1: global_label1 + g_label2: global_label2 + pod-label1: pod-label1 + pod-label2: global_label2 + - documentIndex: *cronJobDoc + isSubset: + path: spec.jobTemplate.spec.template.metadata.annotations + content: + pod-annotation1: pod-annotation1 + pod-annotation2: global_annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/cnpg + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/configmaps + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/mariadb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/mongodb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/persistence + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/redis + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + matchRegex: + path: spec.jobTemplate.spec.template.metadata.annotations.checksum/solr + pattern: ^[0-9a-f]{64}$ + - documentIndex: *cronJobDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *cronJobDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with CronJob created with object namespace from tpl + set: + key: some-namespace + workload: + workload-name: + enabled: true + primary: true + type: CronJob + namespace: "{{ .Values.key }}" + schedule: "*/1 * * * *" + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with CronJob created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "*/1 * * * *" + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with CronJob created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "*/1 * * * *" + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/cronjob/spec_test.yaml b/charts/library/common-test/tests/cronjob/spec_test.yaml new file mode 100644 index 00000000000..388ca06804e --- /dev/null +++ b/charts/library/common-test/tests/cronjob/spec_test.yaml @@ -0,0 +1,126 @@ +suite: cronjob spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with workload enabled + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "* * * * *" + podSpec: {} + asserts: + - documentIndex: &cronJobDoc 0 + isKind: + of: CronJob + - documentIndex: *cronJobDoc + isAPIVersion: + of: batch/v1 + - documentIndex: *cronJobDoc + isSubset: + path: spec + content: + schedule: "* * * * *" + timeZone: UTC + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 3 + startingDeadlineSeconds: 600 + - documentIndex: *cronJobDoc + isSubset: + path: spec.jobTemplate.spec + content: + backoffLimit: 5 + completionMode: NonIndexed + completions: + parallelism: 1 + ttlSecondsAfterFinished: 120 + + - it: should apply spec correctly + set: + cron: "*/5 * * * *" + someTimezone: America/New_York + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "{{ .Values.cron }}" + timezone: "{{ .Values.someTimezone }}" + concurrencyPolicy: Allow + failedJobsHistoryLimit: 2 + successfulJobsHistoryLimit: 4 + startingDeadlineSeconds: 100 + backoffLimit: 5 + completionMode: Indexed + completions: 5 + parallelism: 5 + ttlSecondsAfterFinished: 100 + activeDeadlineSeconds: 100 + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + isSubset: + path: spec + content: + schedule: "*/5 * * * *" + concurrencyPolicy: Allow + failedJobsHistoryLimit: 2 + successfulJobsHistoryLimit: 4 + startingDeadlineSeconds: 100 + timeZone: America/New_York + - documentIndex: *cronJobDoc + isSubset: + path: spec.jobTemplate.spec + content: + backoffLimit: 5 + completionMode: Indexed + completions: 5 + parallelism: 5 + ttlSecondsAfterFinished: 100 + activeDeadlineSeconds: 100 + + - it: should set suspend to true + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "*/5 * * * *" + suspend: true + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + isSubset: + path: spec + content: + schedule: "*/5 * * * *" + timeZone: UTC + suspend: true + + - it: should set suspend to true on stopAll + set: + global: + stopAll: true + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "*/5 * * * *" + suspend: false + podSpec: {} + asserts: + - documentIndex: *cronJobDoc + isSubset: + path: spec + content: + schedule: "*/5 * * * *" + timeZone: UTC + suspend: true diff --git a/charts/library/common-test/tests/cronjob/validation_test.yaml b/charts/library/common-test/tests/cronjob/validation_test.yaml new file mode 100644 index 00000000000..bb56c77add3 --- /dev/null +++ b/charts/library/common-test/tests/cronjob/validation_test.yaml @@ -0,0 +1,60 @@ +suite: cronjob validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with invalid concurrencyPolicy + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + concurrencyPolicy: not-a-policy + podSpec: {} + asserts: + - failedTemplate: + errorMessage: CronJob - Expected [concurrencyPolicy] to be one of [Allow, Forbid, Replace], but got [not-a-policy] + + - it: should fail with empty schedule + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: + podSpec: {} + asserts: + - failedTemplate: + errorMessage: CronJob - Expected non-empty [schedule] + + - it: should fail with invalid completionMode (make sure job validation kicks in) + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "* * * * *" + completionMode: not-a-mode + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Job - Expected [completionMode] to be one of [Indexed, NonIndexed], but got [not-a-mode] + + - it: should fail with namespace longer than 63 characters + set: + workload: + workload-name: + enabled: true + primary: true + type: CronJob + schedule: "* * * * *" + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + podSpec: {} + asserts: + - failedTemplate: + errorMessage: CronJob - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. diff --git a/charts/library/common-test/tests/daemonset/metadata_test.yaml b/charts/library/common-test/tests/daemonset/metadata_test.yaml new file mode 100644 index 00000000000..91fcc6aa297 --- /dev/null +++ b/charts/library/common-test/tests/daemonset/metadata_test.yaml @@ -0,0 +1,255 @@ +suite: daemonset metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with daemonset created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + podSpec: + labels: + pod-label1: pod-label1 + pod-label2: "{{ .Values.label2 }}" + annotations: + pod-annotation1: pod-annotation1 + pod-annotation2: "{{ .Values.annotation2 }}" + asserts: + - documentIndex: &daemonSetDoc 0 + isKind: + of: DaemonSet + - documentIndex: *daemonSetDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *daemonSetDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *daemonSetDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *daemonSetDoc + equal: + path: spec.template.metadata.labels + value: + pod.name: workload-name + pod.lifecycle: permanent + app: common-test-1.0.0 + release: test-release-name + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: v9.9.9 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + g_label1: global_label1 + g_label2: global_label2 + pod-label1: pod-label1 + pod-label2: global_label2 + + - it: should pass with 2 daemonset created with correct selector labels + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + other-workload-name: + enabled: true + primary: false + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + isKind: + of: DaemonSet + - documentIndex: *daemonSetDoc + equal: + path: metadata.name + value: test-release-name-common-test-other-workload-name + - documentIndex: *daemonSetDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *daemonSetDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: other-workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *daemonSetDoc + isSubset: + path: spec.template.metadata.labels + content: + pod.name: other-workload-name + pod.lifecycle: permanent + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/cnpg + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/configmaps + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mariadb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mongodb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/persistence + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/redis + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *daemonSetDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/solr + pattern: ^[0-9a-f]{64}$ + - documentIndex: &otherDaemonSetDoc 1 + isKind: + of: DaemonSet + - documentIndex: *otherDaemonSetDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *otherDaemonSetDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *otherDaemonSetDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *otherDaemonSetDoc + isSubset: + path: spec.template.metadata.labels + content: + pod.name: workload-name + pod.lifecycle: permanent + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + + - it: should pass with DaemonSet created with object namespace from tpl + set: + key: some-namespace + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + namespace: "{{ .Values.key }}" + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with DaemonSet created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with DaemonSet created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/daemonset/spec_test.yaml b/charts/library/common-test/tests/daemonset/spec_test.yaml new file mode 100644 index 00000000000..6f7314fc552 --- /dev/null +++ b/charts/library/common-test/tests/daemonset/spec_test.yaml @@ -0,0 +1,96 @@ +suite: daemonset spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with workload enabled + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: &daemonSetDoc 0 + isKind: + of: DaemonSet + - documentIndex: *daemonSetDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *daemonSetDoc + isSubset: + path: spec + content: + revisionHistoryLimit: 3 + updateStrategy: + type: RollingUpdate + + - it: should apply spec correctly + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + revisionHistoryLimit: 4 + strategy: RollingUpdate + rollingUpdate: + maxSurge: 5 + maxUnavailable: 5 + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + isSubset: + path: spec + content: + revisionHistoryLimit: 4 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 5 + maxUnavailable: 5 + + - it: should apply maxSurge with 0 + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + strategy: RollingUpdate + rollingUpdate: + maxSurge: 0 + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + isSubset: + path: spec + content: + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + + - it: should apply maxUnavailable with 0 + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + strategy: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + isSubset: + path: spec + content: + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 diff --git a/charts/library/common-test/tests/daemonset/validation_test.yaml b/charts/library/common-test/tests/daemonset/validation_test.yaml new file mode 100644 index 00000000000..a21ede1b369 --- /dev/null +++ b/charts/library/common-test/tests/daemonset/validation_test.yaml @@ -0,0 +1,46 @@ +suite: daemonset validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with invalid strategy + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + strategy: not-a-strategy + podSpec: {} + asserts: + - failedTemplate: + errorMessage: DaemonSet - Expected [strategy] to be one of [OnDelete, RollingUpdate], but got [not-a-strategy] + + - it: should fail with rollingUpdate not a dict + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + strategy: RollingUpdate + rollingUpdate: "not a dict" + podSpec: {} + asserts: + - failedTemplate: + errorMessage: DaemonSet - Expected [rollingUpdate] to be a dictionary, but got [string] + + - it: should fail with namespace longer than 63 characters + set: + workload: + workload-name: + enabled: true + primary: true + type: DaemonSet + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + podSpec: {} + asserts: + - failedTemplate: + errorMessage: DaemonSet - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. diff --git a/charts/library/common-test/tests/defaults/defaults-test.yaml b/charts/library/common-test/tests/defaults/defaults-test.yaml new file mode 100644 index 00000000000..28b097fdaf2 --- /dev/null +++ b/charts/library/common-test/tests/defaults/defaults-test.yaml @@ -0,0 +1,141 @@ +suite: default test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with defaults + set: + service: + main: + enabled: true + ports: + main: + enabled: true + port: 1025 + workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + asserts: + - hasDocuments: + count: 2 + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: &serviceDoc 1 + isKind: + of: Service + - documentIndex: *serviceDoc + isAPIVersion: + of: v1 + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + replicas: 1 + revisionHistoryLimit: 3 + strategy: + type: Recreate + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec + content: + serviceAccountName: default + automountServiceAccountToken: false + runtimeClassName: + hostNetwork: false + hostPID: false + shareProcessNamespace: false + enableServiceLinks: false + restartPolicy: Always + dnsPolicy: ClusterFirst + dnsConfig: + options: + - name: ndots + value: "1" + terminationGracePeriodSeconds: 60 + securityContext: + fsGroup: 568 + fsGroupChangePolicy: OnRootMismatch + supplementalGroups: + - 568 + sysctls: [] + - documentIndex: *deploymentDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec + content: + volumes: + - name: devshm + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: shared + emptyDir: {} + - name: tmp + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: varlogs + emptyDir: + medium: Memory + sizeLimit: 8Gi + - name: varrun + emptyDir: + medium: Memory + sizeLimit: 8Gi + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.containers[0] + content: + livenessProbe: + failureThreshold: 5 + httpGet: + path: / + port: 1025 + scheme: HTTP + initialDelaySeconds: 12 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 4 + httpGet: + path: / + port: 1025 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 12 + successThreshold: 2 + timeoutSeconds: 5 + startupProbe: + failureThreshold: 60 + httpGet: + path: / + port: 1025 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 3 diff --git a/charts/library/common-test/tests/defaults/enabled_test.yaml b/charts/library/common-test/tests/defaults/enabled_test.yaml new file mode 100644 index 00000000000..986633c74cb --- /dev/null +++ b/charts/library/common-test/tests/defaults/enabled_test.yaml @@ -0,0 +1,78 @@ +suite: default test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail without enabled key in workload + set: + workload: + workload-name: + type: Deployment + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Workload - Expected the key [enabled] in [workload.workload-name] to exist + + - it: should fail without enabled key in containers + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name: + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Container - Expected the key [enabled] in [containers.container-name] to exist + + - it: should fail without enabled key in initContainers + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + initContainers: + container-name: + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + asserts: + - failedTemplate: + errorMessage: Init Container - Expected the key [enabled] in [initContainers.container-name] to exist + + - it: should fail without enabled key in service + set: + service: + service-name: + primary: true + asserts: + - failedTemplate: + errorMessage: Service - Expected the key [enabled] in [service.service-name] to exist + + - it: should fail without enabled key in persistence + set: + persistence: + persistence-name: + primary: true + asserts: + - failedTemplate: + errorMessage: Persistence - Expected the key [enabled] in [persistence.persistence-name] to exist diff --git a/charts/library/common-test/tests/deployment/metadata_test.yaml b/charts/library/common-test/tests/deployment/metadata_test.yaml new file mode 100644 index 00000000000..a8a1ca3d9ca --- /dev/null +++ b/charts/library/common-test/tests/deployment/metadata_test.yaml @@ -0,0 +1,255 @@ +suite: deployment metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with deployment created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + workload: + workload-name: + enabled: true + primary: true + type: Deployment + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + podSpec: + labels: + pod-label1: pod-label1 + pod-label2: "{{ .Values.label2 }}" + annotations: + pod-annotation1: pod-annotation1 + pod-annotation2: "{{ .Values.annotation2 }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *deploymentDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *deploymentDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *deploymentDoc + equal: + path: spec.template.metadata.labels + value: + pod.name: workload-name + pod.lifecycle: permanent + app: common-test-1.0.0 + release: test-release-name + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: v9.9.9 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + g_label1: global_label1 + g_label2: global_label2 + pod-label1: pod-label1 + pod-label2: global_label2 + + - it: should pass with 2 deployment created with correct selector labels + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + other-workload-name: + enabled: true + primary: false + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: metadata.name + value: test-release-name-common-test-other-workload-name + - documentIndex: *deploymentDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *deploymentDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: other-workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.metadata.labels + content: + pod.name: other-workload-name + pod.lifecycle: permanent + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/cnpg + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/configmaps + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mariadb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mongodb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/persistence + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/redis + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *deploymentDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/solr + pattern: ^[0-9a-f]{64}$ + - documentIndex: &otherDeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *otherDeploymentDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *otherDeploymentDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: *otherDeploymentDoc + equal: + path: spec.selector.matchLabels + value: + pod.name: workload-name + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + - documentIndex: *otherDeploymentDoc + isSubset: + path: spec.template.metadata.labels + content: + pod.name: workload-name + pod.lifecycle: permanent + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + + - it: should pass with deployment created with object namespace from tpl + set: + key: some-namespace + workload: + workload-name: + enabled: true + primary: true + type: Deployment + namespace: "{{ .Values.key }}" + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with deployment created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with deployment created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/deployment/spec_test.yaml b/charts/library/common-test/tests/deployment/spec_test.yaml new file mode 100644 index 00000000000..a91a68e658a --- /dev/null +++ b/charts/library/common-test/tests/deployment/spec_test.yaml @@ -0,0 +1,133 @@ +suite: deployment spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with workload enabled + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + replicas: 1 + revisionHistoryLimit: 3 + strategy: + type: Recreate + + - it: should apply spec correctly + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + replicas: 2 + revisionHistoryLimit: 4 + strategy: RollingUpdate + rollingUpdate: + maxSurge: 5 + maxUnavailable: 5 + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + replicas: 2 + revisionHistoryLimit: 4 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 5 + maxUnavailable: 5 + + - it: should apply maxSurge with 0 + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + strategy: RollingUpdate + rollingUpdate: + maxSurge: 0 + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + + - it: should apply maxUnavailable with 0 + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + strategy: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + + - it: should set replicas to 0 + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + replicas: 0 + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + replicas: 0 + + - it: should set replicas to 0 on stopAll + set: + global: + stopAll: true + workload: + workload-name: + enabled: true + primary: true + type: Deployment + replicas: 2 + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isSubset: + path: spec + content: + replicas: 0 diff --git a/charts/library/common-test/tests/deployment/validation_test.yaml b/charts/library/common-test/tests/deployment/validation_test.yaml new file mode 100644 index 00000000000..83fc7a8e8cc --- /dev/null +++ b/charts/library/common-test/tests/deployment/validation_test.yaml @@ -0,0 +1,46 @@ +suite: deployment validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with invalid strategy + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + strategy: not-a-strategy + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Deployment - Expected [strategy] to be one of [Recreate, RollingUpdate], but got [not-a-strategy] + + - it: should fail with rollingUpdate not a dict + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + strategy: RollingUpdate + rollingUpdate: "not a dict" + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Deployment - Expected [rollingUpdate] to be a dictionary, but got [string] + + - it: should fail with namespace longer than 63 characters + set: + workload: + workload-name: + enabled: true + primary: true + type: Deployment + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Deployment - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. diff --git a/charts/library/common-test/tests/extraTpl/extratpl_test.yaml b/charts/library/common-test/tests/extraTpl/extratpl_test.yaml new file mode 100644 index 00000000000..0c875ace65a --- /dev/null +++ b/charts/library/common-test/tests/extraTpl/extratpl_test.yaml @@ -0,0 +1,68 @@ +suite: extra tpl test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with extra tpl + set: + someKey: someValue + extraTpl: + - | + apiVersion: v1 + kind: Service + metadata: + name: test-release-name-common-test + spec: + type: ClusterIP + publishNotReadyAddresses: false + ports: + - name: main + port: 80 + protocol: TCP + targetPort: 80 + - | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: test-release-name-common-test + labels: + some-label: {{ .Values.someKey }} + spec: + template: + spec: + containers: + - name: test-release-name-common-test + - "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: {{ .Values.someKey }}" + asserts: + - documentIndex: &serviceDoc 0 + isKind: + of: Service + - documentIndex: *serviceDoc + equal: + path: spec.ports[0].name + value: main + - documentIndex: &deploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: metadata.labels.some-label + value: someValue + - documentIndex: &otherDeploymentDoc 2 + isKind: + of: Deployment + - documentIndex: *otherDeploymentDoc + equal: + path: metadata.name + value: someValue + + # Failures + - it: should fail with empty item in extra tpl + set: + extraTpl: + - "" + asserts: + - failedTemplate: + errorMessage: Extra tpl - Expected non-empty [extraTpl] item diff --git a/charts/library/common-test/tests/imagePullSecret/data_test.yaml b/charts/library/common-test/tests/imagePullSecret/data_test.yaml new file mode 100644 index 00000000000..b2c13b9c14a --- /dev/null +++ b/charts/library/common-test/tests/imagePullSecret/data_test.yaml @@ -0,0 +1,51 @@ +suite: imagePullSecret data test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with data + set: + imagePullSecret: + my-secret1: + enabled: true + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - documentIndex: &secretDoc 0 + isKind: + of: Secret + - documentIndex: *secretDoc + equal: + path: data + value: + .dockerconfigjson: eyJhdXRocyI6eyJyZWciOnsiYXV0aCI6ImRYTmxjanB3WVhOeiIsImVtYWlsIjoibWFpbCIsInBhc3N3b3JkIjoicGFzcyIsInVzZXJuYW1lIjoidXNlciJ9fX0= + - documentIndex: *secretDoc + equal: + path: type + value: kubernetes.io/dockerconfigjson + + - it: should pass with data from tpl + set: + registry: quay.io + user: user + pass: secret_pass + email: mail@example.com + imagePullSecret: + my-secret1: + enabled: true + data: + registry: "{{ .Values.registry }}" + username: "{{ .Values.user }}" + password: "{{ .Values.pass }}" + email: "{{ .Values.email }}" + asserts: + - documentIndex: *secretDoc + equal: + path: data + value: + .dockerconfigjson: eyJhdXRocyI6eyJxdWF5LmlvIjp7ImF1dGgiOiJkWE5sY2pwelpXTnlaWFJmY0dGemN3PT0iLCJlbWFpbCI6Im1haWxAZXhhbXBsZS5jb20iLCJwYXNzd29yZCI6InNlY3JldF9wYXNzIiwidXNlcm5hbWUiOiJ1c2VyIn19fQ== diff --git a/charts/library/common-test/tests/imagePullSecret/metadata_test.yaml b/charts/library/common-test/tests/imagePullSecret/metadata_test.yaml new file mode 100644 index 00000000000..b956b76eee8 --- /dev/null +++ b/charts/library/common-test/tests/imagePullSecret/metadata_test.yaml @@ -0,0 +1,137 @@ +suite: imagePullSecret metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with secret created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + imagePullSecret: + my-secret1: + enabled: true + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - documentIndex: &secretDoc 0 + isKind: + of: Secret + - documentIndex: *secretDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *secretDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-secret1 + - documentIndex: *secretDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with secret created with object namespace from tpl + set: + key: some-namespace + imagePullSecret: + my-secret1: + enabled: true + namespace: "{{ .Values.key }}" + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - documentIndex: *secretDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with secret created with namespace from global with tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + imagePullSecret: + my-secret1: + enabled: true + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - documentIndex: *secretDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with secret created with namespace from root with tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + imagePullSecret: + my-secret1: + enabled: true + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - documentIndex: *secretDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/imagePullSecret/name_test.yaml b/charts/library/common-test/tests/imagePullSecret/name_test.yaml new file mode 100644 index 00000000000..67853ef457d --- /dev/null +++ b/charts/library/common-test/tests/imagePullSecret/name_test.yaml @@ -0,0 +1,45 @@ +suite: imagePullSecret name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + imagePullSecret: + my-pull-secret1: + enabled: true + data: + registry: reg1 + username: user1 + password: pass1 + email: mail1 + my-pull-secret2: + enabled: true + data: + registry: reg2 + username: user2 + password: pass2 + email: mail2 + asserts: + - documentIndex: &secretDoc 0 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-pull-secret1 + - documentIndex: &otherSecretDoc 1 + isKind: + of: Secret + - documentIndex: *otherSecretDoc + isAPIVersion: + of: v1 + - documentIndex: *otherSecretDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-pull-secret2 diff --git a/charts/library/common-test/tests/imagePullSecret/validation_test.yaml b/charts/library/common-test/tests/imagePullSecret/validation_test.yaml new file mode 100644 index 00000000000..c2b0e24aad8 --- /dev/null +++ b/charts/library/common-test/tests/imagePullSecret/validation_test.yaml @@ -0,0 +1,147 @@ +suite: imagePullSecret validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with name longer than 253 characters + set: + imagePullSecret: + my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-long-long-long-long-long-name: + enabled: true + data: &data + registry: reg + username: user + password: pass + email: mail + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-name-that-is-longer-than-253-characters-my-pull-secret-super-long-long-long-long-long-long-name] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with name starting with underscore + set: + imagePullSecret: + _my-pull-secret: + enabled: true + data: *data + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-_my-pull-secret] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with labels not a dict + set: + imagePullSecret: + my-pull-secret: + enabled: true + labels: "not a dict" + data: *data + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected [labels] to be a dictionary, but got [string] + + - it: should fail with annotations not a dict + set: + imagePullSecret: + my-pull-secret: + enabled: true + annotations: "not a dict" + data: *data + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected [annotations] to be a dictionary, but got [string] + + - it: should fail with data not a dict + set: + imagePullSecret: + my-pull-secret: + enabled: true + data: "not a dict" + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected [data] to be a dictionary, but got [string] + + - it: should fail with empty data + set: + imagePullSecret: + my-pull-secret: + enabled: true + data: {} + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected non-empty [data] + + - it: should fail with empty registry key + set: + imagePullSecret: + my-pull-secret: + enabled: true + type: "" + data: + registry: "" + username: user + password: pass + email: mail + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected non-empty [registry] + + - it: should fail with empty username key + set: + imagePullSecret: + my-pull-secret: + enabled: true + type: "" + data: + registry: registry + username: "" + password: pass + email: mail + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected non-empty [username] + + - it: should fail with empty password key + set: + imagePullSecret: + my-pull-secret: + enabled: true + type: "" + data: + registry: registry + username: user + password: "" + email: mail + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected non-empty [password] + + - it: should fail with empty email key + set: + imagePullSecret: + my-pull-secret: + enabled: true + type: "" + data: + registry: registry + username: user + password: pass + email: "" + asserts: + - failedTemplate: + errorMessage: Image Pull Secret - Expected non-empty [email] + + - it: should fail with namespace longer than 63 characters + set: + imagePullSecret: + my-secret1: + enabled: true + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + data: + registry: reg + username: user + password: pass + email: mail + asserts: + - failedTemplate: + errorMessage: Secret - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. diff --git a/charts/library/common-test/tests/ingress/cert_manager_test.yaml b/charts/library/common-test/tests/ingress/cert_manager_test.yaml new file mode 100644 index 00000000000..4291c5687b7 --- /dev/null +++ b/charts/library/common-test/tests/ingress/cert_manager_test.yaml @@ -0,0 +1,119 @@ +suite: ingress - cert manager metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with ingress created with annotations from cert manager + set: + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: &traefik + enabled: false + certManager: + enabled: true + certificateIssuer: some-issuer + hosts: &hosts + - host: test-host + paths: + - path: /test-path + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + cert-manager.io/cluster-issuer: some-issuer + cert-manager.io/private-key-rotation-policy: Always + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with ingress created without cert manager annotations when cert manager false + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: *traefik + certManager: + enabled: false + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isNotSubset: + path: metadata.annotations + content: + cert-manager.io/cluster-issuer: some-issuer + cert-manager.io/private-key-rotation-policy: Always + # Failures + - it: should fail with missing certificateIssuer + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + certManager: + enabled: true + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected a non-empty [integrations.certManager.certificateIssuer] + + - it: should fail with certificateIssuer not a string + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + certManager: + enabled: true + certificateIssuer: + - some-issuer + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.certManager.certificateIssuer] to be a [string], but got [slice] diff --git a/charts/library/common-test/tests/ingress/homepage_test.yaml b/charts/library/common-test/tests/ingress/homepage_test.yaml new file mode 100644 index 00000000000..269929af9ab --- /dev/null +++ b/charts/library/common-test/tests/ingress/homepage_test.yaml @@ -0,0 +1,296 @@ +suite: ingress - homepage metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with ingress created with annotations from homepage enabled + set: + k1: some-name + k2: some-desc + k3: some-icon + k4: some-url + k5: some-type + k6: some-group + service: + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: https + port: 9443 + my-service2: + enabled: true + ports: + port-2: + enabled: true + primary: true + port: 80 + someHost: test-host + somePath: /test-path + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: &traefik + enabled: false + homepage: + enabled: true + hosts: + - host: "{{ .Values.someHost }}" + paths: + - path: "{{ .Values.somePath }}" + my-ingress2: + enabled: true + integrations: + traefik: *traefik + homepage: + enabled: true + name: "{{ .Values.k1 }}" + description: "{{ .Values.k2 }}" + icon: "{{ .Values.k3 }}" + group: "{{ .Values.k6 }}" + weight: 1 + podSelector: + - main + - other + widget: + url: "{{ .Values.k4 }}" + type: "{{ .Values.k5 }}" + custom: + some-key: some-value + some-other-key: some-other-value + some-empty-key: "" + customkv: + - key: some-key-slice + value: some-value-slice + - key: some-other-key-slice + value: some-other-value-slice + hosts: &hosts + - host: test-host + paths: + - path: /test-path + my-ingress3: + enabled: true + targetSelector: + my-service2: port-2 + integrations: + traefik: *traefik + homepage: + enabled: true + hosts: + - host: "{{ .Values.someHost }}" + paths: + - path: "{{ .Values.somePath }}" + my-ingress4: + enabled: true + hosts: *hosts + integrations: + traefik: *traefik + homepage: + enabled: true + widget: + enabled: false + url: some-url-4 + type: some-type-4 + custom: + some-key: some-value + some-other-key: some-other-value + customkv: + - key: some-key-slice + value: some-value-slice + - key: some-other-key-slice + value: some-other-value-slice + - key: some-empty-key-slice + value: "" + asserts: + - documentIndex: &ingressDoc 2 + isKind: + of: Ingress + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + gethomepage.dev/enabled: "true" + gethomepage.dev/name: TestReleaseName + gethomepage.dev/description: Helper chart to test different use cases of the common library + gethomepage.dev/href: https://test-host/test-path + gethomepage.dev/widget.url: https://test-release-name-common-test.test-release-namespace.svc:9443 + gethomepage.dev/icon: https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png + gethomepage.dev/widget.type: commontest + gethomepage.dev/pod-selector: app.kubernetes.io/instance=test-release-name,pod.lifecycle in (permanent) + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: &otherIngressDoc 3 + isKind: + of: Ingress + - documentIndex: *otherIngressDoc + isSubset: + path: metadata.annotations + content: + gethomepage.dev/enabled: "true" + gethomepage.dev/name: some-name + gethomepage.dev/description: some-desc + gethomepage.dev/group: some-group + gethomepage.dev/href: https://test-host/test-path + gethomepage.dev/icon: some-icon + gethomepage.dev/widget.url: some-url + gethomepage.dev/weight: "1" + gethomepage.dev/widget.type: some-type + gethomepage.dev/pod-selector: pod.name in (main,other),pod.lifecycle in (permanent) + gethomepage.dev/widget.some-key: some-value + gethomepage.dev/widget.some-other-key: some-other-value + gethomepage.dev/widget.some-key-slice: some-value-slice + gethomepage.dev/widget.some-other-key-slice: some-other-value-slice + - documentIndex: *otherIngressDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-ingress2 + - documentIndex: *otherIngressDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: &thirdIngressDoc 4 + isKind: + of: Ingress + - documentIndex: *thirdIngressDoc + isSubset: + path: metadata.annotations + content: + gethomepage.dev/enabled: "true" + gethomepage.dev/name: TestReleaseName + gethomepage.dev/description: Helper chart to test different use cases of the common library + gethomepage.dev/href: https://test-host/test-path + gethomepage.dev/widget.url: http://test-release-name-common-test-my-service2.test-release-namespace.svc:80 + gethomepage.dev/icon: https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png + gethomepage.dev/widget.type: commontest + gethomepage.dev/pod-selector: app.kubernetes.io/instance=test-release-name,pod.lifecycle in (permanent) + - documentIndex: *thirdIngressDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-ingress3 + - documentIndex: *thirdIngressDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: &fourthIngressDoc 5 + isKind: + of: Ingress + - documentIndex: *fourthIngressDoc + isSubset: + path: metadata.annotations + content: + gethomepage.dev/enabled: "true" + gethomepage.dev/name: TestReleaseName + gethomepage.dev/description: Helper chart to test different use cases of the common library + gethomepage.dev/href: https://test-host/test-path + gethomepage.dev/icon: https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png + gethomepage.dev/pod-selector: app.kubernetes.io/instance=test-release-name,pod.lifecycle in (permanent) + + # Failures + - it: should fail with podSelector not a slice + set: + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: https + port: 9443 + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: false + homepage: + enabled: true + podSelector: main + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.homepage.podSelector] to be a [slice], but got [string] + + - it: should fail with custom widget not a map + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: false + homepage: + enabled: true + widget: + custom: "not a map" + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.homepage.widget.custom] to be a [map], but got [string] + + - it: should fail with customkv widget not a slice + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: false + homepage: + enabled: true + widget: + customkv: "not a slice" + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.homepage.widget.customkv] to be a [slice], but got [string] + + - it: should fail with customkv having empty key + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: false + homepage: + enabled: true + widget: + customkv: + - key: "" + value: some-value + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [key] in [integrations.homepage.widget.customkv] diff --git a/charts/library/common-test/tests/ingress/metadata_test.yaml b/charts/library/common-test/tests/ingress/metadata_test.yaml new file mode 100644 index 00000000000..dd799705017 --- /dev/null +++ b/charts/library/common-test/tests/ingress/metadata_test.yaml @@ -0,0 +1,184 @@ +suite: ingress metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with ingress created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress1: + enabled: true + primary: true + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + integrations: &integrations + traefik: + enabled: false + hosts: &hosts + - host: test-host + paths: + - path: /test-path + my-ingress2: + enabled: true + primary: false + integrations: *integrations + hosts: *hosts + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: test-release-namespace + - documentIndex: &otherIngressDoc 2 + isKind: + of: Ingress + - documentIndex: *otherIngressDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: test-release-name + - documentIndex: *otherIngressDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-ingress2 + - documentIndex: *otherIngressDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with ingress created with object namespace from tpl + set: + key: some-namespace + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + namespace: "{{ .Values.key }}" + integrations: *integrations + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with ingress created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: *integrations + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with ingress created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: *integrations + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/ingress/name_test.yaml b/charts/library/common-test/tests/ingress/name_test.yaml new file mode 100644 index 00000000000..6d01518695e --- /dev/null +++ b/charts/library/common-test/tests/ingress/name_test.yaml @@ -0,0 +1,69 @@ +suite: ingress name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + service: + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress1: + enabled: true + primary: true + hosts: &hosts + - host: test-host + paths: + - path: /test-path + integrations: &integrations + traefik: + enabled: false + my-ingress2: + enabled: true + hosts: *hosts + integrations: *integrations + my-ingress3: + enabled: true + expandObjectName: false + hosts: *hosts + integrations: *integrations + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + isAPIVersion: + of: networking.k8s.io/v1 + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: &otherIngressDoc 2 + isKind: + of: Ingress + - documentIndex: *otherIngressDoc + isAPIVersion: + of: networking.k8s.io/v1 + - documentIndex: *otherIngressDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-ingress2 + - documentIndex: &thirdIngressDoc 3 + isKind: + of: Ingress + - documentIndex: *thirdIngressDoc + isAPIVersion: + of: networking.k8s.io/v1 + - documentIndex: *thirdIngressDoc + equal: + path: metadata.name + value: my-ingress3 diff --git a/charts/library/common-test/tests/ingress/rules_test.yaml b/charts/library/common-test/tests/ingress/rules_test.yaml new file mode 100644 index 00000000000..2b36ef01bdb --- /dev/null +++ b/charts/library/common-test/tests/ingress/rules_test.yaml @@ -0,0 +1,250 @@ +suite: ingress - rules test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with ingress created with ingressClassName + set: + service: + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + ingressClassName: some-class + hosts: + - host: test-host + paths: + - path: /test-path + integrations: &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: some-class + + - it: should pass with ingress created with rules + set: + service: + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + someHost: test-host + somePath: /test-path + someType: Exact + ingress: + my-ingress: + enabled: true + primary: true + hosts: &hosts + - host: "{{ .Values.someHost }}" + paths: + - path: "{{ .Values.somePath }}" + pathType: "{{ .Values.someType }}" + - host: "*.test-other-host" + paths: + - path: /test-other-path + - path: /test-other-path2 + overrideService: + name: some-other-service + expandObjectName: false + port: 8080 + - host: "host-target-primary-service" + paths: + - path: /subpath + overrideService: + # It is primary, so the backend target + # must be just the fullname + name: my-service + port: 8080 + - host: "host-target-override-no-expand" + paths: + - path: /subpath2 + overrideService: + name: my-custom-service + expandObjectName: false + port: 8080 + - host: "host-without-explicit-paths" + - host: "host-without-explicit-path" + paths: + - pathType: Exact + integrations: *integrations + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: spec.rules + value: + - host: test-host + http: + paths: + - path: /test-path + pathType: Exact + backend: + service: + name: test-release-name-common-test + port: + number: 80 + - host: "*.test-other-host" + http: + paths: + - path: /test-other-path + pathType: Prefix + backend: + service: + name: test-release-name-common-test + port: + number: 80 + - path: /test-other-path2 + pathType: Prefix + backend: + service: + name: some-other-service + port: + number: 8080 + - host: "host-target-primary-service" + http: + paths: + - path: /subpath + pathType: Prefix + backend: + service: + name: test-release-name-common-test + port: + number: 8080 + - host: host-target-override-no-expand + http: + paths: + - path: /subpath2 + pathType: Prefix + backend: + service: + name: my-custom-service + port: + number: 8080 + - host: "host-without-explicit-paths" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: test-release-name-common-test + port: + number: 80 + - host: "host-without-explicit-path" + http: + paths: + - path: / + pathType: Exact + backend: + service: + name: test-release-name-common-test + port: + number: 80 + + - it: should pass with ingress created with rules with targetSelector + set: + service: + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + my-service2: + enabled: true + ports: + my-port2: + enabled: true + port: 9000 + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + my-service2: my-port2 + hosts: &hosts + - host: test-host + paths: + - path: /test-path + - host: test-other-host + paths: + - path: /test-other-path + - path: /test-other-path2 + overrideService: + name: other-service + port: 8080 + integrations: *integrations + asserts: + - documentIndex: &ingressDoc 2 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: spec.rules + value: + - host: test-host + http: + paths: + - path: /test-path + pathType: Prefix + backend: + service: + name: test-release-name-common-test-my-service2 + port: + number: 9000 + - host: test-other-host + http: + paths: + - path: /test-other-path + pathType: Prefix + backend: + service: + name: test-release-name-common-test-my-service2 + port: + number: 9000 + - path: /test-other-path2 + pathType: Prefix + backend: + service: + name: test-release-name-common-test-other-service + port: + number: 8080 diff --git a/charts/library/common-test/tests/ingress/stop_test.yaml b/charts/library/common-test/tests/ingress/stop_test.yaml new file mode 100644 index 00000000000..f6250b4d36d --- /dev/null +++ b/charts/library/common-test/tests/ingress/stop_test.yaml @@ -0,0 +1,52 @@ +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: + 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: &integrations + traefik: + enabled: false + homepage: + enabled: true + 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 + - documentIndex: *ingressDoc + isNotSubset: + path: metadata.annotations + content: + gethomepage.dev/enabled: "true" diff --git a/charts/library/common-test/tests/ingress/tls_test.yaml b/charts/library/common-test/tests/ingress/tls_test.yaml new file mode 100644 index 00000000000..e1ba27529ab --- /dev/null +++ b/charts/library/common-test/tests/ingress/tls_test.yaml @@ -0,0 +1,192 @@ +suite: ingress - tls test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with ingress created with certManager integration + set: + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + - host: "*.other-test-host" + paths: + - path: /other-test-path + integrations: &integrations + traefik: + enabled: false + certManager: + enabled: true + certificateIssuer: some-issuer + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + equal: + path: spec.tls + value: + - hosts: + - test-host + secretName: test-release-name-common-test-tls-0 + - hosts: + - "*.other-test-host" + secretName: test-release-name-common-test-tls-1 + + - it: should pass with ingress created with clusterCertificate + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + - host: other-test-host + paths: + - path: /other-test-path + tls: + - hosts: + - test-host + - other-test-host + clusterCertificate: some-cert + - hosts: + - some-other-test-host + clusterCertificate: some-other-cert + integrations: &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.tls + value: + - hosts: + - test-host + - other-test-host + secretName: certificate-issuer-some-cert + - hosts: + - some-other-test-host + secretName: certificate-issuer-some-other-cert + + - it: should pass with ingress created with tls with certificateIssuer + set: + service: *service + otherhost: other-test-host + othercertissuer: some-other-issuer + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + - host: other-test-host + paths: + - path: /other-test-path + tls: + - hosts: + - test-host + - "{{ .Values.otherhost }}" + certificateIssuer: some-issuer + - hosts: + - some-other-test-host + certificateIssuer: "{{ .Values.othercertissuer }}" + integrations: &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.tls + value: + - hosts: + - test-host + - other-test-host + secretName: test-release-name-common-test-tls-0 + - hosts: + - some-other-test-host + secretName: test-release-name-common-test-tls-1 + - documentIndex: &certDoc 2 + isKind: + of: Certificate + - documentIndex: *certDoc + equal: + path: metadata.name + value: test-release-name-common-test-tls-0 + - documentIndex: *certDoc + equal: + path: spec.secretName + value: test-release-name-common-test-tls-0 + - documentIndex: *certDoc + isSubset: + path: spec + content: + secretName: test-release-name-common-test-tls-0 + dnsNames: + - test-host + - other-test-host + issuerRef: + name: some-issuer + kind: ClusterIssuer + group: cert-manager.io + - documentIndex: &otherCertDoc 3 + isKind: + of: Certificate + - documentIndex: *otherCertDoc + equal: + path: metadata.name + value: test-release-name-common-test-tls-1 + - documentIndex: *otherCertDoc + equal: + path: spec.secretName + value: test-release-name-common-test-tls-1 + - documentIndex: *otherCertDoc + isSubset: + path: spec + content: + secretName: test-release-name-common-test-tls-1 + dnsNames: + - some-other-test-host + issuerRef: + name: some-other-issuer + kind: ClusterIssuer + group: cert-manager.io diff --git a/charts/library/common-test/tests/ingress/traefik_test.yaml b/charts/library/common-test/tests/ingress/traefik_test.yaml new file mode 100644 index 00000000000..74b9722efe1 --- /dev/null +++ b/charts/library/common-test/tests/ingress/traefik_test.yaml @@ -0,0 +1,505 @@ +suite: ingress - traefik metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +kubernetesProvider: + scheme: + "traefik.io/v1alpha1/Middleware": + namespaced: true + gvr: + group: "traefik.io" + version: "v1alpha1" + resource: "middlewares" + objects: + - kind: Middleware + apiVersion: traefik.io/v1alpha1 + metadata: + name: my-test-middleware + namespace: other-test-release-namespace +tests: + - it: should pass with ingress created with annotations from traefik + set: + global: &global + traefik: + fixedMiddlewares: + - name: chain-basic + namespace: test-release-namespace + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + hosts: &hosts + - host: test-host + paths: + - path: /test-path + asserts: + - documentIndex: &ingressDoc 1 + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + matchRegex: + path: metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *ingressDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with ingress created without traefik annotations when traefik false + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: false + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isNotSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd + + - it: should replace local fixedMiddlewares when allowCors true + set: + service: *service + global: + traefik: + fixedMiddlewares: + - name: chain-basic + namespace: test-release-namespace + allowCorsMiddlewares: + - name: tc-opencors-chain + namespace: test-release-namespace + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + allowCors: true + fixedMiddlewares: + - name: some-fixed-middleware + namespace: test-release-namespace + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-tc-opencors-chain@kubernetescrd + + - it: should replace global fixedMiddlewares when allowCors true + set: + service: *service + global: + traefik: + fixedMiddlewares: + - name: chain-basic + namespace: test-release-namespace + allowCorsMiddlewares: + - name: tc-opencors-chain + namespace: test-release-namespace + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + allowCors: true + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-tc-opencors-chain@kubernetescrd + + - it: should replace global fixedMiddlewares when local fixedMiddlewares is defined + set: + service: *service + global: *global + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + fixedMiddlewares: + - name: some-fixed-middleware + namespace: test-release-namespace + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-some-fixed-middleware@kubernetescrd + + - it: should override default entrypoint(s) + set: + service: *service + global: *global + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - web + - websecure + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: web,websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd + + - it: should not contain fixed middlewares when are disabled + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + enableFixedMiddlewares: false + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + + - it: should add the defined middlewares to the ingress + set: + service: *service + global: *global + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + middlewares: + - name: some-middleware + namespace: test-release-namespace + - name: some-other-middleware + namespace: test-release-namespace + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd,test-release-namespace-some-middleware@kubernetescrd,test-release-namespace-some-other-middleware@kubernetescrd + + - it: should add the the tls annotation + set: + service: *service + global: *global + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + forceTLS: true + entrypoints: + - web + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd + + - it: should not add the the tls annotation + set: + service: *service + global: *global + ingress: + my-ingress: + enabled: true + primary: true + integrations: + traefik: + enabled: true + forceTLS: false + entrypoints: + - web + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd + + - it: should pass when a middleware does not have a namespace but exists as an object (can be looked up) + set: + service: *service + global: *global + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - websecure + middlewares: + - name: my-test-middleware + hosts: *hosts + asserts: + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + isKind: + of: Ingress + - documentIndex: *ingressDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *ingressDoc + isSubset: + path: metadata.annotations + content: + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: test-release-namespace-chain-basic@kubernetescrd,other-test-release-namespace-my-test-middleware@kubernetescrd + + # Failures + - it: should fail with entrypoint not a slice + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: "not a string" + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.traefik.entrypoints] to be a [slice], but got [string] + + - it: should fail with middlewares not a slice + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + middlewares: "not a slice" + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.traefik.middlewares] to be a [slice], but got [string] + + - it: should fail with fixedMiddlewares not a slice + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + fixedMiddlewares: "not a slice" + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [integrations.traefik.fixedMiddlewares] to be a [slice], but got [string] + + - it: should fail with duplicate middlewares + set: + service: *service + global: *global + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + middlewares: + - name: chain-basic + namespace: test-release-namespace + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Combined traefik middlewares contain duplicates [test-release-namespace-chain-basic@kubernetescrd, test-release-namespace-chain-basic@kubernetescrd] + + - it: should fail with duplicate entrypoints + set: + service: *service + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - websecure + - websecure + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Combined traefik entrypoints contain duplicates [websecure, websecure] + + - it: should fail when a middleware does not have a namespace (or failed to be looked up) + set: + service: *service + global: *global + ingress: + my-ingress1: + enabled: true + primary: true + integrations: + traefik: + enabled: true + entrypoints: + - websecure + middlewares: + - name: some-middleware + hosts: *hosts + asserts: + - failedTemplate: + errorMessage: Ingress - Middleware [some-middleware] is not defined in any namespace. Middleware should be created first. diff --git a/charts/library/common-test/tests/ingress/validation_test.yaml b/charts/library/common-test/tests/ingress/validation_test.yaml new file mode 100644 index 00000000000..590fcb60c65 --- /dev/null +++ b/charts/library/common-test/tests/ingress/validation_test.yaml @@ -0,0 +1,532 @@ +suite: ingress validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail if required is true but enabled is false + set: + service: &service + my-service: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: false + required: true + asserts: + - failedTemplate: + errorMessage: Ingress - Expected ingress [my-ingress] to be enabled. This chart is designed to work only with ingress enabled. + + - it: should fail with name longer than 253 characters + set: + service: *service + ingress: + my-ing: + enabled: true + primary: true + hosts: &hosts + - host: test-host + paths: + - path: /test-path + integrations: &integrations + traefik: + enabled: false + ? my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-long-long-long-long-long-long-long-name + : enabled: true + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-long-long-long-long-long-long-long-name] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with name starting with underscore + set: + service: *service + ingress: + my-ing: + enabled: true + primary: true + hosts: *hosts + _my-ingress: + enabled: true + asserts: + - failedTemplate: + errorMessage: Name [test-release-name-common-test-_my-ingress] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters. + + - it: should fail with namespace longer than 63 characters + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + integrations: *integrations + asserts: + - failedTemplate: + errorMessage: Ingress - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. + + - it: should fail with labels not a dict + set: + ingress: + my-ingress: + enabled: true + primary: true + labels: "not a dict" + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [labels] to be a dictionary, but got [string] + + - it: should fail with annotations not a dict + set: + ingress: + my-ingress: + enabled: true + primary: true + annotations: "not a dict" + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [annotations] to be a dictionary, but got [string] + + - it: should fail with empty enabled + set: + ingress: + my-ingress: + enabled: + asserts: + - failedTemplate: + errorMessage: Ingress - Expected the defined key [enabled] in [ingress.my-ingress] to not be empty + + - it: should fail with targetSelector not a map + set: + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: "not a map" + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [targetSelector] to be a [map], but got [string] + + - it: should fail with targetSelector having more than one key + set: + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + main: main + other: other + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [targetSelector] to have exactly one key, but got [2] + + - it: should fail with targetSelector key missing value + set: + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + main: + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [targetSelector.main] to have a value + + - it: should fail with targetSelector key having non-string value + set: + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + main: + - not a string + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [targetSelector.main] to be a [string], but got [slice] + + - it: should fail with no hosts + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: [] + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [hosts] + + - it: should fail with hosts not a slice + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: not-a-slice + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts] to be a [slice], but got [string] + + - it: should fail with no hosts.host + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [hosts.host] + + - it: should fail with host starting with https:// + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: https://test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.host] to not start with [https://], but got [https://test-host] + + - it: should fail with host starting with http:// + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: http://test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.host] to not start with [http://], but got [http://test-host] + + - it: should fail with host contain ":" + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host:123 + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.host] to not contain [:], but got [test-host:123] + + - it: should fail with paths not a slice + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: not-a-slice + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.paths] to be a [slice], but got [string] + + - it: should fail with invalid pathType + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + pathType: not-a-valid-path-type + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.paths.pathType] to be one of [Prefix, Exact, ImplementationSpecific], but got [not-a-valid-path-type] + + - it: should fail with path not starting with / (only on pathType Exact and Prefix) + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: test-path + pathType: Prefix + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [hosts.paths.path] to start with [/], but got [test-path] + + - it: should fail if name in the overrideService is missing + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + overrideService: + port: 80 + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [hosts.paths.overrideService.name] + + - it: should fail if port in the overrideService is missing + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + overrideService: + name: test-service + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [hosts.paths.overrideService.port] + + - it: should fail if targeted service does not exist + set: + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + my-service: my-port + hosts: + - host: test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected targeted service [my-service] to exist + + - it: should fail if targeted service is not enabled + set: + service: + my-service: + enabled: false + primary: true + ports: + my-port: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + my-service: my-port + hosts: + - host: test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected targeted service [my-service] to be enabled + + - it: should fail without primary service or a targetSelector + set: + ingress: + my-ingress: + enabled: true + primary: true + hosts: + - host: test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [targetSelector] or a primary service to exist + + - it: should fail if the targeted service does not have the targeted port + set: + service: + my-service: + enabled: true + primary: true + ports: + my-other-port: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + my-service: my-port + hosts: + - host: test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected targeted service [my-service] to have port [my-port] + + - it: should fail if the targeted service port is not enabled + set: + service: + my-service: + enabled: true + primary: true + ports: + my-port: + enabled: false + primary: true + port: 80 + my-other-port: + enabled: true + primary: true + port: 80 + ingress: + my-ingress: + enabled: true + primary: true + targetSelector: + my-service: my-port + hosts: + - host: test-host + paths: + - path: /test-path + asserts: + - failedTemplate: + errorMessage: Ingress - Expected targeted service port [my-port] to be enabled + + - it: should fail if tls.hosts are empty + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: [] + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty [tls.hosts] + + - it: should fail if tls.hosts is not a slice + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: not-a-slice + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [tls.hosts] to be a [slice], but got [string] + + - it: should fail if tls.hosts.host is empty + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: + - "" + asserts: + - failedTemplate: + errorMessage: Ingress - Expected non-empty entry in [tls.hosts] + + - it: should fail if tls.hosts.host starts with https:// + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: + - https://test-host + asserts: + - failedTemplate: + errorMessage: Ingress - Expected entry in [tls.hosts] to not start with [https://], but got [https://test-host] + + - it: should fail if tls.hosts.host starts with http:// + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: + - http://test-host + asserts: + - failedTemplate: + errorMessage: Ingress - Expected entry in [tls.hosts] to not start with [http://], but got [http://test-host] + + - it: should fail if tls.hosts.host contains ":" + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: + - test-host:123 + asserts: + - failedTemplate: + errorMessage: Ingress - Expected entry in [tls.hosts] to not contain [:], but got [test-host:123] + + - it: should fail if more than 1 cert option is set under tls + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + tls: + - hosts: + - test-host + secretName: test-secret + clusterCertificate: some-cert + asserts: + - failedTemplate: + errorMessage: Ingress - Expected only one of [secretName, certificateIssuer, clusterCertificate] to be set, but got [secretName, clusterCertificate] + + - it: should fail with ingressClassName set to tc-stopped + set: + service: *service + ingress: + my-ingress: + enabled: true + primary: true + hosts: *hosts + ingressClassName: tc-stopped + asserts: + - failedTemplate: + errorMessage: Ingress - Expected [ingressClassName] to not be [tc-stopped], this is reserved for internal use diff --git a/charts/library/common-test/tests/initContainer/data_test.yaml b/charts/library/common-test/tests/initContainer/data_test.yaml new file mode 100644 index 00000000000..9d7bbea39bb --- /dev/null +++ b/charts/library/common-test/tests/initContainer/data_test.yaml @@ -0,0 +1,235 @@ +suite: init container data test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct init container + set: + initType: install + render: true + persistence: + shared-vol: + enabled: true + type: emptyDir + mountPath: /some/path + targetSelector: + workload-name: + container-name2: {} + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + initImage: &initImage + repository: bash + tag: latest + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: "{{ .Values.render }}" + type: init + imageSelector: initImage + env: + key: value + key2: "{{ .Values.initImage.repository }}" + key3: + secretKeyRef: + expandObjectName: false + name: '{{ printf "secret-name" }}' + key: secret-key + container-name3: + enabled: true + type: upgrade + imageSelector: initImage + container-name2: + enabled: true + type: "{{ .Values.initType }}" + imageSelector: initImage + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + command: + - /bin/sh + - -c + - | + echo "Using image {{ .Values.initImage.repository }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[0] + content: + name: test-release-name-common-test-install-container-name2 + image: bash:latest + command: + - /bin/sh + - -c + - | + echo "Using image bash" + volumeMounts: + - mountPath: /dev/shm + name: devshm + readOnly: false + - mountPath: /shared + name: shared + readOnly: false + - mountPath: /some/path + name: shared-vol + readOnly: false + - mountPath: /tmp + name: tmp + readOnly: false + - mountPath: /var/logs + name: varlogs + readOnly: false + - mountPath: /var/run + name: varrun + readOnly: false + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].livenessProbe + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].readinessProbe + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].startupProbe + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + name: test-release-name-common-test-init-container-name1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + env: + - name: "TZ" + value: "UTC" + - name: "UMASK" + value: "0022" + - name: "UMASK_SET" + value: "0022" + - name: "NVIDIA_VISIBLE_DEVICES" + value: "void" + - name: "S6_READ_ONLY_ROOT" + value: "1" + - name: "key" + value: "value" + - name: "key2" + value: "bash" + - name: "key3" + valueFrom: + secretKeyRef: + key: "secret-key" + name: "secret-name" + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[1].command + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /dev/shm + name: devshm + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /shared + name: shared + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /tmp + name: tmp + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /var/logs + name: varlogs + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /var/run + name: varrun + readOnly: false + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[2] + + - it: should NOT generate render init container + set: + render: false + image: + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: "{{ .Values.render }}" + type: init + imageSelector: image + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isNullOrEmpty: + path: spec.template.spec.initContainers diff --git a/charts/library/common-test/tests/initContainer/data_upgrade_test.yaml b/charts/library/common-test/tests/initContainer/data_upgrade_test.yaml new file mode 100644 index 00000000000..046ae4a5c72 --- /dev/null +++ b/charts/library/common-test/tests/initContainer/data_upgrade_test.yaml @@ -0,0 +1,236 @@ +suite: init container data test (upgrade) +templates: + - common.yaml +release: + upgrade: true + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct init container + set: + initType: upgrade + render: true + persistence: + shared-vol: + enabled: true + type: emptyDir + mountPath: /some/path + targetSelector: + workload-name: + container-name2: {} + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + initImage: &initImage + repository: bash + tag: latest + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: "{{ .Values.render }}" + primary: true + imageSelector: image + probes: &probes + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: true + type: init + imageSelector: initImage + env: + key: value + key2: "{{ .Values.initImage.repository }}" + key3: + secretKeyRef: + expandObjectName: false + name: '{{ printf "secret-name" }}' + key: secret-key + container-name3: + enabled: true + type: install + imageSelector: initImage + container-name2: + enabled: true + type: "{{ .Values.initType }}" + imageSelector: initImage + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + command: + - /bin/sh + - -c + - | + echo "Using image {{ .Values.initImage.repository }}" + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[0] + content: + name: test-release-name-common-test-upgrade-container-name2 + image: bash:latest + command: + - /bin/sh + - -c + - | + echo "Using image bash" + volumeMounts: + - mountPath: /dev/shm + name: devshm + readOnly: false + - mountPath: /shared + name: shared + readOnly: false + - mountPath: /some/path + name: shared-vol + readOnly: false + - mountPath: /tmp + name: tmp + readOnly: false + - mountPath: /var/logs + name: varlogs + readOnly: false + - mountPath: /var/run + name: varrun + readOnly: false + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].livenessProbe + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].readinessProbe + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[0].startupProbe + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + name: test-release-name-common-test-init-container-name1 + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[1].command + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + env: + - name: "TZ" + value: "UTC" + - name: "UMASK" + value: "0022" + - name: "UMASK_SET" + value: "0022" + - name: "NVIDIA_VISIBLE_DEVICES" + value: "void" + - name: "S6_READ_ONLY_ROOT" + value: "1" + - name: "key" + value: "value" + - name: "key2" + value: "bash" + - name: "key3" + valueFrom: + secretKeyRef: + key: "secret-key" + name: "secret-name" + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /dev/shm + name: devshm + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /shared + name: shared + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /tmp + name: tmp + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /var/logs + name: varlogs + readOnly: false + - documentIndex: *deploymentDoc + contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /var/run + name: varrun + readOnly: false + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.initContainers[2] + + - it: should NOT generate render init container + set: + render: false + image: + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: "{{ .Values.render }}" + type: upgrade + imageSelector: image + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isNullOrEmpty: + path: spec.template.spec.initContainers diff --git a/charts/library/common-test/tests/initContainer/name_test.yaml b/charts/library/common-test/tests/initContainer/name_test.yaml new file mode 100644 index 00000000000..9536fe4ff7e --- /dev/null +++ b/charts/library/common-test/tests/initContainer/name_test.yaml @@ -0,0 +1,45 @@ +suite: init container name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct init container name + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + initContainers: + container-name1: + enabled: true + type: init + imageSelector: image + container-name2: + enabled: true + type: install + imageSelector: image + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[0] + content: + name: test-release-name-common-test-install-container-name2 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + name: test-release-name-common-test-init-container-name1 diff --git a/charts/library/common-test/tests/initContainer/name_upgrade_test.yaml b/charts/library/common-test/tests/initContainer/name_upgrade_test.yaml new file mode 100644 index 00000000000..23a7cb8c337 --- /dev/null +++ b/charts/library/common-test/tests/initContainer/name_upgrade_test.yaml @@ -0,0 +1,46 @@ +suite: init container name test (upgrade) +templates: + - common.yaml +release: + upgrade: true + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct init container name + set: + image: &image + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + initContainers: + container-name1: + enabled: true + type: init + imageSelector: image + container-name2: + enabled: true + type: upgrade + imageSelector: image + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isAPIVersion: + of: apps/v1 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[0] + content: + name: test-release-name-common-test-upgrade-container-name2 + - documentIndex: *deploymentDoc + isSubset: + path: spec.template.spec.initContainers[1] + content: + name: test-release-name-common-test-init-container-name1 diff --git a/charts/library/common-test/tests/initContainer/validation_test.yaml b/charts/library/common-test/tests/initContainer/validation_test.yaml new file mode 100644 index 00000000000..bd47cbcd579 --- /dev/null +++ b/charts/library/common-test/tests/initContainer/validation_test.yaml @@ -0,0 +1,71 @@ +suite: init container data test (upgrade) +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: +# Failures + - it: should fail with empty type on init container + set: + image: + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: true + type: "" + asserts: + - failedTemplate: + errorMessage: InitContainer - Expected non-empty [type] + + - it: should fail with invalid type on init container + set: + image: + repository: nginx + tag: 1.19.0 + pullPolicy: IfNotPresent + workload: + workload-name: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + container-name1: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + initContainers: + container-name1: + enabled: true + type: invalid + asserts: + - failedTemplate: + errorMessage: InitContainer - Expected [type] to be one of [system, init, install, upgrade], but got [invalid] diff --git a/charts/library/common-test/tests/job/metadata_test.yaml b/charts/library/common-test/tests/job/metadata_test.yaml new file mode 100644 index 00000000000..7f4b21892de --- /dev/null +++ b/charts/library/common-test/tests/job/metadata_test.yaml @@ -0,0 +1,197 @@ +suite: job metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with job created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + workload: + workload-name: + enabled: true + primary: true + type: Job + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + podSpec: + labels: + pod-label1: pod-label1 + pod-label2: "{{ .Values.label2 }}" + annotations: + pod-annotation1: pod-annotation1 + pod-annotation2: "{{ .Values.annotation2 }}" + asserts: + - documentIndex: &jobDoc 0 + isKind: + of: Job + - documentIndex: *jobDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *jobDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *jobDoc + equal: + path: spec.template.metadata.labels + value: + pod.name: workload-name + pod.lifecycle: fleeting + app: common-test-1.0.0 + release: test-release-name + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: v9.9.9 + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + g_label1: global_label1 + g_label2: global_label2 + pod-label1: pod-label1 + pod-label2: global_label2 + - documentIndex: *jobDoc + isSubset: + path: spec.template.metadata.annotations + content: + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + pod-annotation1: pod-annotation1 + pod-annotation2: global_annotation2 + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/secrets + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/cnpg + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/configmaps + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mariadb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/mongodb + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/persistence + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/redis + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/services + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + matchRegex: + path: spec.template.metadata.annotations.checksum/solr + pattern: ^[0-9a-f]{64}$ + - documentIndex: *jobDoc + equal: + path: metadata.name + value: test-release-name-common-test + - documentIndex: *jobDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with Job created with object namespace from tpl + set: + key: some-namespace + workload: + workload-name: + enabled: true + primary: true + type: Job + namespace: "{{ .Values.key }}" + podSpec: {} + asserts: + - documentIndex: *jobDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with Job created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + workload: + workload-name: + enabled: true + primary: true + type: Job + podSpec: {} + asserts: + - documentIndex: *jobDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with Job created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + workload: + workload-name: + enabled: true + primary: true + type: Job + podSpec: {} + asserts: + - documentIndex: *jobDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/job/spec_test.yaml b/charts/library/common-test/tests/job/spec_test.yaml new file mode 100644 index 00000000000..b44b13b1b85 --- /dev/null +++ b/charts/library/common-test/tests/job/spec_test.yaml @@ -0,0 +1,93 @@ +suite: job spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with workload enabled + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + podSpec: {} + asserts: + - documentIndex: &jobDoc 0 + isKind: + of: Job + - documentIndex: *jobDoc + isAPIVersion: + of: batch/v1 + - documentIndex: *jobDoc + isSubset: + path: spec + content: + backoffLimit: 5 + completionMode: NonIndexed + completions: + parallelism: 1 + ttlSecondsAfterFinished: 120 + + - it: should apply spec correctly + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + backoffLimit: 5 + completionMode: Indexed + completions: 5 + parallelism: 5 + ttlSecondsAfterFinished: 100 + activeDeadlineSeconds: 100 + podSpec: {} + asserts: + - documentIndex: *jobDoc + isSubset: + path: spec + content: + backoffLimit: 5 + completionMode: Indexed + completions: 5 + parallelism: 5 + ttlSecondsAfterFinished: 100 + activeDeadlineSeconds: 100 + + - it: should set parallelism to 0 + set: + global: + stopAll: true + workload: + workload-name: + enabled: true + primary: true + type: Job + parallelism: 0 + podSpec: {} + asserts: + - documentIndex: *jobDoc + isSubset: + path: spec + content: + parallelism: 0 + + - it: should set parallelism to 0 on stopAll + set: + global: + stopAll: true + workload: + workload-name: + enabled: true + primary: true + type: Job + parallelism: 3 + podSpec: {} + asserts: + - documentIndex: *jobDoc + isSubset: + path: spec + content: + parallelism: 0 diff --git a/charts/library/common-test/tests/job/validation_test.yaml b/charts/library/common-test/tests/job/validation_test.yaml new file mode 100644 index 00000000000..123f52529a9 --- /dev/null +++ b/charts/library/common-test/tests/job/validation_test.yaml @@ -0,0 +1,61 @@ +suite: job validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with invalid completionMode + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + completionMode: not-a-mode + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Job - Expected [completionMode] to be one of [Indexed, NonIndexed], but got [not-a-mode] + + - it: should fail with completionMode to Indexed and no completions + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + completionMode: Indexed + completions: + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Job - Expected [completions] to be set when [completionMode] is set to [Indexed] + + - it: should fail with completionMode to Indexed and no parallelism + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + completionMode: Indexed + completions: 5 + parallelism: + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Job - Expected [parallelism] to be set when [completionMode] is set to [Indexed] + + - it: should fail with namespace longer than 63 characters + set: + workload: + workload-name: + enabled: true + primary: true + type: Job + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Job - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. diff --git a/charts/library/common-test/tests/metrics/defaults_test.yaml b/charts/library/common-test/tests/metrics/defaults_test.yaml new file mode 100644 index 00000000000..423d8eb1843 --- /dev/null +++ b/charts/library/common-test/tests/metrics/defaults_test.yaml @@ -0,0 +1,32 @@ +suite: metrics defaults +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: default should pass + set: + service: + main: + enabled: true + ports: + main: + enabled: true + primary: true + port: 12345 + workload: + my-workload: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - hasDocuments: + count: 2 + - documentIndex: 1 + isKind: + of: Service + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment diff --git a/charts/library/common-test/tests/persistence/pv_data_test.yaml b/charts/library/common-test/tests/persistence/pv_data_test.yaml new file mode 100644 index 00000000000..28659b3d848 --- /dev/null +++ b/charts/library/common-test/tests/persistence/pv_data_test.yaml @@ -0,0 +1,335 @@ +suite: pv data test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create nfs pv with csi + set: + version: 4.1 + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /my-path + server: my-server + my-volume2: + enabled: true + type: pvc + static: + mode: nfs + share: /my-path2 + server: my-server2 + size: 2Gi + mountOptions: + - key: hard + - key: nfsvers + value: "{{ .Values.version }}" + my-volume3: + enabled: true + type: pvc + static: + mode: nfs + share: /my-path3 + server: my-server3 + size: 3Gi + mountOptions: + - key: hard + - key: nfsvers + value: "{{ .Values.version }}" + asserts: + - documentIndex: &pvDoc 0 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + equal: + path: spec + value: + capacity: + storage: 100Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume1-1599277109 + accessModes: + - ReadWriteOnce + csi: + driver: nfs.csi.k8s.io + volumeHandle: my-server/my-path#test-release-name-common-test-my-volume1-1599277109 + volumeAttributes: + server: my-server + share: /my-path + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + storageClassName: test-release-name-common-test-my-volume1-1599277109 + volumeName: test-release-name-common-test-my-volume1-1599277109 + - documentIndex: &otherPvDoc 2 + isKind: + of: PersistentVolume + - documentIndex: *otherPvDoc + equal: + path: spec + value: + capacity: + storage: 2Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume2-1702692922 + accessModes: + - ReadWriteOnce + mountOptions: + - hard + - nfsvers=4.1 + csi: + driver: nfs.csi.k8s.io + volumeHandle: my-server2/my-path2#test-release-name-common-test-my-volume2-1702692922 + volumeAttributes: + server: my-server2 + share: /my-path2 + - documentIndex: &otherPvcDoc 3 + isKind: + of: PersistentVolumeClaim + - documentIndex: *otherPvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: test-release-name-common-test-my-volume2-1702692922 + volumeName: test-release-name-common-test-my-volume2-1702692922 + - documentIndex: &thirdPvDoc 4 + isKind: + of: PersistentVolume + - documentIndex: *thirdPvDoc + equal: + path: spec + value: + capacity: + storage: 3Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume3-1705052221 + accessModes: + - ReadWriteOnce + mountOptions: + - hard + - nfsvers=4.1 + csi: + driver: nfs.csi.k8s.io + volumeHandle: my-server3/my-path3#test-release-name-common-test-my-volume3-1705052221 + volumeAttributes: + server: my-server3 + share: /my-path3 + - documentIndex: &thirdPvcDoc 5 + isKind: + of: PersistentVolumeClaim + - documentIndex: *thirdPvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi + storageClassName: test-release-name-common-test-my-volume3-1705052221 + volumeName: test-release-name-common-test-my-volume3-1705052221 + + - it: should create smb pv with csi + set: + version: "3.0" + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: smb + share: my-share + server: my-server + username: my-user + password: my-password + my-volume2: + enabled: true + type: pvc + static: + mode: smb + share: my-share2 + server: my-server2 + username: my-user2 + password: my-password2 + size: 2Gi + mountOptions: + - key: hard + - key: uid + value: 99999999999 + - key: vers + value: "{{ .Values.version }}" + my-volume3: + enabled: true + type: pvc + static: + mode: smb + share: my-share3 + server: my-server3 + username: my-user3 + password: my-password3 + size: 3Gi + mountOptions: + - key: hard + - key: uid + value: 99999999999 + - key: vers + value: "{{ .Values.version }}" + asserts: + - documentIndex: &secretDoc 0 + isKind: + of: Secret + - documentIndex: *secretDoc + equal: + path: stringData + value: + username: my-user + password: my-password + - documentIndex: &pvDoc 1 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + equal: + path: spec + value: + capacity: + storage: 100Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume1-1627785324 + accessModes: + - ReadWriteOnce + csi: + driver: smb.csi.k8s.io + volumeHandle: my-server/my-share#test-release-name-common-test-my-volume1-1627785324 + volumeAttributes: + source: //my-server/my-share + nodeStageSecretRef: + name: test-release-name-common-test-my-volume1-1627785324 + namespace: test-release-namespace + - documentIndex: &pvcDoc 2 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Gi + storageClassName: test-release-name-common-test-my-volume1-1627785324 + volumeName: test-release-name-common-test-my-volume1-1627785324 + - documentIndex: &otherSecretDoc 3 + isKind: + of: Secret + - documentIndex: *otherSecretDoc + equal: + path: stringData + value: + username: my-user2 + password: my-password2 + - documentIndex: &otherPvDoc 4 + isKind: + of: PersistentVolume + - documentIndex: *otherPvDoc + equal: + path: spec + value: + capacity: + storage: 2Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume2-1734805617 + accessModes: + - ReadWriteOnce + mountOptions: + - hard + - uid=99999999999 + - vers=3.0 + csi: + driver: smb.csi.k8s.io + volumeHandle: my-server2/my-share2#test-release-name-common-test-my-volume2-1734805617 + volumeAttributes: + source: //my-server2/my-share2 + nodeStageSecretRef: + name: test-release-name-common-test-my-volume2-1734805617 + namespace: test-release-namespace + - documentIndex: &otherPvcDoc 5 + isKind: + of: PersistentVolumeClaim + - documentIndex: *otherPvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: test-release-name-common-test-my-volume2-1734805617 + volumeName: test-release-name-common-test-my-volume2-1734805617 + - documentIndex: &thirdSecretDoc 6 + isKind: + of: Secret + - documentIndex: *thirdSecretDoc + equal: + path: stringData + value: + username: my-user3 + password: my-password3 + - documentIndex: &thirdPvDoc 7 + isKind: + of: PersistentVolume + - documentIndex: *thirdPvDoc + equal: + path: spec + value: + capacity: + storage: 3Gi + persistentVolumeReclaimPolicy: Delete + storageClassName: test-release-name-common-test-my-volume3-1737164916 + accessModes: + - ReadWriteOnce + mountOptions: + - hard + - uid=99999999999 + - vers=3.0 + csi: + driver: smb.csi.k8s.io + volumeHandle: my-server3/my-share3#test-release-name-common-test-my-volume3-1737164916 + volumeAttributes: + source: //my-server3/my-share3 + nodeStageSecretRef: + name: test-release-name-common-test-my-volume3-1737164916 + namespace: test-release-namespace + - documentIndex: &thirdPvcDoc 8 + isKind: + of: PersistentVolumeClaim + - documentIndex: *thirdPvcDoc + equal: + path: spec + value: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi + storageClassName: test-release-name-common-test-my-volume3-1737164916 + volumeName: test-release-name-common-test-my-volume3-1737164916 diff --git a/charts/library/common-test/tests/persistence/pv_metadata_test.yaml b/charts/library/common-test/tests/persistence/pv_metadata_test.yaml new file mode 100644 index 00000000000..0b9fd4648fa --- /dev/null +++ b/charts/library/common-test/tests/persistence/pv_metadata_test.yaml @@ -0,0 +1,247 @@ +suite: pv metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with pv created with labels and annotations (nfs-pv-pvc) + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + server: someserver + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + asserts: + - documentIndex: &pvDoc 0 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + isAPIVersion: + of: v1 + - documentIndex: *pvDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + pv.kubernetes.io/provisioned-by: nfs.csi.k8s.io + some-annotation: some-value + - documentIndex: *pvDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + + - it: should pass with pvc created with retain set to true (nfs-pv-pvc) + set: + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + server: someserver + retain: true + asserts: + - documentIndex: *pvDoc + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + equal: + path: metadata.annotations + value: + "helm.sh/resource-policy": keep + pv.kubernetes.io/provisioned-by: nfs.csi.k8s.io + - documentIndex: *pvDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/name: common-test + + - it: should pass with pv created with labels and annotations (smb-pv-pvc) + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + password: someuserpoassword + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + asserts: + - documentIndex: &secretDoc 0 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + - documentIndex: *secretDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + - documentIndex: &pvDoc 1 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + isAPIVersion: + of: v1 + - documentIndex: *pvDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + pv.kubernetes.io/provisioned-by: smb.csi.k8s.io + - documentIndex: *pvDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/name: common-test + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + + - it: should pass with pvc created with retain set to true (smb-pv-pvc) + set: + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + password: someuserpoassword + retain: true + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + isNull: + path: metadata.annotations + - documentIndex: *pvDoc + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + equal: + path: metadata.annotations + value: + "helm.sh/resource-policy": keep + pv.kubernetes.io/provisioned-by: smb.csi.k8s.io + - documentIndex: *pvDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + app.kubernetes.io/name: common-test diff --git a/charts/library/common-test/tests/persistence/pv_name_test.yaml b/charts/library/common-test/tests/persistence/pv_name_test.yaml new file mode 100644 index 00000000000..a9dd07174ae --- /dev/null +++ b/charts/library/common-test/tests/persistence/pv_name_test.yaml @@ -0,0 +1,77 @@ +suite: pv name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + persistence: + my-volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + server: someserver + my-volume2: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + password: someuserpoassword + asserts: + - documentIndex: &pvDoc 0 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + isAPIVersion: + of: v1 + - documentIndex: *pvDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1-2156988893 + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + isAPIVersion: + of: v1 + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1-2156988893 + - documentIndex: &secretDoc 2 + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2-2027162030 + - documentIndex: &pvDoc 3 + isKind: + of: PersistentVolume + - documentIndex: *pvDoc + isAPIVersion: + of: v1 + - documentIndex: *pvDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2-2027162030 + - documentIndex: &otherPvcDoc 4 + isKind: + of: PersistentVolumeClaim + - documentIndex: *otherPvcDoc + isAPIVersion: + of: v1 + - documentIndex: *otherPvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2-2027162030 diff --git a/charts/library/common-test/tests/persistence/pvc_data_test.yaml b/charts/library/common-test/tests/persistence/pvc_data_test.yaml new file mode 100644 index 00000000000..c9a03bc8ed6 --- /dev/null +++ b/charts/library/common-test/tests/persistence/pvc_data_test.yaml @@ -0,0 +1,176 @@ +suite: pvc data name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create pvc + set: + persistence: + my-volume1: + enabled: true + type: pvc + size: 1Gi + asserts: + - documentIndex: &pvcDoc 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + isAPIVersion: + of: v1 + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteOnce + - documentIndex: *pvcDoc + equal: + path: spec.resources.requests.storage + value: 1Gi + - documentIndex: *pvcDoc + isNull: + path: spec.volumeName + - documentIndex: *pvcDoc + isNull: + path: spec.storageClassName + + - it: should not create pvc when existingClaim is set + set: + persistence: + my-volume1: + enabled: true + type: pvc + existingClaim: some-existing-claim + asserts: + - hasDocuments: + of: 0 + + - it: should create pvc with accessModes set as string + set: + some_mode: ReadWriteMany + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: "{{ .Values.some_mode }}" + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + + - it: should create pvc with accessModes set as list + set: + some_mode: ReadWriteMany + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: + - "{{ .Values.some_mode }}" + - ReadWriteOnce + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + - ReadWriteOnce + + - it: should create pvc with size set + set: + some_size: 20Gi + persistence: + my-volume1: + enabled: true + type: pvc + size: "{{ .Values.some_size }}" + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.resources.requests.storage + value: 20Gi + + - it: should create pvc with volumeName set + set: + some_vol_name: some-pv-name + persistence: + my-volume1: + enabled: true + type: pvc + volumeName: "{{ .Values.some_vol_name }}" + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.volumeName + value: some-pv-name + + - it: should create pvc with storageClass set "-" + set: + some_storage_class: "-" + persistence: + my-volume1: + enabled: true + type: pvc + storageClass: "{{ .Values.some_storage_class }}" + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.storageClassName + value: "" + + - it: should create pvc with storageClass set + set: + some_storage_class: "some-storage-class" + persistence: + my-volume1: + enabled: true + type: pvc + storageClass: "{{ .Values.some_storage_class }}" + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.storageClassName + value: some-storage-class + + - it: should create pvc with storageClass not set, but have fallbackDefaults set + set: + global: + fallbackDefaults: + storageClass: some-storage-class + persistence: + my-volume1: + enabled: true + type: pvc + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: spec.storageClassName + value: some-storage-class diff --git a/charts/library/common-test/tests/persistence/pvc_metadata_test.yaml b/charts/library/common-test/tests/persistence/pvc_metadata_test.yaml new file mode 100644 index 00000000000..421ae5fc49b --- /dev/null +++ b/charts/library/common-test/tests/persistence/pvc_metadata_test.yaml @@ -0,0 +1,153 @@ +suite: persistence pvc metadata test +templates: + - common.yaml +chart: + appVersion: &appVer v9.9.9 +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with pvc created with labels and annotations + set: + label1: label1 + label2: global_label2 + annotation1: annotation1 + annotation2: global_annotation2 + global: + labels: + g_label1: global_label1 + g_label2: "{{ .Values.label2 }}" + annotations: + g_annotation1: global_annotation1 + g_annotation2: "{{ .Values.annotation2 }}" + persistence: + my-volume1: + enabled: true + type: pvc + labels: + label1: "{{ .Values.label1 }}" + label2: label2 + annotations: + annotation1: "{{ .Values.annotation1 }}" + annotation2: annotation2 + annotationsList: + - name: some-annotation + value: some-value + labelsList: + - name: some-label + value: some-value + asserts: + - documentIndex: &pvcDoc 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + isAPIVersion: + of: v1 + - documentIndex: *pvcDoc + equal: + path: metadata.annotations + value: + annotation1: annotation1 + annotation2: annotation2 + g_annotation1: global_annotation1 + g_annotation2: global_annotation2 + some-annotation: some-value + - documentIndex: *pvcDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + g_label1: global_label1 + g_label2: global_label2 + label1: label1 + label2: label2 + some-label: some-value + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: metadata.namespace + value: test-release-namespace + + - it: should pass with pvc created with retain set to true + set: + persistence: + my-volume1: + enabled: true + type: pvc + retain: true + asserts: + - documentIndex: *pvcDoc + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: metadata.annotations + value: + "helm.sh/resource-policy": keep + - documentIndex: *pvcDoc + equal: + path: metadata.labels + value: + app: common-test-1.0.0 + release: test-release-name + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + app.kubernetes.io/name: common-test + app.kubernetes.io/instance: test-release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: *appVer + + - it: should pass with pvc created with object namespace from tpl + set: + key: some-namespace + persistence: + my-volume1: + enabled: true + type: pvc + namespace: "{{ .Values.key }}" + asserts: + - documentIndex: *pvcDoc + equal: + path: metadata.namespace + value: some-namespace + + - it: should pass with pvc created with global namespace from tpl + set: + key: global-namespace + global: + namespace: "{{ .Values.key }}" + persistence: + my-volume1: + enabled: true + type: pvc + asserts: + - documentIndex: *pvcDoc + equal: + path: metadata.namespace + value: global-namespace + + - it: should pass with pvc created with root namespace from tpl + set: + key: local-namespace + namespace: "{{ .Values.key }}" + global: + namespace: global-namespace + persistence: + my-volume1: + enabled: true + type: pvc + asserts: + - documentIndex: *pvcDoc + equal: + path: metadata.namespace + value: local-namespace diff --git a/charts/library/common-test/tests/persistence/pvc_names_test.yaml b/charts/library/common-test/tests/persistence/pvc_names_test.yaml new file mode 100644 index 00000000000..1a10a3eb1da --- /dev/null +++ b/charts/library/common-test/tests/persistence/pvc_names_test.yaml @@ -0,0 +1,37 @@ +suite: persistence pvc name test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct name + set: + persistence: + my-volume1: + enabled: true + type: pvc + my-volume2: + enabled: true + type: pvc + asserts: + - documentIndex: &pvcDoc 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + isAPIVersion: + of: v1 + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: &otherPvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *otherPvcDoc + isAPIVersion: + of: v1 + - documentIndex: *otherPvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2 diff --git a/charts/library/common-test/tests/persistence/pvc_with_snapshot.yaml b/charts/library/common-test/tests/persistence/pvc_with_snapshot.yaml new file mode 100644 index 00000000000..ba9cb7fc999 --- /dev/null +++ b/charts/library/common-test/tests/persistence/pvc_with_snapshot.yaml @@ -0,0 +1,79 @@ +suite: persistence pvc with snapshots test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct pvc and snapshot + set: + persistence: + my-volume1: + enabled: true + type: pvc + volumeSnapshots: + - name: example1 + enabled: true + volumeSnapshotClassName: some-name + my-volume2: + enabled: true + type: pvc + volumeSnapshots: + - name: example1 + enabled: true + volumeSnapshotClassName: some-name + asserts: + - documentIndex: &pvcDoc 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + isAPIVersion: + of: v1 + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: &volumeSnapshotDoc 1 + isKind: + of: VolumeSnapshot + - documentIndex: *volumeSnapshotDoc + isAPIVersion: + of: snapshot.storage.k8s.io/v1 + - documentIndex: *volumeSnapshotDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1-example1 + - documentIndex: *volumeSnapshotDoc + equal: + path: spec + value: + volumeSnapshotClassName: some-name + source: + persistentVolumeClaimName: test-release-name-common-test-my-volume1 + - documentIndex: &otherPvcDoc 2 + isKind: + of: PersistentVolumeClaim + - documentIndex: *otherPvcDoc + isAPIVersion: + of: v1 + - documentIndex: *otherPvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2 + - documentIndex: &otherVolumeSnapshotDoc 3 + isKind: + of: VolumeSnapshot + - documentIndex: *otherVolumeSnapshotDoc + isAPIVersion: + of: snapshot.storage.k8s.io/v1 + - documentIndex: *otherVolumeSnapshotDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume2-example1 + - documentIndex: *otherVolumeSnapshotDoc + equal: + path: spec + value: + volumeSnapshotClassName: some-name + source: + persistentVolumeClaimName: test-release-name-common-test-my-volume2 diff --git a/charts/library/common-test/tests/persistence/validation_test.yaml b/charts/library/common-test/tests/persistence/validation_test.yaml new file mode 100644 index 00000000000..0d675c036d9 --- /dev/null +++ b/charts/library/common-test/tests/persistence/validation_test.yaml @@ -0,0 +1,360 @@ +suite: persistence validation test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should fail with annotations not a dict + set: + persistence: + volume1: + enabled: true + annotations: not-a-dict + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [annotations] to be a dictionary, but got [string] + + - it: should fail with labels not a dict + set: + persistence: + volume1: + enabled: true + labels: not-a-dict + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [labels] to be a dictionary, but got [string] + + - it: should fail with pod targetSelector not a map + set: + persistence: + volume1: + enabled: true + targetSelector: not-a-map + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [targetSelector] to be [dict], but got [string] + + - it: should fail with invalid type + set: + persistence: + volume1: + enabled: true + type: not-a-type + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [type] to be one of [pvc, vct, emptyDir, nfs, iscsi, hostPath, secret, configmap, device, projected], but got [not-a-type] + + - it: should fail with invalid accessMode + set: + persistence: + volume1: + enabled: true + accessModes: + - not-an-access-mode + asserts: + - failedTemplate: + errorMessage: PVC - Expected [accessModes] entry to be one of [ReadWriteOnce, ReadOnlyMany, ReadWriteMany, ReadWriteOncePod], but got [not-an-access-mode] + + - it: should fail with non-existent configmap + set: + configmap: + my-configmap: + enabled: true + data: + foo: bar + persistence: + volume1: + enabled: true + type: configmap + mountPath: /mnt/volume1 + objectName: my-non-existent-configmap + workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + asserts: + - failedTemplate: + errorMessage: Persistence - Expected configmap [my-non-existent-configmap] defined in [objectName] to exist + + - it: should fail with non-existent secret + set: + secret: + my-secret: + enabled: true + data: + foo: bar + persistence: + volume1: + enabled: true + type: secret + mountPath: /mnt/volume1 + objectName: my-non-existent-secret + workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + asserts: + - failedTemplate: + errorMessage: Persistence - Expected secret [my-non-existent-secret] defined in [objectName] to exist + + - it: should fail with namespace longer than 63 characters + set: + persistence: + volume1: + enabled: true + type: pvc + namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters + asserts: + - failedTemplate: + errorMessage: Persistent Volume Claim - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters. + + - it: should fail without server on pvc static nfs + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + asserts: + - failedTemplate: + errorMessage: NFS CSI - Expected [server] to be non-empty + + - it: should fail without share on pvc static nfs + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: nfs + server: someserver + asserts: + - failedTemplate: + errorMessage: NFS CSI - Expected [share] to be non-empty + + - it: should fail without server on pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected [server] to be non-empty + + - it: should fail without share on pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + server: someserver + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected [share] to be non-empty + + - it: should fail without username pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected [username] to be non-empty + + - it: should fail without password on pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected [password] to be non-empty + + - it: should fail with server starting with // on pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: //someserver + username: someuser + password: someuserpoassword + asserts: + - failedTemplate: + errorMessage: SMB CSI - Did not expect [server] to start with [//] + + - it: should fail with share starting with / on pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: /someshare + server: someserver + username: someuser + password: someuserpoassword + asserts: + - failedTemplate: + errorMessage: SMB CSI - Did not expect [share] to start with [/] + + - it: should fail without share starting with / on pvc static nfs + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: nfs + share: someshare + server: someserver + asserts: + - failedTemplate: + errorMessage: NFS CSI - Expected [share] to start with [/] + + - it: should fail with empty key on mountOptions in pvc static nfs + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + server: someserver + mountOptions: + - key: "" + asserts: + - failedTemplate: + errorMessage: NFS CSI - Expected key in [mountOptions] to be non-empty + + - it: should fail with empty key on mountOptions in pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + password: someuserpoassword + mountOptions: + - key: "" + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected key in [mountOptions] to be non-empty + + - it: should fail with item in mountOptions not a map in pvc static smb + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: smb + share: someshare + server: someserver + username: someuser + password: someuserpoassword + mountOptions: + - not-a-map + asserts: + - failedTemplate: + errorMessage: SMB CSI - Expected [mountOption] item to be a dict, but got [string] + + - it: should fail with item in mountOptions not a map in pvc static nfs + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: nfs + share: /someshare + server: someserver + mountOptions: + - not-a-map + asserts: + - failedTemplate: + errorMessage: NFS CSI - Expected [mountOption] item to be a dict, but got [string] + + - it: should fail with invalid static mode + set: + persistence: + volume1: + enabled: true + type: pvc + static: + mode: not-a-mode + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [static.mode] to be one of [disabled, smb, nfs, custom], but got [not-a-mode] + + - it: should fail with missing name in dataSource + set: + persistence: + volume1: + enabled: true + type: pvc + dataSource: + kind: PersistentVolumeClaim + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [dataSource.name] to be non-empty + + - it: should fail with missing kind in dataSource + set: + persistence: + volume1: + enabled: true + type: pvc + dataSource: + name: some name + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [dataSource.kind] to be non-empty + + - it: should fail with invalid kind in dataSource + set: + persistence: + volume1: + enabled: true + type: pvc + dataSource: + name: some name + kind: invalid + asserts: + - failedTemplate: + errorMessage: Persistence - Expected [dataSource.kind] to be one of [VolumeSnapshot, PersistentVolumeClaim], but got [invalid] diff --git a/charts/library/common-test/tests/pod/automount_sa_token_test.yaml b/charts/library/common-test/tests/pod/automount_sa_token_test.yaml new file mode 100644 index 00000000000..9dd7856c7b5 --- /dev/null +++ b/charts/library/common-test/tests/pod/automount_sa_token_test.yaml @@ -0,0 +1,78 @@ +suite: pod auto mount sa token test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with automountServiceAccountToken disabled from "global" + set: + podOptions: + automountServiceAccountToken: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.automountServiceAccountToken + value: false + + - it: should pass with automountServiceAccountToken enabled from "global" + set: + podOptions: + automountServiceAccountToken: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.automountServiceAccountToken + value: true + + - it: should pass with disabled automountServiceAccountToken from pod + set: + podOptions: + automountServiceAccountToken: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + automountServiceAccountToken: false + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.automountServiceAccountToken + value: false + + - it: should pass with enabled automountServiceAccountToken from pod + set: + podOptions: + automountServiceAccountToken: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + automountServiceAccountToken: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.automountServiceAccountToken + value: true diff --git a/charts/library/common-test/tests/pod/dns_config_test.yaml b/charts/library/common-test/tests/pod/dns_config_test.yaml new file mode 100644 index 00000000000..6e8fc09f613 --- /dev/null +++ b/charts/library/common-test/tests/pod/dns_config_test.yaml @@ -0,0 +1,240 @@ +suite: pod dns config test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with empty dnsConfig + set: + podOptions: + dnsConfig: + nameservers: [] + searches: [] + options: [] + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.dnsConfig + + - it: should pass with dnsConfig from "global" + set: + podOptions: + dnsConfig: + nameservers: + - 1.1.1.1 + - 2.2.2.2 + searches: + - example.com + - example.org + options: + - name: ndots + value: "2" + - name: edns0 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsConfig + value: + nameservers: + - 1.1.1.1 + - 2.2.2.2 + searches: + - example.com + - example.org + options: + - name: ndots + value: "2" + - name: edns0 + + - it: should pass with dnsPolicy from "pod" + set: + podOptions: + dnsConfig: + nameservers: + - 1.1.1.1 + searches: + - example.org + options: + - name: edns0 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + nameservers: + - 1.1.1.1 + - 2.2.2.2 + searches: + - example.com + - example.org + options: + - name: ndots + value: "2" + - name: edns0 + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsConfig + value: + nameservers: + - 1.1.1.1 + - 2.2.2.2 + searches: + - example.com + - example.org + options: + - name: ndots + value: "2" + - name: edns0 + + - it: should pass with dnsPolicy from "pod" with tpl + set: + ns1: 1.1.1.1 + s1: example.com + property: ndots + value: 2 + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsPolicy: None + dnsConfig: + nameservers: + - "{{ .Values.ns1 }}" + - 2.2.2.2 + searches: + - "{{ .Values.s1 }}" + - example.org + options: + - name: "{{ .Values.property }}" + value: "{{ .Values.value }}" + - name: edns0 + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsConfig + value: + nameservers: + - 1.1.1.1 + - 2.2.2.2 + searches: + - example.com + - example.org + options: + - name: ndots + value: "2" + - name: edns0 + + # Failures + - it: should fail with dnsPolicy set to None and no nameservers + set: + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + nameservers: [] + asserts: + - failedTemplate: + errorMessage: Expected non-empty [dnsConfig.nameservers] with [dnsPolicy] set to [None]. + + - it: should fail with dnsPolicy set to None and no searches + set: + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + nameservers: + - 1.1.1.1 + searches: [] + asserts: + - failedTemplate: + errorMessage: Expected non-empty [dnsConfig.searches] with [dnsPolicy] set to [None]. + + - it: should fail with dnsPolicy set to None and no options + set: + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + nameservers: + - 1.1.1.1 + searches: + - example.com + options: [] + asserts: + - failedTemplate: + errorMessage: Expected non-empty [dnsConfig.options] with [dnsPolicy] set to [None]. + + - it: should fail with more than 3 nameservers + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + nameservers: + - 1.1.1.1 + - 1.1.1.1 + - 1.1.1.1 + - 1.1.1.1 + asserts: + - failedTemplate: + errorMessage: Expected no more than [3] [dnsConfig.nameservers], but got [4] + + - it: should fail with more than 6 Searches + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsConfig: + searches: + - example.com + - example.com + - example.com + - example.com + - example.com + - example.com + - example.com + asserts: + - failedTemplate: + errorMessage: Expected no more than [6] [dnsConfig.searches], but got [7] diff --git a/charts/library/common-test/tests/pod/dns_policy_test.yaml b/charts/library/common-test/tests/pod/dns_policy_test.yaml new file mode 100644 index 00000000000..9ebd880e284 --- /dev/null +++ b/charts/library/common-test/tests/pod/dns_policy_test.yaml @@ -0,0 +1,109 @@ +suite: pod dns policy test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with empty dnsPolicy + set: + podOptions: + dnsPolicy: "" + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + + - it: should pass with dnsPolicy from "global" + set: + podOptions: + dnsPolicy: Default + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsPolicy + value: Default + + - it: should pass with dnsPolicy from "pod" + set: + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsPolicy: ClusterFirst + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + + - it: should pass with dnsPolicy from "pod" with tpl + set: + policy: ClusterFirst + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsPolicy: "{{ .Values.policy }}" + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + + - it: should pass with hostNetwork enabled + set: + podOptions: + dnsPolicy: None + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + dnsPolicy: ClusterFirst + hostNetwork: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirstWithHostNet + + # Failures + - it: should fail with invalid dnsPolicy + set: + podOptions: + dnsPolicy: Invalid + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - failedTemplate: + errorMessage: Expected [dnsPolicy] to be one of [ClusterFirst, ClusterFirstWithHostNet, Default, None], but got [Invalid] diff --git a/charts/library/common-test/tests/pod/enable_service_links_test.yaml b/charts/library/common-test/tests/pod/enable_service_links_test.yaml new file mode 100644 index 00000000000..506c04cbb06 --- /dev/null +++ b/charts/library/common-test/tests/pod/enable_service_links_test.yaml @@ -0,0 +1,78 @@ +suite: pod enableServiceLinks test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with enableServiceLinks disabled from "global" + set: + podOptions: + enableServiceLinks: false + workload: + workload-name1: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: &daemonSetDoc 0 + isKind: + of: DaemonSet + - documentIndex: *daemonSetDoc + equal: + path: spec.template.spec.enableServiceLinks + value: false + + - it: should pass with enableServiceLinks enabled from "global" + set: + podOptions: + enableServiceLinks: true + workload: + workload-name1: + enabled: true + primary: true + type: DaemonSet + podSpec: {} + asserts: + - documentIndex: *daemonSetDoc + isKind: + of: DaemonSet + - documentIndex: *daemonSetDoc + equal: + path: spec.template.spec.enableServiceLinks + value: true + + - it: should pass with disabled enableServiceLinks from pod + set: + podOptions: + enableServiceLinks: true + workload: + workload-name1: + enabled: true + primary: true + type: DaemonSet + podSpec: + enableServiceLinks: false + asserts: + - documentIndex: *daemonSetDoc + equal: + path: spec.template.spec.enableServiceLinks + value: false + + - it: should pass with enabled enableServiceLinks from pod + set: + podOptions: + enableServiceLinks: false + workload: + workload-name1: + enabled: true + primary: true + type: DaemonSet + podSpec: + enableServiceLinks: true + asserts: + - documentIndex: *daemonSetDoc + equal: + path: spec.template.spec.enableServiceLinks + value: true diff --git a/charts/library/common-test/tests/pod/host-aliases_test.yaml b/charts/library/common-test/tests/pod/host-aliases_test.yaml new file mode 100644 index 00000000000..c67d3704d5c --- /dev/null +++ b/charts/library/common-test/tests/pod/host-aliases_test.yaml @@ -0,0 +1,129 @@ +suite: pod hostAliases test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with empty hostAliases + set: + podOptions: + hostAliases: "" + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + isNull: + path: spec.template.spec.hostAliases + + - it: should pass with hostAliases from "global" + set: + podOptions: + hostAliases: + - ip: 10.10.10.100 + hostnames: + - myserver.local + - storage.local + - ip: 10.10.10.101 + hostnames: + - myotherserver.local + - backups.local + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostAliases + value: + - ip: 10.10.10.100 + hostnames: + - myserver.local + - storage.local + - ip: 10.10.10.101 + hostnames: + - myotherserver.local + - backups.local + + - it: should pass with hostAliases from "pod" + set: + podOptions: + hostAliases: + - ip: 10.10.10.100 + hostnames: + - myserver.local + - storage.local + - ip: 10.10.10.101 + hostnames: + - myotherserver.local + - backups.local + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostAliases: + - ip: 10.10.10.200 + hostnames: + - server.local + - mystorage.local + - ip: 10.10.10.201 + hostnames: + - otherserver.local + - mybackups.local + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostAliases + value: + - ip: 10.10.10.200 + hostnames: + - server.local + - mystorage.local + - ip: 10.10.10.201 + hostnames: + - otherserver.local + - mybackups.local + + - it: should pass with schedulerName from "pod" with tpl + set: + ip: 10.10.10.200 + host1: server.local + host2: mystorage.local + podOptions: + hostAliases: + - ip: 10.10.10.100 + hostnames: + - myserver.local + - storage.local + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostAliases: + - ip: "{{ .Values.ip }}" + hostnames: + - "{{ .Values.host1 }}" + - "{{ .Values.host2 }}" + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostAliases + value: + - ip: 10.10.10.200 + hostnames: + - server.local + - mystorage.local diff --git a/charts/library/common-test/tests/pod/host_ipc_test.yaml b/charts/library/common-test/tests/pod/host_ipc_test.yaml new file mode 100644 index 00000000000..06a88b1c62c --- /dev/null +++ b/charts/library/common-test/tests/pod/host_ipc_test.yaml @@ -0,0 +1,78 @@ +suite: pod hostIPC test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hostIPC disabled from "global" + set: + podOptions: + hostIPC: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostIPC + value: false + + - it: should pass with hostIPC enabled from "global" + set: + podOptions: + hostIPC: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostIPC + value: true + + - it: should pass with disabled hostIPC from pod + set: + podOptions: + hostIPC: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostIPC: false + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostIPC + value: false + + - it: should pass with enabled hostIPC from pod + set: + podOptions: + hostIPC: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostIPC: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostIPC + value: true diff --git a/charts/library/common-test/tests/pod/host_network_test.yaml b/charts/library/common-test/tests/pod/host_network_test.yaml new file mode 100644 index 00000000000..d83de9a5cae --- /dev/null +++ b/charts/library/common-test/tests/pod/host_network_test.yaml @@ -0,0 +1,78 @@ +suite: pod hostnetwork test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hostnetwork disabled from "global" + set: + podOptions: + hostNetwork: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostNetwork + value: false + + - it: should pass with hostnetwork enabled from "global" + set: + podOptions: + hostNetwork: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostNetwork + value: true + + - it: should pass with disabled hostnetwork from pod + set: + podOptions: + hostNetwork: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: false + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostNetwork + value: false + + - it: should pass with enabled hostnetwork from pod + set: + podOptions: + hostNetwork: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostNetwork + value: true diff --git a/charts/library/common-test/tests/pod/host_pid_test.yaml b/charts/library/common-test/tests/pod/host_pid_test.yaml new file mode 100644 index 00000000000..3e813af1b28 --- /dev/null +++ b/charts/library/common-test/tests/pod/host_pid_test.yaml @@ -0,0 +1,78 @@ +suite: pod hostpid test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hostpid disabled from "global" + set: + podOptions: + hostPID: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostPID + value: false + + - it: should pass with hostpid enabled from "global" + set: + podOptions: + hostPID: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostPID + value: true + + - it: should pass with disabled hostpid from pod + set: + podOptions: + hostPID: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostPID: false + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostPID + value: false + + - it: should pass with enabled hostpid from pod + set: + podOptions: + hostPID: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostPID: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostPID + value: true diff --git a/charts/library/common-test/tests/pod/host_users_test.yaml b/charts/library/common-test/tests/pod/host_users_test.yaml new file mode 100644 index 00000000000..c91ab9841fd --- /dev/null +++ b/charts/library/common-test/tests/pod/host_users_test.yaml @@ -0,0 +1,397 @@ +suite: pod hostUsers test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should pass with hostUsers enabled from "global" + set: + podOptions: + hostUsers: true + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + - it: should pass with hostUsers enabled from podSpec + set: + podOptions: + hostUsers: false + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostUsers: true + asserts: + - documentIndex: *deploymentDoc + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + - it: should pass with enabled hostUsers because of pvc + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: {} + persistence: + vol1: + enabled: true + type: pvc + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + - it: should pass with enabled hostUsers because of hostNet + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostNetwork: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + - it: should pass with enabled hostUsers because of hostPID + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostPID: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + - it: should pass with enabled hostUsers because of hostIPC + set: + workload: + workload-name1: + enabled: true + primary: true + type: Deployment + podSpec: + hostIPC: true + asserts: + - documentIndex: *deploymentDoc + equal: + path: spec.template.spec.hostUsers + value: true + + # Tests that eq