summaryrefslogtreecommitdiffstats
path: root/roles/ands_kaas
diff options
context:
space:
mode:
Diffstat (limited to 'roles/ands_kaas')
-rw-r--r--roles/ands_kaas/defaults/main.yml11
-rw-r--r--roles/ands_kaas/tasks/file.yml9
-rw-r--r--roles/ands_kaas/tasks/keys.yml37
-rw-r--r--roles/ands_kaas/tasks/main.yml12
-rw-r--r--roles/ands_kaas/tasks/oc.yml10
-rw-r--r--roles/ands_kaas/tasks/ocitem.yml13
-rw-r--r--roles/ands_kaas/tasks/ocscript.yml8
-rw-r--r--roles/ands_kaas/tasks/project.yml76
-rw-r--r--roles/ands_kaas/tasks/sync.yml8
-rw-r--r--roles/ands_kaas/tasks/sync_all.yml13
-rw-r--r--roles/ands_kaas/tasks/template.yml17
-rw-r--r--roles/ands_kaas/tasks/templates.yml20
-rw-r--r--roles/ands_kaas/tasks/volume.yml11
-rw-r--r--roles/ands_kaas/templates/0-gfs-volumes.yml.j238
-rw-r--r--roles/ands_kaas/templates/6-kaas-pods.yml.j2173
15 files changed, 456 insertions, 0 deletions
diff --git a/roles/ands_kaas/defaults/main.yml b/roles/ands_kaas/defaults/main.yml
new file mode 100644
index 0000000..3835453
--- /dev/null
+++ b/roles/ands_kaas/defaults/main.yml
@@ -0,0 +1,11 @@
+kaas_resync: false
+kaas_projects: "{{ ands_openshift_projects.keys() }}"
+
+kaas_template_root: "{{ ands_paths.provision }}/kaas/"
+
+kaas_glusterfs_endpoints: gfs
+kaas_openshift_volumes: "{{ ands_openshift_volumes }}"
+
+kaas_default_volume_capacity: "1Ti"
+kaas_default_file_owner: root
+kaas_default_file_group: root
diff --git a/roles/ands_kaas/tasks/file.yml b/roles/ands_kaas/tasks/file.yml
new file mode 100644
index 0000000..9a36e74
--- /dev/null
+++ b/roles/ands_kaas/tasks/file.yml
@@ -0,0 +1,9 @@
+---
+- name: "Setting up files in {{ path }}"
+ file:
+ path: "{{ path }}"
+ recurse: "{{ file.recurse | default(true) }}"
+ mode: "{{ file.mode | default( ((file.state | default('directory')) == 'directory') | ternary('0755', '0644') ) }}"
+ owner: "{{ file.owner | default(kaas_project_config.file_owner) | default(kaas_default_file_owner) }}"
+ group: "{{ file.group | default(kaas_project_config.file_group) | default(kaas_default_file_group) }}"
+ state: "{{ file.state | default('directory') }}"
diff --git a/roles/ands_kaas/tasks/keys.yml b/roles/ands_kaas/tasks/keys.yml
new file mode 100644
index 0000000..2096c75
--- /dev/null
+++ b/roles/ands_kaas/tasks/keys.yml
@@ -0,0 +1,37 @@
+---
+- name: Try to locate pubkey file
+ set_fact: "kaas_{{ pod.key }}_pubkey={{ lookup('file', item) }}"
+ with_first_found:
+ - paths:
+ - "{{ kaas_project_path }}/keys/"
+ files:
+ - "{{ pod.key }}.crt"
+ - "{{ pod.key }}.pub"
+ - "{{ pod.value.service.host | default('default') }}.crt"
+ - "{{ pod.value.service.host | default('default') }}.pub"
+ skip: true
+
+- name: Try to locate privkey file
+ set_fact: "kaas_{{ pod.key }}_privkey={{ lookup('file', item) }}"
+ with_first_found:
+ - paths:
+ - "{{ kaas_project_path }}/keys/"
+ files:
+ - "{{ pod.key }}.key"
+ - "{{ pod.key }}.pem"
+ - "{{ pod.value.service.host | default('default') }}.key"
+ - "{{ pod.value.service.host | default('default') }}.pem"
+ skip: true
+
+- name: Try to locate CA file
+ set_fact: "kaas_{{ pod.key }}_ca={{ lookup('file', item) }}"
+ with_first_found:
+ - paths:
+ - "{{ kaas_project_path }}/keys/"
+ files:
+ - "{{ pod.key }}.ca"
+ - "{{ pod.value.service.host | default('default') }}.ca"
+ - ca-bundle.pem
+ - ca.pem
+ - ca.crt
+ skip: true
diff --git a/roles/ands_kaas/tasks/main.yml b/roles/ands_kaas/tasks/main.yml
new file mode 100644
index 0000000..c9fb857
--- /dev/null
+++ b/roles/ands_kaas/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+- name: Provision OpenShift resources & configurations
+# include: only_templates.yml
+ include: project.yml
+ run_once: true
+ delegate_to: "{{ groups.masters[0] }}"
+ with_items: "{{ kaas_projects }}"
+ loop_control:
+ loop_var: kaas_project
+ vars:
+ kaas_template_path: "{{ kaas_template_root }}/{{ kaas_project }}"
+ kaas_project_path: "{{playbook_dir}}/projects/{{ kaas_project }}"
diff --git a/roles/ands_kaas/tasks/oc.yml b/roles/ands_kaas/tasks/oc.yml
new file mode 100644
index 0000000..d3504f8
--- /dev/null
+++ b/roles/ands_kaas/tasks/oc.yml
@@ -0,0 +1,10 @@
+---
+- name: Configure KaaS resources
+ include_role:
+ name: openshift_resource
+ tasks_from: command.yml
+ vars:
+ resource: "{{ ocitem.resource | default('') }}"
+ command: "{{ ocitem.oc }}"
+ project: "{{ kaas_project }}"
+ recreate: "{{ ocitem.recreate | default(false) }}"
diff --git a/roles/ands_kaas/tasks/ocitem.yml b/roles/ands_kaas/tasks/ocitem.yml
new file mode 100644
index 0000000..f21e8cd
--- /dev/null
+++ b/roles/ands_kaas/tasks/ocitem.yml
@@ -0,0 +1,13 @@
+---
+- name: OpenShift templates
+ include: templates.yml
+ run_once: true
+ vars:
+ kaas_template_glob: "{{ ocitem.template }}"
+ when: ocitem.template is defined
+
+- name: OpenShift commands
+ include: oc.yml
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ when: ocitem.oc is defined
diff --git a/roles/ands_kaas/tasks/ocscript.yml b/roles/ands_kaas/tasks/ocscript.yml
new file mode 100644
index 0000000..4927de4
--- /dev/null
+++ b/roles/ands_kaas/tasks/ocscript.yml
@@ -0,0 +1,8 @@
+---
+- include: ocitem.yml
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ with_items: "{{ kaas_project_config.oc }}"
+ loop_control:
+ loop_var: ocitem
+ \ No newline at end of file
diff --git a/roles/ands_kaas/tasks/project.yml b/roles/ands_kaas/tasks/project.yml
new file mode 100644
index 0000000..002596b
--- /dev/null
+++ b/roles/ands_kaas/tasks/project.yml
@@ -0,0 +1,76 @@
+---
+- name: Load global variables
+ include_vars: "{{kaas_project_path}}/vars/globals.yml"
+ when: "'{{kaas_project_path}}/vars/globals.yml' | is_file"
+
+- name: Load variables
+ include_vars: dir="{{kaas_project_path}}/vars" name="kaas_project_config"
+ when: "'{{kaas_project_path}}/vars' | is_dir"
+
+- name: Ensure OpenShift template directory exists
+ file: path="{{ kaas_template_path }}" state="directory" mode=0755 owner=root group=root
+
+- name: Configure KaaS volumes
+ include: volume.yml
+ run_once: true
+ delegate_to: "{{ groups.masters[0] }}"
+ with_dict: "{{ kaas_project_config.volumes | default(kaas_openshift_volumes) }}"
+ loop_control:
+ loop_var: osv
+ vars:
+ query: "[*].volumes.{{osv.value.volume}}.mount"
+ mntpath: "{{ (ands_storage_domains | json_query(query)) }}"
+ path: "{{ mntpath[0] ~ (osv.value.path | default('')) }}"
+ name: "{{osv.key}}"
+ volume: "{{osv.value}}"
+ when: ( mntpath | length ) > 0
+
+- name: Copy static configuration
+ include: sync_all.yml
+ run_once: true
+ delegate_to: "{{ groups.masters[0] }}"
+ with_items: "{{ lookup('pipe', search).split('\n') }}"
+ loop_control:
+ loop_var: osv_path
+ vars:
+ search: "find {{ kaas_project_path }}/files/ -type d -mindepth 1 -maxdepth 1"
+ osv: "{{ osv_path | basename }}"
+ pvar: "kaas_{{ osv }}_path"
+ local_path: "{{ osv_path }}"
+ remote_path: "{{ hostvars[inventory_hostname][pvar] }}"
+ when:
+ - osv in kaas_openshift_volumes
+ - hostvars[inventory_hostname][pvar] is defined
+
+- name: Configure KaaS files
+ include: file.yml
+ run_once: true
+ delegate_to: "{{ groups.masters[0] }}"
+ with_items: "{{ kaas_project_config.files | default(ands_openshift_files) }}"
+ loop_control:
+ loop_var: file
+ vars:
+ pvar: "kaas_{{ file.osv }}_path"
+ path: "{{ hostvars[inventory_hostname][pvar] }}/{{ file.path }}"
+ when: file.osv in ( kaas_project_config.volumes | default(kaas_openshift_volumes) )
+
+- name: Load OpenSSL keys
+ include: keys.yml
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ with_dict: "{{ kaas_project_config.pods }}"
+ loop_control:
+ loop_var: pod
+
+- name: "Run OC script"
+ include: ocscript.yml
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ when: kaas_project_config.oc is defined
+
+- name: "Configure all templates"
+ include: templates.yml
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ when: kaas_project_config.oc is undefined
+
diff --git a/roles/ands_kaas/tasks/sync.yml b/roles/ands_kaas/tasks/sync.yml
new file mode 100644
index 0000000..399cb66
--- /dev/null
+++ b/roles/ands_kaas/tasks/sync.yml
@@ -0,0 +1,8 @@
+---
+- name: Check if already exists
+ stat: path="{{ item_dest }}"
+ register: result
+
+- name: "Sync '{{ item_name }}'"
+ synchronize: src="{{ item_src }}" dest="{{ remote_path }}/" archive=yes
+ when: (result.stat.exists == False) or (kaas_resync | default(false))
diff --git a/roles/ands_kaas/tasks/sync_all.yml b/roles/ands_kaas/tasks/sync_all.yml
new file mode 100644
index 0000000..58a1710
--- /dev/null
+++ b/roles/ands_kaas/tasks/sync_all.yml
@@ -0,0 +1,13 @@
+# If delegation is enabled, synchronize will look from files on delegated host not locally
+
+- name: "Analyze '{{ local_path | basename }}'"
+# debug: msg="{{ local_path }} - {{ item_name }} - {{ item }}"
+ include: sync.yml
+ run_once: true
+ with_items: "{{ lookup('pipe', filesearch).split('\n') }}"
+ vars:
+ filesearch: "find '{{ local_path }}' -mindepth 1 -maxdepth 1"
+ item_name: "{{ item | basename }}"
+ item_src: "{{ local_path }}/{{ item_name }}"
+ item_dest: "{{ remote_path }}/{{ item_name }}"
+ when: item != ""
diff --git a/roles/ands_kaas/tasks/template.yml b/roles/ands_kaas/tasks/template.yml
new file mode 100644
index 0000000..6a81dd7
--- /dev/null
+++ b/roles/ands_kaas/tasks/template.yml
@@ -0,0 +1,17 @@
+- name: Populate template
+ template: src="{{ item }}" dest="{{ kaas_template_path }}/{{ item | basename | regex_replace('\.j2','') }}" owner=root group=root mode="0644"
+ register: result
+ with_first_found:
+ - paths:
+ - "{{ role_path }}/templates/"
+ - "{{ kaas_project_path }}/templates/"
+ files:
+ - "{{ tmpl_name }}"
+
+- name: Configure KaaS resources
+ include_role: name="openshift_resource"
+ vars:
+ template: "{{ tmpl_name | basename | regex_replace('\\.j2','') }}"
+ template_path: "{{ kaas_template_path }}"
+ project: "{{ kaas_project }}"
+ recreate: "{{ result | changed | ternary (true, false) }}"
diff --git a/roles/ands_kaas/tasks/templates.yml b/roles/ands_kaas/tasks/templates.yml
new file mode 100644
index 0000000..75d43f3
--- /dev/null
+++ b/roles/ands_kaas/tasks/templates.yml
@@ -0,0 +1,20 @@
+---
+# Sorting is not enforeced
+- name: "Find KaaS templates"
+ command: "echo {{ item | quote }}"
+ register: results
+ changed_when: false
+ with_fileglob:
+ - "{{ role_path }}/templates/{{ kaas_template_glob | default('*') }}.j2"
+ - "{{ kaas_project_path }}/templates/{{ kaas_template_glob | default('*') }}.j2"
+
+- name: "Sort and execute KaaS templates"
+ include: "template.yml"
+ delegate_to: "{{ groups.masters[0] }}"
+ run_once: true
+ with_items: "{{ sorted_tmpl }}"
+ vars:
+ sorted_tmpl: "{{ results | json_query('results[*].stdout_lines') | sum(start=[]) | map('basename') | sort | unique }}"
+ loop_control:
+ loop_var: tmpl_name
+
diff --git a/roles/ands_kaas/tasks/volume.yml b/roles/ands_kaas/tasks/volume.yml
new file mode 100644
index 0000000..b82e55f
--- /dev/null
+++ b/roles/ands_kaas/tasks/volume.yml
@@ -0,0 +1,11 @@
+---
+- name: "Configure {{ name }} fact"
+ set_fact: "kaas_{{ name }}_path={{ path }}"
+
+- name: "Ensure {{ path }} exists"
+ file:
+ path: "{{ path }}"
+ state: "directory"
+ mode: "{{ volume.mode | default(0755) }}"
+ owner: "{{ volume.owner | default(kaas_project_config.file_owner) | default(kaas_default_file_owner) }}"
+ group: "{{ volume.group | default(kaas_project_config.file_group) | default(kaas_default_file_group) }}"
diff --git a/roles/ands_kaas/templates/0-gfs-volumes.yml.j2 b/roles/ands_kaas/templates/0-gfs-volumes.yml.j2
new file mode 100644
index 0000000..a162c8b
--- /dev/null
+++ b/roles/ands_kaas/templates/0-gfs-volumes.yml.j2
@@ -0,0 +1,38 @@
+---
+apiVersion: v1
+kind: Template
+metadata:
+ name:
+ annotations:
+ descriptions: "KATRIN Volumes"
+objects:
+{% for name, vol in (kaas_project_config.volumes | default(kaas_openshift_volumes)).iteritems() %}
+ - apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: {{ vol.name | default(name) }}
+ spec:
+ persistentVolumeReclaimPolicy: Retain
+ glusterfs:
+ endpoints: {{ kaas_glusterfs_endpoints }}
+ path: {{ vol.volume }}
+ readOnly: {{ not (vol.write | default(false)) }}
+ accessModes:
+ - {{ vol.access | default('ReadWriteMany') }}
+ capacity:
+ storage: {{ vol.capacity | default(kaas_default_volume_capacity) }}
+ claimRef:
+ name: {{ vol.name | default(name) }}
+ namespace: {{ kaas_project }}
+ - apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: {{ vol.name | default(name) }}
+ spec:
+ volumeName: {{ vol.name | default(name) }}
+ accessModes:
+ - {{ vol.access | default('ReadWriteMany') }}
+ resources:
+ requests:
+ storage: {{ vol.capacity | default(kaas_default_volume_capacity) }}
+{% endfor %}
diff --git a/roles/ands_kaas/templates/6-kaas-pods.yml.j2 b/roles/ands_kaas/templates/6-kaas-pods.yml.j2
new file mode 100644
index 0000000..9849bd3
--- /dev/null
+++ b/roles/ands_kaas/templates/6-kaas-pods.yml.j2
@@ -0,0 +1,173 @@
+#jinja2: trim_blocks: "true", lstrip_blocks: "false"
+---
+apiVersion: v1
+kind: Template
+metadata:
+ name: {{ kaas_project }}-pods
+ annotations:
+ descriptions: {{ kaas_project_config.description | default(kaas_project ~ "auto-generated pod template") }}
+objects:
+{% for name, pod in (kaas_project_config.pods | default(kaas_openshift_volumes)).iteritems() %}
+ {% set pubkey = "kaas_" ~ name ~ "_pubkey" %}
+ {% set privkey = "kaas_" ~ name ~ "_privkey" %}
+ {% set cakey = "kaas_" ~ name ~ "_ca" %}
+ {% if pod.service is defined %}
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ name: {{ pod.name | default(name) }}
+ spec:
+ selector:
+ name: {{ pod.name | default(name) }}
+ {% 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('/')[0] %}
+ - apiVersion: v1
+ kind: Route
+ metadata:
+ name: kaas
+ spec:
+ host: {{ pod.service.host }}
+ to:
+ kind: Service
+ name: {{ pod.name | default(name) }}
+ port:
+ targetPort: {{ first_port }}
+ {% if (first_port == "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: v1
+ kind: DeploymentConfig
+ metadata:
+ name: kaas
+ spec:
+ replicas: {{ pod.sched.replicas | default(1) }}
+ selector:
+ name: {{ pod.name | default(name) }}
+ template:
+ metadata:
+ name: {{ pod.name | default(name) }}
+ labels:
+ name: {{ pod.name | default(name) }}
+ strategy:
+ type: {{ pod.sched.strategy | default('Rolling') }}
+ triggers:
+ - type: ConfigChange
+ spec:
+ {% if pod.selector is defined %}
+ nodeSelector:
+ {% for skey, sval in pod.selector.iteritems() %}
+ {{ skey }}: "{{ sval }}"
+ {% endfor %}
+ {% endif %}
+ {% set mappings = (pod.images | json_query('[*].mappings') | length) %}
+ {% if mappings > 0 %}
+ volumes:
+ {% for img in pod.images %}
+ {% set imgidx = loop.index %}
+ {% for vol in img.mappings %}
+ - name: vol-{{imgidx}}-{{loop.index}}
+ persistentVolumeClaim:
+ claimName: {{ vol.name }}
+ {% endfor %}
+ {% endfor %}
+ {% endif %}
+ containers:
+ {% for img in pod.images %}
+ {% set imgidx = loop.index %}
+ - name: {{ img.name | default(pod.name) | default(name) }}
+ image: {{ img.image }}
+ imagePullPolicy: Always
+ ports:
+ {% if img.ports is defined %}
+ {% for port in img.ports %}
+ - containerPort: {{ port }}
+ {% endfor %}
+ {% else %}
+ {% for port in pod.service.ports %}
+ {% set portmap = (port | string).split('/') %}
+ - containerPort: {{ (portmap[1] is defined) | ternary(portmap[1], portmap[0]) }}
+ {% endfor %}
+ {% endif %}
+ {% if img.env is defined %}
+ env:
+ {% for env_name, env_val in img.env.iteritems() %}
+ {% set env_parts = (env_val | string).split('@') %}
+ {% if env_parts[0] == "secret" %}
+ - name: {{ env_name }}
+ {% 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] }}
+ {% else %}
+ value: {{ env_val }}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ {% if img.mappings is defined %}
+ volumeMounts:
+ {% for vol in img.mappings %}
+ - name: vol-{{imgidx}}-{{loop.index}}
+ subPath: {{ (((kaas_project_config.volumes | default(kaas_openshift_volumes))[vol.name].path | default("")) ~ "/") | regex_replace('^/','') }}{{ vol.path | default("") }}
+ mountPath: {{ vol.mount }}
+ {% endfor %}
+ {% endif %}
+ {% if img.probes is defined %}
+ {% for probe in img.probes %}
+ {% if (probe.type is undefined) %}
+ {% set seq = ['livenessProbe', 'readynessProbe'] %}
+ {% elif (probe.type == "liveness") %}
+ {% set seq = ['livenessProbe'] %}
+ {% else %}
+ {% set seq = ['readynessProbe'] %}
+ {% endif %}
+ {% for type in seq %}
+ {{ type }}:
+ timeoutSeconds: {{ probe.timeout | default(1) }}
+ initialDelaySeconds: {{ probe.delay | default(10) }}
+ {% if (probe.cmd is defined) %}
+ command: "{{ probe.cmd }}"
+ {% 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 %}
+ {% endfor %}
+{% endfor %}