h2oaimichalmarszalek commited on
Commit
466b971
·
1 Parent(s): 2a81d02

add helm tests

Browse files
helm_test_gen.py → tools/helm_test_gen.py RENAMED
File without changes
tools/templates/cm.jinja ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- for workload in get_object_by_kind(document, ('Deployment', 'StatefulSet', 'Job')) %}
3
+ {%- if workload['spec']['template']['spec'].get('volumes') %}
4
+ {%- for volume in workload['spec']['template']['spec']['volumes'] %}
5
+ {%- if volume.get('configMap', {'name': ''}).get('name', '') == name %}
6
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as volume
7
+ documentSelector:
8
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
9
+ value: {{ workload['metadata']['name'] }}
10
+ asserts:
11
+ - contains:
12
+ path: spec.template.spec.volumes
13
+ content:
14
+ name: {{ volume.name }}
15
+ configMap:
16
+ name: {{ name }}
17
+ {%- if 'defaultMode' in volume.configMap %}
18
+ defaultMode: {{ volume.configMap.defaultMode }}
19
+ {% endif %}
20
+ {%- endif %}
21
+ {%- endfor %}
22
+ {%- endif %}
23
+ {%- for container in workload['spec']['template']['spec']['containers'] %}
24
+ {%- set containerIndex = loop.index0 %}
25
+ {%- if container.get('envFrom') %}
26
+ {%- for env in container['envFrom'] %}
27
+ {%- if env.get('configMapRef', {'name': ''}).get('name') == name %}
28
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
29
+ documentSelector:
30
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
31
+ value: {{ workload['metadata']['name'] }}
32
+ asserts:
33
+ - contains:
34
+ path: spec.template.spec.containers[{{ containerIndex }}].envFrom
35
+ content:
36
+ configMapRef:
37
+ name: {{ name }}
38
+ {%- endif %}
39
+ {%- endfor %}
40
+ {%- endif %}
41
+ {%- if container.get('env') %}
42
+ {%- set envs = get_env_by_ref(container, 'configMapKeyRef', name) %}
43
+ {%- if envs %}
44
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
45
+ documentSelector:
46
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
47
+ value: {{ workload['metadata']['name'] }}
48
+ asserts:
49
+ {%- for env in envs %}
50
+ - contains:
51
+ path: spec.template.spec.containers[{{ containerIndex }}].env
52
+ content:
53
+ name: {{ env.name }}
54
+ valueFrom:
55
+ configMapKeyRef:
56
+ name: {{ name }}
57
+ key: {{ env.valueFrom.configMapKeyRef.key }}
58
+ {%- endfor %}
59
+ {%- endif %}
60
+ {%- endif %}
61
+ {%- endfor %}
62
+ {%- for container in workload['spec']['template']['spec']['initContainers'] %}
63
+ {%- set containerIndex = loop.index0 %}
64
+ {%- if container.get('envFrom') %}
65
+ {%- for env in container['envFrom'] %}
66
+ {%- if env.get('configMapRef', {'name': ''}).get('name') == name %}
67
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
68
+ documentSelector:
69
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
70
+ value: {{ workload['metadata']['name'] }}
71
+ asserts:
72
+ - contains:
73
+ path: spec.template.spec.initContainers[{{ containerIndex }}].envFrom
74
+ content:
75
+ configMapRef:
76
+ name: {{ name }}
77
+ {%- endif %}
78
+ {%- endfor %}
79
+ {%- endif %}
80
+ {%- if container.get('env') %}
81
+ {%- set envs = get_env_by_ref(container, 'configMapKeyRef', name) %}
82
+ {%- if envs %}
83
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
84
+ documentSelector:
85
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
86
+ value: {{ workload['metadata']['name'] }}
87
+ asserts:
88
+ {%- for env in envs %}
89
+ - contains:
90
+ path: spec.template.spec.initContainers[{{ containerIndex }}].env
91
+ content:
92
+ name: {{ env.name }}
93
+ valueFrom:
94
+ configMapKeyRef:
95
+ name: {{ name }}
96
+ key: {{ env.valueFrom.configMapKeyRef.key }}
97
+ {%- endfor %}
98
+ {%- endif %}
99
+ {%- endif %}
100
+ {%- endfor %}
101
+ {%- endfor %}
102
+ {#- CronJob #}
103
+ {%- for workload in get_object_by_kind(document, ('CronJob',)) %}
104
+ {%- if workload['spec']['jobTemplate']['spec']['template']['spec'].get('volumes') %}
105
+ {%- for volume in workload['spec']['jobTemplate']['spec']['template']['spec']['volumes'] %}
106
+ {%- if volume.get('configMap', {'name': ''}).get('name', '') == name %}
107
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as volume
108
+ documentSelector:
109
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
110
+ value: {{ workload['metadata']['name'] }}
111
+ asserts:
112
+ - contains:
113
+ path: spec.jobTemplate.spec.template.spec.volumes
114
+ content:
115
+ name: {{ volume.name }}
116
+ configMap:
117
+ name: {{ name }}
118
+ {%- endif %}
119
+ {%- endfor %}
120
+ {%- endif %}
121
+ {%- for container in workload['spec']['jobTemplate']['spec']['template']['spec']['containers'] %}
122
+ {%- set containerIndex = loop.index0 %}
123
+ {%- if container.get('envFrom') %}
124
+ {%- for env in container['envFrom'] %}
125
+ {%- if env.get('configMapRef', {'name': ''}).get('name') == name %}
126
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
127
+ documentSelector:
128
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
129
+ value: {{ workload['metadata']['name'] }}
130
+ asserts:
131
+ - contains:
132
+ path: spec.jobTemplate.spec.template.spec.containers[{{ containerIndex }}].envFrom
133
+ content:
134
+ configMapRef:
135
+ name: {{ name }}
136
+ {%- endif %}
137
+ {%- endfor %}
138
+ {%- endif %}
139
+ {%- if container.get('env') %}
140
+ {%- set envs = get_env_by_ref(container, 'configMapKeyRef', name) %}
141
+ {%- if envs %}
142
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
143
+ documentSelector:
144
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
145
+ value: {{ workload['metadata']['name'] }}
146
+ asserts:
147
+ {%- for env in envs %}
148
+ - contains:
149
+ path: spec.jobTemplate.spec.template.spec.containers[{{ containerIndex }}].env
150
+ content:
151
+ name: {{ env.name }}
152
+ valueFrom:
153
+ configMapKeyRef:
154
+ name: {{ name }}
155
+ key: {{ env.valueFrom.configMapKeyRef.key }}
156
+ {%- endfor %}
157
+ {%- endif %}
158
+ {%- endif %}
159
+ {%- endfor %}
160
+ {%- endfor %}
tools/templates/cronjob.jinja ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ - equal:
3
+ path: spec.schedule
4
+ value: "{{ gyv(item, 'spec.schedule')}}"
5
+ - equal:
6
+ path: spec.concurrencyPolicy
7
+ value: {{ gyv(item, 'spec.concurrencyPolicy')}}
8
+ - equal:
9
+ path: spec.startingDeadlineSeconds
10
+ value: {{ gyv(item, 'spec.startingDeadlineSeconds')}}
11
+ - equal:
12
+ path: spec.failedJobsHistoryLimit
13
+ value: {{ gyv(item, 'spec.failedJobsHistoryLimit')}}
14
+ - equal:
15
+ path: spec.successfulJobsHistoryLimit
16
+ value: {{ gyv(item, 'spec.successfulJobsHistoryLimit')}}
17
+
18
+ - equal:
19
+ path: spec.jobTemplate.spec.backoffLimit
20
+ value: {{ gyv(item, 'spec.jobTemplate.spec.backoffLimit')}}
21
+ - equal:
22
+ path: spec.jobTemplate.spec.completionMode
23
+ value: {{ gyv(item, 'spec.jobTemplate.spec.completionMode')}}
24
+ - equal:
25
+ path: spec.jobTemplate.spec.parallelism
26
+ value: {{ gyv(item, 'spec.jobTemplate.spec.parallelism')}}
27
+ - equal:
28
+ path: spec.jobTemplate.spec.ttlSecondsAfterFinished
29
+ value: {{ gyv(item, 'spec.jobTemplate.spec.ttlSecondsAfterFinished')}}
30
+ - equal:
31
+ path: spec.jobTemplate.spec.template.spec.restartPolicy
32
+ value: {{ gyv(item, 'spec.jobTemplate.spec.template.spec.restartPolicy')}}
33
+ {%- for container in gyv(item, 'spec.jobTemplate.spec.template.spec.containers') %}
34
+ # Container {{loop.index0}}
35
+ {%- set containerIndex = loop.index0 %}
36
+ - equal:
37
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].name
38
+ value: {{container.name}}
39
+ - equal:
40
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].image
41
+ value: {{container.image}}
42
+ - equal:
43
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].imagePullPolicy
44
+ value: {{container.imagePullPolicy}}
45
+ {%- if 'lifecycle' in container %}
46
+ #Lifecycle
47
+ {%- if 'preStop' in container.lifecycle %}
48
+ - isSubset:
49
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.preStop
50
+ content:
51
+ {{ container.lifecycle.preStop }}
52
+ {%- endif %}
53
+ {%- if 'postStart' in container.lifecycle %}
54
+ - isSubset:
55
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.postStart
56
+ content:
57
+ {{ container.lifecycle.postStart }}
58
+ {%- endif %}
59
+ {%- endif %}
60
+ {%- if 'resources' in container %}
61
+ # Resources
62
+ - equal:
63
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].resources.requests.cpu
64
+ value: {{container.resources.requests.cpu}}
65
+ - equal:
66
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].resources.requests.memory
67
+ value: {{container.resources.requests.memory}}
68
+ - equal:
69
+ path: spec.jobTemplate.spec.template.spec.containers[{{loop.index0}}].resources.limits.memory
70
+ value: {{container.resources.limits.memory}}
71
+ {%- endif%}
72
+
73
+ {%- if 'env' in container %}
74
+ # Env
75
+ {%- for env in container.env%}
76
+ - equal:
77
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].env[{{loop.index0}}].name
78
+ value: {{ env.name }}
79
+ {%- endfor %}
80
+ {%- endif %}
81
+ {%- if 'command' in container %}
82
+ # Command
83
+ {%- for cmd in container.command %}
84
+ - equal:
85
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].command[{{loop.index0}}]
86
+ value: "{{ cmd }}"
87
+ {%- endfor %}
88
+ {%- endif %}
89
+ {%- if 'args' in container %}
90
+ # Args
91
+ {%- for arg in container.args %}
92
+ - equal:
93
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].args[{{loop.index0}}]
94
+ value: "{{ arg }}"
95
+ {%- endfor %}
96
+ {%- endif %}
97
+ {%- if 'volumeMounts' in container %}
98
+ # volumeMounts
99
+ {%- for volumeMounts in container.volumeMounts %}
100
+ - equal:
101
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].name
102
+ value: {{ volumeMounts.name }}
103
+ - equal:
104
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].mountPath
105
+ value: {{ volumeMounts.mountPath }}
106
+ - equal:
107
+ path: spec.jobTemplate.spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].readOnly
108
+ value: {{ bool_to_str(volumeMounts.readOnly) }}
109
+ {%- endfor%}
110
+ {%- endif%}
111
+ {%- endfor %}
tools/templates/deployment.jinja ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- if 'replicas' in item['spec'] %}
3
+ - equal:
4
+ path: spec.replicas
5
+ value: {{ gyv(item, 'spec.replicas')}}
6
+ {%- endif %}
7
+ {%- if 'strategy' in item.spec %}
8
+ - equal:
9
+ path: spec.strategy.type
10
+ value: {{ gyv(item, 'spec.strategy.type')}}
11
+ {%- endif %}
12
+ {%- for container in gyv(item, 'spec.template.spec.containers') %}
13
+ # Container {{loop.index0}}
14
+ {%- set containerIndex = loop.index0 %}
15
+ - equal:
16
+ path: spec.template.spec.containers[{{loop.index0}}].name
17
+ value: {{container.name}}
18
+ - equal:
19
+ path: spec.template.spec.containers[{{loop.index0}}].image
20
+ value: {{container.image}}
21
+ - equal:
22
+ path: spec.template.spec.containers[{{loop.index0}}].imagePullPolicy
23
+ value: {{container.imagePullPolicy}}
24
+
25
+ {%- if 'lifecycle' in container %}
26
+ #Lifecycle
27
+ {%- if 'preStop' in container.lifecycle %}
28
+ - isSubset:
29
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.preStop
30
+ content:
31
+ {{ container.lifecycle.preStop }}
32
+ {%- endif %}
33
+ {%- if 'postStart' in container.lifecycle %}
34
+ - isSubset:
35
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.postStart
36
+ content:
37
+ {{ container.lifecycle.postStart }}
38
+ {%- endif %}
39
+ {%- endif %}
40
+
41
+ {%- if 'livenessProbe' in container %}
42
+ # LivenessProbe
43
+ {%- if 'httpGet' in container.livenessProbe %}
44
+ - equal:
45
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.port
46
+ value: {{container.livenessProbe.httpGet.port}}
47
+ - equal:
48
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.path
49
+ value: {{container.livenessProbe.httpGet.path}}
50
+ - equal:
51
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.scheme
52
+ value: {{container.livenessProbe.httpGet.scheme}}
53
+ {%- elif 'tcpSocket' in container.livenessProbe %}
54
+ - equal:
55
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.tcpSocket.port
56
+ value: {{container.livenessProbe.tcpSocket.port}}
57
+ {%- endif %}
58
+ - equal:
59
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.initialDelaySeconds
60
+ value: {{container.livenessProbe.initialDelaySeconds}}
61
+ - equal:
62
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.failureThreshold
63
+ value: {{container.livenessProbe.failureThreshold}}
64
+ - equal:
65
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.successThreshold
66
+ value: {{container.livenessProbe.successThreshold}}
67
+ - equal:
68
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.timeoutSeconds
69
+ value: {{container.livenessProbe.timeoutSeconds}}
70
+ - equal:
71
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.periodSeconds
72
+ value: {{container.livenessProbe.periodSeconds}}
73
+ {%- endif %}
74
+ {%- if 'readinessProbe' in container %}
75
+ # ReadinessProbe
76
+ {%- if 'httpGet' in container.readinessProbe %}
77
+ - equal:
78
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.port
79
+ value: {{container.readinessProbe.httpGet.port}}
80
+ - equal:
81
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.path
82
+ value: {{container.readinessProbe.httpGet.path}}
83
+ - equal:
84
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.scheme
85
+ value: {{container.readinessProbe.httpGet.scheme}}
86
+ {%- elif 'tcpSocket' in container.readinessProbe %}
87
+ - equal:
88
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.tcpSocket.port
89
+ value: {{container.readinessProbe.tcpSocket.port}}
90
+ {%- endif %}
91
+ - equal:
92
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.initialDelaySeconds
93
+ value: {{container.readinessProbe.initialDelaySeconds}}
94
+ - equal:
95
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.failureThreshold
96
+ value: {{container.readinessProbe.failureThreshold}}
97
+ - equal:
98
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.successThreshold
99
+ value: {{container.readinessProbe.successThreshold}}
100
+ - equal:
101
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.timeoutSeconds
102
+ value: {{container.readinessProbe.timeoutSeconds}}
103
+ - equal:
104
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.periodSeconds
105
+ value: {{container.readinessProbe.periodSeconds}}
106
+ {%- endif %}
107
+ {%- if 'resources' in container %}
108
+ # Resources
109
+ - equal:
110
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.cpu
111
+ value: {{container.resources.requests.cpu}}
112
+ - equal:
113
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.memory
114
+ value: {{container.resources.requests.memory}}
115
+ {%- if 'limits' in container.resources %}
116
+ - equal:
117
+ path: spec.template.spec.containers[{{loop.index0}}].resources.limits.memory
118
+ value: {{container.resources.limits.memory}}
119
+ {%- endif%}
120
+ {%- endif%}
121
+
122
+ {%- if 'env' in container %}
123
+ # Env
124
+ {%- for env in container.env%}
125
+ - equal:
126
+ path: spec.template.spec.containers[{{containerIndex}}].env[{{loop.index0}}].name
127
+ value: {{ env.name }}
128
+ {%- endfor %}
129
+ {%- endif %}
130
+
131
+ {%- if 'ports' in container %}
132
+ # Ports
133
+ {%- for port in container.ports %}
134
+ - equal:
135
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].name
136
+ value: {{ port.name }}
137
+ - equal:
138
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].containerPort
139
+ value: {{ port.containerPort }}
140
+ - equal:
141
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].protocol
142
+ value: {{ port.protocol }}
143
+ {%- endfor%}
144
+ {%- endif %}
145
+
146
+ {%- if 'command' in container %}
147
+ # Command
148
+ {%- for cmd in container.command %}
149
+ - equal:
150
+ path: spec.template.spec.containers[{{containerIndex}}].command[{{loop.index0}}]
151
+ value: "{{ cmd }}"
152
+ {%- endfor %}
153
+ {%- endif %}
154
+
155
+ {%- if 'args' in container %}
156
+ # Args
157
+ {%- for arg in container.args %}
158
+ - equal:
159
+ path: spec.template.spec.containers[{{containerIndex}}].args[{{loop.index0}}]
160
+ value: "{{ arg }}"
161
+ {%- endfor %}
162
+ {%- endif %}
163
+
164
+ {%- if 'volumeMounts' in container %}
165
+ # volumeMounts
166
+ {%- for volumeMounts in container.volumeMounts %}
167
+ - equal:
168
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].name
169
+ value: {{ volumeMounts.name }}
170
+ - equal:
171
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].mountPath
172
+ value: {{ volumeMounts.mountPath }}
173
+ - equal:
174
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].readOnly
175
+ value: {{ bool_to_str(volumeMounts.readOnly) }}
176
+ {%- endfor%}
177
+ {%- endif%}
178
+ {%- endfor %}
179
+
180
+ {#- initContainers #}
181
+ {%- for container in gyv(item, 'spec.template.spec').get('initContainers', []) %}
182
+ # initContainer {{loop.index0}}
183
+ {%- set containerIndex = loop.index0 %}
184
+ - equal:
185
+ path: spec.template.spec.initContainers[{{loop.index0}}].name
186
+ value: {{container.name}}
187
+ - equal:
188
+ path: spec.template.spec.initContainers[{{loop.index0}}].image
189
+ value: {{container.image}}
190
+ - equal:
191
+ path: spec.template.spec.initContainers[{{loop.index0}}].imagePullPolicy
192
+ value: {{container.imagePullPolicy}}
193
+ {%- if 'resources' in container %}
194
+ # Resources
195
+ - equal:
196
+ path: spec.template.spec.initContainers[{{loop.index0}}].resources.requests.cpu
197
+ value: {{container.resources.requests.cpu}}
198
+ - equal:
199
+ path: spec.template.spec.initContainers[{{loop.index0}}].resources.requests.memory
200
+ value: {{container.resources.requests.memory}}
201
+ - equal:
202
+ path: spec.template.spec.initContainers[{{loop.index0}}].resources.limits.memory
203
+ value: {{container.resources.limits.memory}}
204
+ {%- endif%}
205
+
206
+ {%- if 'env' in container %}
207
+ # Env
208
+ {%- for env in container.env%}
209
+ - equal:
210
+ path: spec.template.spec.initContainers[{{containerIndex}}].env[{{loop.index0}}].name
211
+ value: {{ env.name }}
212
+ {%- endfor %}
213
+ {%- endif %}
214
+ {%- if 'command' in container %}
215
+ # Command
216
+ {%- for cmd in container.command %}
217
+ - equal:
218
+ path: spec.template.spec.initContainers[{{containerIndex}}].command[{{loop.index0}}]
219
+ value: "{{ cmd }}"
220
+ {%- endfor %}
221
+ {%- endif %}
222
+ {%- if 'args' in container %}
223
+ # Args
224
+ {%- for arg in container.args %}
225
+ - equal:
226
+ path: spec.template.spec.initContainers[{{containerIndex}}].args[{{loop.index0}}]
227
+ value: "{{ arg }}"
228
+ {%- endfor %}
229
+ {%- endif %}
230
+ {%- if 'volumeMounts' in container %}
231
+ # volumeMounts
232
+ {%- for volumeMounts in container.volumeMounts %}
233
+ - equal:
234
+ path: spec.template.spec.initContainers[{{containerIndex}}].volumeMounts[{{loop.index0}}].name
235
+ value: {{ volumeMounts.name }}
236
+ - equal:
237
+ path: spec.template.spec.initContainers[{{containerIndex}}].volumeMounts[{{loop.index0}}].mountPath
238
+ value: {{ volumeMounts.mountPath }}
239
+ - equal:
240
+ path: spec.template.spec.initContainers[{{containerIndex}}].volumeMounts[{{loop.index0}}].readOnly
241
+ value: {{ bool_to_str(volumeMounts.readOnly) }}
242
+ {%- endfor%}
243
+ {%- endif%}
244
+ {%- endfor %}
tools/templates/hpa.jinja ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ - equal:
3
+ path: spec.maxReplicas
4
+ value: {{ gyv(item, 'spec.maxReplicas') }}
5
+ - equal:
6
+ path: spec.minReplicas
7
+ value: {{ gyv(item, 'spec.minReplicas') }}
8
+ - equal:
9
+ path: spec.scaleTargetRef.apiVersion
10
+ value: {{ gyv(item, 'spec.scaleTargetRef.apiVersion') }}
11
+ - equal:
12
+ path: spec.scaleTargetRef.kind
13
+ value: {{ gyv(item, 'spec.scaleTargetRef.kind') }}
14
+ - equal:
15
+ path: spec.scaleTargetRef.name
16
+ value: {{ gyv(item, 'spec.scaleTargetRef.name') }}
17
+ {%- for metric in item['spec']['metrics'] %}
18
+ - equal:
19
+ path: spec.metrics[{{loop.index0}}].type
20
+ value: {{ metric.type }}
21
+ - equal:
22
+ path: spec.metrics[{{loop.index0}}].resource.name
23
+ value: {{ metric.resource.name }}
24
+ - equal:
25
+ path: spec.metrics[{{loop.index0}}].resource.target.type
26
+ value: {{ metric.resource.target.type }}
27
+ - equal:
28
+ path: spec.metrics[{{loop.index0}}].resource.target.averageUtilization
29
+ value: {{ metric.resource.target.averageUtilization }}
30
+ {%- endfor %}
tools/templates/ingress.jinja ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- for rule in item['spec']['rules'] %}
3
+ {%- set ruleIndex = loop.index0 %}
4
+ {%- for k,v in rule.items() %}
5
+ {%- for path in rule[k].paths %}
6
+ - equal:
7
+ path: spec.rules[{{ruleIndex}}].{{k}}.paths[{{loop.index0}}].path
8
+ value: {{ path.path }}
9
+ - equal:
10
+ path: spec.rules[{{ruleIndex}}].{{k}}.paths[{{loop.index0}}].pathType
11
+ value: {{ path.pathType }}
12
+ - equal:
13
+ path: spec.rules[{{ruleIndex}}].{{k}}.paths[{{loop.index0}}].backend.service.name
14
+ value: {{ path.backend.service.name }}
15
+ - equal:
16
+ path: spec.rules[{{ruleIndex}}].{{k}}.paths[{{loop.index0}}].backend.service.port.number
17
+ value: {{ path.backend.service.port.number }}
18
+ {%- endfor %}
19
+ {%- endfor %}
20
+ {%- endfor %}
tools/templates/job.jinja ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%-if 'backoffLimit' in spec %}
3
+ - equal:
4
+ path: spec.backoffLimit
5
+ value: {{ gyv(item, 'spec.backoffLimit')}}
6
+ {%- endif%}
7
+ {%-if 'completionMode' in spec %}
8
+ - equal:
9
+ path: spec.completionMode
10
+ value: {{ gyv(item, 'spec.completionMode')}}
11
+ {%- endif%}
12
+ {%-if 'parallelism' in spec %}
13
+ - equal:
14
+ path: spec.parallelism
15
+ value: {{ gyv(item, 'spec.parallelism')}}
16
+ {%- endif%}
17
+ {%-if 'ttlSecondsAfterFinished' in spec %}
18
+ - equal:
19
+ path: spec.ttlSecondsAfterFinished
20
+ value: {{ gyv(item, 'spec.ttlSecondsAfterFinished')}}
21
+ {%- endif%}
22
+ - equal:
23
+ path: spec.template.spec.restartPolicy
24
+ value: {{ gyv(item, 'spec.template.spec.restartPolicy')}}
25
+ {%- for container in gyv(item, 'spec.template.spec.containers') %}
26
+ # Container {{loop.index0}}
27
+ {%- set containerIndex = loop.index0 %}
28
+ - equal:
29
+ path: spec.template.spec.containers[{{loop.index0}}].name
30
+ value: {{container.name}}
31
+ - equal:
32
+ path: spec.template.spec.containers[{{loop.index0}}].image
33
+ value: {{container.image}}
34
+ - equal:
35
+ path: spec.template.spec.containers[{{loop.index0}}].imagePullPolicy
36
+ value: {{container.imagePullPolicy}}
37
+ {%- if 'lifecycle' in container %}
38
+ #Lifecycle
39
+ {%- if 'preStop' in container.lifecycle %}
40
+ - isSubset:
41
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.preStop
42
+ content:
43
+ {{ container.lifecycle.preStop }}
44
+ {%- endif %}
45
+ {%- if 'postStart' in container.lifecycle %}
46
+ - isSubset:
47
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.postStart
48
+ content:
49
+ {{ container.lifecycle.postStart }}
50
+ {%- endif %}
51
+ {%- endif %}
52
+ {%- if 'resources' in container %}
53
+ # Resources
54
+ - equal:
55
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.cpu
56
+ value: {{container.resources.requests.cpu}}
57
+ - equal:
58
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.memory
59
+ value: {{container.resources.requests.memory}}
60
+ - equal:
61
+ path: spec.template.spec.containers[{{loop.index0}}].resources.limits.memory
62
+ value: {{container.resources.limits.memory}}
63
+ {%- endif%}
64
+
65
+ {%- if 'env' in container %}
66
+ # Env
67
+ {%- for env in container.env%}
68
+ - equal:
69
+ path: spec.template.spec.containers[{{containerIndex}}].env[{{loop.index0}}].name
70
+ value: {{ env.name }}
71
+ {%- endfor %}
72
+ {%- endif %}
73
+ {%- if 'command' in container %}
74
+ # Command
75
+ {%- for cmd in container.command %}
76
+ - equal:
77
+ path: spec.template.spec.containers[{{containerIndex}}].command[{{loop.index0}}]
78
+ value: {{ cmd }}
79
+ {%- endfor %}
80
+ {%- endif %}
81
+ {%- if 'args' in container %}
82
+ # Args
83
+ {%- for arg in container.args %}
84
+ - equal:
85
+ path: spec.template.spec.containers[{{containerIndex}}].args[{{loop.index0}}]
86
+ value: {{ arg }}
87
+ {%- endfor %}
88
+ {%- endif %}
89
+ {%- if 'volumeMounts' in container %}
90
+ # volumeMounts
91
+ {%- for volumeMounts in container.volumeMounts %}
92
+ - equal:
93
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].name
94
+ value: {{ volumeMounts.name }}
95
+ - equal:
96
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].mountPath
97
+ value: {{ volumeMounts.mountPath }}
98
+ - equal:
99
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].readOnly
100
+ value: {{ bool_to_str(volumeMounts.readOnly) }}
101
+ {%- endfor%}
102
+ {%- endif%}
103
+ {%- endfor %}
tools/templates/np.jinja ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+
2
+ {%- for policyType in item['spec']['policyTypes'] %}
3
+ - equal:
4
+ path: spec.policyTypes[{{loop.index0}}]
5
+ value: {{ policyType }}
6
+ {%- endfor %}
tools/templates/pdb.jinja ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+
2
+ {%- if 'minAvailable' in item.sepec %}
3
+ - equal:
4
+ path: spec.minAvailable
5
+ value: {{ gyv(item, 'spec.minAvailable')}}
6
+ {%- endif %}
tools/templates/pvc.jinja ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- for access in item['spec']['accessModes'] %}
3
+ - equal:
4
+ path: spec.accessModes[{{loop.index0}}]
5
+ value: {{ access }}
6
+ {%- endfor %}
7
+ {% if 'volumeMode' in item.spec %}
8
+ - equal:
9
+ path: spec.volumeMode
10
+ value: {{ gyv(item, 'spec.volumeMode')}}
11
+ {%- endif %}
12
+ - equal:
13
+ path: spec.resources.requests.storage
14
+ value: {{ gyv(item, 'spec.resources.requests.storage') }}
15
+
16
+ {%- for workload in get_object_by_kind(document, ('Deployment', 'StatefulSet')) %}
17
+ {%- if workload['spec']['template']['spec'].get('volumes') %}
18
+ {%- for volume in workload['spec']['template']['spec']['volumes'] %}
19
+ {%- if volume.get('persistentVolumeClaim', {'claimName': ''}).get('claimName') == name %}
20
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }}
21
+ documentSelector:
22
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
23
+ value: {{ workload['metadata']['name'] }}
24
+ asserts:
25
+ - contains:
26
+ path: spec.template.spec.volumes
27
+ content:
28
+ name: {{ volume['name'] }}
29
+ persistentVolumeClaim:
30
+ claimName: {{ name }}
31
+ {%- endif %}
32
+ {%- endfor %}
33
+ {%- endif %}
34
+ {%- endfor %}
tools/templates/sa.jinja ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- for workload in get_object_by_kind(document, ('Deployment', 'StatefulSet')) %}
3
+ {%- if gyv(workload, 'spec.template.spec.serviceAccountName') == name %}
4
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }}
5
+ documentSelector:
6
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
7
+ value: {{ workload['metadata']['name'] }}
8
+ asserts:
9
+ - equal:
10
+ path: spec.template.spec.serviceAccountName
11
+ value: {{ name }}
12
+ {%- endif %}
13
+ {%- endfor %}
14
+
15
+ {%- for workload in get_object_by_kind(document, ('RoleBinding', 'ClusterRoleBinding')) %}
16
+ {%- set subjects = get_binding_subjects(workload.subjects, name) %}
17
+ {%- if subjects %}
18
+ - it: should bind {{ name }} {{ kindDesc }} into {{ workload.metadata.name }} {{ workload['kind'].lower() }}
19
+ documentSelector:
20
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
21
+ value: {{ workload['metadata']['name'] }}
22
+ asserts:
23
+ {%- for subject in subjects %}
24
+ - equal:
25
+ path: subjects[{{ loop.index0 }}].name
26
+ value: {{ name }}
27
+ - equal:
28
+ path: subjects[{{ loop.index0 }}].kind
29
+ value: ServiceAccount
30
+ - equal:
31
+ path: roleRef.kind
32
+ value: {{ "Role" if workload.kind == 'RoleBinding' else 'ClusterRole' }}
33
+ - equal:
34
+ path: roleRef.name
35
+ value: {{ workload.roleRef.name }}
36
+ {%- endfor %}
37
+ {%- endif %}
38
+ {%- endfor %}
tools/templates/scenario.jinja ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ suite: {{ app }} {{ kindDesc }} tests
2
+ release:
3
+ name: test-name
4
+ namespace: test-namespace
5
+ tests:
6
+ - it: should render {{ name }} {{ kindDesc }} object
7
+ documentSelector:
8
+ path: $[?(@.kind == "{{ kind }}")].metadata.name
9
+ value: {{ name }}
10
+ asserts:
11
+ - isKind:
12
+ of: {{ kind }}
13
+ {%- if kind == "PersistentVolumeClaim" %}
14
+ {%- include 'pvc.jinja' %}
15
+ {%- elif kind == "ServiceAccount"%}
16
+ {%- include 'sa.jinja' %}
17
+ {%- elif kind == "Service" %}
18
+ {%- include 'service.jinja' %}
19
+ {%- elif kind == "Deployment" %}
20
+ {%- include 'deployment.jinja' %}
21
+ {%- elif kind == "NetworkPolicy" %}
22
+ {%- include 'np.jinja' %}
23
+ {%- elif kind == "Ingress" %}
24
+ {%- include 'ingress.jinja' %}
25
+ {%- elif kind == "HorizontalPodAutoscaler" %}
26
+ {%- include 'hpa.jinja' %}
27
+ {%- elif kind == "Job" %}
28
+ {%- include 'job.jinja' %}
29
+ {%- elif kind == "PodDisruptionBudget" %}
30
+ {%- include 'pdb.jinja' %}
31
+ {%- elif kind == "StatefulSet" %}
32
+ {%- include 'statefulset.jinja' %}
33
+ {%- elif kind == "ConfigMap" %}
34
+ {%- include 'cm.jinja' %}
35
+ {%- elif kind == "Secret" %}
36
+ {%- include 'secret.jinja' %}
37
+ {%- elif kind == "CronJob" %}
38
+ {%- include 'cronjob.jinja' %}
39
+ {% endif %}
tools/templates/secret.jinja ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%- for workload in get_object_by_kind(document, ('Deployment', 'StatefulSet', 'Job')) %}
3
+ {%- if workload['spec']['template']['spec'].get('volumes') %}
4
+ {%- for volume in workload['spec']['template']['spec']['volumes'] %}
5
+ {%- if volume.get('secret', {'secretName': ''}).get('secretName') == name %}
6
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as volume
7
+ documentSelector:
8
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
9
+ value: {{ workload['metadata']['name'] }}
10
+ asserts:
11
+ - contains:
12
+ path: spec.template.spec.volumes
13
+ content:
14
+ name: {{ volume.name }}
15
+ secret:
16
+ secretName: {{ name }}
17
+ {%- endif %}
18
+ {%- endfor %}
19
+ {%- endif %}
20
+ {%- for container in workload['spec']['template']['spec']['containers'] %}
21
+ {%- set containerIndex = loop.index0 %}
22
+ {%- if container.get('envFrom') %}
23
+ {%- for env in container['envFrom'] %}
24
+ {%- if env.get('secretRef', {'name': ''}).get('name') == name %}
25
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
26
+ documentSelector:
27
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
28
+ value: {{ workload['metadata']['name'] }}
29
+ asserts:
30
+ - contains:
31
+ path: spec.template.spec.containers[{{ containerIndex }}].envFrom
32
+ content:
33
+ secretRef:
34
+ name: {{ name }}
35
+ {%- endif %}
36
+ {%- endfor %}
37
+ {%- endif %}
38
+ {%- if container.get('env') %}
39
+ {%- set envs = get_env_by_ref(container, 'secretKeyRef', name) %}
40
+ {%- if envs %}
41
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
42
+ documentSelector:
43
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
44
+ value: {{ workload['metadata']['name'] }}
45
+ asserts:
46
+ {%- for env in envs %}
47
+ - contains:
48
+ path: spec.template.spec.containers[{{ containerIndex }}].env
49
+ content:
50
+ name: {{ env.name }}
51
+ valueFrom:
52
+ secretKeyRef:
53
+ name: {{ name }}
54
+ key: {{ env.valueFrom.secretKeyRef.key }}
55
+ optional: {{ env.valueFrom.secretKeyRef.optional }}
56
+ {%- endfor %}
57
+ {%- endif %}
58
+ {%- endif %}
59
+ {%- endfor %}
60
+ {%- for container in workload['spec']['template']['spec']['initContainers'] %}
61
+ {%- set containerIndex = loop.index0 %}
62
+ {%- if container.get('envFrom') %}
63
+ {%- for env in container['envFrom'] %}
64
+ {%- if env.get('secretRef', {'name': ''}).get('name') == name %}
65
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
66
+ documentSelector:
67
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
68
+ value: {{ workload['metadata']['name'] }}
69
+ asserts:
70
+ - contains:
71
+ path: spec.template.spec.initContainers[{{ containerIndex }}].envFrom
72
+ content:
73
+ secretRef:
74
+ name: {{ name }}
75
+ {%- endif %}
76
+ {%- endfor %}
77
+ {%- endif %}
78
+ {%- if container.get('env') %}
79
+ {%- set envs = get_env_by_ref(container, 'secretKeyRef', name) %}
80
+ {%- if envs %}
81
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
82
+ documentSelector:
83
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
84
+ value: {{ workload['metadata']['name'] }}
85
+ asserts:
86
+ {%- for env in envs %}
87
+ - contains:
88
+ path: spec.template.spec.initContainers[{{ containerIndex }}].env
89
+ content:
90
+ name: {{ env.name }}
91
+ valueFrom:
92
+ secretKeyRef:
93
+ name: {{ name }}
94
+ key: {{ env.valueFrom.secretKeyRef.key }}
95
+ optional: {{ env.valueFrom.secretKeyRef.optional }}
96
+ {%- endfor %}
97
+ {%- endif %}
98
+ {%- endif %}
99
+ {%- endfor %}
100
+ {%- endfor %}
101
+ {#- CronJob #}
102
+ {%- for workload in get_object_by_kind(document, ('CronJob',)) %}
103
+ {%- if workload['spec']['jobTemplate']['spec']['template']['spec'].get('volumes') %}
104
+ {%- for volume in workload['spec']['jobTemplate']['spec']['template']['spec']['volumes'] %}
105
+ {%- if volume.get('secret', {'secretName': ''}).get('secretName') == name %}
106
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as volume
107
+ documentSelector:
108
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
109
+ value: {{ workload['metadata']['name'] }}
110
+ asserts:
111
+ - contains:
112
+ path: spec.jobTemplate.spec.template.spec.volumes
113
+ content:
114
+ name: {{ volume.name }}
115
+ secret:
116
+ secretName: {{ name }}
117
+ {%- endif %}
118
+ {%- endfor %}
119
+ {%- endif %}
120
+ {%- for container in workload['spec']['jobTemplate']['spec']['template']['spec']['containers'] %}
121
+ {%- set containerIndex = loop.index0 %}
122
+ {%- if container.get('envFrom') %}
123
+ {%- for env in container['envFrom'] %}
124
+ {%- if env.get('secretRef', {'name': ''}).get('name') == name %}
125
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as envFrom
126
+ documentSelector:
127
+ path: $[?(@.kind == "{{ workload['kind']}}" )].metadata.name
128
+ value: {{ workload['metadata']['name'] }}
129
+ asserts:
130
+ - contains:
131
+ path: spec.jobTemplate.spec.template.spec.containers[{{ containerIndex }}].envFrom
132
+ content:
133
+ secretRef:
134
+ name: {{ name }}
135
+ {%- endif %}
136
+ {%- endfor %}
137
+ {%- endif %}
138
+ {%- if container.get('env') %}
139
+ {%- set envs = get_env_by_ref(container, 'secretKeyRef', name) %}
140
+ {%- if envs %}
141
+ - it: should use {{ name }} {{ kindDesc }} into {{ workload['kind'].lower() }} as env
142
+ documentSelector:
143
+ path: $[?(@.kind == "{{ workload['kind'] }}" )].metadata.name
144
+ value: {{ workload['metadata']['name'] }}
145
+ asserts:
146
+ {%- for env in envs %}
147
+ - contains:
148
+ path: spec.jobTemplate.spec.template.spec.containers[{{ containerIndex }}].env
149
+ content:
150
+ name: {{ env.name }}
151
+ valueFrom:
152
+ secretKeyRef:
153
+ name: {{ name }}
154
+ key: {{ env.valueFrom.secretKeyRef.key }}
155
+ optional: {{ env.valueFrom.secretKeyRef.optional }}
156
+ {%- endfor %}
157
+ {%- endif %}
158
+ {%- endif %}
159
+ {%- endfor %}
160
+ {%- endfor %}
tools/templates/service.jinja ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ - equal:
3
+ path: spec.type
4
+ value: {{ gyv(item, 'spec.type') }}
5
+ - exists:
6
+ path: spec.ports
7
+ {%- for port in item['spec']['ports'] %}
8
+ - equal:
9
+ path: spec.ports[{{loop.index0}}].name
10
+ value: {{ port.name }}
11
+ - equal:
12
+ path: spec.ports[{{loop.index0}}].port
13
+ value: {{ port.port }}
14
+ - equal:
15
+ path: spec.ports[{{loop.index0}}].protocol
16
+ value: {{ port.protocol }}
17
+ - equal:
18
+ path: spec.ports[{{loop.index0}}].targetPort
19
+ value: {{ port.targetPort }}
20
+ {%- endfor %}
tools/templates/statefulset.jinja ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {%-if 'minReadySeconds' in spec %}
3
+ - equal:
4
+ path: spec.minReadySeconds
5
+ value: {{ gyv(item, 'spec.minReadySeconds')}}
6
+ {%- endif %}
7
+ {%-if 'podManagementPolicy' in spec %}
8
+ - equal:
9
+ path: spec.podManagementPolicy
10
+ value: {{ gyv(item, 'spec.podManagementPolicy')}}
11
+ {%- endif%}
12
+ {%- if 'serviceName' in item['spec'] %}
13
+ - equal:
14
+ path: spec.serviceName
15
+ value: {{ gyv(item, 'spec.serviceName')}}
16
+ {%- endif %}
17
+ {%- if 'persistentVolumeClaimRetentionPolicy' in item['spec'] %}
18
+ - equal:
19
+ path: spec.persistentVolumeClaimRetentionPolicy.whenDeleted
20
+ value: {{ gyv(item, 'spec.persistentVolumeClaimRetentionPolicy.whenDeleted')}}
21
+ - equal:
22
+ path: spec.persistentVolumeClaimRetentionPolicy.whenScaled
23
+ value: {{ gyv(item, 'spec.persistentVolumeClaimRetentionPolicy.whenScaled')}}
24
+ {%- endif %}
25
+ {%- if 'ordinals' in item['spec'] %}
26
+ - equal:
27
+ path: spec.ordinals.start
28
+ value: {{ gyv(item, 'spec.ordinals.start')}}
29
+ {%- endif %}
30
+ {%- if 'replicas' in item['spec'] %}
31
+ - equal:
32
+ path: spec.replicas
33
+ value: {{ gyv(item, 'spec.replicas')}}
34
+ {%- endif %}
35
+ {%-if 'updateStrategy' in spec %}
36
+ - equal:
37
+ path: spec.updateStrategy.type
38
+ value: {{ gyv(item, 'spec.updateStrategy.type')}}
39
+ {%- endif%}
40
+ {%- if 'securityContext' in gyv(item, 'spec.template.spec') %}
41
+ {%- if 'fsGroup' in gyv(item, 'spec.template.spec.securityContext') %}
42
+ - equal:
43
+ path: spec.template.spec.securityContext.fsGroup
44
+ value: {{ gyv(item, 'spec.template.spec.securityContext.fsGroup')}}
45
+ {%- endif %}
46
+ {%- if 'runAsGroup' in gyv(item, 'spec.template.spec.securityContext') %}
47
+ - equal:
48
+ path: spec.template.spec.securityContext.runAsGroup
49
+ value: {{ gyv(item, 'spec.template.spec.securityContext.runAsGroup')}}
50
+ {%- endif %}
51
+ {%- if 'runAsUser' in gyv(item, 'spec.template.spec.securityContext') %}
52
+ - equal:
53
+ path: spec.template.spec.securityContext.runAsUser
54
+ value: {{ gyv(item, 'spec.template.spec.securityContext.runAsUser')}}
55
+ {%- endif %}
56
+ {%- endif %}
57
+ {%- for container in gyv(item, 'spec.template.spec.containers') %}
58
+ # Container {{loop.index0}}
59
+ {%- set containerIndex = loop.index0 %}
60
+ - equal:
61
+ path: spec.template.spec.containers[{{loop.index0}}].name
62
+ value: {{container.name}}
63
+ - equal:
64
+ path: spec.template.spec.containers[{{loop.index0}}].image
65
+ value: {{container.image}}
66
+ - equal:
67
+ path: spec.template.spec.containers[{{loop.index0}}].imagePullPolicy
68
+ value: {{container.imagePullPolicy}}
69
+ {%- if 'lifecycle' in container %}
70
+ #Lifecycle
71
+ {%- if 'preStop' in container.lifecycle %}
72
+ - isSubset:
73
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.preStop
74
+ content:
75
+ {{ container.lifecycle.preStop }}
76
+ {%- endif %}
77
+ {%- if 'postStart' in container.lifecycle %}
78
+ - isSubset:
79
+ path: spec.template.spec.containers[{{loop.index0}}].lifecycle.postStart
80
+ content:
81
+ {{ container.lifecycle.postStart }}
82
+ {%- endif %}
83
+ {%- endif %}
84
+ {%- if 'livenessProbe' in container %}
85
+ # LivenessProbe
86
+ {%- if 'httpGet' in container.livenessProbe %}
87
+ - equal:
88
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.port
89
+ value: {{container.livenessProbe.httpGet.port}}
90
+ - equal:
91
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.path
92
+ value: {{container.livenessProbe.httpGet.path}}
93
+ - equal:
94
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.httpGet.scheme
95
+ value: {{container.livenessProbe.httpGet.scheme}}
96
+ {%- elif 'tcpSocket' in container.livenessProbe %}
97
+ - equal:
98
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.tcpSocket.port
99
+ value: {{container.livenessProbe.tcpSocket.port}}
100
+ {%- endif %}
101
+ - equal:
102
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.initialDelaySeconds
103
+ value: {{container.livenessProbe.initialDelaySeconds}}
104
+ - equal:
105
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.failureThreshold
106
+ value: {{container.livenessProbe.failureThreshold}}
107
+ - equal:
108
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.successThreshold
109
+ value: {{container.livenessProbe.successThreshold}}
110
+ - equal:
111
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.timeoutSeconds
112
+ value: {{container.livenessProbe.timeoutSeconds}}
113
+ - equal:
114
+ path: spec.template.spec.containers[{{loop.index0}}].livenessProbe.periodSeconds
115
+ value: {{container.livenessProbe.periodSeconds}}
116
+ {%- endif %}
117
+ {%- if 'readinessProbe' in container %}
118
+ # ReadinessProbe
119
+ {%- if 'httpGet' in container.readinessProbe %}
120
+ - equal:
121
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.port
122
+ value: {{container.readinessProbe.httpGet.port}}
123
+ - equal:
124
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.path
125
+ value: {{container.readinessProbe.httpGet.path}}
126
+ - equal:
127
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.httpGet.scheme
128
+ value: {{container.readinessProbe.httpGet.scheme}}
129
+ {%- elif 'tcpSocket' in container.readinessProbe %}
130
+ - equal:
131
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.tcpSocket.port
132
+ value: {{container.readinessProbe.tcpSocket.port}}
133
+ {%- endif %}
134
+ - equal:
135
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.initialDelaySeconds
136
+ value: {{container.readinessProbe.initialDelaySeconds}}
137
+ - equal:
138
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.failureThreshold
139
+ value: {{container.readinessProbe.failureThreshold}}
140
+ - equal:
141
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.successThreshold
142
+ value: {{container.readinessProbe.successThreshold}}
143
+ - equal:
144
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.timeoutSeconds
145
+ value: {{container.readinessProbe.timeoutSeconds}}
146
+ - equal:
147
+ path: spec.template.spec.containers[{{loop.index0}}].readinessProbe.periodSeconds
148
+ value: {{container.readinessProbe.periodSeconds}}
149
+ {%- endif %}
150
+ {%- if 'resources' in container %}
151
+ # Resources
152
+ - equal:
153
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.cpu
154
+ value: {{container.resources.requests.cpu}}
155
+ - equal:
156
+ path: spec.template.spec.containers[{{loop.index0}}].resources.requests.memory
157
+ value: {{container.resources.requests.memory}}
158
+ {%-if 'limits' in container.resources %}
159
+ - equal:
160
+ path: spec.template.spec.containers[{{loop.index0}}].resources.limits.memory
161
+ value: {{container.resources.limits.memory}}
162
+ {%- endif%}
163
+ {%- endif%}
164
+
165
+ {%- if 'env' in container %}
166
+ # Env
167
+ {%- for env in container.env%}
168
+ - equal:
169
+ path: spec.template.spec.containers[{{containerIndex}}].env[{{loop.index0}}].name
170
+ value: {{ env.name }}
171
+ {%- endfor %}
172
+ {%- endif %}
173
+
174
+ {%- if 'ports' in container %}
175
+ # Ports
176
+ {%- for port in container.ports %}
177
+ - equal:
178
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].name
179
+ value: {{ port.name }}
180
+ - equal:
181
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].containerPort
182
+ value: {{ port.containerPort }}
183
+ - equal:
184
+ path: spec.template.spec.containers[{{containerIndex}}].ports[{{loop.index0}}].protocol
185
+ value: {{ port.protocol }}
186
+ {%- endfor%}
187
+ {%- endif %}
188
+
189
+ {%- if 'command' in container %}
190
+ # Command
191
+ {%- for cmd in container.command %}
192
+ - equal:
193
+ path: spec.template.spec.containers[{{containerIndex}}].command[{{loop.index0}}]
194
+ value: "{{ cmd }}"
195
+ {%- endfor %}
196
+ {%- endif %}
197
+
198
+ {%- if 'args' in container %}
199
+ # Args
200
+ {%- for arg in container.args %}
201
+ - equal:
202
+ path: spec.template.spec.containers[{{containerIndex}}].args[{{loop.index0}}]
203
+ value: "{{ arg }}"
204
+ {%- endfor %}
205
+ {%- endif %}
206
+
207
+ {%- if 'volumeMounts' in container %}
208
+ # volumeMounts
209
+ {%- for volumeMounts in container.volumeMounts %}
210
+ - equal:
211
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].name
212
+ value: {{ volumeMounts.name }}
213
+ - equal:
214
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].mountPath
215
+ value: {{ volumeMounts.mountPath }}
216
+ - equal:
217
+ path: spec.template.spec.containers[{{containerIndex}}].volumeMounts[{{loop.index0}}].readOnly
218
+ value: {{ bool_to_str(volumeMounts.readOnly) }}
219
+ {%- endfor%}
220
+ {%- endif%}
221
+ {%- endfor %}