pythonciscociscoconfparse

Python CiscoConfParse. How to get full block by command in middle?


I need to get full config of block by some command in middle. In the following example, I got an incomplete block where more indented children 'ip 10.2.2.1' were missing.

from ciscoconfparse import CiscoConfParse
from pprint import pprint

config = """
hostname switch
interface Vlan2
  description vlan2
  ip address 10.2.2.3/24
  hsrp 2
    ip 10.2.2.1
interface Vlan3
  description vlan3
  ip address 10.3.3.3/24
  hsrp 3
    ip 10.3.3.1
""".splitlines()
ccp = CiscoConfParse(config=config)
blocks = ccp.find_blocks("10.2.2.3/24")
print(blocks)  # ['interface Vlan2', '  description vlan2', '  ip address 10.2.2.3/24', '  hsrp 2']

Help me to find elegant way to get next output (with 'ip 10.2.2.1')

['interface Vlan2', '  description vlan2', '  ip address 10.2.2.3/24', '  hsrp 2', 'ip 10.2.2.1']

Solution

  • Using CiscoConfParse 1.9.37...

    from ciscoconfparse import CiscoConfParse
    
    config = """
    hostname switch
    interface Vlan2
      description vlan2
      ip address 10.2.2.3/24
      hsrp 2
        ip 10.2.2.1
    interface Vlan3
      description vlan3
      ip address 10.3.3.3/24
      hsrp 3
        ip 10.3.3.1
    """.splitlines()
    
    ccp = CiscoConfParse(config=config)
    
    # Find '10.2.2.3/24' and then recurse back to the interface object...
    intfobj = ccp.find_objects("10.2.2.3/24")[0].all_parents[0]
    # Buld a list of the parent interface plus all its children
    intf_list = [intfobj]
    intf_list.extend(intfobj.all_children)
    
    # Use recurse=True to search through multiple child levels...
    #    Use \d to ensure that you select the HSRP address instead of 'ip address'
    addrobj = ccp.find_child_objects(intfobj.text, "ip\s+\d\S+", recurse=True)[0]
    hsrp_addr = addrobj.re_match("ip (\S.+)")
    print(hsrp_addr)
    print("")
    print([ii.text for ii in intf_list])
    

    This prints:

    10.2.2.1
    
    ['interface Vlan2', '  description vlan2', '  ip address 10.2.2.3/24', '  hsrp 2', '    ip 10.2.2.1']
    

    To get the full block of children, just use all_children on that object...

    You should avoid find_blocks(), it's part of the old API which I will deprecate in version 2.0.