Ansible VOSS Config Idempotency

It is useful to know when a task has made a change and it should be possible to re-run the same task again and no changes are made. Some commands sent to the switch may return a changed state even though the configuration has changed before. This can be the case when using abbreviated commands. There are also different ways to apply the same configuration and it is worth inspecting the running configuration to see the syntax of the command in there which might be different to what was sent.

For example, you can create a new VLAN with one line and then give the VLAN a name with another. If you do this the playbook will always come back as changed=1 even though it made no changes on subsequent plays. By checking the running config you can see that the two command lines are converted to a single line and also includes quotes around the VLAN name.

Altering the Jinga2 source file used as a template to match the expected result in the running config will change the behaviour. Running the playbook for the first time will change the config and state will be changed=1. Subsequent runs of the playbook will not change anything as the configuration is found in the running config with the exact same string and syntax. The state will be changed=0.

$ ansible-playbook voss_config_vlan.yml

PLAY [PLAY 1: Manage VLANs with voss_config and jinja2] ********************************************

TASK [TASK 1: Apply config via SSH] ****************************************************************

changed: [r1]

RUNNING HANDLER [HANDLER 1: Display changes] *******************************************************

ok: [r1] => {

“msg”: [

“vlan create 300 name \”Sales\” type port-mstprstp 0″,

“vlan create 400 name \”IT\” type port-mstprstp 0″

]

}

PLAY RECAP *****************************************************************************************

r1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

$ ansible-playbook voss_config_vlan.yml

PLAY [PLAY 1: Manage VLANs with voss_config and jinja2] ********************************************

TASK [TASK 1: Apply config via SSH] ****************************************************************

ok: [r1]

PLAY RECAP *****************************************************************************************

r1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

###

VLAN extract from running config:

vlan create 300 name “Sales” type port-mstprstp 0
vlan create 400 name “IT” type port-mstprstp 0

Jinga2 template:

$ cat templates/vlans.j2

{% for vlan in vlans %}

vlan create {{ vlan.vid }} name “{{ vlan.description }}” type port-mstprstp 0

{% endfor %}

 

YAML error checking

Add site-package yamllint to inspect YAML/YML files for errors.

pip install –user yamllint

Yamllint has two default configuration files: default.yaml and relaxed.yaml with pre-set rules. Can extend a configuration file and alter one of the rules.

Mylint.yaml:

# Mylint.yaml is my own configuration file for yamllint
# It extends the default.yaml by adjusting some options.

extends: default

rules:
new-lines: disable

###

Did this to avoid the error about the EOL character on the first line (—).

1:4 error wrong new line character: expected \n (new-lines)

 

 

Netmiko Running-Config

from netmiko import ConnectHandler
voss1 = {‘device_type’: ‘extreme_vsp’, ‘host’: ‘192.168.1.11’, ‘username’: ‘rwa’, ‘password’: ‘rwa’}
net_connect = ConnectHandler(**voss1)
net_connect.find_prompt()
net_connect.enable()
net_connect.send_command(‘terminal more disable’)
output = net_connect.send_command(‘show run’)
print(output)
net_connect.send_command(‘terminal more enable’)
savedoutput = open(“switch” + voss1[‘host’], “w”)
savedoutput.write(output)
savedoutput.close