Now that you have backups running successfully. Let’s talk about abstracting data states!
The Why?
It’s pretty important to differentiate between state and config data. Configuration will only get you half the picture and in many cases less than half. How are relationships built on your network? Do you know who the primary neighbors for your devices are? That’s state information, many people keep it in their visio. But the critical piece here is you need that information to build programmability. That’s where state abstraction comes into play.
We will be using Ansible to gather this information and with the help of the PyATS library do some quick state abstraction and turn it into something useful.
State Abstraction –
What you’ll need –
- Python
- Ansible
- PyATS – Ansible Galaxy Module
The Play –
--- - name: pyATS testing hosts: cisco gather_facts: no connection: network_cli roles: - parse_genie tasks: - name: Run the show ip interface command ios_command: commands: - show ip interface brief register: interface_output - name: Set fact with Genie filter plugin set_fact: pyats_showipinterface: "{{ interface_output['stdout'][0] | parse_genie(command='show ip interface brief', os='ios') }}" - name: Debug interface parse debug: var: pyats_showipinterface - name: Convert parse data to YAML template: src: templates/show_ip_interface_brief.j2 dest: "reports/{{ inventory_hostname }}"
This play book logs into each device and runs the “show ip interface brief” command. It then parses the output into a JSON structure using PyATS Genie. In the final step it calls a Jinja template and converts to a structured YAML format.
You’ll need to install Parse Genie. The directions are available on Ansible Galaxy. I did rename my folder for easier reference. Normally the role is “(user).(module)”.
Here’s the Jinja template –
--- interfaces: {% for key1 in pyats_showipinterface %} {% for nested_key in pyats_showipinterface[key1] %} - name: {{ nested_key }} - IP address: {{ pyats_showipinterface[key1][nested_key]["ip_address"] }} - Status: {{ pyats_showipinterface[key1][nested_key]["status"] }} {% endfor %} {% endfor %}
Jinja is a Python templating engine. If you need anything done at speed, you’ll need to hand your data to Jinja. Could I simplify this and just call the nested key? Yes, but this also shows you how to parse through multiple nested keys. Very handy if say you have a Route Table -> VRFs -> Routes. You may need to parse multiple key value structures.
You can take data that’s human readable-
R1#sh ip int bri Interface IP-Address OK? Method Status Protocol GigabitEthernet1 unassigned YES NVRAM up up GigabitEthernet1.13 155.1.13.1 YES NVRAM up up GigabitEthernet1.100 169.254.100.1 YES NVRAM up up GigabitEthernet1.146 155.1.146.1 YES NVRAM up up GigabitEthernet2 unassigned YES NVRAM administratively down down GigabitEthernet3 192.168.3.61 YES NVRAM up up Loopback0 150.1.1.1 YES NVRAM up up Tunnel0 155.1.0.1 YES NVRAM up up
And present it in a format that a machine can consume and is human readable –
--- interfaces: - name: GigabitEthernet1 - IP address: unassigned - Status: up - name: GigabitEthernet1.13 - IP address: 155.1.13.1 - Status: up - name: GigabitEthernet1.100 - IP address: 169.254.100.1 - Status: up - name: GigabitEthernet1.146 - IP address: 155.1.146.1 - Status: up - name: GigabitEthernet2 - IP address: unassigned - Status: administratively down - name: GigabitEthernet3 - IP address: 192.168.3.61 - Status: up - name: Loopback0 - IP address: 150.1.1.1 - Status: up - name: Tunnel0 - IP address: 155.1.0.1 - Status: up
Conclusion –
Ansible with the power of modules and Jinja allow you to take your current deployment and put it into a consumable format. This is just a fraction of what’s possible. I only picked interfaces since it’s a common and easy item to pull state info from. But the possibilities are endless. Take a look at the Genie parsers for yourself and consider what you can accomplish!
https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/parsers