Merge "Add Salt 2018.3 tests"
diff --git a/README.rst b/README.rst
index 0b5160f..de8b4a6 100644
--- a/README.rst
+++ b/README.rst
@@ -139,6 +139,30 @@
                 address: https://git.openstack.org/openstack/salt-formula-keystone
                 revision: refs/changes/56/123456/1
 
+Salt master logging configuration
+
+.. code-block:: yaml
+
+    salt:
+      master:
+        enabled: true
+        log:
+          level: warning
+          file: '/var/log/salt/master'
+          level_logfile: warning
+
+Salt minion logging configuration
+
+.. code-block:: yaml
+
+    salt:
+      minion:
+        enabled: true
+        log:
+          level: info
+          file: '/var/log/salt/minion'
+          level_logfile: warning
+
 Salt master with logging handlers
 
 .. code-block:: yaml
@@ -340,6 +364,67 @@
 
     salt-call event.send 'salt/key/remove'
 
+Control VM provisioning
+
+.. code-block:: yaml
+
+    virt:
+      disk:
+        three_disks:
+          - system:
+              size: 4096
+              image: ubuntu.qcow
+          - repository_snapshot:
+              size: 8192
+              image: snapshot.qcow
+          - cinder-volume:
+              size: 2048
+      nic:
+        control:
+        - name: nic01
+          bridge: br-pxe
+          model: virtio
+        - name: nic02
+          bridge: br-cp
+          model: virtio
+        - name: nic03
+          bridge: br-store-front
+          model: virtio
+        - name: nic04
+          bridge: br-public
+          model: virtio
+
+
+    salt:
+      control:
+        enabled: true
+        virt_enabled: true
+        size:
+          medium_three_disks:
+            cpu: 2
+            ram: 4
+            disk_profile: three_disks
+        cluster:
+          mycluster:
+            domain: neco.virt.domain.com
+            engine: virt
+            node:
+              ubuntu1:
+                provider: node01.domain.com
+                image: ubuntu.qcow
+                size: medium
+                img_dest: /var/lib/libvirt/ssdimages
+                rng:
+                  backend: /dev/urandom
+                  model: random
+                  rate:
+                    period: '1800'
+                    bytes: '1500'
+                mac:
+                  nic01: AC:DE:48:AA:AA:AA
+                  nic02: AC:DE:48:AA:AA:BB
+
+
 
 Jinja options
 -------------
diff --git a/_modules/virtng.py b/_modules/virtng.py
index 304a6bb..f9f93b9 100644
--- a/_modules/virtng.py
+++ b/_modules/virtng.py
@@ -550,6 +550,7 @@
          start=True,  # pylint: disable=redefined-outer-name
          disk='default',
          saltenv='base',
+         rng=None,
          **kwargs):
     '''
     Initialize a new vm
@@ -562,6 +563,7 @@
         salt 'hypervisor' virt.init vm_name 4 512 nic=profile disk=profile
     '''
 
+    rng = rng or {'backend':'/dev/urandom'}
     hypervisor = __salt__['config.get']('libvirt:hypervisor', hypervisor)
 
     nicp = _nic_profile(nic, hypervisor, **kwargs)
@@ -667,6 +669,28 @@
                                           .format(hypervisor))
 
     xml = _gen_xml(name, cpu, mem, diskp, nicp, hypervisor, **kwargs)
+
+    # TODO: Remove this code and refactor module, when salt-common would have updated libvirt_domain.jinja template
+    if rng:
+        rng_model = rng.get('model', 'random')
+        rng_backend = rng.get('backend', '/dev/urandom')
+        xml_doc = minidom.parseString(xml)
+        rng_xml = xml_doc.createElement("rng")
+        rng_xml.setAttribute("model", "virtio")
+        backend = xml_doc.createElement("backend")
+        backend.setAttribute("model", rng_model)
+        backend.appendChild(xml_doc.createTextNode(rng_backend))
+        rng_xml.appendChild(backend)
+        if 'rate' in rng:
+            rng_rate_period = rng['rate'].get('period', '2000')
+            rng_rate_bytes = rng['rate'].get('bytes', '1234')
+            rate = xml_doc.createElement("rate")
+            rate.setAttribute("period", rng_rate_period)
+            rate.setAttribute("bytes", rng_rate_bytes)
+            rng_xml.appendChild(rate)
+        xml_doc.getElementsByTagName("domain")[0].getElementsByTagName("devices")[0].appendChild(rng_xml)
+        xml = xml_doc.toxml()
+
     define_xml_str(xml)
 
     if start:
diff --git a/metadata.yml b/metadata.yml
index d75dea4..07d8f6f 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,8 +1,8 @@
 name: "salt"
 version: "0.4"
-source: "https://github.com/tcpcloud/salt-formula-salt"
+source: "https://github.com/salt-formulas/salt-formula-salt"
 dependencies:
 - name: git
-  source: "https://github.com/tcpcloud/salt-formula-git"
+  source: "https://github.com/salt-formulas/salt-formula-git"
 - name: reclass
-  source: "https://github.com/tcpcloud/salt-formula-reclass"
\ No newline at end of file
+  source: "https://github.com/salt-formulas/salt-formula-reclass"
\ No newline at end of file
diff --git a/salt/control/virt.sls b/salt/control/virt.sls
index 84d9c12..9177d20 100644
--- a/salt/control/virt.sls
+++ b/salt/control/virt.sls
@@ -41,6 +41,9 @@
   - start: True
   - disk: {{ size.disk_profile }}
   - nic: {{ size.net_profile }}
+  {%- if node.rng is defined %}
+  - rng: {{ node.rng }}
+  {%- endif %}
   - kwargs:
       seed: True
       serial_type: pty
@@ -48,6 +51,11 @@
       {%- if node.img_dest is defined %}
       img_dest: {{ node.img_dest }}
       {%- endif %}
+      {%- if node.mac is defined %}
+      {%- for mac_name, mac in node.mac.items() %}
+      {{ mac_name }}_mac: {{ mac }}
+      {%- endfor %}
+      {%- endif %}
   - unless: virsh list --all --name| grep -E "^{{ node_name }}.{{ cluster.domain }}$"
 
 #salt_control_seed_{{ cluster_name }}_{{ node_name }}:
diff --git a/salt/files/master.conf b/salt/files/master.conf
index 9f9b00a..bbfff60 100644
--- a/salt/files/master.conf
+++ b/salt/files/master.conf
@@ -151,6 +151,22 @@
   {%- endif %}
 {%- endif %}
 
+{%- if master.log is defined %}
+
+{%- if master.log.level is defined %}
+log_level: {{ master.log.level }}
+{%- endif %}
+
+{%- if master.log.file is defined %}
+log_file: {{ master.log.file }}
+{%- endif %}
+
+{%- if master.log.level_logfile is defined %}
+log_level_logfile: {{ master.log.level_logfile }}
+{%- endif %}
+
+{%- endif %}
+
 {%- if pillar.salt.get('minion') %}
 {%- for handler in pillar.salt.minion.get("handlers", []) %}
 {%- if handler.engine == "udp"%}
diff --git a/salt/files/minion.conf b/salt/files/minion.conf
index 12509e1..c3a8e68 100644
--- a/salt/files/minion.conf
+++ b/salt/files/minion.conf
@@ -66,10 +66,25 @@
 
 {%- endif %}
 
-log_level: {{ minion.log.get('level', 'error') }}
-state_output: {{ minion.log.get('state_output', 'changes') }}
+{%- if minion.log is defined %}
 
-{%- if minion.proxy is defined %}
+{%- if minion.log.level is defined %}
+log_level: {{ minion.log.level }}
+{%- endif %}
+
+{%- if minion.log.file is defined %}
+log_file: {{ minion.log.file }}
+{%- endif %}
+
+{%- if minion.log.level_logfile is defined %}
+log_level_logfile: {{ minion.log.level_logfile }}
+{%- endif %}
+
+{%- endif %}
+
+state_output: {{ minion.get('log', {}).get('state_output', 'changes') }}
+
+{%- if minion.get('proxy', {}).get('host', "") != "" %}
 proxy_host: {{ minion.proxy.host }}
 proxy_port: {{ minion.proxy.port }}
 {%- endif %}
diff --git a/salt/meta/prometheus.yml b/salt/meta/prometheus.yml
index 8575ac9..7fa7179 100644
--- a/salt/meta/prometheus.yml
+++ b/salt/meta/prometheus.yml
@@ -3,30 +3,30 @@
 server:
   alert:
   {%- if pillar.salt.get('master', {}).get('enabled', False)  %}
-    SaltMasterProcessDown:
+    {%- raw %}
+    SaltMasterServiceDown:
       if: >-
         procstat_running{process_name="salt-master"} == 0
-      {%- raw %}
       labels:
-        severity: warning
-        service: salt-master
+        severity: critical
+        service: salt
       annotations:
-        summary: 'Salt-master service is down'
-        description: 'Salt-master service is down on node {{ $labels.host }}'
-      {%- endraw %}
+        summary: "Salt-master service is down"
+        description: "The salt-master service on the {{ $labels.host }} node is down."
+    {%- endraw %}
   {%- endif %}
   {%- if pillar.salt.get('minion', {}).get('enabled', False)  %}
-    SaltMinionProcessDown:
+    {%- raw %}
+    SaltMinionServiceDown:
       if: >-
         procstat_running{process_name="salt-minion"} == 0
-      {%- raw %}
       labels:
-        severity: warning
-        service: salt-minion
+        severity: critical
+        service: salt
       annotations:
-        summary: 'Salt-minion service is down'
-        description: 'Salt-minion service is down on node {{ $labels.host }}'
-      {%- endraw %}
+        summary: "Salt-minion service is down"
+        description: "The salt-minion service on the {{ $labels.host }} node is down."
+    {%- endraw %}
   {%- endif %}
 {%- endif %}
 {%- endif %}
diff --git a/salt/minion/base.sls b/salt/minion/base.sls
new file mode 100644
index 0000000..62a1748
--- /dev/null
+++ b/salt/minion/base.sls
@@ -0,0 +1,88 @@
+{#- This state can be called explicitly. Do not include this file in minion.init #}
+{%- from "salt/map.jinja" import minion,renderer with context %}
+{%- if minion.enabled %}
+
+{%- if minion.source.get('engine', 'pkg') == 'pkg' %}
+
+salt_minion_packages:
+  pkg.installed:
+  - names: {{ minion.pkgs }}
+  {%- if minion.source.version is defined %}
+  - version: {{ minion.source.version }}
+  {%- endif %}
+
+salt_minion_dependency_packages:
+  pkg.installed:
+  - pkgs: {{ minion.dependency_pkgs }}
+
+{%- elif minion.source.get('engine', 'pkg') == 'pip' %}
+
+salt_minion_packages:
+  pip.installed:
+  - name: salt{% if minion.source.version is defined %}=={{ minion.source.version }}{% endif %}
+
+salt_minion_dependency_packages:
+  pkg.installed:
+  - pkgs: {{ minion.dependency_pkgs_pip }}
+
+{%- endif %}
+
+/etc/salt/minion.d/minion.conf:
+  file.managed:
+  - source: salt://salt/files/minion.conf
+  - user: root
+  - group: root
+  - template: jinja
+  - require:
+    - {{ minion.install_state }}
+
+{%- if renderer | length > 0 %}
+
+/etc/salt/minion.d/_renderer.conf:
+  file.managed:
+  - source: salt://salt/files/_renderer.conf
+  - user: root
+  - template: jinja
+  - require:
+    - {{ minion.install_state }}
+  - watch_in:
+    - service: salt_minion_service
+
+{%- endif %}
+
+salt_minion_service:
+  service.running:
+    - name: {{ minion.service }}
+    - enable: true
+    - require:
+      - pkg: salt_minion_packages
+      - pkg: salt_minion_dependency_packages
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+
+{#- Restart salt-minion if needed but after all states are executed #}
+salt_minion_service_restart:
+  cmd.run:
+    - 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
+    - order: last
+    - onchanges:
+      - file: /etc/salt/minion.d/minion.conf
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+    - require:
+      - service: salt_minion_service
+
+salt_minion_sync_all:
+  module.run:
+    - name: 'saltutil.sync_all'
+    - onchanges:
+      - service: salt_minion_service
+    - require:
+      - pkg: salt_minion_packages
+      - pkg: salt_minion_dependency_packages
+
+{%- endif %}
diff --git a/tests/pillar/control_virt_custom.sls b/tests/pillar/control_virt_custom.sls
index 7397494..6ca02ad 100644
--- a/tests/pillar/control_virt_custom.sls
+++ b/tests/pillar/control_virt_custom.sls
@@ -53,3 +53,9 @@
             provider: node03.domain.com
             image: meowbuntu.qcom2
             size: medium_three_disks
+            rng:
+              backend: /dev/urandom
+              model: random
+              rate:
+                period: '1800'
+                bytes: '1500'
diff --git a/tests/pillar/master_logging.sls b/tests/pillar/master_logging.sls
new file mode 100644
index 0000000..32e62ed
--- /dev/null
+++ b/tests/pillar/master_logging.sls
@@ -0,0 +1,24 @@
+git:
+  client:
+    enabled: true
+linux:
+  system:
+    enabled: true
+salt:
+  master:
+    command_timeout: 5
+    worker_threads: 2
+    enabled: true
+    source:
+      engine: pkg
+    pillar:
+      engine: salt
+      source:
+        engine: local
+    environment:
+      prd:
+        formula: {}
+    log:
+      level: warning
+      file: '/var/log/salt/master'
+      level_logfile: warning
diff --git a/tests/pillar/minion_logging.sls b/tests/pillar/minion_logging.sls
new file mode 100644
index 0000000..c5f678b
--- /dev/null
+++ b/tests/pillar/minion_logging.sls
@@ -0,0 +1,9 @@
+salt:
+  minion:
+    enabled: true
+    master:
+      host: config01.dc01.domain.com
+    log:
+      level: info
+      file: '/var/log/salt/minion'
+      level_logfile: warning