@@ -0,0 +1,14 @@ | |||
============ | |||
salt-formula | |||
============ | |||
0.0.2 | |||
----- | |||
- Graphing of salt minion states | |||
0.0.1 | |||
----- | |||
- Initial state for installing Salt master |
@@ -0,0 +1,13 @@ | |||
Copyright (c) 2014-2015 tcp cloud a.s. | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. |
@@ -0,0 +1,323 @@ | |||
==== | |||
Salt | |||
==== | |||
Salt is a new approach to infrastructure management. Easy enough to get running in minutes, scalable enough to manage tens of thousands of servers, and fast enough to communicate with them in seconds. | |||
Salt delivers a dynamic communication bus for infrastructures that can be used for orchestration, remote execution, configuration management and much more. | |||
Sample pillars | |||
============== | |||
Salt master | |||
----------- | |||
Salt master with base environment and pillar metadata source | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
command_timeout: 5 | |||
worker_threads: 2 | |||
pillar: | |||
engine: salt | |||
source: | |||
engine: git | |||
address: 'git@repo.domain.com:salt/pillar-demo.git' | |||
branch: 'master' | |||
base_environment: prd | |||
environment: | |||
prd: | |||
enabled: true | |||
formula: | |||
linux: | |||
source: git | |||
address: 'git@repo.domain.com:salt/formula-linux.git' | |||
branch: 'master' | |||
salt: | |||
source: git | |||
address: 'git@repo.domain.com:salt/formula-salt.git' | |||
branch: 'master' | |||
openssh: | |||
source: git | |||
address: 'git@repo.domain.com:salt/formula-openssh.git' | |||
branch: 'master' | |||
Simple Salt master with base environment and custom states | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
... | |||
environment: | |||
base: | |||
states: | |||
- name: gitlab | |||
source: git | |||
address: 'git@repo.domain.cz:salt/state-gitlab.git' | |||
branch: 'master' | |||
formulas: | |||
... | |||
Salt master with reclass ENC | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
... | |||
pillar: | |||
engine: reclass | |||
data_dir: /srv/salt/reclass | |||
Salt master with windows repository | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
... | |||
windows_repo: | |||
type: git | |||
address: 'git@repo.domain.com:salt/win-packages.git' | |||
Salt master with API | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
... | |||
api: | |||
enabled: true | |||
port: 8000 | |||
Salt master with preset minions | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
... | |||
minions: | |||
- name: 'node1.system.location.domain.com' | |||
Salt master syndicate master of masters | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
... | |||
syndic: | |||
mode: master | |||
Salt master syndicate (client) master | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
... | |||
syndicate: | |||
mode: client | |||
host: master-master | |||
Salt master with custom handlers | |||
.. code-block:: yaml | |||
salt: | |||
master: | |||
enabled: true | |||
command_timeout: 5 | |||
worker_threads: 2 | |||
environments: | |||
- name: base | |||
states: | |||
- source: git | |||
address: 'git@repo.domain.com:salt/state-ubuntu.git' | |||
branch: 'master' | |||
pillar: | |||
source: git | |||
address: 'git@repo.domain.com:salt/pillar-demo.git' | |||
branch: 'master' | |||
handlers: | |||
name: logstash | |||
type: udp | |||
bind: | |||
host: 127.0.0.1 | |||
port: 9999 | |||
minion: | |||
handlers: | |||
- engine: udp | |||
bind: | |||
host: 127.0.0.1 | |||
port: 9999 | |||
- engine: zmq | |||
bind: | |||
host: 127.0.0.1 | |||
port: 9999 | |||
Salt minion | |||
----------- | |||
Simplest Salt minion | |||
.. code-block:: yaml | |||
salt: | |||
minion: | |||
enabled: true | |||
master: | |||
host: master.domain.com | |||
Multi-master Salt minion | |||
.. code-block:: yaml | |||
salt: | |||
minion: | |||
enabled: true | |||
masters: | |||
- host: master1.domain.com | |||
- host: master2.domain.com | |||
Salt minion with salt mine options | |||
salt: | |||
minion: | |||
enabled: true | |||
master: | |||
host: master.domain.com | |||
mine: | |||
interval: 60 | |||
module: | |||
grains.items: [] | |||
network.interfaces: [] | |||
Salt minion with graphing dependencies | |||
.. code-block:: yaml | |||
salt: | |||
minion: | |||
enabled: true | |||
graph_states: true | |||
master: | |||
host: master.domain.com | |||
Salt control (cloud/virt) | |||
------------------------- | |||
Salt cloud with local OpenStack insecure (ignoring SSL cert errors) provider | |||
.. code-block:: yaml | |||
salt: | |||
control: | |||
enabled: true | |||
provider: | |||
openstack_account: | |||
engine: openstack | |||
insecure: true | |||
region: RegionOne | |||
identity_url: 'https://10.0.0.2:35357' | |||
tenant: devops | |||
user: user | |||
password: 'password' | |||
fixed_networks: | |||
- 123d3332-18be-4d1d-8d4d-5f5a54456554e | |||
floating_networks: | |||
- public | |||
ignore_cidr: 192.168.0.0/16 | |||
Salt cloud with Digital Ocean provider | |||
.. code-block:: yaml | |||
salt: | |||
control: | |||
enabled: true | |||
provider: | |||
dony1: | |||
engine: digital_ocean | |||
region: New York 1 | |||
client_key: xxxxxxx | |||
api_key: xxxxxxx | |||
Salt cloud with cluster definition | |||
.. code-block:: yaml | |||
salt: | |||
control: | |||
enabled: true | |||
cluster: | |||
devops_ase: | |||
config: | |||
engine: salt | |||
host: 147.32.120.1 | |||
node: | |||
proxy1.ase.cepsos.cz: | |||
provider: cepsos_devops | |||
image: Ubuntu12.04 x86_64 | |||
size: m1.medium | |||
node1.ase.cepsos.cz: | |||
provider: cepsos_devops | |||
image: Ubuntu12.04 x86_64 | |||
size: m1.medium | |||
node2.ase.cepsos.cz: | |||
provider: cepsos_devops | |||
image: Ubuntu12.04 x86_64 | |||
size: m1.medium | |||
node3.ase.cepsos.cz: | |||
provider: cepsos_devops | |||
image: Ubuntu12.04 x86_64 | |||
size: m1.medium | |||
Usage | |||
===== | |||
Working with salt-cloud | |||
.. code-block:: bash | |||
salt-cloud -m /path/to/map --assume-yes | |||
Debug LIBCLOUD for salt-cloud connection | |||
.. code-block:: bash | |||
export LIBCLOUD_DEBUG=/dev/stderr; salt-cloud --list-sizes provider_name --log-level all | |||
Read more | |||
========= | |||
* http://salt.readthedocs.org/en/latest/ | |||
* https://github.com/DanielBryan/salt-state-graph | |||
* http://karlgrz.com/testing-salt-states-rapidly-with-docker/ | |||
* https://mywushublog.com/2013/03/configuration-management-with-salt-stack/ | |||
* http://russell.ballestrini.net/replace-the-nagios-scheduler-and-nrpe-with-salt-stack/ | |||
* https://github.com/saltstack-formulas/salt-formula | |||
* http://docs.saltstack.com/en/latest/topics/tutorials/multimaster.html | |||
salt-cloud | |||
---------- | |||
* http://www.blog.sandro-mathys.ch/2013/07/setting-user-password-when-launching.html | |||
* http://cloudinit.readthedocs.org/en/latest/topics/examples.html | |||
* http://salt-cloud.readthedocs.org/en/latest/topics/install/index.html | |||
* http://docs.saltstack.com/topics/cloud/digitalocean.html | |||
* http://salt-cloud.readthedocs.org/en/latest/topics/rackspace.html | |||
* http://salt-cloud.readthedocs.org/en/latest/topics/map.html | |||
* http://docs.saltstack.com/en/latest/topics/tutorials/multimaster.html |
@@ -0,0 +1 @@ | |||
0.2 |
@@ -0,0 +1,11 @@ | |||
salt-formula-salt (0.2) trusty; urgency=medium | |||
* First public release | |||
-- Filip Pytloun <filip.pytloun@tcpcloud.eu> Tue, 06 Oct 2015 16:38:53 +0200 | |||
salt-formula-salt (0.1) trusty; urgency=medium | |||
* Initial release | |||
-- Ales Komarek <ales.komarek@tcpcloud.eu> Thu, 13 Aug 2015 23:23:41 +0200 |
@@ -0,0 +1 @@ | |||
9 |
@@ -0,0 +1,15 @@ | |||
Source: salt-formula-salt | |||
Maintainer: Ales Komarek <ales.komarek@tcpcloud.eu> | |||
Section: admin | |||
Priority: optional | |||
Build-Depends: debhelper (>= 9) | |||
Standards-Version: 3.9.6 | |||
Homepage: http://www.tcpcloud.eu | |||
Vcs-Browser: https://github.com/tcpcloud/salt-formula-salt | |||
Vcs-Git: https://github.com/tcpcloud/salt-formula-salt.git | |||
Package: salt-formula-salt | |||
Architecture: all | |||
Depends: ${misc:Depends}, salt-master, reclass | |||
Description: Salt salt formula | |||
Install and configure Salt masters and minions. |
@@ -0,0 +1,15 @@ | |||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |||
Upstream-Name: salt-formula-salt | |||
Upstream-Contact: Ales Komarek <ales.komarek@tcpcloud.eu> | |||
Source: https://github.com/tcpcloud/salt-formula-salt | |||
Files: * | |||
Copyright: 2014-2015 tcp cloud a.s. | |||
License: Apache-2.0 | |||
Copyright (C) 2014-2015 tcp cloud a.s. | |||
. | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
. | |||
On a Debian system you can find a copy of this license in | |||
/usr/share/common-licenses/Apache-2.0. |
@@ -0,0 +1,3 @@ | |||
README.rst | |||
CHANGELOG.rst | |||
VERSION |
@@ -0,0 +1,2 @@ | |||
salt/* /usr/share/salt-formulas/env/salt/ | |||
metadata/service/* /usr/share/salt-formulas/reclass/service/salt/ |
@@ -0,0 +1,5 @@ | |||
#!/usr/bin/make -f | |||
%: | |||
dh $@ | |||
@@ -0,0 +1 @@ | |||
3.0 (native) |
@@ -0,0 +1,10 @@ | |||
applications: | |||
- salt | |||
- git | |||
- openssh | |||
parameters: | |||
salt: | |||
master: | |||
enabled: true | |||
command_timeout: 5 | |||
worker_threads: 2 |
@@ -0,0 +1,13 @@ | |||
applications: | |||
- salt | |||
- git | |||
- openssh | |||
parameters: | |||
_param: | |||
salt_master_base_environment: dev | |||
salt: | |||
master: | |||
enabled: true | |||
command_timeout: 5 | |||
worker_threads: 2 | |||
base_environment: ${_param:salt_master_base_environment} |
@@ -0,0 +1,13 @@ | |||
applications: | |||
- salt | |||
parameters: | |||
salt: | |||
minion: | |||
enabled: true | |||
master: | |||
host: ${_param:salt_master_host} | |||
mine: | |||
interval: 60 | |||
module: | |||
grains.items: [] | |||
network.interfaces: [] |
@@ -0,0 +1,10 @@ | |||
applications: | |||
- salt | |||
parameters: | |||
salt: | |||
minion: | |||
enabled: true | |||
local: true | |||
pillar: | |||
engine: reclass | |||
data_dir: /srv/salt/reclass |
@@ -0,0 +1,13 @@ | |||
applications: | |||
- salt | |||
parameters: | |||
salt: | |||
minion: | |||
enabled: true | |||
master: | |||
host: ${_param:salt_master_host} | |||
mine: | |||
interval: 60 | |||
module: | |||
grains.items: [] | |||
network.interfaces: [] |
@@ -0,0 +1,21 @@ | |||
{%- from "salt/map.jinja" import api with context %} | |||
{%- if api.enabled %} | |||
include: | |||
- salt.master | |||
salt_api_packages: | |||
pkg.installed | |||
- names: {{ api.pkgs }} | |||
- require: | |||
- pkg: salt_master_packages | |||
salt_api_service: | |||
service.running: | |||
- name: salt-api | |||
- require: | |||
- pkg: salt_api_packages | |||
- watch: | |||
- file: /etc/salt/master | |||
{%- endif %} |
@@ -0,0 +1,47 @@ | |||
{% from "salt/map.jinja" import control with context %} | |||
{%- if control.enabled %} | |||
/srv/salt/cloud/maps: | |||
file.directory: | |||
- makedirs: true | |||
/srv/salt/cloud/userdata: | |||
file.directory: | |||
- makedirs: true | |||
{%- for cluster_name, cluster in control.cluster.iteritems() %} | |||
/srv/salt/cloud/maps/{{ cluster_name }}: | |||
file.managed: | |||
- source: salt://salt/files/map | |||
- user: root | |||
- group: root | |||
- template: jinja | |||
- require: | |||
- file: /srv/salt/cloud/maps | |||
- defaults: | |||
cluster_name: "{{ cluster_name }}" | |||
/srv/salt/cloud/userdata/{{ cluster_name }}: | |||
file.directory: | |||
- makedirs: true | |||
{%- for node_name, node in cluster.node.iteritems() %} | |||
/srv/salt/cloud/userdata/{{cluster_name }}/{{ node_name }}.conf: | |||
file.managed: | |||
- source: salt://salt/files/userdata | |||
- user: root | |||
- group: root | |||
- template: jinja | |||
- require: | |||
- file: /srv/salt/cloud/userdata/{{ cluster_name }} | |||
- defaults: | |||
cluster_name: "{{ cluster_name }}" | |||
node_name: "{{ node_name }}" | |||
{%- endfor %} | |||
{%- endfor %} | |||
{%- endif %} |
@@ -0,0 +1,4 @@ | |||
include: | |||
- salt.control.service | |||
- salt.control.provider | |||
- salt.control.cluster |
@@ -0,0 +1,18 @@ | |||
{% from "salt/map.jinja" import control with context %} | |||
{%- if control.enabled %} | |||
/etc/salt/cloud.providers: | |||
file.managed: | |||
- source: salt://salt/files/providers.conf | |||
- user: root | |||
- group: root | |||
- template: jinja | |||
/etc/salt/cloud.profiles: | |||
file.managed: | |||
- source: salt://salt/files/profiles.conf | |||
- user: root | |||
- group: root | |||
- template: jinja | |||
{%- endif %} |
@@ -0,0 +1,26 @@ | |||
{% from "salt/map.jinja" import control with context %} | |||
{%- if control.enabled %} | |||
{%- if control.pkgs is defined and control.pkgs|length > 0 %} | |||
salt_control_packages: | |||
pkg.installed: | |||
- names: {{ control.pkgs }} | |||
{%- else %} | |||
{# No system packages defined, install with pip #} | |||
salt_control_packages: | |||
pkg.installed: | |||
- name: python-pip | |||
{%- for package in control.python_pkgs %} | |||
{{ package }}: | |||
pip.installed: | |||
- require: | |||
- pkg: salt_control_packages | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,8 @@ | |||
{%- from "salt/map.jinja" import control with context %} | |||
{%- set cluster = salt['pillar.get']('salt:control:cluster:'+cluster_name) %} | |||
{%- for node_name, node in cluster.node.iteritems() %} | |||
{{ node_name }}.{{ cluster.domain }}: | |||
- {{ node_name }}.{{ cluster.domain }} | |||
{%- endfor %} |
@@ -0,0 +1,120 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- from "linux/map.jinja" import system with context %} | |||
worker_threads: {{ master.worker_threads }} | |||
timeout: {{ master.command_timeout }} | |||
{%- if master.system is defined %} | |||
file_roots: | |||
base: | |||
- /srv/salt/env/{{ master.system.environment }} | |||
{%- for formula_name, formula in master.system.get('formula', {}).iteritems() %} | |||
- /srv/salt/env/{{ master.system.environment }}/{{ formula_name }} | |||
{%- endfor %} | |||
{{ master.system.environment }}: | |||
- /srv/salt/env/{{ master.system.environment }} | |||
{%- for formula_name, formula in master.system.get('formula', {}).iteritems() %} | |||
- /srv/salt/env/{{ master.system.environment }}/{{ formula_name }} | |||
{%- endfor %} | |||
{%- else %} | |||
file_roots: | |||
{%- for environment_name, environment in master.get('environment', {}).iteritems() %} | |||
{%- if master.base_environment == environment_name %} | |||
base: | |||
- /srv/salt/env/{{ environment_name }} | |||
{%- endif %} | |||
{{ environment_name }}: | |||
- /srv/salt/env/{{ environment_name }} | |||
{%- endfor %} | |||
{%- endif %} | |||
pillar_opts: False | |||
{%- if master.accept_policy == 'open_mode' %} | |||
open_mode: True | |||
{%- endif %} | |||
{%- if master.accept_policy == 'auto_accept' %} | |||
auto_accept: True | |||
{%- endif %} | |||
{%- if master.pillar.engine == 'salt' %} | |||
pillar_roots: | |||
base: | |||
- /srv/salt/pillar | |||
{%- endif %} | |||
{%- if master.pillar.engine == 'reclass' %} | |||
reclass: &reclass | |||
storage_type: yaml_fs | |||
inventory_base_uri: /srv/salt/reclass | |||
ext_pillar: | |||
- reclass: *reclass | |||
master_tops: | |||
reclass: *reclass | |||
{%- endif %} | |||
{%- if master.acl is defined %} | |||
client_acl: | |||
{%- for acl in master.acl %} | |||
{{ acl.name }}: | |||
{%- for right in acl.rights %} | |||
- {{ right }} | |||
{%- endfor %} | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- if master.bind.api is defined %} | |||
rest_cherrypy: | |||
port: {{ master.api.port }} | |||
ssl_crt: /etc/ssl/certs/{{ system.name }}.{{ system.domain }}.crt | |||
ssl_key: /etc/ssl/private/{{ system.name }}.{{ system.domain }}.key | |||
{%- if pillar.halite is defined %} | |||
static: /srv/halite/halite | |||
app: /srv/halite/halite/index.html | |||
{%- endif %} | |||
debug: True | |||
{%- endif %} | |||
{%- for handler in pillar.salt.minion.get("handlers", []) %} | |||
{%- if handler.engine == "udp"%} | |||
logstash_udp_handler: | |||
host: {{ handler.host }} | |||
port: {{ handler.port }} | |||
version: 1 | |||
{%- endif %} | |||
{%- if handler.engine == "zmq"%} | |||
logstash_zmq_handler: | |||
address: tcp://{{ handler.host }}:{{ handler.port }} | |||
version: 1 | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- if master.syndic is defined %} | |||
{% if master.syndic.mode == 'master' %} | |||
order_masters: True | |||
{%- endif %} | |||
{% if master.syndic.mode == 'client' %} | |||
syndic_master: {{ master.syndic.host }} | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,143 @@ | |||
{%- from "salt/map.jinja" import minion with context %} | |||
{%- from "linux/map.jinja" import system with context %} | |||
{%- if minion.masters is defined %} | |||
master: | |||
{%- for master in minion.masters %} | |||
- {{ master.host }} | |||
{%- endfor %} | |||
{%- else %} | |||
master: {{ minion.master.host }} | |||
{%- endif %} | |||
id: {{ system.name }}.{{ system.domain }} | |||
grains: | |||
{%- if minion.get('manage_roles', True) %} | |||
roles: | |||
{%- for key, value in pillar.items() %} | |||
{%- if key != 'master' and key != 'system' and key != 'public_keys' and key != 'private_keys' and key != 'known_hosts' and key != '__reclass__' and key != '_secret' %} | |||
{%- for subkey, subvalue in value.iteritems() %} | |||
{%- if subvalue.enabled is defined %} | |||
{%- if subvalue.enabled %} | |||
- {{key}}.{{ subkey }} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endif %} | |||
services: | |||
{%- for key in pillar.__reclass__.applications %} | |||
- {{key}} | |||
{%- endfor %} | |||
grains_dirs: | |||
- /var/lib/salt/grains | |||
{%- if minion.mine is defined %} | |||
mine_functions: | |||
{%- for salt_module, salt_functions in minion.mine.module.iteritems() %} | |||
{{ salt_module }}: {{ salt_functions }} | |||
{%- endfor %} | |||
mine_interval: {{ minion.mine.get('interval', 30) }} | |||
{%- endif %} | |||
{%- if minion.sentry is defined %} | |||
sentry_handler: | |||
{% for server in minion.sentry.servers %} | |||
servers: | |||
- {{ server }} | |||
{% endfor %} | |||
project: {{ pillar.salt.minion.sentry.project }} | |||
public_key: {{ pillar.salt.minion.sentry.public_key }} | |||
secret_key: {{ pillar.salt.minion.sentry.secret_key }} | |||
{% if pillar.salt.minion.sentry.log_level is defined %} | |||
log_level: {{ pillar.salt.minion.sentry.log_level }} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- if pillar.get('mysql', {}).server is defined %} | |||
mysql.unix_socket: /var/run/mysqld/mysqld.sock | |||
{%- if pillar.mysql.server.admin is defined %} | |||
mysql.user: '{{ pillar.mysql.server.admin.user }}' | |||
mysql.pass: '{{ pillar.mysql.server.admin.password }}' | |||
{%- else %} | |||
mysql.user: 'root' | |||
mysql.pass: '' | |||
{%- endif %} | |||
mysql.db: 'mysql' | |||
mysql.charset: 'utf8' | |||
{%- endif %} | |||
{%- if pillar.get('galera', {}).master is defined %} | |||
mysql.unix_socket: /var/run/mysqld/mysqld.sock | |||
mysql.user: '{{ pillar.galera.master.admin.user }}' | |||
mysql.pass: '{{ pillar.galera.master.admin.password }}' | |||
mysql.db: 'mysql' | |||
mysql.charset: 'utf8' | |||
{%- endif %} | |||
{%- if pillar.get('mongodb', {}).server is defined %} | |||
mongodb.host: 'localhost' | |||
mongodb.port: {{ pillar.mongodb.server.bind.port }} | |||
mongodb.user: '{{ pillar.mongodb.server.admin.user }}' | |||
mongodb.password: '{{ pillar.mongodb.server.admin.password }}' | |||
{%- endif %} | |||
{%- if pillar.get('galera', {}).slave is defined %} | |||
mysql.unix_socket: /var/run/mysqld/mysqld.sock | |||
mysql.user: '{{ pillar.galera.slave.admin.user }}' | |||
mysql.pass: '{{ pillar.galera.slave.admin.password }}' | |||
mysql.db: 'mysql' | |||
mysql.charset: 'utf8' | |||
{%- endif %} | |||
{%- if pillar.get('postgresql', {}).server is defined %} | |||
postgres.user: 'postgres' | |||
postgres.pass: '' | |||
postgres.db: 'template1' | |||
{%- endif %} | |||
{%- if pillar.get('gitlab', {}).client is defined %} | |||
gitlab.url: 'https://{{ pillar.gitlab.client.server.host }}/' | |||
gitlab.token: '{{ pillar.gitlab.client.server.token }}' | |||
{%- elif pillar.get('gitlab', {}).server is defined %} | |||
gitlab.url: 'https://{{ pillar.gitlab.server.server_name }}/' | |||
gitlab.token: '{{ pillar.gitlab.server.token }}' | |||
{%- endif %} | |||
{%- if pillar.get('keystone', {}).get('server', {'enabled': False } ).enabled %} | |||
keystone.token: '{{ pillar.keystone.server.service_token }}' | |||
keystone.endpoint: 'http://{{ pillar.keystone.server.bind.private_address }}:{{ pillar.keystone.server.bind.private_port }}/v2.0' | |||
{%- elif pillar.get('keystone', {}).get('client', {'enabled': False } ).enabled %} | |||
{%- if pillar.keystone.client.server.service_token is defined %} | |||
keystone.token: '{{ pillar.keystone.client.server.service_token }}' | |||
keystone.endpoint: 'http://{{ pillar.keystone.client.server.host }}:{{ pillar.keystone.client.server.private_port }}/v2.0' | |||
{%- else %} | |||
keystone.user: '{{ pillar.keystone.client.server.user }}' | |||
keystone.password: '{{ pillar.keystone.client.server.password }}' | |||
keystone.tenant: '{{ pillar.keystone.client.server.tenant }}' | |||
keystone.auth_url: 'http://{{ pillar.keystone.client.server.host }}:{{ pillar.keystone.client.server.public_port }}/v2.0/' | |||
{%- endif %} | |||
{%- endif %} | |||
{%- for handler in pillar.salt.minion.get("handlers", []) %} | |||
{%- if handler.engine == "udp"%} | |||
logstash_udp_handler: | |||
host: {{ handler.host }} | |||
port: {{ handler.port }} | |||
version: 1 | |||
{%- endif %} | |||
{%- if handler.engine == "zmq"%} | |||
logstash_zmq_handler: | |||
address: tcp://{{ handler.host }}:{{ handler.port }} | |||
version: 1 | |||
{%- endif %} | |||
{%- endfor %} |
@@ -0,0 +1,25 @@ | |||
{% from "salt/map.jinja" import control with context %} | |||
{%- for cluster_name, cluster in control.cluster.iteritems() %} | |||
{%- for node_name, node in cluster.node.iteritems() %} | |||
{{ node_name }}.{{ cluster.domain }}: | |||
provider: {{ node.provider }} | |||
image: {{ node.image }} | |||
size: {{ node.size }} | |||
minion: | |||
master: {{ cluster.config.host }} | |||
id: {{ node_name }}.{{ cluster.domain }} | |||
{%- if node.userdata is defined %} | |||
userdata_file: /srv/salt/cloud/userdata/{{ cluster_name }}/{{ node_name }}.conf | |||
{%- endif %} | |||
{%- if 'ubuntu' in node.image|lower %} | |||
ssh_username: ubuntu | |||
{%- elif 'centos' in node.image|lower %} | |||
ssh_username: cloud-user | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endfor %} |
@@ -0,0 +1,43 @@ | |||
{% from "salt/map.jinja" import control with context %} | |||
{%- for provider_name, provider in control.provider.iteritems() %} | |||
{{ provider_name }}: | |||
provider: {{ provider.engine }} | |||
{%- if provider.insecure is defined %} | |||
insecure: true | |||
{%- endif %} | |||
{%- if provider.engine == 'openstack' %} | |||
identity_url: '{{ provider.identity_url }}' | |||
{%- if provider.compute_name is defined %} | |||
compute_name: {{ provider.get('compute_name', 'nova') }} | |||
{%- endif %} | |||
protocol: ipv4 | |||
compute_region: {{ provider.region }} | |||
tenant: {{ provider.tenant }} | |||
user: {{ provider.user }} | |||
{%- if provider.api_key is defined %} | |||
apikey: {{ provider.api_key }} | |||
{%- elif provider.password is defined %} | |||
password: {{ provider.password }} | |||
{%- endif %} | |||
ssh_key_name: salt-cloud | |||
ssh_key_file: /root/.ssh/id_rsa | |||
ssh_interface: {{ provider.get('interface', 'private') }}_ips | |||
networks: | |||
- fixed: | |||
{%- for net in provider.fixed_networks %} | |||
- {{ net }} | |||
{%- endfor %} | |||
- floating: | |||
{%- for net in provider.floating_networks %} | |||
- {{ net }} | |||
{%- endfor %} | |||
{%- if provider.ignore_cidr is defined %} | |||
ignore_cidr: {{ provider.ignore_cidr }} | |||
{%- endif %} | |||
{%- elif provider.engine == 'digital_ocean' %} | |||
{#- location: {{ provider.region }} #} | |||
personal_access_token: {{ provider.api_key }} | |||
{%- endif %} | |||
{%- endfor %} |
@@ -0,0 +1,35 @@ | |||
#!/usr/bin/env python | |||
import cherrypy | |||
import sys | |||
sys.path.append('/srv/salt-api') | |||
from saltapi.netapi.rest_cherrypy import app | |||
def bootstrap_app(): | |||
''' | |||
Grab the opts dict of the master config by trying to import Salt | |||
''' | |||
import salt.client | |||
opts = salt.client.LocalClient().opts | |||
return app.get_app(opts) | |||
def get_application(*args): | |||
''' | |||
Returns a WSGI application function. If you supply the WSGI app and config | |||
it will use that, otherwise it will try to obtain them from a local Salt | |||
installation | |||
''' | |||
opts_tuple = args | |||
def wsgi_app(environ, start_response): | |||
root, _, conf = opts_tuple or bootstrap_app() | |||
cherrypy.tree.mount(root, '/', conf) | |||
return cherrypy.tree(environ, start_response) | |||
return wsgi_app | |||
application = get_application() |
@@ -0,0 +1,115 @@ | |||
#!/usr/bin/env python | |||
""" | |||
salt-state-graph | |||
A tool that ingests the YAML representing the Salt highstate (or sls state) for | |||
a single minion and produces a program written in DOT. | |||
The tool is useful for visualising the dependency graph of a Salt highstate. | |||
""" | |||
from pydot import Dot, Node, Edge | |||
import yaml | |||
import sys | |||
def find(obj, find_key): | |||
""" | |||
Takes a list and a set. Returns a list of all matching objects. | |||
Uses find_inner to recursively traverse the data structure, finding objects | |||
with keyed by find_key. | |||
""" | |||
all_matches = [find_inner(item, find_key) for item in obj] | |||
final = [item for sublist in all_matches for item in sublist] | |||
return final | |||
def find_inner(obj, find_key): | |||
""" | |||
Recursively search through the data structure to find objects | |||
keyed by find_key. | |||
""" | |||
results = [] | |||
if not hasattr(obj, '__iter__'): | |||
# not a sequence type - return nothing | |||
# this excludes strings | |||
return results | |||
if isinstance(obj, dict): | |||
# a dict - check each key | |||
for key, prop in obj.iteritems(): | |||
if key == find_key: | |||
results.extend(prop) | |||
else: | |||
results.extend(find_inner(prop, find_key)) | |||
else: | |||
# a list / tuple - check each item | |||
for i in obj: | |||
results.extend(find_inner(i, find_key)) | |||
return results | |||
def make_node_name(state_type, state_label): | |||
return "{0} - {1}".format(state_type.upper(), state_label) | |||
def find_edges(states, relname): | |||
""" | |||
Use find() to recursively find objects at keys matching | |||
relname, yielding a node name for every result. | |||
""" | |||
try: | |||
deps = find(states, relname) | |||
for dep in deps: | |||
for dep_type, dep_name in dep.iteritems(): | |||
yield make_node_name(dep_type, dep_name) | |||
except AttributeError as e: | |||
sys.stderr.write("Bad state: {0}\n".format(str(states))) | |||
raise e | |||
def main(input): | |||
state_obj = yaml.load(input) | |||
graph = Dot("states", graph_type='digraph') | |||
rules = { | |||
'require': {'color': 'blue'}, | |||
'require_in': {'color': 'blue', 'reverse': True}, | |||
'watch': {'color': 'red'}, | |||
'watch_in': {'color': 'red', 'reverse': True}, | |||
} | |||
for top_key, props in state_obj.iteritems(): | |||
# Add a node for each state type embedded in this state | |||
# keys starting with underscores are not candidates | |||
if top_key == '__extend__': | |||
# TODO - merge these into the main states and remove them | |||
sys.stderr.write( | |||
"Removing __extend__ states:\n{0}\n".format(str(props))) | |||
continue | |||
for top_key_type, states in props.iteritems(): | |||
if top_key_type[:2] == '__': | |||
continue | |||
node_name = make_node_name(top_key_type, top_key) | |||
graph.add_node(Node(node_name)) | |||
for edge_type, ruleset in rules.iteritems(): | |||
for relname in find_edges(states, edge_type): | |||
if 'reverse' in ruleset and ruleset['reverse']: | |||
graph.add_edge(Edge( | |||
node_name, relname, color=ruleset['color'])) | |||
else: | |||
graph.add_edge(Edge( | |||
relname, node_name, color=ruleset['color'])) | |||
graph.write('/dev/stdout') | |||
if __name__ == '__main__': | |||
main(sys.stdin) |
@@ -0,0 +1,6 @@ | |||
#!/bin/bash | |||
salt-call state.show_highstate --out yaml > ./highstate | |||
python salt-state-graph.py < ./highstate > ./highstate.dot | |||
dot -Tpng < ./highstate.dot -o ./highstate.png | |||
dot -Tsvg < ./highstate.dot -o ./highstate.svg |
@@ -0,0 +1,13 @@ | |||
-----BEGIN PGP PUBLIC KEY BLOCK----- | |||
Version: SKS 1.1.4 | |||
Comment: Hostname: keyserver.ubuntu.com | |||
mI0ETs4aowEEALDRpPyebQ5JlJNmleRzZYzxO4Ia8hpCSHzLm6DaMvXcFesfP4OTN0J9JjAv | |||
xbRxw8ROBz4SZ4iPhzPOZlXHBaI/5BF8Cc8CFW/HDqhPNH3qdOC9Te2q0QZgzd7WS94GXgzK | |||
nKCi1bmZ5pCvoJEvu3XK24/jmfLijp/1iO46xuofABEBAAG0HExhdW5jaHBhZCBQUEEgZm9y | |||
IFNhbHQgU3RhY2uIuAQTAQIAIgUCTs4aowIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA | |||
CgkQR1n6lg4nwKYQMwP9FQpta7rMNj2kgIvv3pXOr4z+Rgp3Vd8NmoHlIt6ZyigiisGfuht9 | |||
0PyvBLlJxpqGZt7bdz5QzV3HYSkk1K/L6CzpAgC/o/LPiir/Xi4ur/tgmRp30ONGPrLvSyRk | |||
dv1pIkMqEekOSdTgjyvRq7+rYpqh5obYFJPoxSqDYOND9lo= | |||
=woTM | |||
-----END PGP PUBLIC KEY BLOCK----- |
@@ -0,0 +1,12 @@ | |||
local_salt_master_proc: | |||
command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_procs -C salt-master -u root -c 1:10" | |||
interval: 60 | |||
occurrences: 1 | |||
subscribers: | |||
- local-salt-master | |||
local_salt_minion_proc: | |||
command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_procs -C salt-minion -u root -c 1:10" | |||
interval: 60 | |||
occurrences: 1 | |||
subscribers: | |||
- local-salt-minion |
@@ -0,0 +1,9 @@ | |||
{%- from "salt/map.jinja" import config with context %} | |||
{%- set cluster = salt['pillar.get']('salt:control:cluster:'+cluster_name) %} | |||
{%- set node = salt['pillar.get']('salt:control:cluster:'+cluster_name+':node:'+node_name) %} | |||
#!/bin/bash | |||
curl --insecure -L http://bootstrap.saltstack.org -o install_salt.sh | |||
sh install_salt.sh | |||
echo "id: {{ node_name }}.{{ cluster.domain }}" > /etc/salt/minion.d/minion.conf | |||
echo "master: salt/master: {{ cluster.config.host }}" >> /etc/salt/minion.d/minion.conf | |||
service salt-minion restart |
@@ -0,0 +1,15 @@ | |||
{%- if pillar.salt is defined %} | |||
include: | |||
{%- if pillar.salt.master is defined %} | |||
- salt.master | |||
{%- endif %} | |||
{%- if pillar.salt.minion is defined %} | |||
- salt.minion | |||
{%- endif %} | |||
{%- if pillar.salt.syndic is defined %} | |||
- salt.syndic | |||
{%- endif %} | |||
{%- if pillar.salt.control is defined %} | |||
- salt.control | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,120 @@ | |||
{% set master = salt['grains.filter_by']({ | |||
'Arch': { | |||
'pkgs': ['salt-zmq'], | |||
'service': 'salt-master', | |||
'pillar': { | |||
'engine': 'salt', | |||
}, | |||
'accept_policy': 'preseed', | |||
'bind': {}, | |||
'formula': {}, | |||
'base_environment': 'dev', | |||
}, | |||
'Debian': { | |||
'pkgs': ['salt-master'], | |||
'service': 'salt-master', | |||
'pillar': { | |||
'engine': 'salt', | |||
}, | |||
'accept_policy': 'preseed', | |||
'bind': {}, | |||
'formula': {}, | |||
'base_environment': 'dev', | |||
}, | |||
'Gentoo': { | |||
'pkgs': ['app-admin/salt'], | |||
'service': 'salt-master', | |||
'pillar': { | |||
'engine': 'salt', | |||
}, | |||
'accept_policy': 'preseed', | |||
'bind': {}, | |||
'formula': {}, | |||
'base_environment': 'dev', | |||
}, | |||
'MacOS': { | |||
'pkgs': ['saltstack'], | |||
'service': 'salt-master', | |||
'pillar': { | |||
'engine': 'salt', | |||
}, | |||
'accept_policy': 'preseed', | |||
'bind': {}, | |||
'formula': {}, | |||
'base_environment': 'dev', | |||
}, | |||
'RedHat': { | |||
'pkgs': ['salt-master'], | |||
'service': 'salt-master', | |||
'pillar': { | |||
'engine': 'salt', | |||
}, | |||
'accept_policy': 'preseed', | |||
'bind': {}, | |||
'formula': {}, | |||
'base_environment': 'dev', | |||
}, | |||
}, merge=salt['pillar.get']('salt:master')) %} | |||
{% set minion = salt['grains.filter_by']({ | |||
'Arch': { | |||
'pkgs': ['salt-zmq'], | |||
'graph_pkgs': ['graphviz'], | |||
'graph_states_pkgs': ['python-pydot', 'python-yaml'], | |||
'graph_states': False, | |||
'service': 'salt-minion', | |||
}, | |||
'Debian': { | |||
'pkgs': ['salt-minion'], | |||
'graph_pkgs': ['graphviz'], | |||
'graph_states_pkgs': ['python-pydot', 'python-yaml'], | |||
'graph_states': False, | |||
'service': 'salt-minion', | |||
}, | |||
'Gentoo': { | |||
'pkgs': ['app-admin/salt'], | |||
'graph_pkgs': ['graphviz'], | |||
'graph_states_pkgs': ['python-pydot', 'python-yaml'], | |||
'graph_states': False, | |||
'service': 'salt-minion', | |||
}, | |||
'MacOS': { | |||
'pkgs': ['saltstack'], | |||
'graph_pkgs': ['graphviz'], | |||
'graph_states_pkgs': ['python-pydot', 'python-yaml'], | |||
'graph_states': False, | |||
'service': 'salt-minion', | |||
}, | |||
'RedHat': { | |||
'pkgs': ['salt-minion'], | |||
'graph_pkgs': ['graphviz'], | |||
'graph_states_pkgs': ['python-pydot', 'python-yaml'], | |||
'graph_states': False, | |||
'service': 'salt-minion', | |||
}, | |||
}, merge=salt['pillar.get']('salt:minion')) %} | |||
{% set api = salt['grains.filter_by']({ | |||
'Debian': { | |||
'pkgs': ['salt-api'], | |||
'service': 'salt-api', | |||
}, | |||
'RedHat': { | |||
'pkgs': ['salt-api'], | |||
'service': 'salt-api', | |||
}, | |||
}, merge=salt['pillar.get']('salt:api')) %} | |||
{% set control = salt['grains.filter_by']({ | |||
'Debian': { | |||
'python_pkgs': ['apache-libcloud', 'netaddr'], | |||
'pkgs': ['python-netaddr', 'python-libcloud'], | |||
'cluster': {}, | |||
}, | |||
'RedHat': { | |||
'python_pkgs': ['apache-libcloud', 'netaddr'], | |||
'pkgs': ['python-netaddr', 'python-libcloud'], | |||
'cluster': {}, | |||
}, | |||
}, merge=salt['pillar.get']('salt:control')) %} |
@@ -0,0 +1,22 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
include: | |||
- salt.master.service | |||
salt_api_packages: | |||
pkg.latest | |||
- names: | |||
- salt-api | |||
- require: | |||
- pkg: salt_master_packages | |||
salt_api_service: | |||
service.running: | |||
- name: salt-api | |||
- require: | |||
- pkg: salt_api_packages | |||
- watch: | |||
- file: /etc/salt/master | |||
{%- endif %} |
@@ -0,0 +1,23 @@ | |||
{%- 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 %} |
@@ -0,0 +1,248 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
include: | |||
- git.client | |||
- salt.master.service | |||
{%- if master.system is defined %} | |||
salt_env_{{ master.system.environment }}_dirs: | |||
file.directory: | |||
- names: | |||
- /srv/salt/env/{{ master.system.environment }}/_modules | |||
- /srv/salt/env/{{ master.system.environment }}/_states | |||
- /srv/salt/env/{{ master.system.environment }}/_grains | |||
- /srv/salt/env/{{ master.system.environment }} | |||
- makedirs: True | |||
{%- for grain_name, grain in master.system.get('grain', {}).iteritems() %} | |||
{%- if grain.source == 'git' %} | |||
salt_master_{{ master.system.environment }}_{{ grain_name }}_grain_source: | |||
git.latest: | |||
- name: {{ grain.address }} | |||
- target: /srv/salt/env/{{ master.system.environment }}/_extra/grain_{{ grain_name }} | |||
- rev: {{ grain.revision }} | |||
- require: | |||
- file: salt_env_{{ master.system.environment }}_dirs | |||
- pkg: git_packages | |||
/srv/salt/env/{{ master.system.environment }}/_grains/{{ grain_name }}.py: | |||
file.symlink: | |||
- target: /srv/salt/env/{{ master.system.environment }}/_extra/grain_{{ grain_name }}/{{ grain_name }}.py | |||
- require: | |||
- git: salt_master_{{ master.system.environment }}_{{ grain_name }}_grain_source | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- for state_name, state in master.system.get('state', {}).iteritems() %} | |||
{%- if state.source == 'git' %} | |||
salt_master_{{ master.system.environment }}_{{ state_name }}_state_source: | |||
git.latest: | |||
- name: {{ state.address }} | |||
- target: /srv/salt/env/{{ master.system.environment }}/_extra/state_{{ state_name }} | |||
- rev: {{ state.revision }} | |||
- require: | |||
- file: salt_env_{{ master.system.environment }}_dirs | |||
- pkg: git_packages | |||
/srv/salt/env/{{ master.system.environment }}/_modules/{{ state_name }}.py: | |||
file.symlink: | |||
- target: /srv/salt/env/{{ master.system.environment }}/_extra/state_{{ state_name }}/modules/{{ state_name }}.py | |||
- require: | |||
- git: salt_master_{{ master.system.environment }}_{{ state_name }}_state_source | |||
/srv/salt/env/{{ master.system.environment }}/_states/{{ state_name }}.py: | |||
file.symlink: | |||
- target: /srv/salt/env/{{ master.system.environment }}/_extra/state_{{ state_name }}/states/{{ state_name }}.py | |||
- require: | |||
- git: salt_master_{{ master.system.environment }}_{{ state_name }}_state_source | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- for formula_name, formula in master.system.get('formula', {}).iteritems() %} | |||
{%- if formula.source == 'git' %} | |||
salt_master_{{ master.system.environment }}_{{ formula_name }}_formula_source: | |||
git.latest: | |||
- name: {{ formula.address }} | |||
- target: /srv/salt/env/{{ master.system.environment }}/{{ formula_name }} | |||
- rev: {{ formula.revision }} | |||
- require: | |||
- file: salt_env_{{ master.system.environment }}_dirs | |||
- pkg: git_packages | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- if master.system.returners is defined %} | |||
salt_master_{{ master.system.environment }}_returners: | |||
git.latest: | |||
- name: {{ master.system.returners.address }} | |||
- target: /srv/salt/env/{{ master.system.environment }}/_returners | |||
- rev: {{ master.system.returners.revision }} | |||
- require: | |||
- file: salt_env_{{ master.system.environment }}_dirs | |||
- pkg: git_packages | |||
{%- endif %} | |||
{%- endif %} | |||
{# Start new #} | |||
{%- for environment_name, environment in master.get('environment', {}).iteritems() %} | |||
{%- if master.base_environment == environment_name %} | |||
salt_env_{{ environment_name }}_pre_dirs: | |||
file.directory: | |||
- names: | |||
- /usr/share/salt-formulas/env/_modules | |||
- /usr/share/salt-formulas/env/_states | |||
- /usr/share/salt-formulas/env/_grains | |||
- /usr/share/salt-formulas/env/_formulas | |||
- makedirs: True | |||
salt_env_{{ environment_name }}_dirs: | |||
file.symlink: | |||
- name: /srv/salt/env/{{ environment_name }} | |||
- target: /usr/share/salt-formulas/env | |||
- require: | |||
- file: salt_env_{{ environment_name }}_pre_dirs | |||
{%- else %} | |||
salt_env_{{ environment_name }}_dirs: | |||
file.directory: | |||
- names: | |||
- /srv/salt/env/{{ environment_name }}/_modules | |||
- /srv/salt/env/{{ environment_name }}/_states | |||
- /srv/salt/env/{{ environment_name }}/_grains | |||
- /srv/salt/env/{{ environment_name }}/_formulas | |||
- makedirs: True | |||
{%- endif %} | |||
{%- for formula_name, formula in environment.get('formula', {}).iteritems() %} | |||
{%- if formula.source == 'pkg' %} | |||
salt_master_{{ environment_name }}_{{ formula.name }}_formula: | |||
pkg.latest: | |||
- name: {{ formula.name }} | |||
{%- elif formula.source == 'git' %} | |||
{%- if master.base_environment == environment_name %} | |||
salt_master_{{ environment_name }}_{{ formula_name }}_formula: | |||
git.latest: | |||
- name: {{ formula.address }} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }} | |||
- rev: {{ formula.revision }} | |||
- require: | |||
- file: salt_env_{{ environment_name }}_dirs | |||
- pkg: git_packages | |||
salt_env_{{ environment_name }}_{{ formula_name }}_link: | |||
file.symlink: | |||
- name: /usr/share/salt-formulas/env/{{ formula_name }} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }}/{{ formula_name }} | |||
- require: | |||
- file: salt_env_{{ environment_name }}_dirs | |||
{%- for grain_name, grain in formula.get('grain', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ grain_name }}_grain: | |||
file.symlink: | |||
- name: /usr/share/salt-formulas/env/_grains/{{ grain_name }} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }}/_grains/{{ grain_name }} | |||
{%- endfor %} | |||
{%- for module_name, module in formula.get('module', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ module_name }}_module: | |||
file.symlink: | |||
- name: /usr/share/salt-formulas/env/_modules/{{ module_name }} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }}/_modules/{{ module_name }} | |||
{%- endfor %} | |||
{%- for state_name, state in formula.get('state', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ state_name }}_state: | |||
file.symlink: | |||
- name: /usr/share/salt-formulas/env/_states/{{ state_name }} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }}/_states/{{ state_name }} | |||
{%- endfor %} | |||
{%- else %} | |||
salt_master_{{ environment_name }}_{{ formula_name }}_formula: | |||
git.latest: | |||
- name: {{ formula.address }} | |||
- target: /srv/salt/env/{{ environment_name }}/_formulas/{{ formula_name }} | |||
- rev: {{ formula.revision }} | |||
- require: | |||
- file: salt_env_{{ environment_name }}_dirs | |||
- pkg: git_packages | |||
salt_env_{{ environment_name }}_{{ formula_name }}_link: | |||
file.symlink: | |||
- name: /srv/salt/env/{{ environment_name }}/{{ formula_name }} | |||
- target: /srv/salt/env/{{ environment_name }}/_formulas/{{ formula_name }}/{{ formula_name }} | |||
- require: | |||
- file: salt_env_{{ environment_name }}_dirs | |||
{%- for grain_name, grain in formula.get('grain', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ grain_name }}_grain: | |||
file.symlink: | |||
- name: /srv/salt/env/{{ environment_name }}/_grains/{{ grain_name }} | |||
- target: /srv/salt/env/{{ environment_name }}/_formulas/{{ formula_name }}/_grains/{{ grain_name }} | |||
{%- endfor %} | |||
{%- for module_name, module in formula.get('module', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ module_name }}_module: | |||
file.symlink: | |||
- name: /srv/salt/env/{{ environment_name }}/_grains/{{ module_name }} | |||
- target: /srv/salt/env/{{ environment_name }}/_formulas/{{ formula_name }}/_grains/{{ module_name }} | |||
{%- endfor %} | |||
{%- for state_name, state in formula.get('state', {}).iteritems() %} | |||
salt_master_{{ environment_name }}_{{ state_name }}_state: | |||
file.symlink: | |||
- name: /srv/salt/env/{{ environment_name }}/_grains/{{ state_name }} | |||
- target: /srv/salt/env/{{ environment_name }}/_formulas/{{ formula_name }}/_grains/{{ state_name }} | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endfor %} | |||
{# end new #} | |||
{%- endif %} |
@@ -0,0 +1,7 @@ | |||
include: | |||
- salt.master.service | |||
- salt.master.env | |||
- salt.master.pillar | |||
- salt.master.minion | |||
- salt.master.win_repo | |||
- salt.master.ca |
@@ -0,0 +1,46 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
include: | |||
- salt.master.service | |||
{%- if master.minion is defined %} | |||
/srv/salt/minion_keys: | |||
file.directory: | |||
- makedirs: true | |||
- require: | |||
- pkg: salt_master_packages | |||
{%- for name, environment in master.environment.iteritems() %} | |||
/srv/salt/env/{{ name }}/minion_keys: | |||
file.symlink: | |||
- target: /srv/salt/minion_keys | |||
- require: | |||
- file: /srv/salt/env/{{ name }} | |||
- file: /srv/salt/minion_keys | |||
{%- endfor %} | |||
{%- for minion in master.minion %} | |||
generate_key_{{ minion.name }}: | |||
cmd.run: | |||
- name: salt-key --gen-keys={{ minion.name }} --gen-keys-dir=/srv/salt/minion_keys | |||
- unless: "test -e /srv/salt/minion_keys/{{ minion.name}}.pem" | |||
- require: | |||
- file: /srv/salt/minion_keys | |||
copy_generated_key_{{ minion.name }}: | |||
cmd.run: | |||
- name: cp /srv/salt/minion_keys/{{ minion.name }}.pub /etc/salt/pki/master/minions/{{ minion.name }} | |||
- unless: "test -e /etc/salt/pki/master/minions/{{ minion.name }}" | |||
- require: | |||
- cmd: generate_key_{{ minion.name }} | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,76 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
{%- if master.pillar.engine == 'salt' %} | |||
include: | |||
- git.client | |||
- salt.master.service | |||
{{ master.pillar.source.address }}: | |||
git.latest: | |||
- target: /srv/salt/pillar | |||
- rev: {{ master.pillar.source.branch }} | |||
- require: | |||
- file: /srv/salt/env | |||
- pkg: git_packages | |||
/srv/salt/env/{{ master.system.environment }}/top.sls: | |||
file.symlink: | |||
- target: /srv/salt/pillar/files_top.sls | |||
- require: | |||
- file: /srv/salt/env/{{ master.system.environment }} | |||
{%- elif master.pillar.engine == 'reclass' %} | |||
include: | |||
- reclass.storage.data | |||
/srv/salt/reclass/classes/service: | |||
file.directory | |||
{%- if master.system is defined %} | |||
{%- for formula_name, formula in master.system.get('formula', {}).iteritems() %} | |||
/srv/salt/reclass/classes/service/{{ formula_name }}: | |||
file.symlink: | |||
- target: /srv/salt/env/{{ master.system.environment }}/{{ formula_name }}/metadata/service | |||
- require: | |||
- git: reclass_data_source | |||
- file: /srv/salt/reclass/classes/service | |||
{%- endfor %} | |||
{%- else %} | |||
{%- for environment_name, environment in master.environment.iteritems() %} | |||
{%- for formula_name, formula in environment.get('formula', {}).iteritems() %} | |||
{%- if environment_name == master.base_environment %} | |||
/srv/salt/reclass/classes/service/{{ formula_name }}: | |||
file.symlink: | |||
{%- if formula.source == 'pkg' %} | |||
- target: /usr/share/salt-formulas/reclass/service/{{ formula_name }} | |||
{%- else %} | |||
- target: /usr/share/salt-formulas/env/_formulas/{{ formula_name }}/metadata/service | |||
{%- endif %} | |||
- require: | |||
- git: reclass_data_source | |||
- file: /srv/salt/reclass/classes/service | |||
{%- endif %} | |||
{%- endfor %} | |||
{%- endfor %} | |||
{%-endif %} | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,29 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
salt_master_packages: | |||
pkg.latest: | |||
- names: {{ master.pkgs }} | |||
/etc/salt/master.d/master.conf: | |||
file.managed: | |||
- source: salt://salt/files/master.conf | |||
- user: root | |||
- template: jinja | |||
- require: | |||
- pkg: salt_master_packages | |||
- watch_in: | |||
- service: salt_master_service | |||
salt_master_service: | |||
service.running: | |||
- name: {{ master.service }} | |||
- enable: true | |||
/srv/salt/env: | |||
file.directory: | |||
- user: root | |||
- mode: 755 | |||
- makedirs: true | |||
{%- endif %} |
@@ -0,0 +1,49 @@ | |||
{%- from "salt/map.jinja" import master with context %} | |||
{%- if master.enabled %} | |||
include: | |||
- git.client | |||
- salt.master.service | |||
{%- if master.windows_repo is defined %} | |||
/srv/salt/win: | |||
file.directory: | |||
- user: root | |||
- mode: 755 | |||
- makedirs: true | |||
- require: | |||
- file: /srv/salt/env | |||
{%- if master.windows_repo.source == 'git' %} | |||
{{ master.windows_repo.address }}: | |||
git.latest: | |||
- target: /srv/salt/win/repo | |||
- rev: {{ master.windows_repo.branch }} | |||
- require: | |||
- file: /srv/salt/win | |||
- pkg: git_packages | |||
salt_master_update_win_repo: | |||
cmd.run: | |||
- name: salt-run winrepo.genrepo | |||
- require: | |||
- git: {{ master.windows_repo.address }} | |||
{%- for environment in master.environments %} | |||
/srv/salt/env/{{ name }}/win: | |||
file.symlink: | |||
- target: /srv/salt/win | |||
- require: | |||
- file: /srv/salt/env/{{ name }} | |||
- git: {{ master.windows_repo.address }} | |||
{%- endfor %} | |||
{%- endif %} | |||
{%- endif %} | |||
{%- endif %} |
@@ -0,0 +1,58 @@ | |||
{%- 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: /var/lib/salt/grains | |||
- mode: 700 | |||
- makedirs: true | |||
- user: root | |||
/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 %} |
@@ -0,0 +1,44 @@ | |||
wlan0: | |||
network.managed: | |||
- enabled: True | |||
- type: eth | |||
- bridge: br0 | |||
br0: | |||
network.managed: | |||
- enabled: True | |||
- type: bridge | |||
- proto: dhcp | |||
- require: | |||
- network: wlan0 | |||
libvirt: | |||
pkg.installed: [] | |||
file.managed: | |||
- name: /etc/sysconfig/libvirtd | |||
- contents: 'LIBVIRTD_ARGS="--listen"' | |||
- require: | |||
- pkg: libvirt | |||
libvirt.keys: | |||
- require: | |||
- pkg: libvirt | |||
service.running: | |||
- name: libvirtd | |||
- require: | |||
- pkg: libvirt | |||
- network: br0 | |||
- libvirt: libvirt | |||
- watch: | |||
- file: libvirt | |||
libvirt-python: | |||
pkg.installed: [] | |||
libguestfs: | |||
pkg.installed: | |||
- pkgs: | |||
- libguestfs | |||
- libguestfs-tools | |||