使用Python读取fortigate配置文件

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (6)

对于真正长期存在的问题的应用。

我试图在配置文件中读取并获取规则列表。我曾尝试使用ConfigParser来执行此操作,但它不是标准配置文件。该文件不包含节头,也没有令牌。

config section a set something to something else config subsection a set this to next end config firewall policy edit 76 set srcintf“There” set dstintf“Here” set srcaddr“all” set dstaddr“all” set action accept set schedule“always” set service“TCP_5600” next edit 77 set srcintf“here” set dstintf“there “ set srcaddr”all“ set dstaddr”all“ set action accept set schedule”always“ set service”PING“ next end

由于我无法弄清楚如何使ConfigParser工作,我以为我会尝试迭代文件,不幸的是我没有太多的编程技能所以我卡住了。我真的认为我让它变得比它应该更复杂。这是我写的代码;

class Parser(object):

    def __init__(self):
        self.config_section = ""
        self.config_header = ""
        self.section_list = []
        self.header_list = []

    def parse_config(self, fields): # Create a new section
        new_list = []
        self.config_section = " ".join(fields)
        new_list.append(self.config_section)

        if self.section_list: # Create a sub section
            self.section_list[-1].append(new_list)
        else: self.section_list.append(new_list)

    def parse_edit(self, line): # Create a new header
        self.config_header = line[0]
        self.header_list.append(self.config_header)

        self.section_list[-1].append(self.header_list)  

    def parse_set(self, line): # Key and values
        key_value = {}

        key = line[0]
        values = line[1:]
        key_value[key] = values

        if self.header_list:
            self.header_list.append(key_value)
        else: self.section_list[-1].append(key_value)

    def parse_next(self, line): # Close the header
        self.config_header = []

    def parse_end(self, line): # Close the section
        self.config_section = []

    def parse_file(self, path):
        with open(path) as f:
            for line in f:

                # Clean up the fields and remove unused lines.            
                fields = line.replace('"', '').strip().split(" ")

                if fields[0] == "set":
                    pass
                elif fields[0] == "end":
                    pass
                elif fields[0] == "edit":
                    pass
                elif fields[0] == "config":
                    pass
                elif fields[0] == "next":
                    pass
                else: continue

                # fetch and call method.
                method = fields[0]
                parse_method = "parse_" + method

                getattr(Parser, parse_method)(self, fields[1:])
                return self.section_list

config = Parser().parse_file('test_config.txt')

print config

我正在寻找的输出类似于以下内容;

[['section a',{'something':'to something else'},['subsection a',{'this':'to that'}]],['firewall policy',['76',{ 'srcintf':'There'},{'dstintf':'Here'} {etc。} {etc。}]]]

这就是我得到的

[['section a']]

编辑

我已经改变了上述内容以反映我目前所处的位置。我仍有问题得到我期望的输出。我似乎无法让清单正确。

提问于
用户回答回答于

我在尝试解析Fortigate配置文件时,首先来自谷歌的人发布了我的答案!我根据自己的需要改写了我在这里找到的东西,它很有效。

from collections import defaultdict
from pprint import pprint
import sys

f = lambda: defaultdict(f)

def getFromDict(dataDict, mapList):
    return reduce(lambda d, k: d[k], mapList, dataDict)

def setInDict(dataDict, mapList, value):
    getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value    

class Parser(object):

    def __init__(self):
        self.config_header = []
        self.section_dict = defaultdict(f)     

    def parse_config(self, fields): # Create a new section
        self.config_header.append(" ".join(fields))

    def parse_edit(self, line): # Create a new header
        self.config_header.append(line[0])

    def parse_set(self, line): # Key and values
        key = line[0]
        values = " ".join(line[1:])
        headers= self.config_header+[key]
        setInDict(self.section_dict,headers,values)

    def parse_next(self, line): # Close the header
        self.config_header.pop()

    def parse_end(self, line): # Close the section
        self.config_header.pop()

    def parse_file(self, path):          
        with open(path) as f:
            gen_lines = (line.rstrip() for line in f if line.strip())
            for line in gen_lines:
               # pprint(dict(self.section_dict))
                # Clean up the fields and remove unused lines.            
                fields = line.replace('"', '').strip().split(" ")

                valid_fields= ["set","end","edit","config","next"]
                if fields[0] in valid_fields:
                    method = fields[0]
                    # fetch and call method
                    getattr(Parser, "parse_" + method)(self, fields[1:])

        return self.section_dict

config = Parser().parse_file('FGT02_20130308.conf')

print config["system admin"]["admin"]["dashboard-tabs"]["1"]["name"]
print config["firewall address"]["ftp.fr.debian.org"]["type"]

热门问答

服务器操作台不是Windows咋换?

蒋小爱

腾讯云 · 技术支持 (已认证)

推荐
您好,您参考重装Windows系统;仅支持中国大陆地域(不含香港)。例如,Linux 重装为 Windows,Windows 重装为 Linux 。 登陆控制台 图片.png 选择【公共镜像】中Windows ,配置Windows密码,点击【开始重装】即可更换Windows 图片...... 展开详请

Golang云函数怎么做CORS?

Alfred

腾讯云 · 高级产品经理 (已认证)

推荐
设置响应 header 主要也就是相应数据结构, https://github.com/tencentyun/scf-go-lib/blob/master/cloudevents/scf/apigw.go APIGatewayProxyResponse 结构中的 header 字...... 展开详请

IM如何在离线登录后获取到多个会话的未读消息数量?

风子猪未来的前端开发工程师!成长的路上加油!勿忘初心方得始终
推荐
您好,建议按照以下步骤操作: 1. 离线上线后调用 webim.syncMsgs(updateUnreadCount); // 同步未读消息。 2. 在updateUnreadCount 回调函数中调用 webim.MsgStore.sessMap();获取会话列表,返回值是...... 展开详请

腾讯云短信服务有没有提供接口?

滑稽园扛把子

Swoole Inc · PHP工程师 (已认证)

As a PHP Developer
推荐
有接口的,个人认证用户不支持使用 API 申请短信模板,企业用户可以。详情文档:https://cloud.tencent.com/document/product/382/5817 URL 示例 POST https://yun.tim.qq.com/v5/tlssmssvr...... 展开详请

为什么无服务没有cpu资源?

Tina

腾讯云 · 产品经理 (已认证)

Go Serverless!
推荐
您好 函数实例可以使用的 CPU 资源与配置内存对应,例如 1024 MB 内存配置的函数,获得的 CPU 将是分配 512 MB 内存时的两倍。您可以通过提高配置内存,获得更多的 CPU。 相关文档:https://cloud.tencent.com/document/pr...... 展开详请

云函数怎么区分是公众号或小程序?

您好,是希望区分从微信公众号或者是小程序过来的请求吗?可以在请求里加字段标识一下做区分

所属标签

扫码关注云+社区

领取腾讯云代金券