SaltStack - Architect integration
Change-Id: I96e16a3b203f9b3c9c150db1cb85e966bd14b573
diff --git a/README.rst b/README.rst
index 454f465..705efd4 100644
--- a/README.rst
+++ b/README.rst
@@ -28,6 +28,21 @@
.. literalinclude:: tests/pillar/master_single_reclass.sls
:language: yaml
+Salt master with Architect ENC metadata backend
+
+.. code-block:: yaml
+
+ salt:
+ master:
+ enabled: true
+ pillar:
+ engine: architect
+ project: project-name
+ host: architect-api
+ port: 8181
+ username: salt
+ password: password
+
Salt master with multiple ext_pillars
.. literalinclude:: tests/pillar/master_single_extpillars.sls
@@ -150,7 +165,6 @@
host: 127.0.0.1
port: 9999
-
Salt engine definition for saltgraph metadata collector
.. code-block:: yaml
@@ -166,6 +180,21 @@
password: salt
database: salt
+Salt engine definition for Architect service
+
+.. code-block:: yaml
+
+ salt:
+ master:
+ engine:
+ architect:
+ engine: architect
+ project: project-name
+ host: architect-api
+ port: 8181
+ username: salt
+ password: password
+
Salt engine definition for sending events from docker events
.. code-block:: yaml
diff --git a/_engines/architect.py b/_engines/architect.py
new file mode 100644
index 0000000..4096a73
--- /dev/null
+++ b/_engines/architect.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+"""
+Salt engine for intercepting state jobs and forwarding to the Architect
+service.
+"""
+
+# Import python libs
+from __future__ import absolute_import
+import json
+import logging
+
+# Import salt libs
+import salt.utils.event
+import salt.utils.http
+
+log = logging.getLogger(__name__)
+
+
+def start(project='default',
+ host='127.0.0.1',
+ port=8181,
+ username=None,
+ password=None):
+ '''
+ Listen to state jobs events and forward Salt states
+ '''
+ url = "{}://{}:{}/salt/{}/event/{}".format('http',
+ host,
+ port,
+ 'v1',
+ project)
+ target_functions = ['state.sls', 'state.apply', 'state.highstate']
+
+ if __opts__['__role'] == 'master':
+ event_bus = salt.utils.event.get_master_event(__opts__,
+ __opts__['sock_dir'],
+ listen=True)
+ else:
+ event_bus = salt.utils.event.get_event(
+ 'minion',
+ transport=__opts__['transport'],
+ opts=__opts__,
+ sock_dir=__opts__['sock_dir'],
+ listen=True)
+
+ log.info('Salt Architect engine initialised')
+
+ while True:
+ event = event_bus.get_event()
+ if event and event.get('fun', None) in target_functions:
+ is_test_run = 'test=true' in [arg.lower() for arg in event.get('fun_args', [])]
+ if not is_test_run:
+ data = salt.utils.http.query(url=url,
+ method='POST',
+ decode=False,
+ data=json.dumps(event))
+ if 'OK' in data.get('body', ''):
+ log.info("Architect Engine request to '{}'"
+ " was successful".format(url))
+ else:
+ log.warning("Problem with Architect Engine"
+ " request to '{}' ({})".format(url, data))
diff --git a/salt/files/architect.yml b/salt/files/architect.yml
new file mode 100644
index 0000000..dcba23f
--- /dev/null
+++ b/salt/files/architect.yml
@@ -0,0 +1,8 @@
+{% from "salt/map.jinja" import master with context %}
+project: {{ master.pillar.project }}
+host: {{ master.pillar.host }}
+port: {{ master.pillar.port }}
+{%- if master.pillar.username is defined %}
+username: {{ master.pillar.username }}
+password: {{ master.pillar.password }}
+{%- endif %}
diff --git a/salt/files/master.conf b/salt/files/master.conf
index 1802d82..ddbbf18 100644
--- a/salt/files/master.conf
+++ b/salt/files/master.conf
@@ -60,6 +60,14 @@
- {{ master.pillar.get('salt', {}).get('path', '/srv/salt/pillar') }}
{%- endif %}
+{%- if master.pillar.engine == 'architect' %}
+ext_pillar:
+ - cmd_yaml: 'architect-salt-pillar %s'
+
+master_tops:
+ ext_nodes: architect-salt-top
+{%- endif %}
+
{%- if master.pillar.engine == 'reclass' or (master.pillar.engine == 'composite' and master.pillar.reclass is defined) %}
reclass: &reclass
diff --git a/salt/master/pillar.sls b/salt/master/pillar.sls
index 806511d..709cc8c 100644
--- a/salt/master/pillar.sls
+++ b/salt/master/pillar.sls
@@ -31,6 +31,25 @@
{%- endif %}
+{%- elif master.pillar.engine == 'architect' %}
+
+salt_pillar_architect_package:
+ pip.installed:
+ - name: architect-client
+
+salt_pillar_architect_package_config_dir:
+ file.directory:
+ - name: /etc/architect
+
+salt_pillar_architect_package_config_file:
+ file.managed:
+ - name: /etc/architect/client.yml
+ - source: salt://salt/files/architect.yml
+ - user: root
+ - template: jinja
+ - require:
+ - file: salt_pillar_architect_package_config_dir
+
{%- elif master.pillar.engine == 'reclass' %}
include: