Merge pull request #43 from salt-formulas/pr/fix/ca_cert_whitespaces

fix prepending whitespaces starting 2nd line
diff --git a/README.rst b/README.rst
index 546129b..941934d 100644
--- a/README.rst
+++ b/README.rst
@@ -171,6 +171,14 @@
           ".*":
           - x509.sign_remote_certificate
 
+Configure verbosity of state output (used for `salt` command)
+
+.. code-block:: yaml
+
+    salt:
+      master:
+        state_output: changes
+
 Salt proxy
 ----------
 
diff --git a/salt/control/virt.sls b/salt/control/virt.sls
index b5eab40..b30f7af 100644
--- a/salt/control/virt.sls
+++ b/salt/control/virt.sls
@@ -8,34 +8,13 @@
   pkg.installed:
     - names: {{ control.virt_pkgs }}
 
+{% if grains.oscodename == 'trusty' %}
+{#- This tool is not available in newer releases #}
 update-guestfs-appliance:
   cmd.wait:
     - watch:
       - pkg: salt_control_virt_packages
-
-{#
-{%- for package in control.virt_pips %}
-
-{{ package }}:
-  pip.installed:
-  - require:
-    - pkg: salt_control_virt_packages
-
-{%- endfor %}
-#}
-
-/etc/salt/minion.d/_virt.conf:
-  file.managed:
-  - source: salt://salt/files/_virt.conf
-  - user: root
-  - group: root
-  - template: jinja
-  - require:
-    - pkg: salt_control_virt_packages
-  {%- if not grains.get('noservices', False) %}
-  - watch_in:
-    - service: salt_minion_service
-  {%- endif %}
+{%- endif %}
 
 {%- for cluster_name, cluster in control.cluster.iteritems() %}
 
@@ -43,6 +22,10 @@
 
 {%- for node_name, node in cluster.node.iteritems() %}
 
+{%- if node.name is defined %}
+{%- set node_name = node.name %}
+{%- endif %}
+
 {%- if node.provider == grains.id %}
 
 {%- set size = control.size.get(node.size) %}
diff --git a/salt/files/_pki.conf b/salt/files/_pki.conf
deleted file mode 100644
index f3e9cb9..0000000
--- a/salt/files/_pki.conf
+++ /dev/null
@@ -1,47 +0,0 @@
-{%- from "salt/map.jinja" import minion with context %}
-
-x509_signing_policies:
-{%- for ca_name,ca in minion.ca.items() %}
-{%- for signing_policy_name, signing_policy in ca.signing_policy.iteritems() %}
-  {{ ca_name }}_{{ signing_policy_name }}:
-    - minions: '{{ signing_policy.minions }}'
-    - signing_private_key: /etc/pki/ca/{{ ca_name }}/ca.key
-    - signing_cert: /etc/pki/ca/{{ ca_name }}/ca.crt
-    {%- if ca.country is defined %}
-    - C: {{ ca.country }}
-    {%- endif %}
-    {%- if ca.state is defined %}
-    - ST: {{ ca.state }}
-    {%- endif %}
-    {%- if ca.locality is defined %}
-    - L: {{ ca.locality }}
-    {%- endif %}
-    {%- if ca.organization is defined %}
-    - O: {{ ca.organization }}
-    {%- endif %}
-    {%- if ca.organization_unit is defined %}
-    - OU: {{ ca.organization_unit }}
-    {%- endif %}
-    {%- if signing_policy.type == 'v3_edge_cert_client' %}
-    - basicConstraints: "CA:FALSE"
-    - keyUsage: "critical digitalSignature,nonRepudiation,keyEncipherment"
-    - extendedKeyUsage: "critical clientAuth"
-    {%- elif signing_policy.type == 'v3_edge_cert_server' %}
-    - basicConstraints: "CA:FALSE"
-    - keyUsage: "critical digitalSignature,nonRepudiation,keyEncipherment"
-    - extendedKeyUsage: "critical,serverAuth"
-    {%- elif signing_policy.type == 'v3_intermediate_ca' %}
-    - basicConstraints: "CA:TRUE"
-    - keyUsage: "critical cRLSign,keyCertSign"
-    {%- elif signing_policy.type == 'v3_edge_ca' %}
-    - basicConstraints: "CA:TRUE,pathlen:0"
-    - keyUsage: "critical cRLSign,keyCertSign"
-    {%- elif signing_policy.type == 'v3_edge_cert_open' %}
-    - basicConstraints: "CA:FALSE"
-    {%- endif %}
-    - subjectKeyIdentifier: hash
-    - authorityKeyIdentifier: keyid,issuer:always
-    - days_valid: {{ ca.days_valid.certificate }}
-    - copypath: /etc/pki/ca/{{ ca_name }}/certs/
-{%- endfor %}
-{%- endfor %}
diff --git a/salt/files/_virt.conf b/salt/files/_virt.conf
deleted file mode 100644
index fc6032c..0000000
--- a/salt/files/_virt.conf
+++ /dev/null
@@ -1,37 +0,0 @@
-{% from "salt/map.jinja" import control with context %}
-
-{%- if control.net_profile is defined or control.disk_profile is defined %}
-virt:
-  {%- if control.net_profile is defined %}
-  nic:
-    {%- for item_name, item in control.net_profile.iteritems() %}
-    {{ item_name }}:
-      {%- for iface_name, iface in item.iteritems() %}
-      {{ iface_name }}:
-        {%- if iface.bridge is defined %}
-        bridge: {{ iface.bridge }}
-        {%- endif %}
-        {%- if iface.network is defined %}
-        network: {{ iface.network }}
-        {%- endif %}
-        {%- if iface.model is defined %}
-        model: {{ iface.model }}
-        {%- endif %}
-      {%- endfor %}
-    {%- endfor %}
-  {%- endif %}
-  {%- if control.disk_profile is defined %}
-  disk:
-    {%- for item_name, item in control.disk_profile.iteritems() %}
-    {{ item_name }}:
-      {%- for disk_name, disk in item.iteritems() %}
-      - {{ disk }}:
-          {%- if disk.size is defined %}
-          size: {{ disk.size }}
-          {%- endif %}
-      {%- endfor %} 
-    {%- endfor %} 
-  {%- endif %}
-{%- endif %}
-
-virt.images: /var/lib/libvirt/images
diff --git a/salt/files/master.conf b/salt/files/master.conf
index 0b1333f..2ee44d9 100644
--- a/salt/files/master.conf
+++ b/salt/files/master.conf
@@ -4,6 +4,8 @@
 worker_threads: {{ master.worker_threads }}
 timeout: {{ master.command_timeout }}
 
+state_output: {{ master.get('state_output', 'changes') }}
+
 {%- if master.system is defined %}
 
 file_roots:
diff --git a/salt/map.jinja b/salt/map.jinja
index 8693250..b3ff3cd 100644
--- a/salt/map.jinja
+++ b/salt/map.jinja
@@ -89,15 +89,12 @@
 Arch:
   pkgs:
   - salt-zmq
-  grains_validity_pkgs:
-    - python-yaml
 Debian:
   pkgs:
   - salt-minion
   - python-m2crypto
   - python-psutil
-  grains_validity_pkgs:
-    - python-yaml
+  - python-yaml
 Gentoo:
   pkgs:
   - app-admin/salt
@@ -107,10 +104,9 @@
 RedHat:
   pkgs:
   - salt-minion
-  - python-m2ext
-  - python-psutil
-  grains_validity_pkgs:
-    - PyYaml
+  - m2crypto
+  - psutils
+  - PyYAML
 {%- endload %}
 
 {%- if pillar.salt.minion is defined %}
diff --git a/salt/meta/salt.yml b/salt/meta/salt.yml
index 81225fe..1a97657 100644
--- a/salt/meta/salt.yml
+++ b/salt/meta/salt.yml
@@ -1,10 +1,103 @@
 orchestrate:
   master:
     priority: 60
-  minion: 
+  minion:
     priority: 70
-  control: 
+  control:
     priority: 400
     require:
     - salt: salt.master
 
+minion:
+  {%- if pillar.get('salt', {}).get('minion', {}).get('ca') %}
+  pki:
+    {%- from "salt/map.jinja" import minion with context %}
+    x509_signing_policies:
+    {%- for ca_name,ca in minion.ca.items() %}
+    {%- for signing_policy_name, signing_policy in ca.signing_policy.iteritems() %}
+      {{ ca_name }}_{{ signing_policy_name }}:
+        - minions: '{{ signing_policy.minions }}'
+        - signing_private_key: /etc/pki/ca/{{ ca_name }}/ca.key
+        - signing_cert: /etc/pki/ca/{{ ca_name }}/ca.crt
+        {%- if ca.country is defined %}
+        - C: {{ ca.country }}
+        {%- endif %}
+        {%- if ca.state is defined %}
+        - ST: {{ ca.state }}
+        {%- endif %}
+        {%- if ca.locality is defined %}
+        - L: {{ ca.locality }}
+        {%- endif %}
+        {%- if ca.organization is defined %}
+        - O: {{ ca.organization }}
+        {%- endif %}
+        {%- if ca.organization_unit is defined %}
+        - OU: {{ ca.organization_unit }}
+        {%- endif %}
+        {%- if signing_policy.type == 'v3_edge_cert_client' %}
+        - basicConstraints: "CA:FALSE"
+        - keyUsage: "critical digitalSignature,nonRepudiation,keyEncipherment"
+        - extendedKeyUsage: "critical clientAuth"
+        {%- elif signing_policy.type == 'v3_edge_cert_server' %}
+        - basicConstraints: "CA:FALSE"
+        - keyUsage: "critical digitalSignature,nonRepudiation,keyEncipherment"
+        - extendedKeyUsage: "critical,serverAuth"
+        {%- elif signing_policy.type == 'v3_intermediate_ca' %}
+        - basicConstraints: "CA:TRUE"
+        - keyUsage: "critical cRLSign,keyCertSign"
+        {%- elif signing_policy.type == 'v3_edge_ca' %}
+        - basicConstraints: "CA:TRUE,pathlen:0"
+        - keyUsage: "critical cRLSign,keyCertSign"
+        {%- elif signing_policy.type == 'v3_edge_cert_open' %}
+        - basicConstraints: "CA:FALSE"
+        {%- endif %}
+        - subjectKeyIdentifier: hash
+        - authorityKeyIdentifier: keyid,issuer:always
+        - days_valid: {{ ca.days_valid.certificate }}
+        - copypath: /etc/pki/ca/{{ ca_name }}/certs/
+    {%- endfor %}
+    {%- endfor %}
+  {%- endif %}
+
+  {%- if pillar.salt.control is defined and pillar.salt.control.virt_enabled is defined %}
+  virt:
+    {% from "salt/map.jinja" import control with context %}
+    {%- if control.net_profile is defined or control.disk_profile is defined %}
+    virt:
+      {%- if control.net_profile is defined %}
+      nic:
+        {%- for item_name, item in control.net_profile.iteritems() %}
+        {{ item_name }}:
+          {%- for iface_name, iface in item.iteritems() %}
+          {{ iface_name }}:
+            {%- if iface.bridge is defined %}
+            bridge: {{ iface.bridge }}
+            {%- endif %}
+            {%- if iface.network is defined %}
+            network: {{ iface.network }}
+            {%- endif %}
+            {%- if iface.model is defined %}
+            model: {{ iface.model }}
+            {%- endif %}
+          {%- endfor %}
+        {%- endfor %}
+      {%- endif %}
+      {%- if control.disk_profile is defined %}
+      disk:
+        {%- for item_name, item in control.disk_profile.iteritems() %}
+        {{ item_name }}:
+          {%- for disk_name, disk in item.iteritems() %}
+          - {{ disk }}:
+              {%- if disk.size is defined %}
+              size: {{ disk.size }}
+              {%- endif %}
+          {%- endfor %}
+        {%- endfor %}
+      {%- endif %}
+    {%- endif %}
+    virt.images: /var/lib/libvirt/images
+  {%- endif %}
+
+{#-
+  vim: syntax=jinja
+-#}
diff --git a/salt/minion/ca.sls b/salt/minion/ca.sls
index b39323e..f2b3e22 100644
--- a/salt/minion/ca.sls
+++ b/salt/minion/ca.sls
@@ -4,17 +4,6 @@
 include:
 - salt.minion.service
 
-/etc/salt/minion.d/_pki.conf:
-  file.managed:
-  - source: salt://salt/files/_pki.conf
-  - template: jinja
-  - require:
-    - {{ minion.install_state }}
-  {%- if not grains.get('noservices', False) %}
-  - watch_in:
-    - service: salt_minion_service
-  {%- endif %}
-
 {%- for ca_name,ca in minion.ca.iteritems() %}
 
 /etc/pki/ca/{{ ca_name }}/certs:
diff --git a/salt/minion/cert.sls b/salt/minion/cert.sls
index 15f39be..b4a1a1d 100644
--- a/salt/minion/cert.sls
+++ b/salt/minion/cert.sls
@@ -10,6 +10,8 @@
 
 {%- if minion.cert is defined %}
 
+{%- set created_ca_files = [] %}
+
 {%- for cert_name,cert in minion.get('cert', {}).iteritems() %}
 {%- set rowloop = loop %}
 
@@ -94,30 +96,26 @@
     - watch:
       - x509: {{ cert_file }}
 
-{%- if cert.host is defined %}
+{%- if cert.host is defined and ca_file not in created_ca_files %}
 {%- for ca_path,ca_cert in salt['mine.get'](cert.host, 'x509.get_pem_entries').get(cert.host, {}).iteritems() %}
 
 {%- if '/etc/pki/ca/'+cert.authority in ca_path %}
 
-{{ ca_file }}_{{ rowloop.index }}:
+{{ ca_file }}:
   x509.pem_managed:
     - name: {{ ca_file }}
     - text: {{ ca_cert|replace('\n', '') }}
     - watch:
       - x509: {{ cert_file }}
-    {%- if cert.all_file is defined %}
-    - watch_in:
-      - cmd: salt_minion_cert_{{ cert_name }}_all
-    {%- endif %}
 
-{{ ca_file }}_cert_permissions_{{ rowloop.index }}:
+{{ ca_file }}_cert_permissions:
   file.managed:
     - name: {{ ca_file }}
     - mode: 0644
     - watch:
       - x509: {{ ca_file }}
 
-{{ ca_file }}_{{ rowloop.index }}_local_trusted_symlink:
+{{ ca_file }}_local_trusted_symlink:
   file.symlink:
     - name: "{{ cacerts_dir }}/ca-{{ cert.authority }}.crt"
     - target: {{ ca_file }}
@@ -127,6 +125,7 @@
 {%- endif %}
 
 {%- endfor %}
+{%- do created_ca_files.append(ca_file) %}
 {%- endif %}
 
 {%- if cert.all_file is defined %}
@@ -136,6 +135,7 @@
     - watch:
       - x509: {{ key_file }}
       - x509: {{ cert_file }}
+      - x509: {{ ca_file }}
 
 {{ cert.all_file }}_cert_permissions:
   file.managed:
diff --git a/salt/minion/grains.sls b/salt/minion/grains.sls
index dab3585..df5205b 100644
--- a/salt/minion/grains.sls
+++ b/salt/minion/grains.sls
@@ -22,16 +22,12 @@
   - require:
     - file: salt_minion_grains_dir
 
-salt_minion_grains_pkg_validity_check:
-  pkg.installed:
-  - pkgs: {{ minion.grains_validity_pkgs }}
-
 {%- for service_name, service in pillar.items() %}
   {%- set support_fragment_file = service_name+'/meta/salt.yml' %}
   {%- macro load_support_file() %}{% include support_fragment_file ignore missing %}{% endmacro %}
   {%- set support_yaml = load_support_file()|load_yaml %}
 
-  {%- if support_yaml %}
+  {%- if support_yaml and support_yaml.get('grain', {}) %}
     {%- for name, grain in support_yaml.get('grain', {}).iteritems() %}
 salt_minion_grain_{{ service_name }}_{{ name }}:
   file.managed:
@@ -44,8 +40,6 @@
 salt_minion_grain_{{ service_name }}_{{ name }}_validity_check:
   cmd.wait:
     - name: python -c "import yaml; stream = file('/etc/salt/grains.d/{{ name }}', 'r'); yaml.load(stream); stream.close()"
-    - require:
-      - pkg: salt_minion_grains_pkg_validity_check
     - watch:
       - file: salt_minion_grain_{{ service_name }}_{{ name }}
     - watch_in:
diff --git a/salt/minion/service.sls b/salt/minion/service.sls
index eb50b80..5befc0c 100644
--- a/salt/minion/service.sls
+++ b/salt/minion/service.sls
@@ -31,11 +31,52 @@
     - service: salt_minion_service
   {%- endif %}
 
+{%- for service_name, service in pillar.items() %}
+    {%- set support_fragment_file = service_name+'/meta/salt.yml' %}
+    {%- macro load_support_file() %}{% include support_fragment_file ignore missing %}{% endmacro %}
+    {%- set support_yaml = load_support_file()|load_yaml %}
+
+    {%- if support_yaml and support_yaml.get('minion', {}) %}
+      {%- for name, conf in support_yaml.get('minion', {}).iteritems() %}
+salt_minion_config_{{ service_name }}_{{ name }}:
+  file.managed:
+    - name: /etc/salt/minion.d/_{{ name }}.conf
+    - contents: |
+        {{ conf|yaml(False)|indent(8) }}
+    {%- if not grains.get('noservices', False) %}
+    - watch_in:
+      - cmd: salt_minion_service_restart
+    {%- endif %}
+    - require:
+      - {{ minion.install_state }}
+
+salt_minion_config_{{ service_name }}_{{ name }}_validity_check:
+  cmd.wait:
+    - name: python -c "import yaml; stream = file('/etc/salt/minion.d/_{{ name }}.conf', 'r'); yaml.load(stream); stream.close()"
+    - watch:
+      - file: salt_minion_config_{{ service_name }}_{{ name }}
+        {%- if not grains.get('noservices', False) %}
+    - require_in:
+      - cmd: salt_minion_service_restart
+        {%- endif %}
+      {%- endfor %}
+    {%- endif %}
+{%- endfor %}
+
 {%- if not grains.get('noservices', False) %}
 salt_minion_service:
   service.running:
   - name: {{ minion.service }}
   - enable: true
+
+{#- Restart salt-minion if needed but after all states are executed #}
+salt_minion_service_restart:
+  cmd.wait:
+    - name: 'while true; do salt-call saltutil.running|grep fun: && continue; salt-call --local service.restart {{ minion.service }}; break; done'
+    - shell: /bin/bash
+    - bg: true
+    - require:
+      - service: salt_minion_service
 {%- endif %}
 
 salt_minion_sync_all: