# Getting Config Values with CiscoConfParse¶

Now that we’re familiar with parent / child relationships, let’s tackle another common problem. How do you get specific values from a configuration?

For sure, you could use traditional Python techniques, such as Python’s re module; however, the re module is rather cumbersome when you’re retrieving a lot of config values.

CiscoConfParse introduces methods directly on CiscoConfParse objects which simplify getting values from a configuration:

For the next examples, we will use this configuration…

! Filename: short.conf
!
hostname IAHS1MDF-AR01A
!
vlan 10
name 192.0.2.0_24_HoustonUsers_S1_Bldg_MDF
vlan 20
name 128.66.0.0_24_HoustonPrinters_S1_Bldg_MDF
!
interface Vlan10
description Connection to Houston office LAN switches
standby 10 ip 192.0.2.1
standby 10 priority 110
arp timeout 240
no ip proxy-arp
!
interface Vlan20
description Connection to Houston printer subnet
standby 20 ip 128.66.01
standby 20 priority 110
!


## re_match_typed(): Get a value from an object¶

Let’s suppose we want the hostname of short.conf above. One approach is to use find_objects() and then use re_match_typed() to get the hostname:

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('short.conf')
>>> global_obj = parse.find_objects(r'^hostname')[0]
>>> hostname = global_obj.re_match_typed(r'^hostname\s+(\S+)', default='')
>>> hostname
'IAHS1MDF-AR01A'
>>>


Take note of the regex we used: r'hostname\s+(\S+)'. This regex has a capture group (bounded by the parenthesis), which re_match_typed() requires. re_match_typed() uses the contents of this capture group to return the value.

This technique is fine, but we have to tell Python to iterate over all config objects with find_objects() and then we extract the hostname from that object.

What if there was a way to get the hostname without calling find_objects()? As it happens, re_match_iter_typed() does it for you.

## re_match_iter_typed(): Iterate over all children and get a value¶

re_match_iter_typed() iterates over child objects and returns the first value it finds. This is very useful because re_match_iter_typed() does all the iteration for us.

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('short.conf')
>>> hostname = parse.re_match_iter_typed(r'^hostname\s+(\S+)', default='')
>>> hostname
'IAHS1MDF-AR01A'
>>>


Take note of the regex we used: r'hostname\s+(\S+)'. This regex has a capture group (bounded by the parenthesis), which re_match_iter_typed() requires. re_match_iter_typed() uses the contents of this capture group to return the value.

This code is better than the previous example, because it eliminates the call to find_objects() that we used above.

However, there are still times when you need to call find_objects(); one example is when you need to get the HSRP address from an interface.

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('short.conf')
>>> intf_obj = parse.find_objects(r'^interface\s+Vlan10$')[0] >>> hsrp_ip = intf_obj.re_match_iter_typed(r'standby\s10\sip\s(\S+)', ... default='') >>> hsrp_ip '192.0.2.1' >>>  The reason we had to call find_objects() is so we can get the specific inteface object that contains the HSRP address in question. You may be wondering, “Why does this method have typed in its name?”. This is because re_match_iter_typed() can return the value cast as a python type. By default, all return values are cast as a Python str. The following example looks for the ARP timeout on interface Vlan10, and returns it cast as a Python int. >>> from ciscoconfparse import CiscoConfParse >>> parse = CiscoConfParse('short.conf') >>> intf_obj = parse.find_objects(r'^interface\s+Vlan10$')[0]
>>> arp_timeout = intf_obj.re_match_iter_typed(r'arp\s+timeout\s+(\d+)',
...     result_type=int, default=4*3600)
>>> arp_timeout
240
>>>


Finally, let’s talk about two more re_match_iter_typed() keywords: default and untyped_default.

re_match_iter_typed() has a default keyword, which specifies what the default value should be if the regular expression doesn’t match the configuration. The value in default is automatically cast as the result_type.

However, there may be times when you don’t want default’s value to be cast as result_type. If you find yourself in that situation, you can call re_match_iter_typed() with untyped_default=True.

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('short.conf')
>>> intf_obj = parse.find_objects(r'^interface\s+Vlan20$')[0] >>> arp_timeout = intf_obj.re_match_iter_typed(r'arp\s+timeout\s+(\d+)', ... result_type=int, untyped_default=True, default='__no_explicit_value__') >>> arp_timeout '__no_explicit_value__' >>>  ## Getting multiple values from an interface with re_match_typed()¶ re_match_typed() and re_match_iter_typed() does not return mutliple values. Suppose we want to get all the DHCP helper-addresses from an interface. The best way to do this is to manually iterate over the children and append the values we want to a list. This script will get all the DHCP helper-addresses from Vlan10: >>> from ciscoconfparse import CiscoConfParse >>> parse = CiscoConfParse('short.conf') >>> retval = list() >>> >>> HELPER_REGEX = r'ip\s+helper-address\s+(\S+)$'
>>> NO_MATCH = '__no_match__'
>>>
>>> # Iterate over matching interfaces
>>> for intf_obj in parse.find_objects(r'^interface\s+Vlan10\$'):
...     for child_obj in intf_obj.children:  # Iterate over intf children
...         val = child_obj.re_match_typed(HELPER_REGEX, default=NO_MATCH)
...         if val!=NO_MATCH:
...             retval.append(val)
...
>>> retval
['198.51.100.12', '203.0.113.12']
>>>
`