#jinja2: trim_blocks: "true", lstrip_blocks: "false" --- {% set app = app | default('{}') %} apiVersion: v1 kind: Template {% if parameters | length %} parameters: {{ parameters | to_json }} {% endif %} metadata: name: {{ appname | default(kaas_project) }}-pods annotations: descriptions: {{ kaas_project_config.description | default(appname | default(kaas_project) ~ " auto-generated pod template") }} {% set applabels = ( app.labels | default({}) | combine( { 'app': appname }) ) if appname is defined else (app.labels | default({})) %} {% if applabels | length > 0 %} labels: {{ applabels | to_json }} {% endif %} objects: {% for name, pod in pods.items() %} {% set kind = pod.kind | default('DeploymentConfig') %} {% set podname = pod.name | default(name) | regex_replace('_','-') %} {% if pod.enabled | default(true) %} {% set pubkey = "kaas_" ~ name ~ "_pubkey" %} {% set privkey = "kaas_" ~ name ~ "_privkey" %} {% set cakey = "kaas_" ~ name ~ "_ca" %} {% if pod.variant is defined %} {% set pod = pod[pod.variant] %} {% endif %} {% set sched = pod.sched | default({}) %} {% set service = pod.service | default({}) %} {% set headless = (service.headles | default(false)) if kind == 'StatefulSet' else false %} {% set network = pod.network | default({}) %} {% set hostnet = network.host | default(false) %} {% set node_selector = (sched.selector is defined) | ternary(sched.selector, ands_default_node_selector | combine(sched.restrict | default({}))) %} {% set labels = pod.general_labels | default({}) | combine(applabels) %} {% if pod.service is defined %} {% if headless and pod.service.ports is defined %} - apiVersion: v1 kind: Service metadata: name: {{ podname }}-ss annotations: {{ pod.service.annotations | default({}) | combine({"service.alpha.kubernetes.io/tolerate-unready-endpoints": "true" }) | to_json }} {% if labels | length > 0 %} labels: {{ labels | to_json }} {% endif %} spec: clusterIP: None publishNotReadyAddresses: True selector: name: {{ podname }} ports: {% for port in pod.service.ports %} {% set portmap = (port | string).split('/') %} - name: "{{ portmap[0] }}" port: {{ portmap[0] }} targetPort: {{ (portmap[1] is defined) | ternary(portmap[1], portmap[0]) }} {% endfor %} {% endif %} - apiVersion: v1 kind: Service metadata: name: {{ podname }} {% if pod.service.annotations is defined %} annotations: {{ pod.service.annotations | to_json }} {% endif %} {% if labels | length > 0 %} labels: {{ labels | to_json }} {% endif %} spec: selector: name: {{ podname }} {% if pod.service.ip is defined %} clusterIP: {{ pod.service.ip }} {% endif %} {% if pod.service.ports is defined %} ports: {% for port in pod.service.ports %} {% set portmap = (port | string).split('/') %} - name: "{{ portmap[0] }}" port: {{ portmap[0] }} targetPort: {{ (portmap[1] is defined) | ternary(portmap[1], portmap[0]) }} {% endfor %} {% endif %} {% if (pod.service.ports is defined) and (pod.service.host is defined) %} {% set first_port = (pod.service.ports[0] | string).split('/') %} - apiVersion: v1 kind: Route metadata: name: {{ podname }} {% if labels | length > 0 %} labels: {{ labels | to_json }} {% endif %} spec: host: {{ pod.service.host }} to: kind: Service name: {{ podname }} port: targetPort: {{ (first_port[1] is defined) | ternary(first_port[1], first_port[0]) }} {% if (first_port[0] == "80") %} tls: termination: edge insecureEdgeTerminationPolicy: Allow {% if hostvars[inventory_hostname][pubkey] is defined %} certificate: |- {{ hostvars[inventory_hostname][pubkey] | indent(10) }} {% endif %} {% if hostvars[inventory_hostname][privkey] is defined %} key: |- {{ hostvars[inventory_hostname][privkey] | indent(10) }} {% endif %} {% if hostvars[inventory_hostname][cakey] is defined %} caCertificate: |- {{ hostvars[inventory_hostname][cakey] | indent(10) }} {% endif %} {% endif %} {% endif %} {% endif %} - apiVersion: {{ kaas_openshift_api_versions[kind] | default('v1') }} kind: {{ kind }} metadata: name: {{ podname }} {% if labels | length > 0 %} labels: {{ labels | to_json }} {% endif %} spec: replicas: {{ ( sched | default({})).replicas | default(1) }} revisionHistoryLimit: 2 strategy: type: {{ (sched | default({})).strategy | default('Rolling') }} updateStrategy: {% if pod.update %} type: {{ pod.update.strategy | default('OnDelete') }} {% if pod.update.min_ready is defined %} minReadySeconds: {{ pod.update.min_ready }} {% endif %} {% endif %} triggers: - type: ConfigChange {% for img in pod.images %} {% if img.stream is defined %} {% set stream = img.stream.split('/') %} {% set stream_name = stream[1] | default(stream[0]) %} - type: ImageChange imageChangeParams: automatic: true containerNames: - {{ img.name | default(podname) }} from: kind: "ImageStreamTag" name: {{ stream_name }} {% if (stream[1] is defined) %} namespace: {{ stream[0] }} {% endif %} {% endif %} {% endfor %} {% if kind == 'StatefulSet' %} {% if headless %} serviceName: {{ podname }}-ss {% else %} serviceName: {{ podname }} {% endif %} selector: matchLabels: name: {{ podname }} {% else %} selector: name: {{ podname }} {% endif %} {% if pod.pvc is defined %} volumeClaimTemplates: {% for name, pvc in pod.pvc.items() %} {% set pvcname = name | regex_replace('_','-') %} {% set pv = kaas_project_local_volumes[pvcname] | default({}) %} {% set oc_name = pv.name | default(pvcname) | regex_replace('_','-') %} {% if oc_name | regex_search("^" + kaas_project) %} {% set pvname = oc_name %} {% else %} {% set pvname = (kaas_project + "-" + oc_name) | regex_replace('_','-') %} {% endif %} - metadata: name: {{ pvcname }} spec: storageClassName: {{ pvc.sc | default(pv.sc | default('kaas-lst-' + pvname)) }} accessModes: - ReadWriteOnce resources: requests: storage: {{ pvc.capacity | default(pv.capacity | default(kaas_default_volume_capacity)) }} {% endfor %} {% endif %} template: metadata: name: {{ podname }} {% if headless %} annotations: {{ pod.annotations | default({}) | combine({"pod.alpha.kubernetes.io/initialized": "true"}) | to_json }} {% elif pod.annotations is defined %} annotations: {{ pod.annotations | to_json }} {% endif %} labels: {{ pod.labels | default({}) | combine(labels) | combine({'name': podname, 'app': (appname | default('kaas'))}) | to_json }} spec: {% if pod.sa is defined %} serviceAccountName: {{ pod.sa }} {% endif %} hostNetwork: {{ hostnet }} {% if (headless) and (hostnet) %} dnsPolicy: {{ network.dns_policy | default('ClusterFirstWithHostNet') }} {% elif network.dns_policy is defined %} dnsPolicy: {{ network.dns_policy }} {% endif %} {% if node_selector | length > 0 %} nodeSelector: {{ node_selector | to_json }} {% endif %} {% set mappings = (pod.images | json_query('[*].mappings') | length) %} {% set paths = (pod.images | json_query('[*].hostpath') | length) %} {% if mappings > 0 or paths > 0 %} volumes: {% for img in pod.images %} {% set imgidx = loop.index %} {% for vol in (img.mappings | default([])) %} {% if (vol.name | default(name)) in kaas_project_volumes.keys() %} {% set oc_name = vol.name | default(name) | regex_replace('_','-') %} - name: vol-{{imgidx}}-{{loop.index}} persistentVolumeClaim: claimName: {{ oc_name }} {% endif %} {% endfor %} {% for vol in (img.hostpath | default([])) %} - name: host-{{imgidx}}-{{loop.index}} hostPath: path: {{ vol.path }} {% endfor %} {% endfor %} {% endif %} {% if (pod.groups is defined) or (pod.run_as is defined) %} securityContext: {% if (pod.run_as is defined) %} runAsUser: {{ (kaas_project_uids[pod.run_as] is defined) | ternary(kaas_project_uids[pod.run_as].id, pod.run_as) }} {% endif %} {% if (pod.groups is defined) %} {% if (ands_openshift_gid_mode | default('')) == "RunAsAny" %} fsGroup: {{ (kaas_project_gids[pod.groups[0]] is defined) | ternary(kaas_project_gids[pod.groups[0]].id, pod.groups[0]) }} {% endif %} supplementalGroups: {% for group in pod.groups %} - {{ (kaas_project_gids[group] is defined) | ternary(kaas_project_gids[group].id, group) }} {% endfor %} {% endif %} {% endif %} containers: {% for img in pod.images %} {% set imgidx = loop.index %} - name: {{ img.name | default(podname) }} image: {{ img.stream | default(img.image) }} imagePullPolicy: {{ img.pull | default('Always') }} {% if (img.command is defined) %} command: {{ img.command | to_json }} {% endif %} {% if img.ports is defined %} ports: {% for port in img.ports %} {% if hostnet %} {% set portmap = (port | string).split('/') %} - containerPort: {{ (portmap[1] is defined) | ternary(portmap[1], portmap[0]) }} hostPort: {{ portmap[0] }} {% else %} - containerPort: {{ port }} {% endif %} {% endfor %} {% elif pod.service.ports is defined %} ports: {% for port in pod.service.ports %} {% set portmap = (port | string).split('/') %} - containerPort: {{ (portmap[1] is defined) | ternary(portmap[1], portmap[0]) }} {% if hostnet %} hostPort: {{ portmap[0] }} {% endif %} {% endfor %} {% endif %} {% if kind == 'StatefulSet' %} {% set extra_env = [ { "name": "POD_NAMESPACE", "value": "fieldref@metadata.namespace" }, { "name": "POD_REPLICAS", "value": sched.replicas } ] %} {% set env = img.env | default([]) | union(extra_env) %} {% elif img.env is defined %} {% set env = img.env %} {% endif %} {% if img.env is defined %} env: {% for env_item in env %} {% set env_name = env_item.name %} {% set env_val = env_item.value %} {% set env_parts = (env_val | string).split('@') %} - name: "{{ env_name }}" {% if env_parts[0] == "secret" %} {% set env_sec = (env_parts[1] | string).split('/') %} valueFrom: secretKeyRef: name: {{ env_sec[0] }} key: {{ env_sec[1] }} {% elif env_parts[0] == "cm" %} {% set env_cm = (env_parts[1] | string).split('/') %} valueFrom: configMapKeyRef: name: {{ env_cm[0] }} key: {{ env_cm[1] }} {% elif env_parts[0] == "fieldref" %} valueFrom: fieldRef: apiVersion: v1 fieldPath: {{ env_parts[1] }} {% else %} value: "{{ env_val }}" {% endif %} {% endfor %} {% endif %} {% if img.mappings is defined or img.hostpath is defined %} volumeMounts: {% for vol in (img.mappings | default([])) %} {% if vol.name in kaas_project_volumes.keys() %} - name: vol-{{imgidx}}-{{loop.index}} {% elif vol.name in kaas_project_local_volumes.keys() %} {% set pvcname = vol.name | regex_replace('_','-') %} - name: {{ pvcname }} {% endif %} subPath: {{ vol.path | default("") }} mountPath: {{ vol.mount }} {% endfor %} {% for vol in (img.hostpath | default([])) %} - name: host-{{imgidx}}-{{loop.index}} mountPath: {{ vol.mount }} {% endfor %} {% endif %} {% if img.resources is defined %} resources: {% if img.resources.request is defined %} {% set res = img.resources.request %} requests: {% if res.cpu %} cpu: {{ res.cpu }} {% endif %} {% if res.cpu %} memory: {{ res.mem }} {% endif %} {% endif %} {% if img.resources.limit is defined %} {% set res = img.resources.limit %} limits: {% if res.cpu %} cpu: {{ res.cpu }} {% endif %} {% if res.cpu %} memory: {{ res.mem }} {% endif %} {% endif %} {% endif %} {% if img.probes is defined %} {% for probe in img.probes %} {% if (probe.type is undefined) %} {% set seq = ['livenessProbe', 'readinessProbe'] %} {% elif (probe.type == "liveness") %} {% set seq = ['livenessProbe'] %} {% else %} {% set seq = ['readinessProbe'] %} {% endif %} {% for type in seq %} {{ type }}: timeoutSeconds: {{ probe.timeout | default(1) }} initialDelaySeconds: {{ probe.delay | default(10) }} {% if (probe.command is defined) %} exec: command: {{ probe.command | to_json }} {% elif (probe.path is defined) %} httpGet: path: {{ probe.path }} port: {{ probe.port | default(80) }} {% else %} tcpSocket: port: {{ probe.port | default(80) }} {% endif %} {% endfor %} {% endfor %} {% endif %} {% if img.hooks is defined %} lifecycle: {% for hook in img.hooks %} {{ hook.type }}: exec: command: {{ hook.command | to_json }} {% endfor %} {% endif %} {% endfor %} {% endif %} {% endfor %}