|
1 import collections |
1 import ipaddress, ipaddr # XXX: conversion |
2 import ipaddress, ipaddr # XXX: conversion |
2 import pvl.hosts |
3 import pvl.hosts |
|
4 import pvl.hosts.host |
3 |
5 |
4 def parse_interfaces(interfaces): |
6 class HostInterface(object): |
5 for interface, value in interfaces.iteritems(): |
7 """ |
6 if not isinstance(value, dict): |
8 A single host-interface. |
7 yield (interface, None), ipaddress.ip_interface(value) |
9 """ |
8 else: |
|
9 for unit, ip in value.iteritems(): |
|
10 yield (interface, int(unit)), ipaddress.ip_interface(value) |
|
11 |
10 |
|
11 ip4 = None |
|
12 |
|
13 def __init__(self, name): |
|
14 self.name = name |
|
15 |
|
16 def __str__(self): |
|
17 return self.name |
|
18 |
12 @pvl.hosts.extension |
19 @pvl.hosts.extension |
13 class HostInterface(object): |
20 class HostInterfaces(object): |
|
21 """ |
|
22 A host with multiple sub-interfaces. |
|
23 |
|
24 Typically used for point-to-point interfaces between routers. For multi-homed hosts, it might make |
|
25 more sense to use multiple hosts in different domains. |
|
26 |
|
27 [foo] |
|
28 interface:ip.eth0 = 10.255.1.1/30 |
|
29 |
|
30 [bar] |
|
31 interface:ip.eth1 = 10.255.1.2/30 |
|
32 """ |
|
33 |
14 EXTENSION = 'interface' |
34 EXTENSION = 'interface' |
15 |
35 |
16 @classmethod |
36 @classmethod |
17 def build (cls, **interfaces): |
37 def build (cls, ip={}): |
18 return cls(dict(parse_interfaces(interfaces))) |
38 interfaces = collections.defaultdict(HostInterface) |
|
39 |
|
40 for iface, ip in pvl.hosts.host.parse_dict(ip, parse=ipaddress.ip_interface).iteritems(): |
|
41 if iface in interfaces: |
|
42 iface = interfaces[iface] |
|
43 else: |
|
44 iface = interfaces[iface] = HostInterface(iface) |
|
45 |
|
46 interfaces[iface].ip4 = ip |
|
47 |
|
48 return cls(interfaces) |
19 |
49 |
20 def __init__ (self, interfaces): |
50 def __init__ (self, interfaces): |
21 self.interfaces = interfaces |
51 self.interfaces = interfaces |
22 |
52 |
23 def addresses (self): |
53 def addresses (self): |
24 for (iface, unit), ip in self.interfaces.iteritems(): |
54 """ |
25 # XXX: ipaddr |
55 Yield additional sub-addresses for host interfaces. |
26 yield iface, ipaddr.IPAddress(str(ip.ip)) |
56 """ |
|
57 |
|
58 for iface in self: |
|
59 if iface.ip4: |
|
60 # XXX: convert |
|
61 yield iface.name, ipaddr.IPv4Address(str(iface.ip4.ip)) |
|
62 |
|
63 def __iter__(self): |
|
64 """ |
|
65 HostInterface's with stable ordering. |
|
66 """ |
|
67 |
|
68 return iter(sorted(self.interfaces.itervalues(), key=str)) |
|
69 |