Commit ·
466b971
1
Parent(s): 2a81d02
add helm tests
Browse files- helm_test_gen.py → tools/helm_test_gen.py +0 -0
- tools/templates/cm.jinja +160 -0
- tools/templates/cronjob.jinja +111 -0
- tools/templates/deployment.jinja +244 -0
- tools/templates/hpa.jinja +30 -0
- tools/templates/ingress.jinja +20 -0
- tools/templates/job.jinja +103 -0
- tools/templates/np.jinja +6 -0
- tools/templates/pdb.jinja +6 -0
- tools/templates/pvc.jinja +34 -0
- tools/templates/sa.jinja +38 -0
- tools/templates/scenario.jinja +39 -0
- tools/templates/secret.jinja +160 -0
- tools/templates/service.jinja +20 -0
- tools/templates/statefulset.jinja +221 -0
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 %}
|