@!@
from univention.config_registry.interfaces import Interfaces
from itertools import groupby
from operator import itemgetter

def auto(interface, start):
	"""Print 'auto iface' statements only once."""
	print
	if not start:
		return
	if interface not in auto.printed_interfaces:
		print 'auto %s' % (interface,)
		auto.printed_interfaces.add(interface)
auto.printed_interfaces = set()

def ipv4(ucr, interfaces):
	"""Setup IPv4."""
	gateway = interfaces.ipv4_gateway
	if gateway is False:
		print '# WARNING: invalid IPv4 address in gateway'

	for name, iface in interfaces.all_interfaces:
		addr = iface.ipv4_address()
		if iface.type == 'dhcp':
			if interfaces.handler == 'ifplugd' and \
					ucr.is_true(value=iface.get('ifplugd', '1')):
				auto(iface.name, iface.start)
				print 'iface %s inet dhcp' % (iface.name,)
			else:
				continue
		elif iface.type == 'manual':
			auto(iface.name, iface.start)
			print 'iface %s inet manual' % (iface.name,)
		elif addr is False:
			print '# ERROR: invalid IPv4 address for interface %s' % (name,)
			continue
		elif addr:
			auto(iface.name, iface.start)
			print 'iface %s inet static' % (iface.name,)
			print '\taddress %s' % (addr.ip,)
			print '\tnetmask %s' % (addr.netmask,)
			if iface.network:
				print '\tnetwork %s' % (iface.network,)
			if iface.broadcast:
				print '\tbroadcast %s' % (iface.broadcast,)
			if gateway:
				if addr.prefixlen == addr.max_prefixlen and \
						interfaces.primary in (name, iface.name):
					print '\tpointopoint %s' % (gateway,)
					print '\tgateway %s' % (gateway,)
					gateway = None
				elif gateway in addr:
					print '\tgateway %s' % (gateway,)
					gateway = None
		else:
			continue

		for route in iface.routes:
			print '\tup route add -%s dev %s' % (route, iface.name)

		for value in iface.options:
			print '\t%s' % (value,)

def ipv6(interfaces):
	"""Setup IPv6."""
	gateway = interfaces.ipv6_gateway
	if gateway is False:
		print '# WARNING: invalid IPv6 address in ipv6/gateway)'

	# Validate addresses
	interface_addresses = {}
	for iface, name in interfaces.ipv6_interfaces:
		addr = iface.ipv6_address(name)
		if addr is False:
			print '# ERROR: invalid IPv6 address in interfaces/%s/ipv6/%s/*' % \
				(iface.name, name)
			continue
		addresses = interface_addresses.setdefault(iface.name, set())
		if addr in addresses:
			print '# ERROR: duplicate IPv6 address in interfaces/%s/ipv6/%s/*' % \
				(iface.name, name)
			continue
		addresses.add(addr)

	# configure interface
	for iface, names in groupby(interfaces.ipv6_interfaces, itemgetter(0)):
		try:
			addresses = interface_addresses[iface.name]
		except KeyError:
			continue  # validation failed
		if not addresses:
			continue  # validation failed

		auto(iface.name, iface.start)
		print 'iface %s inet6 static' % (iface.name,)

		for i, (iface, name) in enumerate(names):
			addr = iface.ipv6_address(name)
			try:
				addresses.remove(addr)
			except KeyError:
				continue  # invalid or duplicate
			print '# %s' % (name,)
			if i == 0:  # first
				print '\taddress %s' % (addr.ip,)
				print '\tnetmask %s' % (addr.prefixlen,)
			else:
				print '\tup   ip -6 addr add %s dev %s' % (addr.ip, iface.name)
				print '\tdown ip -6 addr del %s dev %s' % (addr.ip, iface.name)
			# check if gateway is local on this interface
			if gateway:
				if addr.prefixlen == addr.max_prefixlen and \
						iface.name == interfaces.primary:
					data = (gateway, iface.name)
					print '\tup   ip -6 route add %s dev %s' % data
					print '\tup   ip -6 route add default via %s dev %s' % data
					print '\tdown ip -6 route del default via %s dev %s' % data
					print '\tdown ip -6 route del %s dev %s' % data
					gateway = None
				elif gateway in addr:
					print '\tgateway %s' % (gateway,)
					gateway = None

		if not iface.ipv4_address():
			for value in iface.options:
				print '\t%s' % (value,)

def main():
	"""Create configured interfaces."""
	interfaces = Interfaces(configRegistry)
	ipv4(configRegistry, interfaces)
	ipv6(interfaces)

main()
# vim:set sw=4 ts=4 noet:
@!@
