#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 %}
        {% for vol in (img.configs | default([])) %}
            - name: cfg-{{imgidx}}-{{loop.index}}
          {% if (vol.secret | default(false)) | bool %}
              secret:
                secretName: {{vol.name}}
          {% else %}
              configMap:
                name: {{vol.name}}
          {% endif %}
        {% 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 %}
        {% for vol in (img.configs | default([])) %}
                - name: cfg-{{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) }}
                periodSeconds: {{ probe.period | default(60) }}
            {% 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 %}
