使用python来解析cisco配置文件以查找具有特定服务策略的接口

时间:2013-09-30 18:50:50

标签: python regex cisco

我有数百个cisco配置文件,我需要找到(通过python)具有特定服务策略的接口,在这种情况下应用WIRELESS-IN。 我用来捕获接口的正则表达式是: ( '?!(接口*)$',re.DOTALL | re.M被)轻拍= re.compile

在这种情况下,我需要返回FastEthernet1/0/2

示例数据可能是这样的:

我有一个正则表达式将Interface元素与一个组匹配,但不是如何在该组中查看。 有人可以帮忙吗?

interface FastEthernet1/0/1
 description Foo
 switchport access vlan 300
 switchport mode access
 switchport port-security aging time 2
 no logging event link-status
 speed 100
 duplex full
 priority-queue out
 mls qos trust dscp
 no snmp trap link-status
 no cdp enable
 spanning-tree portfast
 hold-queue 120 in
 hold-queue 200 out
 ip dhcp snooping trust
!
interface FastEthernet1/0/2
 description wlap2
 switchport access vlan 100
 switchport mode access
 switchport port-security maximum 15
 switchport port-security
 switchport port-security aging time 2
 switchport port-security aging type inactivity
 ip access-group 100 in
 no logging event link-status
 srr-queue bandwidth shape 0 0 0 10
 queue-set 2
 priority-queue out
 no snmp trap link-status
 storm-control broadcast level pps 100 50
 storm-control multicast level pps 100 50
 storm-control action trap
 spanning-tree portfast
 spanning-tree bpduguard enable
 service-policy input WIRELESS_IN
 ip dhcp snooping limit rate 15
!
interface FastEthernet1/0/3
 description Test3
 switchport access vlan 199
 switchport mode access
 switchport port-security aging time 2
 no logging event link-status
 queue-set 2
 priority-queue out
 mls qos trust dscp
 no snmp trap link-status
 no cdp enable
 spanning-tree portfast
 service-policy input VOICE-LAN

我拼凑了这段代码:

import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)
pat2 = re.compile("service-policy.input.WIRELESS-IN")

data = pat.findall(cfgdata)
i=0
while i < len(data):
    if  pat2.findall(data[i]):
        print (data[i].split("\n")[0])
        i = i+1

    else:
        i = i+1
        pass

4 个答案:

答案 0 :(得分:4)

  

我有数百个cisco配置文件,我需要找到(通过python)具有特定服务策略的接口,在这种情况下应用WIRELESS-IN。我用来捕获接口的正则表达式是:pat = re.compile('(interface。*?)!$',re.DOTALL | re.M)   ...

     

在这种情况下,我需要返回FastEthernet1/0/2

答案:

您应该使用ciscoconfparse 1 ...假设我将您的配置存储在名为stackoverflow_question.conf的文件中...

>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('stackoverflow_question.conf')
>>> wifi_qos_intf = parse.find_parents_w_child('^interface', 'WIRELESS_IN')
>>> print wifi_qos_intf
['interface FastEthernet1/0/2']
>>>

如何运作

ciscoconfparse的API非常简单;它将思科配置分解为父母/子女。 service-policy input WIRELESS_IN被视为interface FastEthernet1/0/2的孩子。

当您致电CiscoConfParse(configuration_file)时,ciscoconfparse会将与Cisco IOS配置行的关系建立为父语句和子语句;返回包含所有这些关系的对象。然后parse.find_parent_w_child(parentstr, childstr)是上述对象的一种方法,该方法遍历配置并返回与parentstr匹配的文本行列表,并且有一个或多个子项匹配childstr

我使用像^interface这样的正则表达式来保证parentstr仅匹配Cisco IOS接口线。而不是其他可能在其中使用interface一词的陈述。


1 完全披露:我是ciscoconfparse的作者。

答案 1 :(得分:1)

这是否是一个更好的方式可以争议,但它至少有些不同:

import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat = '(?sm)interface (\S*)(?:(?!^!$).)*service-policy.input.WIRELESS_IN.*?!$'
data = re.findall(pat, cfgdata)

答案 2 :(得分:0)

    import re,string
f = open("sampleconfig.cfg")
cfgdata = f.read()
pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)
pat2 = re.compile("service-policy.input.WIRELESS-IN")

data = pat.findall(cfgdata)
i=0
while i < len(data):
    if  pat2.findall(data[i]):
        print (data[i].split("\n")[0])
        i = i+1

    else:
        i = i+1
        pass

答案 3 :(得分:0)

解决此任务的另一种方法是使用TTP模块(我是作者)使用匹配结果过滤功能,例如以下代码:

my_template="""
<group 
name="interfaces_with_WIRELESS-IN_policy.{{ interface }}" functions="contains(policy)">
interface {{ interface }}
 service-policy input {{ policy | equal(WIRELESS_IN) }}
</group>
"""

from ttp import ttp
parser = ttp(template=my_template)
parser.parse()
print(parser.result(format="json")[0])

将产生以下结果:

[
    {
        "interfaces_with_WIRELESS-IN_policy": {
            "FastEthernet1/0/2": {
                "policy": "WIRELESS_IN"
            }
        }
    }
]

工作方式

TTP解析OP提供的文本数据,以提取与之相连的接口和策略,而不会对这些结果进行任何过滤:

[
    {
        "interfaces_with_WIRELESS-IN_policy": {
            "FastEthernet1/0/1": {},
            "FastEthernet1/0/2": {
                "policy": "WIRELESS_IN"
            },
            "FastEthernet1/0/3": {
                "policy": "VOICE-LAN"
            }
        }
    }
]

但是通过使用匹配变量函数“等于”,我们可以指示TTP使不等于“ WIRELESS_IN”的匹配结果无效,此外,在为组定义function =“ contains(policy)”之后,TTP将检查组是否结果(是python字典)具有名为“ policy”的键,如果没有这样的键,组匹配结果将无效。

但是,上述代码将不会产生接口列表(按OP的要求),直到您应用另一个TTP分组功能-“ itemize”-会从分组结果中创建项目列表,例如模板:

my_template="""
<group 
name="interfaces_with_WIRELESS-IN_policy" functions="contains(policy) | itemize(interface)">
interface {{ interface }}
 service-policy input {{ policy | equal(WIRELESS_IN) }}
</group>
"""

将发出以下结果:

[
    {
        "interfaces_with_WIRELESS-IN_policy": [
            "FastEthernet1/0/2"
        ]
    }
]