-
Notifications
You must be signed in to change notification settings - Fork 0
17. junos_syslog engine and Salt's reactor system end to end demo
Reactors files are executed when an event with a specific topic comes on the master event bus.
This mapping between an event and the reactor file to execute is present in the reactor section of the master config file.
Example:
reactor:
- 'jnpr/syslog/*/UI_COMMIT_COMPLETED':
- /srv/reactor/on_commit.sls
Reactor sls files should be placed in the /srv/reactor/ directory for consistency between environments, but this is not currently enforced by Salt.
Reactor sls files follow a similar format to other sls files in Salt.
Example:
reactor:
- 'jnpr/syslog/*/UI_COMMIT_COMPLETED':
- /srv/reactor/on_commit.sls
This demo is about using SaltStack as an event driven orchestrator to fire ansible playbooks based Juniper syslog messages (i.e based on Salt events from junos syslog engine and reactors).
# more /etc/salt/master
file_roots:
base:
- /srv/salt
pillar_roots:
base:
- /srv/pillar
engines_dirs:
- /srv/engines
engines:
- junos_syslog:
port: 516
reactor:
- 'jnpr/syslog/*/UI_COMMIT_COMPLETED':
- /srv/reactor/on_commit.sls
copy junos_syslog.py in one of the engines_dirs directory
# ls /srv/engines/
junos_syslog.py junos_syslog.pyc
# more /srv/reactor/on_commit.sls
Run ansible playbook:
local.cmd.run:
- tgt: minion_1
- arg:
- ansible-playbook /srv/ansible/junos_get_config/pb.2.yml --extra-vars target={{ data['hostname'] }} -i /srv/ansible/hosts
junos_syslog engine ip address (salt master):
# ifconfig ens33 | grep "inet addr"
inet addr:192.168.233.17 Bcast:192.168.233.255 Mask:255.255.255.0
junos device syslog configuration:
For junos_syslog engine to receive events, syslog must be set on the junos device. The ip address is the one of the device running the syslog engine and port is the port where the engine is listening for events.
vagrant@vqfx01> show configuration system syslog host 192.168.233.17
any any;
match UI_COMMIT_COMPLETED;
port 516;
# salt minion_1 test.ping
minion_1:
True
# salt "vq*" test.ping
vqfx01:
True
sudo tcpdump -i ens33 port 516 -XX
salt-run state.event pretty=True
# more /srv/ansible/junos_get_config/pb.2.yml
---
- name: create a directory
hosts: localhost
gather_facts: no
tasks:
- name: create a directory
file:
path: "{{playbook_dir}}/configs"
state: directory
- name: Retrieve configuration from junos devices
hosts: "{{ target }}"
roles:
- Juniper.junos
connection: local
gather_facts: no
tasks:
- name: remove old files from the configs directory
file:
path: "{{playbook_dir}}/configs/{{inventory_hostname}}.conf"
state: absent
- name: include vars
include_vars: "{{playbook_dir}}/vars.yml"
- name: Retrieve interfaces configuration from junos devices
junos_get_config:
host: "{{ junos_host }}"
port: "{{ junos_port }}"
user: "{{ USERNAME }}"
passwd: "{{ DEVICE_PASSWORD }}"
dest: "{{playbook_dir}}/configs/{{ inventory_hostname }}.conf"
format: text
logfile: "{{playbook_dir}}/junos_get_config.log"
filter: interfaces
$ more /srv/ansible/junos_get_config/vars.yml
---
DEVICE_PASSWORD: Poclab123
USERNAME: pytraining
$ more /srv/ansible/hosts
[EX4200]
ex4200-7 junos_host=172.30.179.107
[VQFX]
vqfx01 junos_host=127.0.0.1 junos_port=8331
[EX4300]
ex4300-9 junos_host=172.30.179.95
ex4300-18 junos_host=172.30.179.74
ex4300-17 junos_host=172.30.179.73
minion_1 doesnt have the vqfx01 configuration file:
# more /srv/ansible/junos_get_config/configs/vqfx01.conf
/srv/ansible/junos_get_config/configs/vqfx01.conf: No such file or directory
# ls -l /srv/ansible/junos_get_config/configs
ls: cannot access /srv/ansible/junos_get_config/configs: No such file or directory
# date
Tue Jun 27 14:02:39 PDT 2017
commit a change on junos device:
vagrant@vqfx01# commit
configuration check succeeds
commit complete
minion_1 has the vqfx01 new configuration file:
# ls -l /srv/ansible/junos_get_config/configs/vqfx01.conf
-rw-r--r-- 1 root root 75633 Jun 27 14:03 /srv/ansible/junos_get_config/configs/vqfx01.conf
# ls -l /srv/ansible/junos_get_config/configs
-rw-r--r-- 1 root root 75633 Jun 27 14:03 vqfx01.conf
# more /srv/ansible/junos_get_config/configs/vqfx01.conf
interfaces {
et-0/0/0 {
unit 0 {
family inet {
....
tcpdump on master shows the syslog:
22:48:53.957045 IP 192.168.233.158.59781 > 192.168.233.17.516: UDP, length 75
0x0000: 000c 2911 2ecd 000c 2943 2de4 0800 4500 ..).....)C-...E.
0x0010: 0067 cef6 0000 3f11 588e c0a8 e99e c0a8 .g....?.X.......
0x0020: e911 e985 0204 0053 8ea6 3c31 3838 3e4a .......S..<188>J
0x0030: 756e 2032 3720 3230 3a34 383a 3431 2076 un.27.20:48:41.v
0x0040: 7166 7830 3120 6d67 645b 3137 3132 5d3a qfx01.mgd[1712]:
0x0050: 2055 495f 434f 4d4d 4954 5f43 4f4d 504c .UI_COMMIT_COMPL
0x0060: 4554 4544 3a20 636f 6d6d 6974 2063 6f6d ETED:.commit.com
0x0070: 706c 6574 65 plete
salt internal events:
jnpr/syslog/vqfx01/UI_COMMIT_COMPLETED {
"_stamp": "2017-06-27T20:58:09.034524",
"daemon": "mgd",
"event": "UI_COMMIT_COMPLETED",
"facility": 23,
"hostip": "192.168.233.158",
"hostname": "vqfx01",
"message": "commit complete",
"pid": "2945",
"priority": 188,
"raw": "<188>Jun 27 20:57:55 vqfx01 mgd[2945]: UI_COMMIT_COMPLETED: commit complete",
"severity": 4,
"timestamp": "2017-06-27 22:58:09"
}
20170627225809048834 {
"_stamp": "2017-06-27T20:58:09.049214",
"minions": [
"minion_1"
]
}
salt/job/20170627225809048834/new {
"_stamp": "2017-06-27T20:58:09.051006",
"arg": [
"ansible-playbook /srv/ansible/junos_get_config/pb.2.yml --extra-vars target=vqfx01 -i /srv/ansible/hosts"
],
"fun": "cmd.run",
"jid": "20170627225809048834",
"minions": [
"minion_1"
],
"tgt": "minion_1",
"tgt_type": "glob",
"user": "sudo_ksator"
}
salt/job/20170627225809048834/ret/minion_1 {
"_stamp": "2017-06-27T20:58:11.730328",
"cmd": "_return",
"fun": "cmd.run",
"fun_args": [
"ansible-playbook /srv/ansible/junos_get_config/pb.2.yml --extra-vars target=vqfx01 -i /srv/ansible/hosts"
],
"id": "minion_1",
"jid": "20170627225809048834",
"retcode": 0,
"return": "\nPLAY [create a directory] ******************************************************\n\nTASK [create a directory] ******************************************************\nok: [localhost]\n\nPLAY [Retrieve configuration from junos devices] *******************************\n\nTASK [remove old files from the configs directory for each host] ***************\nchanged: [vqfx01]\n\nTASK [include vars] ************************************************************\nok: [vqfx01]\n\nTASK [Retrieve configuration from junos devices] *******************************\nchanged: [vqfx01]\n\nPLAY RECAP *********************************************************************\nlocalhost : ok=1 changed=0 unreachable=0 failed=0 \nvqfx01 : ok=3 changed=2 unreachable=0 failed=0",
"success": true
}
master configuration file:
# more /etc/salt/master
file_roots:
base:
- /srv/salt
pillar_roots:
base:
- /srv/pillar
engines_dirs:
- /srv/engines
engines:
- junos_syslog:
port: 516
reactor:
- 'jnpr/syslog/*/UI_COMMIT_COMPLETED':
- /srv/reactor/on_commit1.sls
reactor file:
# more /srv/reactor/on_commit1.sls
Run interface sls:
local.state.apply:
- tgt: {{ data['hostname'] }}
- arg:
- junos
state file:
# more /srv/salt/junos.sls
get-interface-information:
junos:
- rpc
- dest: /tmp/rpc.log
- interface_name: lo0