Added Salt PKI setup, orchestration skeleton
diff --git a/README.rst b/README.rst
index ee38b34..ec4f666 100644
--- a/README.rst
+++ b/README.rst
@@ -120,6 +120,15 @@
.. literalinclude:: tests/pillar/minion_graph.sls
:language: yaml
+Salt minion with PKI CA
+
+.. literalinclude:: tests/pillar/minion_pki_ca.sls
+ :language: yaml
+
+Salt minion with PKI certificate
+
+.. literalinclude:: tests/pillar/minion_pki_cert.sls
+ :language: yaml
Salt control (cloud/kvm/docker)
-------------------------------
diff --git a/metadata/service/support.yml b/metadata/service/support.yml
index 676bced..7399f96 100644
--- a/metadata/service/support.yml
+++ b/metadata/service/support.yml
@@ -1,5 +1,7 @@
parameters:
salt:
+ _orchestrate:
+ priority: 20
_support:
collectd:
enabled: false
diff --git a/salt/files/_signing_policies.conf b/salt/files/_signing_policies.conf
new file mode 100644
index 0000000..19bc552
--- /dev/null
+++ b/salt/files/_signing_policies.conf
@@ -0,0 +1,18 @@
+{%- from "salt/map.jinja" import minion with context %}
+
+x509_signing_policies:
+{%- for ca_name,ca in minion.ca.items() %}
+ {{ ca_name }}:
+ - minions: '*'
+ - signing_private_key: /etc/pki/ca/{{ ca_name }}/ca.key
+ - signing_cert: /etc/pki/ca/{{ ca_name }}/ca.crt
+ - C: {{ ca.country }}
+ - ST: {{ ca.state }}
+ - L: {{ ca.locality }}
+ - basicConstraints: "critical CA:false"
+ - keyUsage: "critical cRLSign, keyCertSign"
+ - subjectKeyIdentifier: hash
+ - authorityKeyIdentifier: keyid,issuer:always
+ - days_valid: {{ ca.days_valid.certificate }}
+ - copypath: /etc/pki/ca/{{ ca_name }}/certs/
+{%- endfor %}
diff --git a/salt/files/minion.conf b/salt/files/minion.conf
index 54d4943..22893af 100644
--- a/salt/files/minion.conf
+++ b/salt/files/minion.conf
@@ -57,7 +57,6 @@
{%- endif %}
-
{%- if minion.sentry is defined %}
sentry_handler:
{% for server in minion.sentry.servers %}
diff --git a/salt/files/orchestrate.sls b/salt/files/orchestrate.sls
new file mode 100644
index 0000000..39ed271
--- /dev/null
+++ b/salt/files/orchestrate.sls
@@ -0,0 +1,43 @@
+{%- from "salt/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+{{ formula_dict }}
+
+{%- for environment_name, environment in master.get('environment', {}).iteritems() %}
+
+{%- if master.base_environment == environment_name %}
+
+{%- set formula_dict = environment.get('formula', {}) %}
+{%- set new_formula_dict = {} %}
+
+{%- for formula_name, formula in formula_dict.iteritems() %}
+
+{%- set _tmp = new_formula_dict.update({formula_name: formula.get('orchestrate_order', 100)}) %}
+
+{%- endfor %}
+
+{%- set sorted_formula_list = new_formula_dict|dictsort(false, 'value') %}
+
+{%- for formula in sorted_formula_list %}
+
+{%- if salt['file.file_exists']('/srv/salt/env/'+environment_name+'/'+formula.0+'/orchestrate.sls') %}
+
+{{ salt['cmd.run']('cat /srv/salt/env/'+environment_name+'/'+formula.0+'/orchestrate.sls') }}
+
+{%- else %}
+
+{{ formula.0 }}:
+ salt.state:
+ - tgt: 'services:{{ formula.0 }}'
+ - tgt_type: grain
+ - sls: {{ formula.0 }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/master/ca.sls b/salt/master/ca.sls
deleted file mode 100644
index 83568b7..0000000
--- a/salt/master/ca.sls
+++ /dev/null
@@ -1,23 +0,0 @@
-{%- from "salt/map.jinja" import master with context %}
-{%- if master.enabled %}
-
-{%- if pillar.django_pki is defined %}
-{%- if pillar.django_pki.server.enabled %}
-
-include:
-- salt.master.service
-
-{#
-{%- for environment_name, environment in master.environment.iteritems() %}
-
-/srv/salt/env/{{ environment_name }}/pki:
- file.symlink:
- - target: /srv/django_pki/site/pki
-
-{%- endfor %}
-#}
-
-{%- endif %}
-{%- endif %}
-
-{%- endif %}
\ No newline at end of file
diff --git a/salt/master/init.sls b/salt/master/init.sls
index b4e4142..139b142 100644
--- a/salt/master/init.sls
+++ b/salt/master/init.sls
@@ -3,5 +3,9 @@
- salt.master.env
- salt.master.pillar
- salt.master.minion
+{%- if pillar.salt.master.windows_repo is defined %}
- salt.master.win_repo
-- salt.master.ca
\ No newline at end of file
+{%- endif %}
+{#
+- salt.master.orchestrate
+#}
\ No newline at end of file
diff --git a/salt/master/orchestrate.sls b/salt/master/orchestrate.sls
new file mode 100644
index 0000000..4aae098
--- /dev/null
+++ b/salt/master/orchestrate.sls
@@ -0,0 +1,32 @@
+{%- from "salt/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+{%- for environment_name, environment in master.get('environment', {}).iteritems() %}
+
+{%- if master.base_environment == environment_name %}
+
+{%- set formula_dict = {} %}
+{%- for formula_name, formula in formula_dict.iteritems() %}
+
+{%- if salt['file.file_exists']('salt://'+formula_name+'/meta/salt.yml') %}
+{%- set grains_fragment_file = formula_name+'/meta/salt.yml' %}
+{%- macro load_grains_file() %}{% include grains_fragment_file %}{% endmacro %}
+{%- set grains_yaml = load_grains_file()|load_yaml %}
+{% _dummy = formula_dict.update{formula_name: grains_yaml.orchestrate }}
+{%- else %}
+{%- endif %}
+{%- endfor %}
+
+/srv/salt/env/{{ environment_name}}/orchestrate.sls:
+ file.managed:
+ - source: salt://salt/files/orchestrate.sls
+ - user: root
+ - template: jinja
+ - defaults:
+ formula_dict: {{ formula_dict|yaml }}
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/meta/salt.yml b/salt/meta/salt.yml
new file mode 100644
index 0000000..4f3a32b
--- /dev/null
+++ b/salt/meta/salt.yml
@@ -0,0 +1,9 @@
+orchestrate:
+ master:
+ priority: 10
+ minion:
+ priority: 20
+ syndic:
+ priority: 200
+ control:
+ priority: 400
diff --git a/salt/minion.sls b/salt/minion.sls
deleted file mode 100644
index 5e8361e..0000000
--- a/salt/minion.sls
+++ /dev/null
@@ -1,70 +0,0 @@
-{%- from "salt/map.jinja" import minion with context %}
-{%- if minion.enabled %}
-
-salt_minion_packages:
- pkg.latest:
- - names: {{ minion.pkgs }}
-
-salt_minion_grains_dir:
- file.directory:
- - name: /etc/salt/grains.d
- - mode: 700
- - makedirs: true
- - user: root
-
-salt_minion_grains_placeholder:
- file.touch:
- - name: /etc/salt/grains.d/placeholder
- - require:
- - file: salt_minion_grains_dir
-
-salt_minion_grains_file:
- cmd.run:
- - name: cat /etc/salt/grains.d/* > /etc/salt/grains
- - require:
- - file: salt_minion_grains_placeholder
-
-/etc/salt/minion.d/minion.conf:
- file.managed:
- - source: salt://salt/files/minion.conf
- - user: root
- - group: root
- - template: jinja
- - require:
- - pkg: salt_minion_packages
- - file: salt_minion_grains_dir
- - watch_in:
- - service: salt_minion_service
-
-salt_minion_service:
- service.running:
- - name: {{ minion.service }}
- - enable: true
-
-{%- if minion.graph_states %}
-
-salt_graph_packages:
- pkg.latest:
- - names: {{ minion.graph_pkgs }}
- - require:
- - pkg: salt_minion_packages
-
-salt_graph_states_packages:
- pkg.latest:
- - names: {{ minion.graph_states_pkgs }}
-
-/root/salt-state-graph.py:
- file.managed:
- - source: salt://salt/files/salt-state-graph.py
- - require:
- - pkg: salt_graph_packages
-
-/root/salt-state-graph.sh:
- file.managed:
- - source: salt://salt/files/salt-state-graph.sh
- - require:
- - pkg: salt_graph_packages
-
-{%- endif %}
-
-{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/ca.sls b/salt/minion/ca.sls
new file mode 100644
index 0000000..e3027bb
--- /dev/null
+++ b/salt/minion/ca.sls
@@ -0,0 +1,56 @@
+{%- from "salt/map.jinja" import minion with context %}
+{%- if minion.enabled %}
+
+include:
+- salt.minion.service
+
+/etc/salt/minion.d/_signing_policies.conf:
+ file.managed:
+ - source: salt://salt/files/_signing_policies.conf
+ - template: jinja
+ - require:
+ - pkg: salt_minion_packages
+ - watch_in:
+ - service: salt_minion_service
+
+{%- for ca_name,ca in minion.ca.iteritems() %}
+
+/etc/pki/ca/{{ ca_name }}/certs:
+ file.directory:
+ - makedirs: true
+
+/etc/pki/ca/{{ ca_name }}/ca.key:
+ x509.private_key_managed:
+ - bits: 4096
+ - backup: True
+ - require:
+ - file: /etc/pki/ca/{{ ca_name }}/certs
+
+/etc/pki/ca/{{ ca_name }}/ca.crt:
+ x509.certificate_managed:
+ - signing_private_key: /etc/pki/ca/{{ ca_name }}/ca.key
+ - CN: {{ ca.common_name }}
+ - C: {{ ca.country }}
+ - ST: {{ ca.state }}
+ - L: {{ ca.locality }}
+ - basicConstraints: "critical CA:true"
+ - keyUsage: "critical cRLSign, keyCertSign"
+ - subjectKeyIdentifier: hash
+ - authorityKeyIdentifier: keyid,issuer:always
+ - days_valid: {{ ca.days_valid.authority }}
+ - days_remaining: 0
+ - backup: True
+ - require:
+ - x509: /etc/pki/ca/{{ ca_name }}/ca.key
+
+mine.send:
+ module.run:
+ - func: x509.get_pem_entries
+ - kwargs:
+ glob_path: /etc/pki/ca/{{ ca_name }}/ca.crt
+ - onchanges:
+ - x509: /etc/pki/ca/{{ ca_name }}/ca.crt
+
+{%- endfor %}
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/cert.sls b/salt/minion/cert.sls
new file mode 100644
index 0000000..419ca5a
--- /dev/null
+++ b/salt/minion/cert.sls
@@ -0,0 +1,41 @@
+{%- from "salt/map.jinja" import minion with context %}
+{%- if minion.enabled %}
+
+include:
+- salt.minion.service
+
+{%- for cert_name,cert in minion.cert.iteritems() %}
+
+/etc/pki/cert/{{ cert.authority }}:
+ file.directory:
+ - makedirs: true
+
+/etc/pki/cert/{{ cert.authority }}/{{ cert.common_name }}.key:
+ x509.private_key_managed:
+ - bits: 4096
+
+/etc/pki/cert/{{ cert.authority }}/{{ cert.common_name }}.crt:
+ x509.certificate_managed:
+ - ca_server: wst01.newt.cz
+ - signing_policy: {{ cert.authority }}
+ - public_key: /etc/pki/cert/{{ cert.authority }}/{{ cert.common_name }}.key
+ - CN: {{ cert.common_name }}
+ - days_remaining: 30
+ - backup: True
+
+{%- endfor %}
+
+{#
+/usr/local/share/ca-certificates:
+ file.directory: []
+
+{%- for ca_path,ca in salt['mine.get']('ca', 'x509.get_pem_entries')['ca'].iteritems() %}
+
+/usr/local/share/ca-certificates/{{ ca }}.crt:
+ x509.pem_managed:
+ - text: {{ salt['mine.get']('ca', 'x509.get_pem_entries')['ca']['/etc/pki/ca.crt']|replace('\n', '') }}
+
+{%- endfor %}
+#}
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/grains.sls b/salt/minion/grains.sls
new file mode 100644
index 0000000..f1003b1
--- /dev/null
+++ b/salt/minion/grains.sls
@@ -0,0 +1,30 @@
+{%- from "salt/map.jinja" import minion with context %}
+{%- if minion.enabled %}
+
+include:
+- salt.minion.service
+
+salt_minion_grains_dir:
+ file.directory:
+ - name: /etc/salt/grains.d
+ - mode: 700
+ - makedirs: true
+ - user: root
+ - require:
+ - pkg: salt_minion_packages
+
+salt_minion_grains_placeholder:
+ file.touch:
+ - name: /etc/salt/grains.d/placeholder
+ - require:
+ - file: salt_minion_grains_dir
+
+salt_minion_grains_file:
+ cmd.run:
+ - name: cat /etc/salt/grains.d/* > /etc/salt/grains
+ - require:
+ - file: salt_minion_grains_dir
+ - watch_in:
+ - service: salt_minion_service
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/graph.sls b/salt/minion/graph.sls
new file mode 100644
index 0000000..440bad2
--- /dev/null
+++ b/salt/minion/graph.sls
@@ -0,0 +1,26 @@
+{%- from "salt/map.jinja" import minion with context %}
+{%- if minion.enabled %}
+
+salt_graph_packages:
+ pkg.latest:
+ - names: {{ minion.graph_pkgs }}
+ - require:
+ - pkg: salt_minion_packages
+
+salt_graph_states_packages:
+ pkg.latest:
+ - names: {{ minion.graph_states_pkgs }}
+
+/root/salt-state-graph.py:
+ file.managed:
+ - source: salt://salt/files/salt-state-graph.py
+ - require:
+ - pkg: salt_graph_packages
+
+/root/salt-state-graph.sh:
+ file.managed:
+ - source: salt://salt/files/salt-state-graph.sh
+ - require:
+ - pkg: salt_graph_packages
+
+{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/init.sls b/salt/minion/init.sls
new file mode 100644
index 0000000..59f75f6
--- /dev/null
+++ b/salt/minion/init.sls
@@ -0,0 +1,12 @@
+include:
+- salt.minion.service
+- salt.minion.grains
+{%- if pillar.salt.minion.graph_states %}
+- salt.minion.graph
+{%- endif %}
+{%- if pillar.salt.minion.ca is defined %}
+- salt.minion.ca
+{%- endif %}
+{%- if pillar.salt.minion.cert is defined %}
+- salt.minion.cert
+{%- endif %}
\ No newline at end of file
diff --git a/salt/minion/service.sls b/salt/minion/service.sls
new file mode 100644
index 0000000..1f7ce58
--- /dev/null
+++ b/salt/minion/service.sls
@@ -0,0 +1,24 @@
+{%- from "salt/map.jinja" import minion with context %}
+{%- if minion.enabled %}
+
+salt_minion_packages:
+ pkg.latest:
+ - names: {{ minion.pkgs }}
+
+/etc/salt/minion.d/minion.conf:
+ file.managed:
+ - source: salt://salt/files/minion.conf
+ - user: root
+ - group: root
+ - template: jinja
+ - require:
+ - pkg: salt_minion_packages
+ - watch_in:
+ - service: salt_minion_service
+
+salt_minion_service:
+ service.running:
+ - name: {{ minion.service }}
+ - enable: true
+
+{%- endif %}
\ No newline at end of file
diff --git a/tests/pillar/control_virt.sls b/tests/pillar/control_virt.sls
index 51255f6..e07319b 100644
--- a/tests/pillar/control_virt.sls
+++ b/tests/pillar/control_virt.sls
@@ -1,6 +1,8 @@
salt:
minion:
enabled: true
+ master:
+ host: config01.dc01.domain.com
control:
enabled: true
virt_enabled: true
@@ -8,15 +10,12 @@
small:
cpu: 1
ram: 1
- hdd: 10
medium:
cpu: 2
ram: 4
- hdd: 20
large:
cpu: 4
ram: 8
- hdd: 70
cluster:
vpc20_infra:
domain: neco.virt.domain.com
@@ -27,9 +26,9 @@
node:
ubuntu1:
provider: node01.domain.com
- image: "salt://ubuntu.qcow"
+ image: ubuntu.qcow
size: medium
ubuntu2:
provider: node02.domain.com
- image: "http://ubuntu.com"
- size: small
+ image: bubuntu.qcomw
+ size: small
\ No newline at end of file
diff --git a/tests/pillar/minion_pki_ca.sls b/tests/pillar/minion_pki_ca.sls
new file mode 100644
index 0000000..8bbd952
--- /dev/null
+++ b/tests/pillar/minion_pki_ca.sls
@@ -0,0 +1,12 @@
+salt:
+ minion:
+ enabled: true
+ ca:
+ vagrant:
+ common_name: Test CA
+ country: Czech
+ state: Prague
+ locality: Zizkov
+ days_valid:
+ authority: 3650
+ certificate: 90
diff --git a/tests/pillar/minion_pki_cert.sls b/tests/pillar/minion_pki_cert.sls
new file mode 100644
index 0000000..13f7515
--- /dev/null
+++ b/tests/pillar/minion_pki_cert.sls
@@ -0,0 +1,7 @@
+salt:
+ minion:
+ enabled: true
+ cert:
+ test_service:
+ authority: Company CA
+ common_name: test.service.domain.tld
\ No newline at end of file