[Netconf-devel] Please test my /e/n/i parser
Thomas Hood
jdthood@aglu.demon.nl
Tue, 19 Apr 2005 16:45:13 +0200
--=-YPclYvqkxyxHkGgT6EPq
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
I have written and attached a Python program to
parse /etc/network/interfaces into data structures useful for possible
further work on network configuration tools written in Python. Please
test on _your_ /etc/network/interfaces file and let me know whether or
not you are able to break it. :)
--
Thomas Hood <jdthood@aglu.demon.nl>
--=-YPclYvqkxyxHkGgT6EPq
Content-Disposition: attachment; filename=parse-interfaces
Content-Type: application/x-python; name=parse-interfaces
Content-Transfer-Encoding: 7bit
#!/usr/bin/env python
#
# Copyright (C) 2005 by Thomas Hood
#
# This is free software. You can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
import os
import re
class IfupdownConfig:
def __init__(self, file):
self.ifaces = [] # list of dictionaries
# each with keys 'name', 'family', 'method', 'options'
# each of whose values is a string
# except for 'options' whose value is a list of pairs
self.mappings = [] # list of dictionaries
# each with keys 'patterns', 'maps' and 'script'
# each of whose values is a list
# except for 'script' whose value is a string
self.allows = dict([('auto',[])]) # dictionary with keys that are group names
# each of whose values is a list
fd = open(file)
comment_line = re.compile(r'^\s*#.*')
mapping_line = re.compile(r'^\s*mapping\s+([^\s]+(\s+[^\s]+)*)\s*$')
map_line = re.compile(r'^\s*map\s+([^\s]+(\s+[^\s]+)*)\s*$')
script_line = re.compile(r'^\s*script\s+([^\s]+(\s+[^\s]+)*)\s*$')
allow_line = re.compile(r'^\s*allow-([^\s]+)\s+([^\s]+(\s+[^\s]+)*)\s*$')
auto_line = re.compile(r'^\s*auto\s+([^\s]+(\s+[^\s]+)*)\s*$')
iface_line = re.compile(r'^\s*iface\s+(?P<name>[^\s]+)\s+(?P<family>[^\s]+)\s+(?P<method>[^\s]+)')
option_line = re.compile(r'^\s*([^\s]+)\s+([^\s]+(\s+[^\s]+)*)\s*$')
current_mapping = None
current_iface = None
for line in fd:
m = comment_line.match(line)
if m:
continue
m = allow_line.match(line)
if m:
current_mapping = None
current_iface = None
iface_list = re.split( r'\s+', m.group(2) )
if self.allows.has_key( m.group(1) ):
self.allows[ m.group(1) ] = self.allows[ m.group(1) ] + iface_list
else:
new_item = ( m.group(1), iface_list )
self.allows = dict( self.allows.items() + [ new_item ] )
continue
m = auto_line.match(line)
if m:
current_mapping = None
current_iface = None
iface_list = re.split( r'\s+', m.group(1) )
self.allows[ 'auto' ] = self.allows[ 'auto' ] + iface_list
continue
m = mapping_line.match(line)
if m:
current_iface = None
pattern_list = re.split( r'\s+', m.group(1) )
current_mapping = { 'patterns': pattern_list, 'maps': [] }
self.mappings.append(current_mapping)
continue
m = map_line.match(line)
if m:
if current_mapping:
self.mappings[-1]['maps'].append( m.group(1) )
continue
m = script_line.match(line)
if m:
if current_mapping:
self.mappings[-1]['script'] = m.group(1)
continue
m = iface_line.match(line)
if m:
current_mapping = None
current_iface = { 'name': '', 'family': '', 'method': '', 'options': [] }
current_iface.update( m.groupdict() )
self.ifaces.append( current_iface )
continue
# iface option lines must be matched last because there is
# no list of all possible options
m = option_line.match(line)
if m:
if current_iface:
self.ifaces[-1]['options'].append( m.group(1,2) )
continue
e_n_interfaces_file = '/etc/network/interfaces'
cfg = IfupdownConfig(e_n_interfaces_file)
print '--- allows ---'
print
for k, v in cfg.allows.iteritems():
print k, v
print
print '--- mappings ---'
for i in cfg.mappings:
print
for k, v in i.iteritems():
print k, v
print
print '--- ifaces ---'
for i in cfg.ifaces:
print
for k, v in i.iteritems():
print k ,v
--=-YPclYvqkxyxHkGgT6EPq--