[python]show run object network

Cisco ASA’s show run object network will show the subnet, host and range objects, netmiko has a textfsm template to match the result in dictionary, however there is no template to match show run object service hence for the service part you will need to write your own textfsm template.

On this example I will be using nornir framework, however you can use netmiko directly as well, there is no difference between these two.
I will be using a self written package to get the device, this is a portion of the functions of my package which I will be using:

from pyvault2.vault.hvault2 import get_kv2_secret
from nornir import InitNornir
from pathlib import Path
from os.path import join

host_file_path = join(Path(__file__).parent.absolute(), "inventory", "hosts.yaml")

def connect_asa_host(hostname=None):
    vault_data = get_asa_credential(hostname=hostname)

    with InitNornir(
            inventory={
                "plugin": "nornir.plugins.inventory.simple.SimpleInventory",
                "options": {
                    "host_file": host_file_path
                }
            }
    ) as nr:
        nr.inventory.hosts.get(hostname, None).username = vault_data["username"]
        nr.inventory.hosts.get(hostname, None).password = vault_data["password"]
        return nr.filter(filter_func=lambda h: h.name == hostname)

def get_asa_credential(hostname=None):
    """
    Get asa's device credentials.
    :param hostname:
    :return: credential in json
    """
    return get_kv2_secret(mount_path="cisco_asa", path=hostname, find="data")

def sh_run_object_network(hostname=None, object_id=None):
    """
    Netmiko will return a dictionary of show run object network.
    if no object_id specified all dictionary is displayed.
    :param hostname: hostname of Cisco ASA
    :param object_id: The firewall object name
    :return: dictionary
    """
    target_device = connect_asa_host(hostname=hostname)
    response = target_device.run(task=netmiko_send_command,
                                 command_string="show run object network",
                                 use_textfsm=True)
    result = response[hostname][0].result
    if object_id is not None:
        object_id_result = next(filter(lambda x: x["name"] == object_id, result), None)
        return object_id_result
    return result

sh_run_object_network function returns a dictionary of all network objects if no object_id is specified, if an object_id is specified, the filter function will be use to match the item in iterables (tuple or list), next function is to find the next item to match if the first item is not match, next function can define a default value if there is no match found from the iterables, hence the line is written as next(filter(lambda x: x["name"] == object_id, result), None).

Filter function takes in two arguments, one function and one iterable, lambda function is used to find a match of the dictionary’s key “name” with object_id, if the match is found the result will be shown.

The firewall has these network objects:
nor38

To get all network objects dictionary:

from network.ciscoasa import sh_run_object_network
from pprint import pprint


pprint(sh_run_object_network(hostname="fw02"))

The result of the script to return all network objects:

[{'cidr': '',
  'desc': 'Test object',
  'end_ip': '',
  'host': '192.168.1.1',
  'mask': '',
  'name': 'centos',
  'network': '',
  'start_ip': '',
  'type': 'host'},
 {'cidr': '',
  'desc': 'Test object',
  'end_ip': '192.168.1.120',
  'host': '',
  'mask': '',
  'name': 'host1',
  'network': '',
  'start_ip': '192.168.1.100',
  'type': 'range'},
 {'cidr': '',
  'desc': 'test subnet',
  'end_ip': '',
  'host': '',
  'mask': '255.255.255.0',
  'name': 'test2',
  'network': '192.168.1.0',
  'start_ip': '',
  'type': 'subnet'},
 {'cidr': '',
  'desc': 'test host',
  'end_ip': '',
  'host': '192.168.1.100',
  'mask': '',
  'name': 'test3',
  'network': '',
  'start_ip': '',
  'type': 'host'}]

To get the dictionary of specific object, in this example I want to show only “test2” network object:
pprint(sh_run_object_network(hostname="fw02", object_id="test2"))

{'cidr': '',
 'desc': 'test subnet',
 'end_ip': '',
 'host': '',
 'mask': '255.255.255.0',
 'name': 'test2',
 'network': '192.168.1.0',
 'start_ip': '',
 'type': 'subnet'}

Another test to get only the network object test3 dictionary:
pprint(sh_run_object_network(hostname="fw02", object_id="test3"))

{'cidr': '',
 'desc': 'test host',
 'end_ip': '',
 'host': '192.168.1.100',
 'mask': '',
 'name': 'test3',
 'network': '',
 'start_ip': '',
 'type': 'host'}

The flexibility is high if the data is structured, and thank to TextFSM unstructured data can easily be converted to structured.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s