我正在尝试解析 cisco 配置防火墙输出。我正在尝试递归查找嵌套的object-group
,直到找到每个object-group
这是一个场景示例:
asa# sh object-group id aws_all_critical_vpcs
object-group network aws_all_critical_vpcs
group-object aws_criticalprd_us_west_2_app_db
group-object aws_critical_us_west_2_app_db
group-object aws_criticalprd_us_east_1_app_db
group-object aws_critical_us_east_1_app_db
group-object aws_criticalprd_eu_west_1_app_db
group-object aws_critical_eu_west_1_app_db
group-object aws_criticalprd_eu_central_1_app_db
group-object aws_critical_eu_central_1_app_db
asa# sh object-group id aws_criticalprd_us_west_2_app_db
object-group network aws_criticalprd_us_west_2_app_db
group-object aws_criticalprd_us_west_2_app
group-object aws_criticalprd_us_west_2_db
asa# sh object-group id aws_criticalprd_us_west_2_app
object-group network aws_criticalprd_us_west_2_app
network-object 10.159.160.0 255.255.248.0
asa# sh object-group id aws_criticalprd_us_west_2_db
object-group network aws_criticalprd_us_west_2_db
network-object 10.159.168.0 255.255.248.0
我已经设法让一些东西可以工作,但是由于硬编码的if/else
,代码可以挖掘出嵌套级别的限制
for e in og_content:
if 'group-object' not in e:
new_og_content.append(e)
elif 'group-object' in e:
new_og_content.append(e)
for k in find_the_lines(og_list,e.split()[1]):
new_og_content.append(k)
if 'network-object' in k:
new_og_content.append(' ' + k)
elif 'group-object' in k:
for z in find_the_lines(og_list,k.split()[1]):
if 'network-object' in z:
new_og_content.append(' ' + z)
输出看起来不错,正如我想要的,但我想要一些更智能的东西,在嵌套对象组的查找数量上没有限制。这是一个输出示例:
group-object aws_criticalprd_us_west_2_app_db
group-object aws_criticalprd_us_west_2_app
network-object 10.159.160.0 255.255.248.0
group-object aws_criticalprd_us_west_2_db
network-object 10.159.168.0 255.255.248.0
group-object aws_critical_us_west_2_app_db
group-object aws_critical_us_west_2_app
network-object 10.159.192.0 255.255.248.0
group-object aws_critical_us_west_2_db
...etc...
有什么建议吗?
最佳答案
TTP 可以帮助解析这些数据并使用 python 函数对其进行转换,以下是示例代码:
from ttp import ttp
template = """
<input load="text">
asa# sh object-group id aws_criticalprd_us_west_2_app
object-group network aws_criticalprd_us_west_2_app
network-object 10.159.160.0 255.255.248.0
network-object 10.159.161.0 255.255.248.0
asa# sh object-group id aws_criticalprd_us_west_2_db
object-group network aws_criticalprd_us_west_2_db
network-object 10.159.168.0 255.255.248.0
asa# sh object-group id aws_criticalprd_us_west_2_app_db
object-group network aws_criticalprd_us_west_2_app_db
group-object aws_criticalprd_us_west_2_app
group-object aws_criticalprd_us_west_2_db
asa# sh object-group id aws_all_critical_vpcs
object-group network aws_all_critical_vpcs
group-object aws_criticalprd_us_west_2_app_db
group-object aws_critical_us_west_2_app_db
group-object aws_criticalprd_us_east_1_app_db
group-object aws_critical_us_east_1_app_db
group-object aws_criticalprd_eu_west_1_app_db
group-object aws_critical_eu_west_1_app_db
group-object aws_criticalprd_eu_central_1_app_db
group-object aws_critical_eu_central_1_app_db
</input>
<group name="{{ network_obj }}">
object-group network {{ network_obj }}
group-object {{ group_obj | to_list | joinmatches }}
network-object {{ subnet | PHRASE | to_list | joinmatches }}
</group>
<macro>
def lookup_objects(data, name=""):
# kick recursion off
if name == "":
return {key: lookup_objects(data, name=key) for key in data[0].keys()}
# if name in data, check if it contains subnet or run recursion for group_obj:
elif name in data[0]:
if "subnet" in data[0][name]:
return data[0][name]["subnet"]
return {
group_obj: lookup_objects(data, name=group_obj)
for group_obj in data[0][name].get("group_obj", [])
}
else:
return {}
</macro>
<output macro="lookup_objects"/>
"""
parser = ttp(template=template)
parser.parse()
print(parser.result(format="json")[0])
输出为:
{
"aws_all_critical_vpcs": {
"aws_critical_eu_central_1_app_db": {},
"aws_critical_eu_west_1_app_db": {},
"aws_critical_us_east_1_app_db": {},
"aws_critical_us_west_2_app_db": {},
"aws_criticalprd_eu_central_1_app_db": {},
"aws_criticalprd_eu_west_1_app_db": {},
"aws_criticalprd_us_east_1_app_db": {},
"aws_criticalprd_us_west_2_app_db": {
"aws_criticalprd_us_west_2_app": [
"10.159.160.0 255.255.248.0",
"10.159.161.0 255.255.248.0"
],
"aws_criticalprd_us_west_2_db": [
"10.159.168.0 255.255.248.0"
]
}
},
"aws_criticalprd_us_west_2_app": [
"10.159.160.0 255.255.248.0",
"10.159.161.0 255.255.248.0"
],
"aws_criticalprd_us_west_2_app_db": {
"aws_criticalprd_us_west_2_app": [
"10.159.160.0 255.255.248.0",
"10.159.161.0 255.255.248.0"
],
"aws_criticalprd_us_west_2_db": [
"10.159.168.0 255.255.248.0"
]
},
"aws_criticalprd_us_west_2_db": [
"10.159.168.0 255.255.248.0"
]
}
工作原理
TTP 使用定义的组运行解析,该组本身将产生以下输出:
[
{
"aws_all_critical_vpcs": {
"group_obj": [
"aws_criticalprd_us_west_2_app_db",
"aws_critical_us_west_2_app_db",
"aws_criticalprd_us_east_1_app_db",
"aws_critical_us_east_1_app_db",
"aws_criticalprd_eu_west_1_app_db",
"aws_critical_eu_west_1_app_db",
"aws_criticalprd_eu_central_1_app_db",
"aws_critical_eu_central_1_app_db"
]
},
"aws_criticalprd_us_west_2_app": {
"subnet": [
"10.159.160.0 255.255.248.0",
"10.159.161.0 255.255.248.0"
]
},
"aws_criticalprd_us_west_2_app_db": {
"group_obj": [
"aws_criticalprd_us_west_2_app",
"aws_criticalprd_us_west_2_db"
]
},
"aws_criticalprd_us_west_2_db": {
"subnet": [
"10.159.168.0 255.255.248.0"
]
}
}
]
使用宏标记中定义的“lookup_objects”函数进一步处理上述结构,该函数递归查找“group_obj”名称,并用上面结果中的值替换它们。
如果你想运行上面的模板,TTP需要从github存储库安装,而不是从pypi安装,例如从 repo 克隆源代码,解压并运行“python setup.py install”
关于Python——递归字符串查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58861229/