From fbb4e2f7a5af8fecfc87abea5525ae945bee24da Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sat, 6 Jun 2020 10:18:25 +0200 Subject: [PATCH 1/5] systemd-networkd: first draft --- bundles/systemd-networkd/files/interfaces | 3 ++ .../systemd-networkd/files/template.network | 33 +++++++++++++++++++ bundles/systemd-networkd/items.py | 22 +++++++++++++ groups/all.py | 1 + 4 files changed, 59 insertions(+) create mode 100644 bundles/systemd-networkd/files/interfaces create mode 100644 bundles/systemd-networkd/files/template.network create mode 100644 bundles/systemd-networkd/items.py diff --git a/bundles/systemd-networkd/files/interfaces b/bundles/systemd-networkd/files/interfaces new file mode 100644 index 0000000..2e67d1c --- /dev/null +++ b/bundles/systemd-networkd/files/interfaces @@ -0,0 +1,3 @@ +auto lo +iface lo inet loopback +iface lo inet6 loopback diff --git a/bundles/systemd-networkd/files/template.network b/bundles/systemd-networkd/files/template.network new file mode 100644 index 0000000..3784104 --- /dev/null +++ b/bundles/systemd-networkd/files/template.network @@ -0,0 +1,33 @@ +[Match] +Name=${interface} + +[Network] +% if config.get('dhcp', False): +DHCP=yes +IPv6AcceptRA=yes +UseHostname=no +% else: +DHCP=no +IPv6AcceptRA=no +% endif + +% for addr in sorted(config.get('ip_addresses', set())): +Address=${addr} +% endfor + +% if config.get('ip4_masquerade_outgoing', False): +IPMasquerade=yes +IPForward=ipv4 +%endif + +% if 'ip6_gateway' in config: +[Route] +Gateway=${config['ip6_gateway']} +GatewayOnLink=yes +% endif + +% if 'ip4_gateway' in config: +[Route] +Gateway=${config['ip4_gateway']} +GatewayOnLink=yes +% endif diff --git a/bundles/systemd-networkd/items.py b/bundles/systemd-networkd/items.py new file mode 100644 index 0000000..6f0764e --- /dev/null +++ b/bundles/systemd-networkd/items.py @@ -0,0 +1,22 @@ +assert node.has_bundle('systemd') + +files = { + '/etc/network/interfaces': {}, +} + +for interface, config in node.metadata.get('interfaces', {}).items(): + files['/etc/systemd/network/10-{}.network'.format(interface)] = { + 'source': 'template.network', + 'content_type': 'mako', + 'context': { + 'interface': interface, + 'config': config, + }, + 'triggers': { + 'svc_systemd:systemd-networkd:restart', + }, + } + +svc_systemd = { + 'systemd-networkd': {}, +} diff --git a/groups/all.py b/groups/all.py index a8e4494..7a5e9e4 100644 --- a/groups/all.py +++ b/groups/all.py @@ -9,6 +9,7 @@ groups['all'] = { 'postfix', 'sudo', 'systemd', + 'systemd-networkd', 'users', }, 'metadata': { From 5e7c7671e00250f665381df09f13b05dcb3050e1 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Mon, 9 Nov 2020 14:48:19 +0100 Subject: [PATCH 2/5] bundles/systemd-networkd: proper config --- bundles/systemd-networkd/files/interfaces | 3 -- .../systemd-networkd/files/template.network | 50 ++++++++++++------- bundles/systemd-networkd/items.py | 17 ++++++- 3 files changed, 46 insertions(+), 24 deletions(-) delete mode 100644 bundles/systemd-networkd/files/interfaces diff --git a/bundles/systemd-networkd/files/interfaces b/bundles/systemd-networkd/files/interfaces deleted file mode 100644 index 2e67d1c..0000000 --- a/bundles/systemd-networkd/files/interfaces +++ /dev/null @@ -1,3 +0,0 @@ -auto lo -iface lo inet loopback -iface lo inet6 loopback diff --git a/bundles/systemd-networkd/files/template.network b/bundles/systemd-networkd/files/template.network index 3784104..03bb020 100644 --- a/bundles/systemd-networkd/files/template.network +++ b/bundles/systemd-networkd/files/template.network @@ -1,6 +1,35 @@ +<% + from ipaddress import ip_network +%>\ [Match] Name=${interface} + +% for addr in sorted(config.get('ips', set())): +[Address] +<% + if '/' in addr: + ip, prefix = addr.split('/') + else: + ip = addr + prefix = '32' +%>\ +Address=${ip}/${prefix} + +% endfor + +% if 'gateway4' in config: +[Route] +Gateway=${config['gateway4']} +GatewayOnLink=yes +% endif + +% if 'gateway6' in config: +[Route] +Gateway=${config['gateway6']} +GatewayOnLink=yes +% endif + [Network] % if config.get('dhcp', False): DHCP=yes @@ -11,23 +40,6 @@ DHCP=no IPv6AcceptRA=no % endif -% for addr in sorted(config.get('ip_addresses', set())): -Address=${addr} -% endfor - -% if config.get('ip4_masquerade_outgoing', False): -IPMasquerade=yes -IPForward=ipv4 +% if config.get('forwarding', False): +IPForward=yes %endif - -% if 'ip6_gateway' in config: -[Route] -Gateway=${config['ip6_gateway']} -GatewayOnLink=yes -% endif - -% if 'ip4_gateway' in config: -[Route] -Gateway=${config['ip4_gateway']} -GatewayOnLink=yes -% endif diff --git a/bundles/systemd-networkd/items.py b/bundles/systemd-networkd/items.py index 6f0764e..9980ab5 100644 --- a/bundles/systemd-networkd/items.py +++ b/bundles/systemd-networkd/items.py @@ -1,10 +1,20 @@ assert node.has_bundle('systemd') files = { - '/etc/network/interfaces': {}, + '/etc/network/interfaces': { + 'delete': True, + }, } -for interface, config in node.metadata.get('interfaces', {}).items(): +directories = { + '/etc/systemd/network': { + 'purge': True, + }, +} + +# Don't use .get() here. We might end up with a node without a network +# config! +for interface, config in node.metadata['interfaces'].items(): files['/etc/systemd/network/10-{}.network'.format(interface)] = { 'source': 'template.network', 'content_type': 'mako', @@ -12,6 +22,9 @@ for interface, config in node.metadata.get('interfaces', {}).items(): 'interface': interface, 'config': config, }, + 'needed_by': { + 'svc_systemd:systemd-networkd', + }, 'triggers': { 'svc_systemd:systemd-networkd:restart', }, From 91fd33cfa03aaf647669c59e802826b6cf8efca0 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Mon, 9 Nov 2020 14:58:09 +0100 Subject: [PATCH 3/5] bundles/systemd-networkd: better dhcp support --- .../systemd-networkd/files/template-dhcp.network | 14 ++++++++++++++ bundles/systemd-networkd/files/template.network | 7 ------- bundles/systemd-networkd/items.py | 7 ++++++- 3 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 bundles/systemd-networkd/files/template-dhcp.network diff --git a/bundles/systemd-networkd/files/template-dhcp.network b/bundles/systemd-networkd/files/template-dhcp.network new file mode 100644 index 0000000..65c4a67 --- /dev/null +++ b/bundles/systemd-networkd/files/template-dhcp.network @@ -0,0 +1,14 @@ +<% + from ipaddress import ip_network +%>\ +[Match] +Name=${interface} + +[Network] +DHCP=yes +IPv6AcceptRA=yes +UseHostname=no + +% if config.get('forwarding', False): +IPForward=yes +%endif diff --git a/bundles/systemd-networkd/files/template.network b/bundles/systemd-networkd/files/template.network index 03bb020..2d9d124 100644 --- a/bundles/systemd-networkd/files/template.network +++ b/bundles/systemd-networkd/files/template.network @@ -4,7 +4,6 @@ [Match] Name=${interface} - % for addr in sorted(config.get('ips', set())): [Address] <% @@ -31,14 +30,8 @@ GatewayOnLink=yes % endif [Network] -% if config.get('dhcp', False): -DHCP=yes -IPv6AcceptRA=yes -UseHostname=no -% else: DHCP=no IPv6AcceptRA=no -% endif % if config.get('forwarding', False): IPForward=yes diff --git a/bundles/systemd-networkd/items.py b/bundles/systemd-networkd/items.py index 9980ab5..448b705 100644 --- a/bundles/systemd-networkd/items.py +++ b/bundles/systemd-networkd/items.py @@ -15,8 +15,13 @@ directories = { # Don't use .get() here. We might end up with a node without a network # config! for interface, config in node.metadata['interfaces'].items(): + if config.get('dhcp', False): + template = 'template-dhcp.network' + else: + template = 'template.network' + files['/etc/systemd/network/10-{}.network'.format(interface)] = { - 'source': 'template.network', + 'source': template, 'content_type': 'mako', 'context': { 'interface': interface, From d90c9edc2294ff6922827828078eee67cea9fe0d Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Mon, 9 Nov 2020 15:16:29 +0100 Subject: [PATCH 4/5] nodes: fix interface config --- nodes/gce/bind01.py | 4 ++-- nodes/gce/dns02.py | 4 ++-- nodes/gce/dns03.py | 4 ++-- nodes/htz-cloud/luther.py | 6 ++---- nodes/htz-cloud/pirmasens.py | 6 ++---- nodes/htz-cloud/sewfile.py | 6 ++---- nodes/htz/ex42-1048908.py | 10 ++++------ nodes/rx300.py | 11 +++++++++++ 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/nodes/gce/bind01.py b/nodes/gce/bind01.py index 16252ef..3372669 100644 --- a/nodes/gce/bind01.py +++ b/nodes/gce/bind01.py @@ -13,8 +13,8 @@ nodes['gce.bind01'] = { }, 'metadata': { 'interfaces': { - 'eth0': { - 'ipv4': { + 'ens4': { + 'ips': { '10.156.0.4', }, 'gateway4': '10.156.0.1', diff --git a/nodes/gce/dns02.py b/nodes/gce/dns02.py index 0424e7d..7e2120f 100644 --- a/nodes/gce/dns02.py +++ b/nodes/gce/dns02.py @@ -9,8 +9,8 @@ nodes['gce.dns02'] = { }, 'metadata': { 'interfaces': { - 'eth0': { - 'ipv4': { + 'ens4': { + 'ips': { '10.132.0.2', }, 'gateway4': '10.132.0.1', diff --git a/nodes/gce/dns03.py b/nodes/gce/dns03.py index c2264b1..60d31c4 100644 --- a/nodes/gce/dns03.py +++ b/nodes/gce/dns03.py @@ -9,8 +9,8 @@ nodes['gce.dns03'] = { }, 'metadata': { 'interfaces': { - 'eth0': { - 'ipv4': { + 'ens4': { + 'ips': { '10.166.0.2', }, 'gateway4': '10.166.0.1', diff --git a/nodes/htz-cloud/luther.py b/nodes/htz-cloud/luther.py index bed9b1c..ba31b64 100644 --- a/nodes/htz-cloud/luther.py +++ b/nodes/htz-cloud/luther.py @@ -10,11 +10,9 @@ nodes['htz-cloud.luther'] = { 'metadata': { 'interfaces': { 'eth0': { - 'ipv4': { + 'ips': { '195.201.136.20', - }, - 'ipv6': { - '2a01:4f8:c2c:fc3b::1', + '2a01:4f8:c2c:fc3b::1/64', }, 'gateway4': '172.31.1.1', 'gateway6': 'fe80::1', diff --git a/nodes/htz-cloud/pirmasens.py b/nodes/htz-cloud/pirmasens.py index 351d5ed..15d7a9b 100644 --- a/nodes/htz-cloud/pirmasens.py +++ b/nodes/htz-cloud/pirmasens.py @@ -6,11 +6,9 @@ nodes['htz-cloud.pirmasens'] = { 'metadata': { 'interfaces': { 'eth0': { - 'ipv4': { + 'ips': { '195.201.90.143', - }, - 'ipv6': { - '2a01:4f8:1c1c:2acf::1', + '2a01:4f8:1c1c:2acf::1/64', }, 'gateway4': '172.31.1.1', 'gateway6': 'fe80::1', diff --git a/nodes/htz-cloud/sewfile.py b/nodes/htz-cloud/sewfile.py index e421124..66a579b 100644 --- a/nodes/htz-cloud/sewfile.py +++ b/nodes/htz-cloud/sewfile.py @@ -11,11 +11,9 @@ nodes['htz-cloud.sewfile'] = { 'metadata': { 'interfaces': { 'eth0': { - 'ipv4': { + 'ips': { '116.203.205.248', - }, - 'ipv6': { - '2a01:4f8:c0c:c71b::1', + '2a01:4f8:c0c:c71b::1/64', }, 'gateway4': '172.31.1.1', 'gateway6': 'fe80::1', diff --git a/nodes/htz/ex42-1048908.py b/nodes/htz/ex42-1048908.py index 2290fd4..854fe6c 100644 --- a/nodes/htz/ex42-1048908.py +++ b/nodes/htz/ex42-1048908.py @@ -24,12 +24,10 @@ nodes['htz.ex42-1048908'] = { 'metadata': { 'interfaces': { 'enp0s31f6': { - 'ipv4': { - '94.130.52.224', - }, - 'ipv6': { - '2a01:4f8:10b:2a5f::02', - '2a01:4f8:10b:2a5f::1337', + 'ips': { + '94.130.52.224/26', + '2a01:4f8:10b:2a5f::02/64', + '2a01:4f8:10b:2a5f::1337/64', }, 'gateway4': '94.130.52.193', 'gateway6': 'fe80::1', diff --git a/nodes/rx300.py b/nodes/rx300.py index 58c2316..7232492 100644 --- a/nodes/rx300.py +++ b/nodes/rx300.py @@ -13,6 +13,17 @@ nodes['rx300'] = { }, 'groups': set(), 'metadata': { + 'interfaces': { + 'eth0': { + 'ips': { + '172.19.138.26/24', + }, + 'gateway4': '172.19.138.1', + }, + 'eth1': { + 'dhcp': True, + }, + }, 'zfs': { 'module_options': { 'zfs_arc_max_mb': 16384, # 16GB From 44414f2375e0a09e4932ec090fe62b0645082261 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Mon, 9 Nov 2020 15:23:44 +0100 Subject: [PATCH 5/5] libs/tools: adjust resolve_identifier() to new interface config --- libs/tools.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/tools.py b/libs/tools.py index e84bd38..3f42c74 100644 --- a/libs/tools.py +++ b/libs/tools.py @@ -20,10 +20,11 @@ def resolve_identifier(repo, identifier): found_ips = set() for node in nodes: for interface, config in node.metadata.get('interfaces', {}).items(): - for ip in config.get('ipv4', set()): - found_ips.add(ip_address(ip)) - for ip in config.get('ipv4', set()): - found_ips.add(ip_address(ip)) + for ip in config.get('ips', set()): + if '/' in ip: + found_ips.add(ip_address(ip.split('/')[0])) + else: + found_ips.add(ip_address(ip)) if node.metadata.get('external_ipv4', None): found_ips.add(ip_address(node.metadata.get('external_ipv4')))