pvl.hosts.dhcp: implement support for dhcp:subclass=... using hardware ethernet
--- a/pvl/hosts/dhcp.py Mon Mar 02 19:45:06 2015 +0200
+++ b/pvl/hosts/dhcp.py Mon Mar 02 19:45:56 2015 +0200
@@ -1,10 +1,22 @@
import pvl.dhcp.config
import pvl.hosts.host
+def dhcp_host_subclass (host, subclass, ethernet):
+ """
+ Build a DHCP Item for declaring a subclass for a host.
+ """
+
+ # hardware-type prefixed hardware-address
+ hardware = pvl.dhcp.config.Field('1:' + ethernet)
+
+ return pvl.dhcp.config.Block(None, [
+ ('subclass', subclass, hardware),
+ ])
+
class HostDHCPError(pvl.hosts.host.HostError):
pass
-def dhcp_host_options (host, ethernet):
+def dhcp_host_options (host, ethernet, subclass=None):
"""
Yield specific dhcp.conf host { ... } items.
"""
@@ -19,9 +31,15 @@
if bootopt in host.boot:
yield bootopt, host.boot[bootopt]
-def dhcp_host (host):
+def dhcp_host (host,
+ subclass = None,
+):
"""
Yield pvl.dhcp.config.Block's
+
+ Takes dhcp:* extensions as keyword arguments
+
+ subclass: name - generate a subclass name $ethernet for this host
"""
if set(host.ethernet) == set([None]) :
@@ -39,8 +57,12 @@
for index, ethernet in host.ethernet.iteritems() :
name = host_fmt.format(host=host, index=index)
+ items = list(dhcp_host_options(host, ethernet))
- yield pvl.dhcp.config.Block(('host', name), list(dhcp_host_options(host, ethernet)), comment=comment)
+ yield pvl.dhcp.config.Block(('host', name), items, comment=comment)
+
+ if subclass:
+ yield dhcp_host_subclass(host, subclass, ethernet)
def dhcp_hosts (hosts):
"""
@@ -51,7 +73,9 @@
blocks = { }
for host in hosts:
- for block in dhcp_host(host):
+ extensions = host.extensions.get('dhcp', {})
+
+ for block in dhcp_host(host, **extensions):
if block.key in blocks:
raise HostDHCPError(host, "dhcp {block} conflict with {other}; hosts on multiple networks must use unique ethernet.XXX=... naming".format(block=block, other=blocks[block.key]))
--- a/pvl/hosts/tests.py Mon Mar 02 19:45:06 2015 +0200
+++ b/pvl/hosts/tests.py Mon Mar 02 19:45:56 2015 +0200
@@ -799,6 +799,23 @@
], []),
])
+ def testHostSubclass(self):
+ hosts = [Host.build('foo', 'test',
+ ethernet = '00:11:22:33:44:55',
+ extensions = dict(dhcp=dict(
+ subclass = 'debian',
+ )),
+ )]
+
+ self.assertBlocksEqual(list(dhcp.dhcp_hosts(hosts)), [
+ (('host', 'foo'), [
+ ('option', 'host-name', "foo"),
+ ('hardware', 'ethernet', '00:11:22:33:44:55'),
+ ], []),
+ (None, [
+ ('subclass', 'debian', '1:00:11:22:33:44:55'),
+ ], []),
+ ])
if __name__ == '__main__':
unittest.main()