[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--