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

问题描述 投票:2回答:4

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

在这种情况下,我需要返回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
python regex cisco
4个回答
5
投票

我有数百个cisco配置文件,我需要(通过python)查找具有在此情况下应用的无线服务的特定服务策略的接口。我用来捕获接口的Regex是: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非常简单;它将Cisco配置分解为父母/子女。 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的作者。

是否是更好的方法尚有争议,但至少有所不同:

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

如何解决此任务的另一种方法是使用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"
        ]
    }
]

1
投票

是否是更好的方法尚有争议,但至少有所不同:


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

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.