Skip to content Skip to sidebar Skip to footer

Reading A Fortigate Configuration File With Python

Appologies for the really long drawn out question. I am trying to read in a config file and get a list of rules out. I have tried to use ConfigParser to do this but it is not a sta

Solution 1:

classParser(object):

     def__init__(self):
         self.my_section = 0
         self.flag_section = False# ...defparse_config(self, fields):
         self.my_section += 1# go on with fields# ...
         self.flag_section = Truedefparse_edit(self, line):
         ...

     defparse_set(self, line):
         ...

     defparse_end(self, line):
         ...

     defparse_file(self, path):
         withopen(path) as f:
              for line in f:
                  fields = f.strip().split(" ")

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

Solution 2:

I post my answer for people who first come here from Google when trying to parse Fortigate configuration file ! I rewrote what I found here based on my own needs and it works great.

from collections import defaultdict
from pprint import pprint
import sys

f = lambda: defaultdict(f)

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

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

classParser(object):

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

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

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

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

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

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

    defparse_file(self, path):          
        withopen(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 methodgetattr(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"]

Solution 3:

I do not know if this can help you too, but it did for me : http://wiki.python.org/moin/ConfigParserExamples

Have fun !

Solution 4:

I would do it in a simpler way:

flagSection = False
flagSub = False

mySection = 0
mySubsection = 0
myItem = 0withopen('d:/config.txt', 'r') as f:
    gen_lines = (line.rstrip() for line in f if line.strip())

    for line in gen_lines:

            if line[0:7]=='config ':
                mySection = mySection + 1
                newLine = line[7:]
                # Create a new section# Mark section as open
                flagSection == Trueelif line[0:5]=='edit '):
                mySubsection = mySubsection + 1
                newLine = line[5:]
                # Create a new sub-section# Mark subsection as open
                flagSub == true

            elif line[0:4]=='set '):
                myItem = myItem + 1
                name, value = x.split(' ',2)[1:]
                # Add to whatever is openelif line=='end':
                # If subsection = open then close and goto endif flagSub:
                # Or if section = open then close and goto endelif flagSection:
                # :Endcontinue

The instruction gen_lines = (line.rstrip() for line in f if line.strip()) creates a generator of not empty lines (thanks to the test if line.strip()) without newline and without blanks at the right (thanks to line.rstrip())

.

If I would know more about the operations you want to perform with name,value and in the section opened with if line=='end' , I could propose a code using regexes.

Edit

from time import clock

n = 1000000print'Measuring times with clock()'

te = clock()
for i in xrange(n):
    x = ('abcdfafdf'[:3] == 'end')
printclock()-te,
print"\tx = ('abcdfafdf'[:3] == 'end')"


te = clock()
for i in xrange(n):
    x = 'abcdfafdf'.startswith('end')
printclock()-te,
print"\tx = 'abcdfafdf'.startswith('end')"print'\nMeasuring times with timeit module'

import timeit

ti = timeit.repeat("x = ('abcdfafdf'[:3] == 'end')",repeat=10,number = n)
printmin(ti),
print"\tx = ('abcdfafdf'[:3] == 'end')"

to = timeit.repeat("x = 'abcdfafdf'.startswith('end')",repeat=10,number = n)
printmin(to),
print"\tx = 'abcdfafdf'.startswith('end')"

result:

Measuring times withclock()
0.543445605517  x = ('abcdfafdf'[:3] == 'end')
1.08590449345   x = 'abcdfafdf'.startswith('end')

Measuring times with timeit module
0.294152748464  x = ('abcdfafdf'[:3] == 'end')
0.901923289133  x = 'abcdfafdf'.startswith('end')

Is the fact the times are smaller with timieit than with clock() due to the fact that the GC is unplugged when the program is run ? Anyway, with either clock() or timeit module , executing startswith() takes more time than slicing.

Post a Comment for "Reading A Fortigate Configuration File With Python"