defaults = { 'apt': { 'packages': { 'isc-dhcp-server': {}, }, }, 'bash_aliases': { 'leases': 'sudo dhcp-lease-list | tail -n +4 | sort -k 2,2', }, } @metadata_reactor.provides( 'dhcpd/fixed_allocations', ) def get_static_allocations(metadata): allocations = {} for rnode in repo.nodes: if rnode.metadata.get('location', '') != metadata.get('location', ''): continue for iface_name, iface_config in rnode.metadata.get('interfaces', {}).items(): if iface_config.get('dhcp', False): try: allocations[f'{rnode.name}_{iface_name}'] = { 'ipv4': sorted(iface_config['ips'])[0], 'mac': iface_config['mac'], } except KeyError: pass return { 'dhcpd': { 'fixed_allocations': allocations, } } @metadata_reactor.provides( 'nftables/rules/input/dhcpd', ) def nftables(metadata): rules = set() for iface in node.metadata.get('dhcpd/subnets', {}): rules.add(f'udp dport {{ 67, 68 }} iif {iface} accept') return { 'nftables': { 'rules': { 'input': { # can't use port_rules here, because we're generating interface based rules. 'dhcpd': sorted(rules), }, }, } }