tero@479: import pvl.dhcp.config tero@479: import pvl.hosts.host tero@479: tero@698: def dhcp_host_subclass (host, subclass, ethernet): tero@698: """ tero@698: Build a DHCP Item for declaring a subclass for a host. tero@698: """ tero@698: tero@698: # hardware-type prefixed hardware-address tero@698: hardware = pvl.dhcp.config.Field('1:' + ethernet) tero@698: tero@698: return pvl.dhcp.config.Block(None, [ tero@698: ('subclass', subclass, hardware), tero@698: ]) tero@698: tero@479: class HostDHCPError(pvl.hosts.host.HostError): tero@479: pass tero@479: tero@698: def dhcp_host_options (host, ethernet, subclass=None): tero@479: """ terom@669: Yield specific dhcp.conf host { ... } items. tero@479: """ tero@479: tero@479: yield 'option', 'host-name', host.name tero@697: yield 'hardware', 'ethernet', pvl.dhcp.config.Field(ethernet) tero@479: tero@479: if host.ip: tero@697: yield 'fixed-address', pvl.dhcp.config.Field(str(host.ip)) tero@479: tero@689: for bootopt in ('next-server', 'filename'): tero@689: if bootopt in host.boot: tero@689: yield bootopt, host.boot[bootopt] tero@479: tero@698: def dhcp_host (host, tero@698: subclass = None, tero@698: ): tero@479: """ terom@669: Yield pvl.dhcp.config.Block's tero@698: tero@698: Takes dhcp:* extensions as keyword arguments tero@698: tero@698: subclass: name - generate a subclass name $ethernet for this host tero@479: """ tero@479: tero@479: if set(host.ethernet) == set([None]) : tero@479: host_fmt = "{host.name}" tero@479: elif host.ethernet : tero@479: host_fmt = "{host.name}-{index}" tero@479: else : tero@479: # nothing to be seen here tero@479: return tero@479: tero@479: if host.owner : tero@479: comment = u"Owner: {host.owner}".format(host=host) tero@479: else: tero@479: comment = None tero@479: tero@479: for index, ethernet in host.ethernet.iteritems() : tero@479: name = host_fmt.format(host=host, index=index) tero@698: items = list(dhcp_host_options(host, ethernet)) tero@479: tero@698: yield pvl.dhcp.config.Block(('host', name), items, comment=comment) tero@698: tero@698: if subclass: tero@698: yield dhcp_host_subclass(host, subclass, ethernet) tero@479: tero@483: def dhcp_hosts (hosts): tero@479: """ tero@479: tero@479: Verifies that there are no dupliate hosts. tero@479: """ tero@479: tero@479: blocks = { } tero@479: tero@479: for host in hosts: tero@698: extensions = host.extensions.get('dhcp', {}) tero@698: tero@698: for block in dhcp_host(host, **extensions): terom@669: if block.key in blocks: terom@669: 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])) tero@483: terom@669: blocks[block.key] = host tero@483: terom@669: yield block