diff --git a/.gitignore b/.gitignore index d1f7e7b..6feee2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .secrets.cfg __pycache__ +*.swp diff --git a/bundles/dhcpd/files/dhcpd.conf b/bundles/dhcpd/files/dhcpd.conf new file mode 100644 index 0000000..98ff2b4 --- /dev/null +++ b/bundles/dhcpd/files/dhcpd.conf @@ -0,0 +1,33 @@ +#dhcpd.conf + +<% +import re +%> +ddns-update-style none; + +authoritative; + +% for identfier, subnet in dhcp_config.get('subnets', {}).items(): +subnet ${subnet['subnet']} netmask ${subnet['netmask']} { +% if subnet.get('range_lower', None) and subnet.get('range_higher', None): + range ${subnet['range_lower']} ${subnet['range_higher']}; +% endif + interface "${subnet['interface']}"; + default-lease-time ${subnet.get('default-lease-time', 600)}; + max-lease-time ${subnet.get('max-lease-time', 3600)}; +% for option, value in sorted(subnet.get('options', {}).items()): + % if re.match('([^0-9\.,\ ])', value): + option ${option} "${value}"; + % else: + option ${option} ${value}; + % endif +% endfor +} +% endfor + +% for identifier, allocation in dhcp_config.get('fixed_allocations', {}).items(): +host ${identifier} { + hardware ethernet ${allocation['mac']}; + fixed-address ${allocation['ipv4']}; +} +% endfor diff --git a/bundles/dhcpd/files/isc-dhcp-server b/bundles/dhcpd/files/isc-dhcp-server new file mode 100644 index 0000000..8d0ee70 --- /dev/null +++ b/bundles/dhcpd/files/isc-dhcp-server @@ -0,0 +1,18 @@ +# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) + +# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). +#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf +#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf + +# Path to dhcpd's PID file (default: /var/run/dhcpd.pid). +#DHCPDv4_PID=/var/run/dhcpd.pid +#DHCPDv6_PID=/var/run/dhcpd6.pid + +# Additional options to start dhcpd with. +# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead +#OPTIONS="" + +# On what interfaces should the DHCP server (dhcpd) serve DHCP requests? +# Separate multiple interfaces with spaces, e.g. "eth0 eth1". +INTERFACESv4="${listen_interfaces}" +INTERFACESv6="" diff --git a/bundles/dhcpd/items.py b/bundles/dhcpd/items.py new file mode 100644 index 0000000..85e388e --- /dev/null +++ b/bundles/dhcpd/items.py @@ -0,0 +1,37 @@ +files = { + '/etc/dhcp/dhcpd.conf': { + 'content_type': 'mako', + 'context': { + 'dhcp_config': node.metadata.get('dhcpd'), + }, + 'needs': { + 'pkg_apt:isc-dhcp-server' + }, + 'triggers': { + 'svc_systemd:isc-dhcp-server:restart', + }, + }, + '/etc/default/isc-dhcp-server': { + 'content_type': 'mako', + 'context': { + 'listen_interfaces': node.metadata.get('dhcpd', {}).get('listen_interfaces'), + }, + 'needs': { + 'pkg_apt:isc-dhcp-server' + }, + 'triggers': { + 'svc_systemd:isc-dhcp-server:restart', + }, + }, +} + +svc_systemd = { + 'isc-dhcp-server': { + 'needs': { + 'pkg_apt:isc-dhcp-server', + 'file:/etc/dhcp/dhcpd.conf', + 'file:/etc/default/isc-dhcp-server', + }, + }, +} + diff --git a/bundles/dhcpd/metadata.py b/bundles/dhcpd/metadata.py new file mode 100644 index 0000000..ce6fb6b --- /dev/null +++ b/bundles/dhcpd/metadata.py @@ -0,0 +1,36 @@ +defaults = { + 'apt': { + 'packages': { + 'isc-dhcp-server': {}, + }, + }, +} + + +@metadata_reactor +def get_static_allocations(metadata): + allocations = {} + for rnode in repo.nodes_in_group('home'): + for identifier, interface in rnode.metadata.get('interfaces', {}).items(): + if interface.get('dhcp', False): + allocations[rnode.name] = { + 'ipv4': sorted(interface['ips'])[0], + 'mac': interface['mac'], + } + return { + 'dhcpd': { + 'fixed_allocations': allocations, + } + } + +@metadata_reactor +def get_listen_interfaces(metadata): + listen_interfaces = [] + for identfier, subnet in node.metadata.get('dhcpd/subnets', {}).items(): + listen_interfaces.append(subnet.get('interface')) + + return { + 'dhcpd': { + 'listen_interfaces': ' '.join(sorted(listen_interfaces)), + } + } diff --git a/groups/locations.py b/groups/locations.py index c52b766..b9bc5c3 100644 --- a/groups/locations.py +++ b/groups/locations.py @@ -49,6 +49,7 @@ groups['home'] = { 'lldp', }, 'metadata': { + 'location': 'home', 'nameservers': { '172.19.138.1', }, diff --git a/nodes/home/router.py b/nodes/home/router.py index 4c7f197..12a6f45 100644 --- a/nodes/home/router.py +++ b/nodes/home/router.py @@ -3,6 +3,7 @@ nodes['home.router'] = { 'bundles': { 'iptables', 'pppd', + 'dhcpd', }, 'groups': set(), 'metadata': { @@ -45,6 +46,26 @@ nodes['home.router'] = { 'password': vault.decrypt('encrypt$gAAAAABfruaXEDkaFksFMU8g97ydWyJF8p2KcSDJJBlzaOLDsLL6oCDYjG1kMPVESOzqjn8ThtSht1uZDuMCstA-sATmLS-EWQ=='), 'interface': 'enp1s0.100', }, + 'dhcpd': { + 'subnets': { + 'home': { + 'subnet': '172.19.138.0', + 'netmask': '255.255.255.0', + 'range_lower': '172.19.138.100', + 'range_higher': '172.19.138.250', + 'interface': 'enp1s0.42', + 'options': { + 'routers': '172.19.138.1', + 'domain-name-servers': '8.8.8.8, 8.8.4.4', + 'domain-name': 'franzi-home.kunbox.net', + 'broadcast-address': '172.19.138.255', + 'subnet-mask': '255.255.255.0', + }, + 'default-lease-time': 300, + 'max-lease-time': 1800, + }, + }, + }, 'vm': { 'cpu': 2, 'ram': 2,