add job generation support
Change-Id: I92e3ad3264b1555c47bd81baeb23e76fc41cd3da
diff --git a/README.rst b/README.rst
index b215c92..0ee5fa5 100644
--- a/README.rst
+++ b/README.rst
@@ -568,6 +568,46 @@
key: policy.json
path: policy.json
+Generating Jobs
+===============
+
+Example pillar:
+
+.. code-block:: yaml
+
+ kubernetes:
+ control:
+ job:
+ sleep:
+ job: sleep
+ restart_policy: Never
+ container:
+ sleep:
+ image: busybox
+ tag: latest
+ command:
+ - sleep
+ - "3600"
+
+Volumes and Variables can be used as the same way as during Deployment generation.
+
+Custom params:
+
+.. code-block:: yaml
+
+ kubernetes:
+ control:
+ job:
+ host_network: True
+ host_pid: True
+ container:
+ sleep:
+ privileged: True
+ node_selector:
+ key: node
+ value: one
+ image_pull_secretes: password
+
Documentation and Bugs
======================
diff --git a/kubernetes/control/cluster.sls b/kubernetes/control/cluster.sls
index 98a8188..32f4f84 100644
--- a/kubernetes/control/cluster.sls
+++ b/kubernetes/control/cluster.sls
@@ -5,6 +5,26 @@
file.directory:
- makedirs: true
+{%- if control.job is defined %}
+
+{%- for job_name, job in control.job.iteritems() %}
+
+/srv/kubernetes/jobs/{{ job_name }}-job.yml:
+ file.managed:
+ - source: salt://kubernetes/files/job.yml
+ - user: root
+ - group: root
+ - template: jinja
+ - makedirs: true
+ - require:
+ - file: /srv/kubernetes
+ - defaults:
+ job: {{ job|yaml }}
+
+{%- endfor %}
+
+{%- endif %}
+
{%- for service_name, service in control.service.iteritems() %}
{%- if service.enabled %}
diff --git a/kubernetes/files/job.yml b/kubernetes/files/job.yml
new file mode 100644
index 0000000..48cc47a
--- /dev/null
+++ b/kubernetes/files/job.yml
@@ -0,0 +1,89 @@
+{% from "kubernetes/map.jinja" import control with context %}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ job.job }}-job
+ namespace: {{ job.get('namespace', 'default') }}
+spec:
+ template:
+ metadata:
+ spec:
+ {%- if job.host_network is defined %}
+ hostNetwork: True
+ {%- endif %}
+ {%- if job.host_pid is defined %}
+ hostPID: True
+ {%- endif %}
+ containers:
+ {%- for container_name, container in job.container.iteritems() %}
+ - name: {{ container_name }}
+ image: {% if container.registry is defined %}{{ container.registry }}/{%- endif %}{{ container.image }}{%- if container.tag is defined %}:{{ container.tag }}{%- endif %}
+ imagePullPolicy: {{ container.get('image_pull_policy', 'IfNotPresent') }}
+ {%- if container.privileged is defined %}
+ securityContext:
+ privileged: True
+ {%- endif %}
+ {%- if container.variables is defined %}
+ env:
+ {%- for variable in container.variables %}
+ - name: {{ variable.name }}
+ {%- if variable.field_path is defined %}
+ valueFrom:
+ fieldRef:
+ fieldPath: {{ variable.fieldPath }}
+ {%- else %}
+ value: {{ variable.value }}
+ {%- endif %}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.command is defined %}
+ command:
+ {%- for command in container.command %}
+ - {{ command }}
+ {%- endfor %}
+ {%- endif %}
+ {%- if container.volumes is defined %}
+ volumeMounts:
+ {%- for volume in container.volumes %}
+ - name: {{ volume.name }}
+ mountPath: {{ volume.mount }}
+ readOnly: {{ volume.get('read_only', 'False') }}
+ {%- endfor %}
+ {%- endif %}
+ {%- endfor %}
+ {%- if job.volume is defined %}
+ volumes:
+ {%- for volume_name, volume in job.volume.iteritems() %}
+ - name: {{ volume_name }}
+ {%- if volume.type == 'empty_dir' %}
+ emptyDir: {}
+ {%- elif volume.type == 'host_path' %}
+ hostPath:
+ path: {{ volume.path }}
+ {%- elif volume.type == 'glusterfs' %}
+ glusterfs:
+ endpoints: {{ volume.endpoints }}
+ path: {{ volume.path }}
+ readOnly: {{ volume.get('read_only', 'False') }}
+ {%- elif volume.type == 'config_map' %}
+ configMap:
+ name: {{ volume_name }}
+ items:
+ {%- for name, item in volume.item.iteritems() %}
+ - key: {{ item.key }}
+ path: {{ item.path }}
+ {%- endfor %}
+ {%- endif %}
+ {%- endfor %}
+ {%- endif %}
+ restartPolicy: {{ job.restart_policy }}
+ {%- if job.nodeSelector is defined %}
+ nodeSelector:
+ {%- for selector in job.node_selector %}
+ {{ selector.key }}: {{ selector.value }}
+ {%- endfor %}
+ {%- endif %}
+ {%- if job.image_pull_secretes is defined %}
+ imagePullSecrets:
+ - name: {{ job.image_pull_secretes }}
+ {%- endif %}
\ No newline at end of file