我有数百个思科配置文件,我需要(通过 python)查找(通过 python)在本例无线输入中应用了特定服务策略的接口。
这是我用来捕获界面的正则表达式:
pat=re.compile('(interface.*?)!$',re.DOTALL|re.M)
应该返回“FastEthernet1/0/2”。
我的正则表达式将界面元素分类为行列表,但我应该如何在行列表中搜索 WIRELESS-IN?
配置示例:
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)在本例无线输入中应用了特定服务策略的接口。我用来捕获接口的正则表达式是: pat=re.compile('(interface.*?)!$',re.DOTALL|re.M) ...
在这种情况下我需要返回
。FastEthernet1/0/2
您应该使用 ciscoconfparse1...假设我将您的配置存储在名为
stackoverflow_question.conf
... 的文件中
>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse('stackoverflow_question.conf')
>>> # .find_parents_w_child() returns a list of matching parent conf lines
>>> wifi_qos_intfs = parse.find_parents_w_child('^interface', 'WIRELESS_IN')
>>> print(wifi_qos_intfs)
['interface FastEthernet1/0/2']
>>>
ciscoconfparse 的 API 相当简单;它将 Cisco 配置分为父级/子级。
service-policy input WIRELESS_IN
被视为 interface FastEthernet1/0/2
的子级。
当您调用
CiscoConfParse(configuration_file)
时,ciscoconfparse 将与 Cisco IOS 配置行建立关系作为父语句和子语句;返回具有所有这些关系的对象。 然后 parse.find_parents_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)
解决此任务的另一种方法是使用 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"
}
}
}
]
但是通过使用匹配变量函数“equal”,我们可以指示TTP使不等于“WIRELESS_IN”的匹配结果无效,此外,在为组定义functions =“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"
]
}
]
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)查找(通过 python)在本例无线输入中应用了特定服务策略的接口。我用来捕获接口的正则表达式是: pat=re.compile('(interface.*?)!$',re.DOTALL|re.M) ...
在这种情况下我需要返回
。FastEthernet1/0/2
仅供参考,ciscoconfparse2 有不同的 API,这就是我添加新答案的原因。 如果您正在编写新代码,请使用 ciscoconfparse2。
您应该使用 ciscoconfparse21...假设我将您的配置存储在名为
stackoverflow_question.conf
... 的文件中
>>> from ciscoconfparse2 import CiscoConfParse
>>> parse = CiscoConfParse('stackoverflow_question.conf')
>>> # .find_parent_objects() returns a list of matching parent conf lines
>>> wifi_qos_intfs = parse.find_parent_objects(['^interface', 'WIRELESS_IN'])
>>> print(wifi_qos_intfs)
['interface FastEthernet1/0/2']
>>>
ciscoconfparse2 的 API 相当简单;它将 Cisco 配置分为父级/子级。
service-policy input WIRELESS_IN
被视为 interface FastEthernet1/0/2
的子级。
当您调用
CiscoConfParse(configuration_file)
时,[ciscoconfparse] 将与 Cisco IOS 配置行建立关系作为父语句和子语句;返回具有所有这些关系的对象。 然后 parse.find_parent_objects([parentstr, childstr])
是上述对象上的一种方法,它遍历配置并返回与 parentstr
匹配的文本行列表,并且有一个或多个与 childstr
匹配的子级。
我使用了像
^interface
这样的正则表达式来保证 parentstr
仅匹配 Cisco IOS 接口线路。而不是其他可能也使用单词 interface
的陈述。
1全面披露:我是 ciscoconfparse2 的作者。