In this lesson, we will cover:
- What is Dq?
- The different Dq usages and installation.
- The common Dq methods.
- Using Dq for real-world use cases such as querying IP to MAC, OSPF Neighbor validation and interface errors.
The scripts and code for this lesson can be found within the pyATS repo under the directory: 004_libraries/dq/
.
What is Dq?
Dq (Dictionary query) is a PyATS/Genie Python library that provides an easy and simplistic way to query Python dictionaries. It avoids much of the heavy lifting required when dealing with large nested dictionaries such as iteration, looping and specifying the various keys to get to the point in the data structure to collect the value of interest.
For example, let’s say we have obtained the output of show ip ospf neighbor detail
via a pyATS Parse and now want to work with the data in Python.
ospf_output = device.parse("show ip ospf neighbor detail")
pprint(ospf_output)
===
{
"vrf": {
"default": {
"address_family": {
"ipv4": {
"instance": {
"1": {
"areas": {
"0.0.0.0": {
"interfaces": {
"GigabitEthernet0/0": {
"neighbors": {
"3.3.3.3": {
"address": "10.1.1.2",
"bdr_ip_addr": "10.1.1.2",
"dbd_options": "0x42",
"dead_timer": "00:00:35",
"dr_ip_addr": "10.1.1.1",
"first": "0x0(0)/0x0(0)/0x0(0)",
"hello_options": "0x2",
"index": "1/6/6,",
"interface": "GigabitEthernet0/0",
"neighbor_router_id": "3.3.3.3",
"next": "0x0(0)/0x0(0)/0x0(0)",
"priority": 1,
"state": "full",
"statistics": {
"last_retrans_max_scan_length": 0,
"last_retrans_max_scan_time_msec": 0,
"last_retrans_scan_length": 0,
"last_retrans_scan_time_msec": 0,
"nbr_event_count": 6,
"nbr_retrans_qlen": 0,
"total_retransmission": 0,
},
"uptime": "7w1d",
}
}
},
…
To even get to the interface keys, we would need to perform something along the lines of:
ospf_output['vrf']['default']['address_family']['ipv4']['instance']['1']['areas']
===
['0.0.0.0']['interfaces'].keys()
dict_keys(['GigabitEthernet0/5', 'GigabitEthernet0/4', 'GigabitEthernet0/3', 'GigabitEthernet0/2', 'GigabitEthernet0/1', 'GigabitEthernet0/0'])
I think you can now see the problem! To perform this in Dq we would simply perform the following.
ospf_output.q.get_values('interfaces')
===
['GigabitEthernet0/5', 'GigabitEthernet0/4', 'GigabitEthernet0/3', 'GigabitEthernet0/2', 'GigabitEthernet0/1', 'GigabitEthernet0/0']
Let’s dive into the various options within Dq. Before we do, let's load the testbed file and connect to one of our devices. Like so:
$ export $(cat .env)
$ pyats shell --testbed-file testbeds/testbed.yml
from pprint import pprint
device = testbed.devices["spine1-nxos"]
device.connect()