From e41e21f6d0f5ca7aace86bf60e8b503bb20fdcd5 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 15 Aug 2019 06:57:07 +0200 Subject: Support BuildConfig in ands_kaas role --- roles/ands_kaas/tasks/do_app.yml | 13 + roles/ands_kaas/tasks/do_apps.yml | 6 +- roles/ands_kaas/tasks/project.yml | 2 + roles/ands_kaas/tasks/template.yml | 4 +- roles/ands_kaas/tasks/templates.yml | 3 +- .../templates/40-kaas-app-builders.yml.j2 | 93 +++++ roles/ands_kaas/templates/50-kaas-app-pods.yml.j2 | 388 +++++++++++++++++++++ roles/ands_kaas/templates/50-kaas-pods.yml.j2 | 371 -------------------- 8 files changed, 503 insertions(+), 377 deletions(-) create mode 100644 roles/ands_kaas/tasks/do_app.yml create mode 100644 roles/ands_kaas/templates/40-kaas-app-builders.yml.j2 create mode 100644 roles/ands_kaas/templates/50-kaas-app-pods.yml.j2 delete mode 100644 roles/ands_kaas/templates/50-kaas-pods.yml.j2 (limited to 'roles/ands_kaas') diff --git a/roles/ands_kaas/tasks/do_app.yml b/roles/ands_kaas/tasks/do_app.yml new file mode 100644 index 0000000..556a421 --- /dev/null +++ b/roles/ands_kaas/tasks/do_app.yml @@ -0,0 +1,13 @@ +- name: "Process KaaS App builders" + include_tasks: "template.yml" + run_once: true + vars: + tmpl_name: "40-kaas-app-builders.yml.j2" + yml_name: ternary ( '80-' + (appname | default('kaas')) + '-builder.yml' + +- name: "Process KaaS App pods" + include_tasks: "template.yml" + run_once: true + vars: + tmpl_name: "50-kaas-app-pods.yml.j2" + yml_name: ternary ( '90-' + (appname | default('kaas')) + '.yml' diff --git a/roles/ands_kaas/tasks/do_apps.yml b/roles/ands_kaas/tasks/do_apps.yml index 0e49981..382eb3c 100644 --- a/roles/ands_kaas/tasks/do_apps.yml +++ b/roles/ands_kaas/tasks/do_apps.yml @@ -1,5 +1,5 @@ - name: "Process KaaS apps" - include_tasks: "template.yml" + include_tasks: "app.yml" run_once: true with_dict: "{{ kaas_project_apps | default({}) }}" loop_control: @@ -16,5 +16,5 @@ delete: "{{ options.delete | default(true) }}" instantiate: "{{ appitem.value.instantiate | default(false) }}" load: "{{ app.load | default(false) }}" - pods: "{{ app.pods }}" - tmpl_name: "50-kaas-pods.yml.j2" + pods: "{{ app.pods | default({}) }}" + builders: "{{ app.builders | default({}) }}" diff --git a/roles/ands_kaas/tasks/project.yml b/roles/ands_kaas/tasks/project.yml index 0376477..f1c596b 100644 --- a/roles/ands_kaas/tasks/project.yml +++ b/roles/ands_kaas/tasks/project.yml @@ -15,6 +15,7 @@ vars: var_empty: pods: {} + builders: {} var_name: "var_{{kaas_project}}_config" when: hostvars[inventory_hostname][var_name] is not defined @@ -58,6 +59,7 @@ kaas_project_config: "{{ hostvars[inventory_hostname][var_name] }}" kaas_project_volumes: "{{ kaas_project_config.volumes | default(kaas_project_config.extra_volumes | default({}) | combine(kaas_openshift_volumes)) }}" kaas_project_local_volumes: "{{ kaas_project_config.local_volumes | default({}) }}" + kaas_project_builders: "{{ kaas_project_config.builders | default({}) }}" kaas_project_pods: "{{ kaas_project_config.pods | default({}) }}" kaas_project_apps: "{{ kaas_project_config.apps | default({}) }}" kaas_project_gids: "{{ kaas_project_config.gids | default(kaas_openshift_gids) }}" diff --git a/roles/ands_kaas/tasks/template.yml b/roles/ands_kaas/tasks/template.yml index 89c30e0..73cf1c4 100644 --- a/roles/ands_kaas/tasks/template.yml +++ b/roles/ands_kaas/tasks/template.yml @@ -3,7 +3,7 @@ register: result vars: default_name: "{{ item | basename | regex_replace('\\.j2','') }}" - dest_name: "{{ (appname is defined) | ternary ( '90-' + (appname | default('')) + '.yml', default_name ) }}" + dest_name: "{{ yml_name | default(default_name) }}" with_first_found: - paths: - "{{ role_path }}/templates/" @@ -16,7 +16,7 @@ when: instantiate == true vars: default_name: "{{ tmpl_name | basename | regex_replace('\\.j2','') }}" - dest_name: "{{ (appname is defined) | ternary ( '90-' + (appname | default('')) + '.yml', default_name ) }}" + dest_name: "{{ yml_name | default(default_name) }}" template: "{{ dest_name }}" template_path: "{{ kaas_template_path }}" project: "{{ kaas_namespace | default(kaas_project) }}" diff --git a/roles/ands_kaas/tasks/templates.yml b/roles/ands_kaas/tasks/templates.yml index 4417cf3..07b71ea 100644 --- a/roles/ands_kaas/tasks/templates.yml +++ b/roles/ands_kaas/tasks/templates.yml @@ -4,7 +4,7 @@ command: "echo {{ item | quote }}" register: results changed_when: false - when: (kaas_project_pods | length > 0) or not (item | regex_search('kaas-pods')) + when: not (item | regex_search('kaas-app')) or ((kaas_project_pods | length > 0) and (item | regex_search('kaas-app-pods'))) or ((kaas_project_builders | length > 0) and (item | regex_search('kaas-app-builders'))) with_fileglob: - "{{ role_path }}/templates/{{ kaas_template_glob | default('*') }}.j2" - "{{ kaas_project_path }}/templates/{{ kaas_template_glob | default('*') }}.j2" @@ -22,6 +22,7 @@ instantiate: true load: false pods: "{{ kaas_project_pods }}" + builders: "{{ kaas_project_builders }}" loop_control: loop_var: tmpl_name diff --git a/roles/ands_kaas/templates/40-kaas-app-builders.yml.j2 b/roles/ands_kaas/templates/40-kaas-app-builders.yml.j2 new file mode 100644 index 0000000..090f15a --- /dev/null +++ b/roles/ands_kaas/templates/40-kaas-app-builders.yml.j2 @@ -0,0 +1,93 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +--- +{% set app = app | default('{}') %} +{% set have_triggers = 0 %} +apiVersion: v1 +kind: Template +metadata: + name: {{ appname | default(kaas_project) }}-builders + annotations: + descriptions: {{ kaas_project_config.description | default(appname | default(kaas_project) ~ " auto-generated image-builder 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, builder in builders.iteritems() %} + {% set isname = builder.name | default(name) | regex_replace('_','-') %} + {% set istag = builder.version | default("latest") %} + {% set type = builder.type | default("Docker") %} + {% set src_type = builder.src_type | default("git") %} + {% set image_type = builder.image_type | default("ImageStreamTag") %} + - kind: ImageStream + apiVersion: v1 + metadata: + name: {{ isname }} + - kind: "BuildConfig" + apiVersion: v1 + metadata: + name: {{ isname }} + spec: + successfulBuildsHistoryLimit: "{{ kaas_pod_history_limit }}" + failedBuildsHistoryLimit: "{{ kaas_pod_history_limit }}" + triggers: + - type: "ConfigChange" + source: + type: {{ src_type }} + {{ src_type }}: + uri: "{{ builder.src }}" + {% if builder.src_path is defined %} + contextDir: "{{ builder.src_path }}" + {% endif %} + strategy: + {% if type == 'Docker' %} + type: {{ type }} + {{ type | lower }}Strategy: + dockerfilePath: "{{ builder.dockerfile | default('Dockerfile') }}" + {% if builder.args is defined %} + buildArgs: {{ builder.args | to_json }} + {% endif %} + {% else %} + type: {{ type }} + {{ type | lower }}Strategy: + {% if builder.image is defined %} + from: + kind: {{ image_type }} + name: "{{ builder.image }}" + {% if image_type == 'ImageStreamTag' %} + namespace: "{{ builder.image_namespace | default('openshift') }}" + {% endif %} + {% endif %} + {% endif %} + {% if builder.env is defined %} + env: {{ builder.env | to_json }} + {% endif %} + output: + to: + kind: "ImageStreamTag" + name: "{{ isname }}:{{ istag }}" + imageLabels: + - name: "vendor" + value: "{{ builder.vendor | default(ands_info.vendor) }}" + - name: "author" + value: "{{ builder.author | default(ands_info.admin) }}" + - name: "authoritative-source-url" + value: "{{ builder.url | default(ands_info.git_url) }}" + triggers: + - type: ConfigChange + - type: ImageChange + {% if builder.trigger is defined %} + {% set have_triggers = 1 %} + {% set trigger_type = "Generic" if 'github.com' in builder.src else "Generic" %} + - type: {{ trigger_type }} + {{ trigger_type | lower }}: + secret: ${TRIGGER_SECRET} + {% endif %} +{% endfor %} +parameters: +{% if have_triggers %} + - description: Trigger secret + from: '[a-zA-Z0-9]{8}' + generate: expression + name: TRIGGER_SECRET +{% endif %} diff --git a/roles/ands_kaas/templates/50-kaas-app-pods.yml.j2 b/roles/ands_kaas/templates/50-kaas-app-pods.yml.j2 new file mode 100644 index 0000000..2174962 --- /dev/null +++ b/roles/ands_kaas/templates/50-kaas-app-pods.yml.j2 @@ -0,0 +1,388 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +--- +{% set app = app | default('{}') %} +apiVersion: v1 +kind: Template +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.iteritems() %} + {% 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.iteritems() %} + {% 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 %} diff --git a/roles/ands_kaas/templates/50-kaas-pods.yml.j2 b/roles/ands_kaas/templates/50-kaas-pods.yml.j2 deleted file mode 100644 index 8c7fe85..0000000 --- a/roles/ands_kaas/templates/50-kaas-pods.yml.j2 +++ /dev/null @@ -1,371 +0,0 @@ -#jinja2: trim_blocks: "true", lstrip_blocks: "false" ---- -{% set app = app | default('{}') %} -apiVersion: v1 -kind: Template -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.iteritems() %} - {% 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 - {% 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.iteritems() %} - {% 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.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 %} -- cgit v1.2.3