用Python读取Fortigate配置文件

1 投票
4 回答
6205 浏览
提问于 2025-04-17 03:05

抱歉提了个很长的问题。

我想读取一个配置文件,并从中获取一系列规则。我尝试使用ConfigParser来实现,但这个文件不是标准的配置文件。这个文件没有章节标题,也没有标记。

比如说:

配置部分 a
把某个东西设置成另一个东西
配置子部分 a
把这个设置成那个
下一个
结束

配置防火墙策略
编辑 76
设置源接口 "那里"
设置目标接口 "这里"
设置源地址 "所有"
设置目标地址 "所有"
设置动作 接受
设置时间表 "总是"
设置服务 "TCP_5600"
下一个
编辑 77
设置源接口 "这里"
设置目标接口 "那里"
设置源地址 "所有"
设置目标地址 "所有"
设置动作 接受
设置时间表 "总是"
设置服务 "PING"
下一个
结束

因为我搞不定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'}{等等}{等等}]]]

而我得到的是:

[['section a']]

编辑

我已经更新了上面的内容,反映我目前的进展。我仍然在获取预期输出方面遇到问题。我就是无法把列表弄对。

4 个回答

0

我不知道这对你是否有帮助,但对我来说是有用的:http://wiki.python.org/moin/ConfigParserExamples

祝你玩得开心!

1

我在这里分享我的答案,主要是为了那些从谷歌搜索过来,想要解析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"]
1
 class Parser(object):

     def __init__(self):
         self.my_section = 0
         self.flag_section = False
         # ...

    def parse_config(self, fields):
         self.my_section += 1
         # go on with fields
         # ...
         self.flag_section = True

     def parse_edit(self, line):
         ...

     def parse_set(self, line):
         ...

     def parse_end(self, line):
         ...

     def parse_file(self, path):
         with open(path) as f:
              for line in f:
                  fields = f.strip().split(" ")

                  method = fields[0]
                  # fetch and call method
                  getattr(Parser, "parse_" + method)(self, fields[1:])

当然可以!请把你想要翻译的内容发给我,我会帮你把它变得更简单易懂。

撰写回答