diff --git a/.github/workflows/common_library_tests.yaml b/.github/workflows/common_library_tests.yaml index 7aa2b784..718ddde1 100644 --- a/.github/workflows/common_library_tests.yaml +++ b/.github/workflows/common_library_tests.yaml @@ -105,7 +105,7 @@ jobs: - basic-values.yaml - configmap-values.yaml - daemonset-values.yaml - - extracontainers-values.yaml + - extra-containers-values.yaml - job-cron-values.yaml - persistence-values.yaml - rbac-values.yaml diff --git a/library/common-test/ci/daemonset-values.yaml b/library/common-test/ci/daemonset-values.yaml index 371f5718..dd678d27 100644 --- a/library/common-test/ci/daemonset-values.yaml +++ b/library/common-test/ci/daemonset-values.yaml @@ -9,8 +9,6 @@ controller: # -- Set the controller type. # Valid options are: Deployment | DaemonSet | StatefulSet type: DaemonSet - # -- Number of desired pods - replicas: 2 service: main: diff --git a/library/common-test/ci/extra-containers-values.yaml b/library/common-test/ci/extra-containers-values.yaml index 9d4a714b..edc0676d 100644 --- a/library/common-test/ci/extra-containers-values.yaml +++ b/library/common-test/ci/extra-containers-values.yaml @@ -3,6 +3,11 @@ image: pullPolicy: IfNotPresent tag: latest +someImage: + repository: traefik/whoami + tag: latest + pullPolicy: IfNotPresent + service: main: ports: @@ -14,7 +19,49 @@ args: - --port - "8080" -# TODO: Add extra containers +additionalContainers: + some-name: + imageSelector: someImage + 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: / +initContainers: + some-name: + imageSelector: someImage + command: + - /bin/sh + - -c + - echo "Hello World" +systemContainers: + some-name: + imageSelector: someImage + command: + - /bin/sh + - -c + - echo "Hello World" +installContainers: + some-name: + imageSelector: someImage + command: + - /bin/sh + - -c + - echo "Hello World" probes: liveness: diff --git a/library/common-test/ci/extracontainers-values.yaml b/library/common-test/ci/extracontainers-values.yaml deleted file mode 100644 index 16c6b98b..00000000 --- a/library/common-test/ci/extracontainers-values.yaml +++ /dev/null @@ -1,23 +0,0 @@ -image: - repository: traefik/whoami - pullPolicy: IfNotPresent - tag: latest - -service: - main: - ports: - main: - protocol: HTTP - port: 8080 - -args: - - --port - - "8080" - -probes: - liveness: - enabled: true - readiness: - enabled: true - startup: - enabled: true diff --git a/library/common-test/tests/daemonset/annotations_test.yaml b/library/common-test/tests/daemonset/annotations_test.yaml new file mode 100644 index 00000000..7f6009f0 --- /dev/null +++ b/library/common-test/tests/daemonset/annotations_test.yaml @@ -0,0 +1,64 @@ +suite: daemonset annotation test +templates: + - common.yaml +tests: + - it: should pass with default values + documentIndex: &daemonsetDoc 0 + set: + controller.type: DaemonSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - isNull: + path: metadata.annotations + - matchRegex: + path: spec.template.metadata.annotations.rollme + pattern: "^[a-zA-Z0-9]{5}$" + + - it: should pass with controller and global annotations + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + some_key: some_value + controller: + annotations: + controller_key: controller_value + controller_key2: "{{ .Values.some_key }}" + global: + annotations: + global_key: global_value + global_key2: "{{ .Values.some_key }}" + asserts: + - equal: + path: metadata.annotations + value: + controller_key: controller_value + controller_key2: some_value + global_key: global_value + global_key2: some_value + - isNull: + path: metadata.annotations.rollme + - matchRegex: + path: spec.template.metadata.annotations.rollme + pattern: "^[a-zA-Z0-9]{5}$" + + - it: should pass with podAnnotations set + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + some_key: some_value2 + podAnnotations: + test: some_value + test2: "{{ .Values.some_key }}" + asserts: + - isSubset: + path: spec.template.metadata.annotations + content: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: common-test + release: RELEASE-NAME + test2: some_value2 + test: some_value diff --git a/library/common-test/tests/daemonset/controller_test.yaml b/library/common-test/tests/daemonset/controller_test.yaml new file mode 100644 index 00000000..82b9de35 --- /dev/null +++ b/library/common-test/tests/daemonset/controller_test.yaml @@ -0,0 +1,63 @@ +suite: daemonset strategy test +templates: + - common.yaml +tests: + - it: should pass with strategy changed in DaemonSet + documentIndex: &dameonsetDoc 0 + set: + controller: + type: DaemonSet + strategy: OnDelete + rollingUpdate: + surge: 5 + unavailable: 6 + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - equal: + path: spec.updateStrategy + value: + type: OnDelete + - isNull: + path: spec.updateStrategy.rollingUpdate + + - it: should pass with strategy changed in DaemonSet + documentIndex: *dameonsetDoc + set: + controller: + type: DaemonSet + strategy: RollingUpdate + rollingUpdate: + surge: 5 + unavailable: 6 + asserts: + - equal: + path: spec.updateStrategy + value: + type: RollingUpdate + rollingUpdate: + maxSurge: 5 + maxUnavailable: 6 + + - it: should fail with wrong strategy + documentIndex: *dameonsetDoc + set: + controller: + type: DaemonSet + strategy: not_valid_strategy + asserts: + - failedTemplate: + errorMessage: Not a valid strategy type for DaemonSet (not_valid_strategy) + + - it: should pass with revisionHistoryLimit changed + documentIndex: *dameonsetDoc + set: + controller: + type: DaemonSet + revisionHistoryLimit: 1 + asserts: + - equal: + path: spec.revisionHistoryLimit + value: 1 diff --git a/library/common-test/tests/daemonset/default_test.yaml b/library/common-test/tests/daemonset/default_test.yaml new file mode 100644 index 00000000..a4275783 --- /dev/null +++ b/library/common-test/tests/daemonset/default_test.yaml @@ -0,0 +1,110 @@ +suite: daemonset default test +templates: + - common.yaml +tests: + - it: should pass with controller set to DaemonSet + documentIndex: &daemonsetDoc 0 + set: + controller.type: DaemonSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - isAPIVersion: + of: apps/v1 + - equal: + path: spec.revisionHistoryLimit + value: 3 + - equal: + path: spec.updateStrategy.type + value: RollingUpdate + - equal: + path: spec.template.spec.serviceAccountName + value: default + - equal: + path: spec.template.spec.hostNetwork + value: false + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 10 + - equal: + path: spec.template.spec.enableServiceLinks + value: false + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 10 + - isNull: + path: spec.template.spec.hostname + - equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + - isNull: + path: spec.template.spec.dnsConfig + - isNull: + path: spec.template.spec.priorityClassName + - isNull: + path: spec.template.spec.schedulerName + - equal: + path: spec.template.spec.containers[0].name + value: RELEASE-NAME-common-test + - equal: + path: spec.template.spec.containers[0].image + value: repo:tag + - isNull: + path: spec.template.spec.containers[0].command + - isNull: + path: spec.template.spec.containers[0].args + - equal: + path: spec.template.spec.containers[0].tty + value: false + - equal: + path: spec.template.spec.containers[0].stdin + value: false + - isNull: + path: spec.template.spec.containers[0].lifecycle + - isNull: + path: spec.template.spec.containers[0].terminationMessagePath + - isNull: + path: spec.template.spec.containers[0].terminationMessagePolicy + - equal: + path: spec.template.spec.securityContext + value: + fsGroup: 568 + fsGroupChangePolicy: OnRootMismatch + supplementalGroups: [] + - equal: + path: spec.template.spec.containers[0].securityContext + value: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 568 + runAsGroup: 568 + capabilities: + add: [] + drop: + - ALL + - equal: + path: spec.template.spec.containers[0].env + value: + - name: TZ + value: UTC + - name: UMASK + value: "002" + - name: UMASK_SET + value: "002" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: S6_READ_ONLY_ROOT + value: "1" + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - mountPath: /shared + name: shared + - mountPath: /tmp + name: tmp + - mountPath: /var/logs + name: varlogs diff --git a/library/common-test/tests/daemonset/generic_test.yaml b/library/common-test/tests/daemonset/generic_test.yaml new file mode 100644 index 00000000..c216c1eb --- /dev/null +++ b/library/common-test/tests/daemonset/generic_test.yaml @@ -0,0 +1,228 @@ +suite: daemonset generic test +templates: + - common.yaml +tests: + - it: should pass with controller set to DaemonSet + documentIndex: &daemonsetDoc 0 + set: + controller.type: DaemonSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - isAPIVersion: + of: apps/v1 + + + - it: should pass with podSecurityContext changed + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + podSecurityContext: + fsGroup: 0 + fsGroupChangePolicy: Always + supplementalGroups: + - 1000 + asserts: + - equal: + path: spec.template.spec.securityContext + value: + fsGroup: 0 + fsGroupChangePolicy: Always + supplementalGroups: + - 1000 + + - it: should pass with podSecurityContext changed + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + add: + - something + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext + value: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + add: + - something + drop: + - ALL + + - it: should pass with multiple envs defined via tpl + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + some_string: a_string + some_int: 123 + some_bool: false + env: + ENVVAR: "{{ .Values.some_string }}" + ENVVAR2: "{{ .Values.some_int }}" + ENVVAR3: "{{ .Values.some_bool }}" + asserts: + - equal: + path: spec.template.spec.containers[0].env + value: + - name: TZ + value: "UTC" + - name: UMASK + value: "002" + - name: UMASK_SET + value: "002" + - name: NVIDIA_VISIBLE_DEVICES + value: "void" + - name: S6_READ_ONLY_ROOT + value: "1" + - name: ENVVAR + value: "a_string" + - name: ENVVAR2 + value: "123" + - name: ENVVAR3 + value: "false" + + - it: should pass with image defined in init containers + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + image: + repository: some-repo + tag: some-tag + pullPolicy: Always + someImage: + repository: some-other-repo + tag: some-other-tag + pullPolicy: Never + additionalContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + initContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + systemContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + installContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + asserts: + - isSubset: + path: spec.template.spec.containers[0] + content: + image: some-repo:some-tag + imagePullPolicy: Always + - lengthEqual: + path: spec.template.spec.containers + count: 2 + - lengthEqual: + path: spec.template.spec.initContainers + count: 3 + + - it: should pass with added persistence + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + persistence: + volume0: + type: pvc + enabled: true + mountPath: /pvc./path + volume1: + enabled: true + type: nfs + server: some.server.local + path: /nfs/path + mountPath: /nfs + volume2: + enabled: true + type: ixVolume + datasetName: ix-app + mountPath: /ixVol + volume3: + enabled: true + type: hostPath + hostPath: /mnt/pool/test + mountPath: /some/path + volume4: + enabled: true + type: emptyDir + medium: Memory + sizeLimit: 1Gi + mountPath: /temp-path + volume5: + type: secret + enabled: true + objectName: some_object_name + defaultMode: "0777" + mountPath: /secret-path + volume6: + type: configMap + enabled: true + objectName: some_object_name + defaultMode: "0777" + mountPath: /configmap-path + ixVolumes: + - /mnt/pool/ix-applications/ix-app + asserts: + - hasDocuments: + count: 4 + - contains: + path: spec.template.spec.volumes + content: + name: volume0 + persistentVolumeClaim: + claimName: RELEASE-NAME-common-test-volume0 + - contains: + path: spec.template.spec.volumes + content: + name: volume1 + nfs: + path: /nfs/path + server: some.server.local + - contains: + path: spec.template.spec.volumes + content: + name: volume2 + hostPath: + path: /mnt/pool/ix-applications/ix-app + - contains: + path: spec.template.spec.volumes + content: + name: volume3 + hostPath: + path: /mnt/pool/test + - contains: + path: spec.template.spec.volumes + content: + name: volume4 + emptyDir: + medium: Memory + sizeLimit: 1Gi + - contains: + path: spec.template.spec.volumes + content: + name: volume5 + secret: + defaultMode: 511 + secretName: some_object_name + - contains: + path: spec.template.spec.volumes + content: + name: volume6 + configMap: + defaultMode: 511 + name: some_object_name diff --git a/library/common-test/tests/daemonset/label_test.yaml b/library/common-test/tests/daemonset/label_test.yaml new file mode 100644 index 00000000..7311d4d7 --- /dev/null +++ b/library/common-test/tests/daemonset/label_test.yaml @@ -0,0 +1,79 @@ +suite: daemonset label test +templates: + - common.yaml +chart: + appVersion: &appVer v1.2.3 +tests: + - it: should pass with default values + documentIndex: &daemonsetDoc 0 + set: + controller.type: DaemonSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - equal: + path: metadata.labels + value: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: *appVer + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: RELEASE-NAME + - equal: + path: spec.selector.matchLabels + value: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: common-test + release: RELEASE-NAME + + - it: should pass with controller and global labels + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + some_key: some_value + controller: + labels: + controller_key: controller_value + controller_key2: "{{ .Values.some_key }}" + global: + labels: + global_key: global_value + global_key2: "{{ .Values.some_key }}" + asserts: + - equal: + path: metadata.labels + value: + controller_key: controller_value + controller_key2: some_value + global_key: global_value + global_key2: some_value + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: *appVer + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: RELEASE-NAME + + - it: should pass with podLabels set + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + some_key: some_value2 + podLabels: + test: some_value + test2: "{{ .Values.some_key }}" + asserts: + - equal: + path: spec.template.metadata.labels.test2 + value: some_value2 + - equal: + path: spec.template.metadata.labels.test + value: some_value diff --git a/library/common-test/tests/daemonset/names_test.yaml b/library/common-test/tests/daemonset/names_test.yaml new file mode 100644 index 00000000..54153b0a --- /dev/null +++ b/library/common-test/tests/daemonset/names_test.yaml @@ -0,0 +1,38 @@ +suite: daemonset name test +templates: + - common.yaml +tests: + - it: should pass with default values + documentIndex: &daemonsetDoc 0 + set: + controller.type: DaemonSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: DaemonSet + - equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: should pass with nameOverride + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + nameOverride: overrodeName + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-overrodeName + + - it: should pass with global.nameOverride + documentIndex: *daemonsetDoc + set: + controller.type: DaemonSet + nameOverride: overrodeName + global: + nameOverride: globalOverrodeName + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-globalOverrodeName diff --git a/library/common-test/tests/deployment/controller_test.yaml b/library/common-test/tests/deployment/controller_test.yaml index a7aff2ba..a2147d48 100644 --- a/library/common-test/tests/deployment/controller_test.yaml +++ b/library/common-test/tests/deployment/controller_test.yaml @@ -78,3 +78,23 @@ tests: asserts: - failedTemplate: errorMessage: Not a valid strategy type for Deployment (not_valid_strategy) + + - it: should pass with revisionHistoryLimit changed + documentIndex: *deploymentDoc + set: + controller: + revisionHistoryLimit: 1 + asserts: + - equal: + path: spec.revisionHistoryLimit + value: 1 + + - it: should pass with replicas changed + documentIndex: *deploymentDoc + set: + controller: + replicas: 6 + asserts: + - equal: + path: spec.replicas + value: 6 diff --git a/library/common-test/tests/deployment/default_test.yaml b/library/common-test/tests/deployment/default_test.yaml index f3f62188..88d35dea 100644 --- a/library/common-test/tests/deployment/default_test.yaml +++ b/library/common-test/tests/deployment/default_test.yaml @@ -11,6 +11,15 @@ tests: of: Deployment - isAPIVersion: of: apps/v1 + - equal: + path: spec.revisionHistoryLimit + value: 3 + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.strategy.type + value: Recreate - equal: path: spec.template.spec.serviceAccountName value: default diff --git a/library/common-test/tests/job_standalone/controller_test.yaml b/library/common-test/tests/job_standalone/controller_test.yaml new file mode 100644 index 00000000..d3311b5f --- /dev/null +++ b/library/common-test/tests/job_standalone/controller_test.yaml @@ -0,0 +1,14 @@ +suite: job strategy test +templates: + - common.yaml +tests: + - it: should pass with strategy changed in job + documentIndex: &jobDoc 2 + set: + controller: + type: Job + asserts: + - hasDocuments: + count: 3 + - isKind: + of: Job diff --git a/library/common-test/tests/jobcron_standalone/controller_test.yaml b/library/common-test/tests/jobcron_standalone/controller_test.yaml new file mode 100644 index 00000000..26865aab --- /dev/null +++ b/library/common-test/tests/jobcron_standalone/controller_test.yaml @@ -0,0 +1,15 @@ +suite: cronjob strategy test +templates: + - common.yaml +tests: + - it: should pass with strategy changed in cronjob + documentIndex: &cronJobDoc 2 + set: + controller: + type: CronJob + schedule: "* * * * *" + asserts: + - hasDocuments: + count: 3 + - isKind: + of: CronJob diff --git a/library/common-test/tests/statefulset/annotations_test.yaml b/library/common-test/tests/statefulset/annotations_test.yaml new file mode 100644 index 00000000..694068ce --- /dev/null +++ b/library/common-test/tests/statefulset/annotations_test.yaml @@ -0,0 +1,64 @@ +suite: statefulset annotation test +templates: + - common.yaml +tests: + - it: should pass with default values + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - isNull: + path: metadata.annotations + - matchRegex: + path: spec.template.metadata.annotations.rollme + pattern: "^[a-zA-Z0-9]{5}$" + + - it: should pass with controller and global annotations + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + some_key: some_value + controller: + annotations: + controller_key: controller_value + controller_key2: "{{ .Values.some_key }}" + global: + annotations: + global_key: global_value + global_key2: "{{ .Values.some_key }}" + asserts: + - equal: + path: metadata.annotations + value: + controller_key: controller_value + controller_key2: some_value + global_key: global_value + global_key2: some_value + - isNull: + path: metadata.annotations.rollme + - matchRegex: + path: spec.template.metadata.annotations.rollme + pattern: "^[a-zA-Z0-9]{5}$" + + - it: should pass with podAnnotations set + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + some_key: some_value2 + podAnnotations: + test: some_value + test2: "{{ .Values.some_key }}" + asserts: + - isSubset: + path: spec.template.metadata.annotations + content: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: common-test + release: RELEASE-NAME + test2: some_value2 + test: some_value diff --git a/library/common-test/tests/statefulset/controller_test.yaml b/library/common-test/tests/statefulset/controller_test.yaml new file mode 100644 index 00000000..4e2ec7e9 --- /dev/null +++ b/library/common-test/tests/statefulset/controller_test.yaml @@ -0,0 +1,74 @@ +suite: statefulset strategy test +templates: + - common.yaml +tests: + - it: should pass with strategy changed in StatefulSet + documentIndex: &statefulsetDoc 0 + set: + controller: + type: StatefulSet + strategy: OnDelete + rollingUpdate: + partition: 5 + unavailable: 6 + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - equal: + path: spec.updateStrategy + value: + type: OnDelete + - isNull: + path: spec.updateStrategy.rollingUpdate + + - it: should pass with strategy changed in StatefulSet + documentIndex: *statefulsetDoc + set: + controller: + type: StatefulSet + strategy: RollingUpdate + rollingUpdate: + partition: 5 + unavailable: 6 + asserts: + - equal: + path: spec.updateStrategy + value: + type: RollingUpdate + rollingUpdate: + partition: 5 + maxUnavailable: 6 + + - it: should fail with wrong strategy + documentIndex: *statefulsetDoc + set: + controller: + type: StatefulSet + strategy: not_valid_strategy + asserts: + - failedTemplate: + errorMessage: Not a valid strategy type for StatefulSet (not_valid_strategy) + + - it: should pass with revisionHistoryLimit changed + documentIndex: *statefulsetDoc + set: + controller: + type: StatefulSet + revisionHistoryLimit: 1 + asserts: + - equal: + path: spec.revisionHistoryLimit + value: 1 + + - it: should pass with replicas changed + documentIndex: *statefulsetDoc + set: + controller: + type: StatefulSet + replicas: 6 + asserts: + - equal: + path: spec.replicas + value: 6 diff --git a/library/common-test/tests/statefulset/default_test.yaml b/library/common-test/tests/statefulset/default_test.yaml new file mode 100644 index 00000000..99ad290b --- /dev/null +++ b/library/common-test/tests/statefulset/default_test.yaml @@ -0,0 +1,116 @@ +suite: statefulset default test +templates: + - common.yaml +tests: + - it: should pass with controller set to StatefulSet + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - isAPIVersion: + of: apps/v1 + - equal: + path: spec.serviceName + value: RELEASE-NAME-common-test + - equal: + path: spec.revisionHistoryLimit + value: 3 + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.updateStrategy.type + value: RollingUpdate + - equal: + path: spec.template.spec.serviceAccountName + value: default + - equal: + path: spec.template.spec.hostNetwork + value: false + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 10 + - equal: + path: spec.template.spec.enableServiceLinks + value: false + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 10 + - isNull: + path: spec.template.spec.hostname + - equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + - isNull: + path: spec.template.spec.dnsConfig + - isNull: + path: spec.template.spec.priorityClassName + - isNull: + path: spec.template.spec.schedulerName + - equal: + path: spec.template.spec.containers[0].name + value: RELEASE-NAME-common-test + - equal: + path: spec.template.spec.containers[0].image + value: repo:tag + - isNull: + path: spec.template.spec.containers[0].command + - isNull: + path: spec.template.spec.containers[0].args + - equal: + path: spec.template.spec.containers[0].tty + value: false + - equal: + path: spec.template.spec.containers[0].stdin + value: false + - isNull: + path: spec.template.spec.containers[0].lifecycle + - isNull: + path: spec.template.spec.containers[0].terminationMessagePath + - isNull: + path: spec.template.spec.containers[0].terminationMessagePolicy + - equal: + path: spec.template.spec.securityContext + value: + fsGroup: 568 + fsGroupChangePolicy: OnRootMismatch + supplementalGroups: [] + - equal: + path: spec.template.spec.containers[0].securityContext + value: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 568 + runAsGroup: 568 + capabilities: + add: [] + drop: + - ALL + - equal: + path: spec.template.spec.containers[0].env + value: + - name: TZ + value: UTC + - name: UMASK + value: "002" + - name: UMASK_SET + value: "002" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: S6_READ_ONLY_ROOT + value: "1" + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - mountPath: /shared + name: shared + - mountPath: /tmp + name: tmp + - mountPath: /var/logs + name: varlogs diff --git a/library/common-test/tests/statefulset/generic_test.yaml b/library/common-test/tests/statefulset/generic_test.yaml new file mode 100644 index 00000000..82b876dd --- /dev/null +++ b/library/common-test/tests/statefulset/generic_test.yaml @@ -0,0 +1,229 @@ +suite: statefulset generic test +templates: + - common.yaml +tests: + - it: should pass with controller set to StatefulSet + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - isAPIVersion: + of: apps/v1 + + + - it: should pass with podSecurityContext changed + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + podSecurityContext: + fsGroup: 0 + fsGroupChangePolicy: Always + supplementalGroups: + - 1000 + asserts: + - equal: + path: spec.template.spec.securityContext + value: + fsGroup: 0 + fsGroupChangePolicy: Always + supplementalGroups: + - 1000 + + + - it: should pass with podSecurityContext changed + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + add: + - something + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext + value: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + add: + - something + drop: + - ALL + + - it: should pass with multiple envs defined via tpl + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + some_string: a_string + some_int: 123 + some_bool: false + env: + ENVVAR: "{{ .Values.some_string }}" + ENVVAR2: "{{ .Values.some_int }}" + ENVVAR3: "{{ .Values.some_bool }}" + asserts: + - equal: + path: spec.template.spec.containers[0].env + value: + - name: TZ + value: "UTC" + - name: UMASK + value: "002" + - name: UMASK_SET + value: "002" + - name: NVIDIA_VISIBLE_DEVICES + value: "void" + - name: S6_READ_ONLY_ROOT + value: "1" + - name: ENVVAR + value: "a_string" + - name: ENVVAR2 + value: "123" + - name: ENVVAR3 + value: "false" + + - it: should pass with image defined in init containers + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + image: + repository: some-repo + tag: some-tag + pullPolicy: Always + someImage: + repository: some-other-repo + tag: some-other-tag + pullPolicy: Never + additionalContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + initContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + systemContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + installContainers: + some-name: + imageSelector: someImage + pullPolicy: Never + asserts: + - isSubset: + path: spec.template.spec.containers[0] + content: + image: some-repo:some-tag + imagePullPolicy: Always + - lengthEqual: + path: spec.template.spec.containers + count: 2 + - lengthEqual: + path: spec.template.spec.initContainers + count: 3 + + - it: should pass with added persistence + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + persistence: + volume0: + type: pvc + enabled: true + mountPath: /pvc./path + volume1: + enabled: true + type: nfs + server: some.server.local + path: /nfs/path + mountPath: /nfs + volume2: + enabled: true + type: ixVolume + datasetName: ix-app + mountPath: /ixVol + volume3: + enabled: true + type: hostPath + hostPath: /mnt/pool/test + mountPath: /some/path + volume4: + enabled: true + type: emptyDir + medium: Memory + sizeLimit: 1Gi + mountPath: /temp-path + volume5: + type: secret + enabled: true + objectName: some_object_name + defaultMode: "0777" + mountPath: /secret-path + volume6: + type: configMap + enabled: true + objectName: some_object_name + defaultMode: "0777" + mountPath: /configmap-path + ixVolumes: + - /mnt/pool/ix-applications/ix-app + asserts: + - hasDocuments: + count: 4 + - contains: + path: spec.template.spec.volumes + content: + name: volume0 + persistentVolumeClaim: + claimName: RELEASE-NAME-common-test-volume0 + - contains: + path: spec.template.spec.volumes + content: + name: volume1 + nfs: + path: /nfs/path + server: some.server.local + - contains: + path: spec.template.spec.volumes + content: + name: volume2 + hostPath: + path: /mnt/pool/ix-applications/ix-app + - contains: + path: spec.template.spec.volumes + content: + name: volume3 + hostPath: + path: /mnt/pool/test + - contains: + path: spec.template.spec.volumes + content: + name: volume4 + emptyDir: + medium: Memory + sizeLimit: 1Gi + - contains: + path: spec.template.spec.volumes + content: + name: volume5 + secret: + defaultMode: 511 + secretName: some_object_name + - contains: + path: spec.template.spec.volumes + content: + name: volume6 + configMap: + defaultMode: 511 + name: some_object_name diff --git a/library/common-test/tests/statefulset/label_test.yaml b/library/common-test/tests/statefulset/label_test.yaml new file mode 100644 index 00000000..2a4fac55 --- /dev/null +++ b/library/common-test/tests/statefulset/label_test.yaml @@ -0,0 +1,79 @@ +suite: statefulset label test +templates: + - common.yaml +chart: + appVersion: &appVer v1.2.3 +tests: + - it: should pass with default values + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - equal: + path: metadata.labels + value: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: *appVer + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: RELEASE-NAME + - equal: + path: spec.selector.matchLabels + value: + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: common-test + release: RELEASE-NAME + + - it: should pass with controller and global labels + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + some_key: some_value + controller: + labels: + controller_key: controller_value + controller_key2: "{{ .Values.some_key }}" + global: + labels: + global_key: global_value + global_key2: "{{ .Values.some_key }}" + asserts: + - equal: + path: metadata.labels + value: + controller_key: controller_value + controller_key2: some_value + global_key: global_value + global_key2: some_value + app: common-test + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + app.kubernetes.io/version: *appVer + helm-revision: "0" + helm.sh/chart: common-test-1.0.0 + release: RELEASE-NAME + + - it: should pass with podLabels set + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + some_key: some_value2 + podLabels: + test: some_value + test2: "{{ .Values.some_key }}" + asserts: + - equal: + path: spec.template.metadata.labels.test2 + value: some_value2 + - equal: + path: spec.template.metadata.labels.test + value: some_value diff --git a/library/common-test/tests/statefulset/names_test.yaml b/library/common-test/tests/statefulset/names_test.yaml new file mode 100644 index 00000000..fa013ee6 --- /dev/null +++ b/library/common-test/tests/statefulset/names_test.yaml @@ -0,0 +1,38 @@ +suite: statefulset name test +templates: + - common.yaml +tests: + - it: should pass with default values + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + asserts: + - hasDocuments: + count: 3 + - isKind: + of: StatefulSet + - equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: should pass with nameOverride + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + nameOverride: overrodeName + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-overrodeName + + - it: should pass with global.nameOverride + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + nameOverride: overrodeName + global: + nameOverride: globalOverrodeName + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-globalOverrodeName diff --git a/library/common-test/tests/statefulset/vct_test.yaml b/library/common-test/tests/statefulset/vct_test.yaml new file mode 100644 index 00000000..195f8bdc --- /dev/null +++ b/library/common-test/tests/statefulset/vct_test.yaml @@ -0,0 +1,125 @@ +suite: statefulset vct test +templates: + - common.yaml +tests: + - it: should pass with vct defined in StatefulSet + documentIndex: &statefulsetDoc 0 + set: + controller.type: StatefulSet + volumeClaimTemplates: + data: + enabled: true + mountPath: "/bitnami/mariadb" + asserts: + - isKind: + of: StatefulSet + - equal: + path: spec.volumeClaimTemplates[0] + value: + metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 999Gi + + - it: should pass with multiple vct defined in StatefulSet + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + volumeClaimTemplates: + data: + enabled: true + mountPath: "/bitnami/mariadb" + other-data: + enabled: true + mountPath: "/bitnami/mariadb" + asserts: + - isKind: + of: StatefulSet + - equal: + path: spec.volumeClaimTemplates[0] + value: + metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 999Gi + - equal: + path: spec.volumeClaimTemplates[1] + value: + metadata: + name: other-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 999Gi + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - mountPath: /shared + name: shared + - mountPath: /tmp + name: tmp + - mountPath: /var/logs + name: varlogs + - mountPath: /bitnami/mariadb + name: data + - mountPath: /bitnami/mariadb + name: other-data + + - it: should pass with vct size changed in StatefulSet + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + volumeClaimTemplates: + data: + enabled: true + size: 10Gi + mountPath: "/bitnami/mariadb" + asserts: + - isKind: + of: StatefulSet + - equal: + path: spec.volumeClaimTemplates[0] + value: + metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + + - it: should pass with accessMode changed in StatefulSet + documentIndex: *statefulsetDoc + set: + controller.type: StatefulSet + volumeClaimTemplates: + data: + enabled: true + size: 10Gi + accessMode: ReadWriteMany + mountPath: "/bitnami/mariadb" + asserts: + - isKind: + of: StatefulSet + - equal: + path: spec.volumeClaimTemplates[0] + value: + metadata: + name: data + spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 10Gi diff --git a/library/common-test/values.yaml b/library/common-test/values.yaml index db0e439e..67cebbb6 100644 --- a/library/common-test/values.yaml +++ b/library/common-test/values.yaml @@ -3,10 +3,3 @@ service: ports: main: port: 65535 - -# controller: -# type: Job - -# cron: -# enabled: true -# schedule: "* * * * *" diff --git a/library/common/templates/lib/container/_volumeMounts.tpl b/library/common/templates/lib/container/_volumeMounts.tpl index 5e5be10c..f70ef17c 100644 --- a/library/common/templates/lib/container/_volumeMounts.tpl +++ b/library/common/templates/lib/container/_volumeMounts.tpl @@ -16,7 +16,7 @@ {{- end -}} {{/* TODO: write tests when statefulset is ready */}} - {{- if eq $root.Values.controller.type "statefulset" -}} + {{- if eq $root.Values.controller.type "StatefulSet" -}} {{- range $index, $vct := $root.Values.volumeClaimTemplates -}} {{- include "ix.v1.common.container.volumeMount" (dict "root" $root "item" $vct diff --git a/library/common/templates/loader/_apply.tpl b/library/common/templates/loader/_apply.tpl index c74b8291..625208bf 100644 --- a/library/common/templates/loader/_apply.tpl +++ b/library/common/templates/loader/_apply.tpl @@ -19,10 +19,10 @@ {{- include "ix.v1.common.daemonset" . | nindent 0 -}} {{- else if eq .Values.controller.type "StatefulSet" -}} {{- include "ix.v1.common.statefulset" . | nindent 0 -}} - {{- else if eq .Values.controller.type "Job" -}} + {{- else if (mustHas .Values.controller.type (list "Job" "CronJob")) -}} {{/* Pass, it will render from the spawner.jobAndCronJob bellow */}} {{- else -}} - {{- fail (printf "Not a valid controller.type (%s). Valid options are Deployment, DaemonSet, StatefulSet, Job" .Values.controller.type) -}} + {{- fail (printf "Not a valid controller.type (%s). Valid options are Deployment, DaemonSet, StatefulSet, Job, CronJob" .Values.controller.type) -}} {{- end -}} {{- end -}} diff --git a/library/common/templates/pods/_daemonset.tpl b/library/common/templates/pods/_daemonset.tpl index 624b7bc7..0e5144bf 100644 --- a/library/common/templates/pods/_daemonset.tpl +++ b/library/common/templates/pods/_daemonset.tpl @@ -22,7 +22,7 @@ spec: revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} {{- $strategy := default "RollingUpdate" .Values.controller.strategy -}} {{- if not (mustHas $strategy (list "OnDelete" "RollingUpdate")) -}} - {{- fail (printf "Not a valid strategy type for Daemonset (%s)" $strategy) -}} + {{- fail (printf "Not a valid strategy type for DaemonSet (%s)" $strategy) -}} {{- end }} updateStrategy: type: {{ $strategy }} @@ -52,4 +52,3 @@ spec: spec: {{- include "ix.v1.common.controller.pod" $ | trim | nindent 6 }} {{- end }} -{{/*TODO: unittests*/}} diff --git a/library/common/templates/pods/_statefulset.tpl b/library/common/templates/pods/_statefulset.tpl index 4f834ff0..bcc6d349 100644 --- a/library/common/templates/pods/_statefulset.tpl +++ b/library/common/templates/pods/_statefulset.tpl @@ -21,13 +21,10 @@ metadata: spec: revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} replicas: {{ .Values.controller.replicas }} - selector: - matchLabels: - {{- include "ix.v1.common.labels.selectorLabels" . | nindent 6 }} serviceName: {{ include "ix.v1.common.names.fullname" . }} {{- $strategy := default "RollingUpdate" .Values.controller.strategy -}} {{- if not (mustHas $strategy (list "OnDelete" "RollingUpdate")) -}} - {{- fail (printf "Not a valid strategy type for Deployment (%s)" $strategy) -}} + {{- fail (printf "Not a valid strategy type for StatefulSet (%s)" $strategy) -}} {{- end }} updateStrategy: type: {{ $strategy }} @@ -40,7 +37,22 @@ spec: {{- with $rollingUpdate.partition }} partition: {{ . }} {{- end -}} - {{- end -}} + {{- end }} + selector: + matchLabels: + {{- include "ix.v1.common.labels.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with (mustMerge (include "ix.v1.common.labels.selectorLabels" . | fromYaml) (include "ix.v1.common.annotations.workload" . | fromYaml) (include "ix.v1.common.podAnnotations" . | fromYaml)) }} + annotations: + {{- . | toYaml | trim | nindent 8 }} + {{- end -}} + {{- with (mustMerge (include "ix.v1.common.labels.selectorLabels" . | fromYaml) (include "ix.v1.common.podLabels" . | fromYaml)) }} + labels: + {{- . | toYaml | trim | nindent 8 }} + {{- end }} + spec: + {{- include "ix.v1.common.controller.pod" $ | trim | nindent 6 }} {{- if .Values.volumeClaimTemplates }} volumeClaimTemplates: {{- range $index, $vct := .Values.volumeClaimTemplates }} @@ -56,18 +68,5 @@ spec: requests: storage: {{ tpl ($vct.size | default $.Values.global.defaults.VCTSize) $ | quote }} {{- end -}} - {{- end }} - template: - metadata: - {{- with (mustMerge (include "ix.v1.common.labels.selectorLabels" . | fromYaml) (include "ix.v1.common.annotations.workload" . | fromYaml) (include "ix.v1.common.podAnnotations" . | fromYaml)) }} - annotations: - {{- . | toYaml | trim | nindent 8 }} - {{- end -}} - {{- with (mustMerge (include "ix.v1.common.labels.selectorLabels" . | fromYaml) (include "ix.v1.common.podLabels" . | fromYaml)) }} - labels: - {{- . | toYaml | trim | nindent 8 }} - {{- end }} - spec: - {{- include "ix.v1.common.controller.pod" $ | trim | nindent 6 }} + {{- end -}} {{- end }} -{{/*TODO: unittests*/}} diff --git a/library/common/templates/spawner/_jobAndCronJob.tpl b/library/common/templates/spawner/_jobAndCronJob.tpl index 98b404f8..445d3ab0 100644 --- a/library/common/templates/spawner/_jobAndCronJob.tpl +++ b/library/common/templates/spawner/_jobAndCronJob.tpl @@ -9,8 +9,7 @@ {{/* If it's CronJob prepare the cron dict with enabled forced */}} {{- if eq $.Values.controller.type "CronJob" -}} - {{- $_ := set $jobValues "cron" dict -}} - {{- $_ := set $jobValues.cron $.Values.controller -}} + {{- $_ := set $jobValues "cron" $.Values.controller -}} {{- $_ := set $jobValues.cron "enabled" true -}} {{- end -}}