add additional containers (only if a main exists) + tests

This commit is contained in:
Stavros kois
2023-01-04 22:43:22 +02:00
parent 7a43943d23
commit 26944bdc77
2 changed files with 1002 additions and 1 deletions

View File

@@ -0,0 +1,999 @@
suite: additionalContainer in deployment test
templates:
- common.yaml
tests:
- it: should pass with default values
documentIndex: &deploymentDoc 0
asserts:
- hasDocuments:
count: 3
- isKind:
of: Deployment
- it: should pass with image defined in additional container
documentIndex: *deploymentDoc
set:
image:
repository: some-repo
tag: some-tag
pullPolicy: Always
additionalImage:
repository: some-repo-additional
tag: some-tag-additional
pullPolicy: Never
additionalContainers:
some-name:
imageSelector: additionalImage
pullPolicy: Never
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
image: some-repo:some-tag
imagePullPolicy: Always
- isSubset:
path: spec.template.spec.containers[1]
content:
image: some-repo-additional:some-tag-additional
imagePullPolicy: Never
- it: should pass with image defined in multiple additional container
documentIndex: *deploymentDoc
set:
image:
repository: some-repo
tag: some-tag
pullPolicy: Always
additionalImage:
repository: some-repo-additional
tag: some-tag-additional
pullPolicy: Never
additionalImage2:
repository: some-repo-additional2
tag: some-tag-additional2
pullPolicy: IfNotPresent
additionalContainers:
some-name:
imageSelector: additionalImage
pullPolicy: Never
some-name2:
imageSelector: additionalImage2
pullPolicy: Never
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
image: some-repo:some-tag
imagePullPolicy: Always
- isSubset:
path: spec.template.spec.containers[1]
content:
image: some-repo-additional:some-tag-additional
imagePullPolicy: Never
- isSubset:
path: spec.template.spec.containers[2]
content:
image: some-repo-additional2:some-tag-additional2
imagePullPolicy: IfNotPresent
- it: should pass with tty and stdin defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
tty: true
stdin: true
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
tty: false
stdin: false
- isSubset:
path: spec.template.spec.containers[1]
content:
tty: true
stdin: true
- it: should pass with command and args defined in additional container
documentIndex: *deploymentDoc
set:
port: 8080
entrypoint: ./run.sh
additionalContainers:
some-name:
command:
- /bin/sh
- -c
- |
{{ .Values.entrypoint }}
args:
- --port
- "{{ .Values.port }}"
extraArgs:
- --data_dir
- /data
asserts:
- isNotSubset:
path: spec.template.spec.containers[0]
content:
command:
- /bin/sh
- -c
- |
./run.sh
args:
- --port
- "8080"
- --data_dir
- /data
- isSubset:
path: spec.template.spec.containers[1]
content:
command:
- /bin/sh
- -c
- |
./run.sh
args:
- --port
- "8080"
- --data_dir
- /data
- it: should pass with termination defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
termination:
messagePath: somePath
messagePolicy: File
asserts:
- isNotSubset:
path: spec.template.spec.containers[0]
content:
terminationMessagePath: somePath
terminationMessagePolicy: File
- isSubset:
path: spec.template.spec.containers[1]
content:
terminationMessagePath: somePath
terminationMessagePolicy: File
- it: should pass with resources inherited from main container and modified in additional container
documentIndex: *deploymentDoc
set:
resources:
requests:
cpu: 25m
memory: 80Mi
additionalContainers:
some-name:
resources:
inherit: true
limits:
cpu: 1000m
memory: 1Gi
requests:
memory: 120Mi
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 25m
memory: 80Mi
- isSubset:
path: spec.template.spec.containers[1]
content:
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 25m
memory: 120Mi
- it: should pass with resources defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
nvidiaCaps:
- compute
scaleGPU:
gpu.intel.com/i915: "1"
resources:
limits:
cpu: 3000m
memory: 4Gi
requests:
cpu: 20m
memory: 100Mi
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 10m
memory: 50Mi
- isSubset:
path: spec.template.spec.containers[1]
content:
resources:
limits:
cpu: 3000m
memory: 4Gi
gpu.intel.com/i915: "1"
requests:
cpu: 20m
memory: 100Mi
- notContains:
path: spec.template.spec.containers[0].env
content:
name: NVIDIA_DRIVER_CAPABILITIES
value: all
- contains:
path: spec.template.spec.containers[1].env
content:
name: NVIDIA_DRIVER_CAPABILITIES
value: compute
- it: should pass with envFrom defined in additional container
documentIndex: *deploymentDoc
set:
some_name: a_name
some_name2: a_name2
additionalContainers:
some-name:
envFrom:
- configMapRef:
name: "{{ .Values.some_name }}"
- configMapRef:
name: "{{ .Values.some_name2 }}"
asserts:
- isNotSubset:
path: spec.template.spec.containers[0]
content:
envFrom:
- configMapRef:
name: a_name
- configMapRef:
name: a_name2
- isSubset:
path: spec.template.spec.containers[1]
content:
envFrom:
- configMapRef:
name: a_name
- configMapRef:
name: a_name2
- it: should pass with env and envList defined in additional container
documentIndex: *deploymentDoc
set:
some_value: value
some_value2: value2
some_value3: value3
some_value4: value4
additionalContainers:
some-name:
env:
var1: "{{ .Values.some_value }}"
var2: "{{ .Values.some_value2 }}"
envList:
- name: var3
value: "{{ .Values.some_value3 }}"
- name: var4
value: "{{ .Values.some_value4 }}"
asserts:
- isNotSubset:
path: spec.template.spec.containers[0]
content:
env:
- name: var1
value: value
- name: var2
value: value2
- name: var3
value: value3
- name: var4
value: value4
- isSubset:
path: spec.template.spec.containers[1]
content:
env:
- 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: var1
value: value
- name: var2
value: value2
- name: var3
value: value3
- name: var4
value: value4
- it: should pass with changed PUID/UMASK
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
securityContext:
runAsUser: 0
runAsNonRoot: false
security:
UMASK: "003"
PUID: 1000
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
env:
- 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"
- isSubset:
path: spec.template.spec.containers[1]
content:
env:
- name: TZ
value: UTC
- name: UMASK
value: "003"
- name: UMASK_SET
value: "003"
- name: NVIDIA_VISIBLE_DEVICES
value: void
- name: PUID
value: "1000"
- name: USER_ID
value: "1000"
- name: UID
value: "1000"
- name: PGID
value: "568"
- name: GROUP_ID
value: "568"
- name: GID
value: "568"
- name: S6_READ_ONLY_ROOT
value: "1"
- it: should pass with disabled injectFixedEnvs
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
securityContext:
runAsUser: 0
runAsNonRoot: false
injectFixedEnvs: false
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
env:
- 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"
- isNull:
path: spec.template.spec.containers[0].e1v
- it: should fail with lifecycle defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
lifecycle:
postStart:
command:
- /bin/bash
- test1
preStop:
command:
- /bin/bash
- test2
asserts:
- isNull:
path: spec.template.spec.containers[0].lifecycle
- isSubset:
path: spec.template.spec.containers[1]
content:
lifecycle:
postStart:
exec:
command:
- /bin/bash
- test1
preStop:
exec:
command:
- /bin/bash
- test2
- it: should fail with env trying to override fixedEnvs in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
env:
TZ: something
asserts:
- failedTemplate:
errorMessage: Environment Variable (TZ) on container (RELEASE-NAME-common-test-some-name) is set more than once. [to (UTC) on (fixedEnv)] and [to (something) on (env)]
- it: should fail with env trying to override configmap in additional container
documentIndex: *deploymentDoc
set:
configmap:
some-confmap:
enabled: true
parseAsEnv: true
content:
TZ: something
additionalContainers:
some-name:
envFrom:
- configMapRef:
name: '{{ include "ix.v1.common.names.fullname" . }}-some-confmap'
asserts:
- failedTemplate:
errorMessage: Environment Variable (TZ) on container (RELEASE-NAME-common-test-some-name) is set more than once. [to (UTC) on (fixedEnv)] and [to (something) on (configmap-RELEASE-NAME-common-test-some-confmap)]
- it: should fail with env trying to override secret in additional container
documentIndex: *deploymentDoc
set:
secret:
some-secret:
enabled: true
parseAsEnv: true
content:
TZ: something
additionalContainers:
some-name:
envFrom:
- secretRef:
name: '{{ include "ix.v1.common.names.fullname" . }}-some-secret'
asserts:
- failedTemplate:
errorMessage: Environment Variable (TZ) on container (RELEASE-NAME-common-test-some-name) is set more than once. [to (UTC) on (fixedEnv)] and [to (something) on (secret-RELEASE-NAME-common-test-some-secret)]
- it: should pass with securityContext inherited
documentIndex: *deploymentDoc
set:
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
privileged: true
allowPrivilegeEscalation: true
capabilities:
add:
- Something
drop:
- Something_Else
additionalContainers:
some_container:
imageSelector: image
securityContext:
inherit: true
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
privileged: true
allowPrivilegeEscalation: true
capabilities:
add:
- Something
drop:
- Something_Else
- isSubset:
path: spec.template.spec.containers[1]
content:
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- Something
drop:
- Something_Else
privileged: true
readOnlyRootFilesystem: false
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
- it: should pass with securityContext default
documentIndex: *deploymentDoc
set:
additionalContainers:
some_container:
imageSelector: image
securityContext:
inherit: true
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: []
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: true
runAsUser: 568
- isSubset:
path: spec.template.spec.containers[1]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: []
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: true
runAsUser: 568
- it: should pass with securityContext changed
documentIndex: *deploymentDoc
set:
additionalContainers:
some_container:
imageSelector: image
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
privileged: true
allowPrivilegeEscalation: true
capabilities:
add:
- Something
drop:
- Something_Else
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: []
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: true
runAsUser: 568
- isSubset:
path: spec.template.spec.containers[1]
content:
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- Something
drop:
- Something_Else
privileged: true
readOnlyRootFilesystem: false
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
- it: should pass with securityContext with some values changed
documentIndex: *deploymentDoc
set:
additionalContainers:
some_container:
imageSelector: image
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
capabilities:
add:
- Something
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: []
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: true
runAsUser: 568
- isSubset:
path: spec.template.spec.containers[1]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- Something
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
- it: should pass with securityContext with inherit and at least one value changed
documentIndex: *deploymentDoc
set:
securityContext:
privileged: true
allowPrivilegeEscalation: true
capabilities:
drop:
- something_else
additionalContainers:
some_container:
imageSelector: image
securityContext:
inherit: true
runAsNonRoot: false
runAsUser: 0
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
securityContext:
allowPrivilegeEscalation: true
capabilities:
add: []
drop:
- something_else
privileged: true
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: true
runAsUser: 568
- isSubset:
path: spec.template.spec.containers[1]
content:
securityContext:
allowPrivilegeEscalation: true
capabilities:
add: []
drop:
- something_else
privileged: true
readOnlyRootFilesystem: true
runAsGroup: 568
runAsNonRoot: false
runAsUser: 0
- it: should fail with probe type set to auto in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
probes:
liveness:
enabled: true
type: auto
asserts:
- failedTemplate:
errorMessage: <auto> probe type in probe (liveness) in (RELEASE-NAME-common-test-some-name) container, is only supported for the main container and only if there is at least 1 port enabled
- it: should pass with probes defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
probes:
liveness:
enabled: true
type: tcp
port: 3000
readiness:
enabled: true
type: http
port: 3000
path: /
startup:
enabled: true
type: exec
command:
- /bin/bash
- -c
- |
echo "start!"
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
livenessProbe:
httpGet:
path: /
scheme: HTTP
port: 65535
initialDelaySeconds: 10
failureThreshold: 5
timeoutSeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
scheme: HTTP
port: 65535
initialDelaySeconds: 10
failureThreshold: 5
timeoutSeconds: 5
periodSeconds: 10
startupProbe:
httpGet:
path: /
scheme: HTTP
port: 65535
initialDelaySeconds: 10
failureThreshold: 60
timeoutSeconds: 2
periodSeconds: 5
- isSubset:
path: spec.template.spec.containers[1]
content:
livenessProbe:
tcpSocket:
port: 3000
initialDelaySeconds: 10
failureThreshold: 5
timeoutSeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
scheme: HTTP
port: 3000
initialDelaySeconds: 10
failureThreshold: 5
timeoutSeconds: 5
periodSeconds: 10
startupProbe:
exec:
command:
- /bin/bash
- -c
- |
echo "start!"
initialDelaySeconds: 10
failureThreshold: 60
timeoutSeconds: 2
periodSeconds: 5
- it: should fail with invalid protocol in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: 5678
protocol: invalid-proto
name: tcp-port
asserts:
- failedTemplate:
errorMessage: Invalid <protocol> (invalid-proto) in port (tcp-port) in (RELEASE-NAME-common-test-some-name) container. Valid protocols are TCP and UDP.
- it: should fail without name in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: 5678
protocol: TCP
name: ""
asserts:
- failedTemplate:
errorMessage: <name> is required in all <ports> in (RELEASE-NAME-common-test-some-name) container.
- it: should fail without containerPort in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: ""
name: tcp-port
asserts:
- failedTemplate:
errorMessage: <containerPort> is required in port (tcp-port) in (RELEASE-NAME-common-test-some-name) container.
- it: should fail with non-int containerPort in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: not-int
name: tcp-port
asserts:
- failedTemplate:
errorMessage: Invalid <containerPort> (not-int) in port (tcp-port) in (RELEASE-NAME-common-test-some-name) container. Must be an int.
- it: should fail with non-int hostPort in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: 1234
hostPort: not-int
name: tcp-port
asserts:
- failedTemplate:
errorMessage: Invalid <hostPort> (not-int) in port (tcp-port) in (RELEASE-NAME-common-test-some-name) container. Must be an int.
- it: should pass without protocol in ports in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: 5678
name: tcp-port
asserts:
- isSubset:
path: spec.template.spec.containers[1]
content:
ports:
- containerPort: 5678
protocol: TCP
name: tcp-port
- it: should pass with ports defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
ports:
- containerPort: 5678
protocol: TCP
name: tcp-port
- containerPort: 1234
protocol: UDP
name: udp-port
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
ports:
- containerPort: 65535
protocol: TCP
name: main
- isSubset:
path: spec.template.spec.containers[1]
content:
ports:
- containerPort: 5678
protocol: TCP
name: tcp-port
- containerPort: 1234
protocol: UDP
name: udp-port
- it: should fail without trying to mount a non existent volume in volumeMounts defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
volumeMounts:
- name: some-volume
mountPath: /some/path
asserts:
- failedTemplate:
errorMessage: You are trying to mount a volume that does not exist (some-volume). Please define the volume in <persistence>.
- it: should fail without name in volumeMounts defined in additional container
documentIndex: *deploymentDoc
set:
additionalContainers:
some-name:
volumeMounts:
- name:
mountPath: /some/path
readOnly: false
subPath: /some/sub/path
asserts:
- failedTemplate:
errorMessage: <name> is required in volumeMounts in init/install/upgrade/additional containers.
- it: should pass with volumeMounts defined in additional container
documentIndex: *deploymentDoc
set:
persistence:
some-volume:
enabled: true
noMount: true
type: emptyDir
some-other-volume:
enabled: true
noMount: true
type: emptyDir
additionalContainers:
some-name:
volumeMounts:
- name: some-volume
mountPath: /some/path
readOnly: false
subPath: /some/sub/path
- name: some-other-volume
mountPath: /some/other/path
readOnly: false
subPath: /some/other/sub/path
asserts:
- isSubset:
path: spec.template.spec.containers[0]
content:
ports:
- containerPort: 65535
protocol: TCP
name: main
- isSubset:
path: spec.template.spec.containers[1]
content:
volumeMounts:
- name: some-volume
mountPath: /some/path
readOnly: false
subPath: /some/sub/path
- name: some-other-volume
mountPath: /some/other/path
readOnly: false
subPath: /some/other/sub/path

View File

@@ -1,5 +1,6 @@
{{/* The pod definition included in the controller. */}}
{{- define "ix.v1.common.controller.pod" -}}
{{- $root := . }}
serviceAccountName: {{ (include "ix.v1.common.names.serviceAccountName" .) }}
{{- with .Values.schedulerName }}
schedulerName: {{ tpl . $ }}
@@ -51,8 +52,9 @@ imagePullSecrets:
runtimeClassName: {{ . }}
{{- end -}}
{{- with (include "ix.v1.common.controller.mainContainer" . | trim) }}
containers: {{/* TODO: Additional Containers */}}
containers:
{{- . | nindent 2 }}
{{- (include "ix.v1.common.controller.extraContainers" (dict "root" $root "containerList" $root.Values.additionalContainers "type" "addititional") | trim) | nindent 2 }}
{{- end -}}
{{- if or .Values.initContainers .Values.installContainers .Values.upgradeContainers }}
initContainers: