============ | |||||
salt-formula | |||||
============ | |||||
0.0.2 | |||||
----- | |||||
- Graphing of salt minion states | |||||
0.0.1 | |||||
----- | |||||
- Initial state for installing Salt master |
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. |
==== | |||||
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.2 |
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 |
9 |
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. |
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. |
README.rst | |||||
CHANGELOG.rst | |||||
VERSION |
salt/* /usr/share/salt-formulas/env/salt/ | |||||
metadata/service/* /usr/share/salt-formulas/reclass/service/salt/ |
#!/usr/bin/make -f | |||||
%: | |||||
dh $@ | |||||
3.0 (native) |
applications: | |||||
- salt | |||||
- git | |||||
- openssh | |||||
parameters: | |||||
salt: | |||||
master: | |||||
enabled: true | |||||
command_timeout: 5 | |||||
worker_threads: 2 |
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} |
applications: | |||||
- salt | |||||
parameters: | |||||
salt: | |||||
minion: | |||||
enabled: true | |||||
master: | |||||
host: ${_param:salt_master_host} | |||||
mine: | |||||
interval: 60 | |||||
module: | |||||
grains.items: [] | |||||
network.interfaces: [] |
applications: | |||||
- salt | |||||
parameters: | |||||
salt: | |||||
minion: | |||||
enabled: true | |||||
local: true | |||||
pillar: | |||||
engine: reclass | |||||
data_dir: /srv/salt/reclass |
applications: | |||||
- salt | |||||
parameters: | |||||
salt: | |||||
minion: | |||||
enabled: true | |||||
master: | |||||
host: ${_param:salt_master_host} | |||||
mine: | |||||
interval: 60 | |||||
module: | |||||
grains.items: [] | |||||
network.interfaces: [] |
{%- 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 %} |
{% 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 %} |
include: | |||||
- salt.control.service | |||||
- salt.control.provider | |||||
- salt.control.cluster |
{% 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 %} |
{% 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 %} |
{%- 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 %} |
{%- 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 %} |
{%- 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 %} |
{% 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 %} |
{% 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 %} |
#!/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() |
#!/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) |
#!/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 |
-----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----- |
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 |
{%- 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 |
{%- 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 %} |
{% 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')) %} |
{%- 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 %} |
{%- 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 %} |
{%- 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 %} |
include: | |||||
- salt.master.service | |||||
- salt.master.env | |||||
- salt.master.pillar | |||||
- salt.master.minion | |||||
- salt.master.win_repo | |||||
- salt.master.ca |
{%- 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 %} |
{%- 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 %} |
{%- 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 %} |
{%- 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 %} |
{%- 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 %} |
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 | |||||