From 0cb4db946c3436cd54e62056af7da42f6c4049ca Mon Sep 17 00:00:00 2001 From: Jonathon Anderson Date: Thu, 31 Oct 2024 13:55:31 -0600 Subject: [PATCH] Add support for VLANs and static routes #1257 - NetworkManager - wicked - ifcfg - debian.network_interfaces Signed-off-by: Jonathon Anderson --- CHANGELOG.md | 2 + .../internal/networkmanager_test.go | 128 +++++++++++------- .../NetworkManager/internal/nodes.conf-vlan | 13 ++ .../NetworkManager/conf.d/ww4-unmanaged.ww | 1 + .../system-connections/ww4-managed.ww | 80 ++++++----- .../internal/debian_interfaces_test.go | 18 +-- .../debian.interfaces/internal/nodes.conf | 2 + .../etc/network/interfaces.d/default.ww | 29 ++-- overlays/ifcfg/internal/ifcfg_test.go | 81 +++++++++-- overlays/ifcfg/internal/nodes.conf-vlan | 11 ++ .../etc/sysconfig/network-scripts/ifcfg.ww | 44 +++--- .../etc/sysconfig/network-scripts/route.ww | 10 ++ overlays/wicked/internal/nodes.conf-vlan | 13 ++ overlays/wicked/internal/wicked_test.go | 101 ++++++++++++-- .../rootfs/etc/wicked/ifconfig/ifcfg.xml.ww | 46 ++++--- 15 files changed, 410 insertions(+), 169 deletions(-) create mode 100644 overlays/NetworkManager/internal/nodes.conf-vlan create mode 100644 overlays/ifcfg/internal/nodes.conf-vlan create mode 100644 overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww create mode 100644 overlays/wicked/internal/nodes.conf-vlan diff --git a/CHANGELOG.md b/CHANGELOG.md index f1c7a687..02aedd6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add `wwctl clean` to remove OCI cache and overlays from deleted nodes - Add `wwctl container import --platform`. #1381 - Read environment variables from `/etc/default/warewulfd` #725 +- Add support for VLANs to NetworkManager, wicked, ifcfg, debian.network_interfaces overlays. #1257 +- Add support for static routes to NetworkManager, wicked, ifcfg, debian.network_interfaces overlays. #1257 ### Changed diff --git a/overlays/NetworkManager/internal/networkmanager_test.go b/overlays/NetworkManager/internal/networkmanager_test.go index 64e12940..2fb52d6a 100644 --- a/overlays/NetworkManager/internal/networkmanager_test.go +++ b/overlays/NetworkManager/internal/networkmanager_test.go @@ -13,66 +13,44 @@ import ( func Test_networkmanagerOverlay(t *testing.T) { env := testenv.New(t) defer env.RemoveAll(t) - env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf") env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww", "../rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww") env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww", "../rootfs/etc/NetworkManager/system-connections/ww4-managed.ww") tests := []struct { - name string - args []string - log string + name string + nodes_conf string + args []string + log string }{ { - name: "NetworkManager:ww4-unmanaged.ww", - args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"}, - log: networkmanager_unmanaged, + name: "NetworkManager:ww4-unmanaged.ww", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"}, + log: networkmanager_unmanaged, }, { - name: "NetworkManager:ww4-managed.ww", - args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"}, - log: networkmanager_managed, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd := show.GetCommand() - cmd.SetArgs(tt.args) - stdout := bytes.NewBufferString("") - stderr := bytes.NewBufferString("") - logbuf := bytes.NewBufferString("") - cmd.SetOut(stdout) - cmd.SetErr(stderr) - wwlog.SetLogWriter(logbuf) - err := cmd.Execute() - assert.NoError(t, err) - assert.Empty(t, stdout.String()) - assert.Empty(t, stderr.String()) - assert.Equal(t, tt.log, logbuf.String()) - }) - } -} - -func Test_unmanaged_networkmanagerOverlay_with_empty_mac(t *testing.T) { - env := testenv.New(t) - defer env.RemoveAll(t) - env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes_empty_mac.conf") - env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww", "../rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww") - - tests := []struct { - name string - args []string - log string - }{ - { - name: "NetworkManager:ww4-unmanaged.ww", - args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"}, - log: networkmanager_unmanaged_with_empty_mac, + name: "NetworkManager:ww4-managed.ww", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"}, + log: networkmanager_managed, + }, + { + name: "NetworkManager:ww4-unmanaged.ww with empty mac address", + nodes_conf: "nodes_empty_mac.conf", + args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"}, + log: networkmanager_unmanaged_with_empty_mac, + }, + { + name: "NetworkManager:ww4-managed.ww with vlan", + nodes_conf: "nodes.conf-vlan", + args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"}, + log: networkmanager_managed_with_vlan, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf) cmd := show.GetCommand() cmd.SetArgs(tt.args) stdout := bytes.NewBufferString("") @@ -94,6 +72,7 @@ const networkmanager_unmanaged_with_empty_mac string = `backupFile: true writeFile: true Filename: warewulf-unmanaged.conf # This file is autogenerated by warewulf + [main] plugins=keyfile @@ -105,6 +84,7 @@ const networkmanager_unmanaged string = `backupFile: true writeFile: true Filename: warewulf-unmanaged.conf # This file is autogenerated by warewulf + [main] plugins=keyfile @@ -116,14 +96,16 @@ const networkmanager_managed string = `backupFile: true writeFile: true Filename: warewulf-default.conf # This file is autogenerated by warewulf + [connection] id=default interface-name=wwnet0 type=ethernet autoconnect=true + [ethernet] mac-address=e6:92:39:49:7b:03 -# bond + [ipv4] address=192.168.3.21/24 gateway=192.168.3.1 @@ -137,14 +119,16 @@ backupFile: true writeFile: true Filename: warewulf-secondary.conf # This file is autogenerated by warewulf + [connection] id=secondary interface-name=wwnet1 type=ethernet autoconnect=true + [ethernet] mac-address=9a:77:29:73:14:f1 -# bond + [ipv4] address=192.168.3.22/24 gateway=192.168.3.1 @@ -156,3 +140,49 @@ addr-gen-mode=stable-privacy method=ignore never-default=true ` + +const networkmanager_managed_with_vlan string = `backupFile: true +writeFile: true +Filename: warewulf-tagged.conf +# This file is autogenerated by warewulf + +[connection] +id=tagged +interface-name=eth0.902 +type=vlan +autoconnect=true + +[ipv4] +address= +method=manual +route1=192.168.1.0/24,192.168.2.254 + +[vlan] +interface-name=eth0.902 +parent=eth0 +id=902 + +[ipv6] +addr-gen-mode=stable-privacy +method=ignore +never-default=true +backupFile: true +writeFile: true +Filename: warewulf-untagged.conf +# This file is autogenerated by warewulf + +[connection] +id=untagged +interface-name=eth0 +type=ethernet +autoconnect=true + +[ipv4] +address= +method=manual + +[ipv6] +addr-gen-mode=stable-privacy +method=ignore +never-default=true +` diff --git a/overlays/NetworkManager/internal/nodes.conf-vlan b/overlays/NetworkManager/internal/nodes.conf-vlan new file mode 100644 index 00000000..3302207f --- /dev/null +++ b/overlays/NetworkManager/internal/nodes.conf-vlan @@ -0,0 +1,13 @@ +nodes: + node1: + primary network: untagged + network devices: + untagged: + device: eth0 + tagged: + type: vlan + device: eth0.902 + tags: + vlan_id: 902 + parent_device: eth0 + route1: "192.168.1.0/24,192.168.2.254" diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww index be8a9cbb..a8edc267 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww @@ -1,6 +1,7 @@ {{- $filename := print "warewulf-unmanaged.conf" }} {{- file $filename }} # This file is autogenerated by warewulf + [main] plugins=keyfile diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww index c4adc114..2640b892 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww @@ -2,78 +2,84 @@ {{- $filename := print "warewulf-" $connection_id ".conf" }} {{- file $filename }} # This file is autogenerated by warewulf + [connection] id={{ $connection_id }} interface-name={{ $netdev.Device }} -{{ if eq $netdev.Type "bond-slave" -}} +{{- if eq $netdev.Type "bond-slave" }} slave-type=bond {{- $conn := split "_" $connection_id }} {{- $master := $conn._0 }} master={{ $master }} type=ethernet -{{ else -}} +{{- else }} type={{if $netdev.Type}}{{ $netdev.Type }}{{ else }}ethernet{{end}} -{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}} +{{- if or $netdev.OnBoot (eq $netdev.OnBoot nil) }} autoconnect=true -{{ end -}} -{{ end -}} -{{ if $netdev.Hwaddr -}} -{{ if or (eq $netdev.Type "ethernet") (not $netdev.Type ) -}} +{{- end }} +{{- end }} +{{- if $netdev.Hwaddr }} +{{- if or (eq $netdev.Type "ethernet") (not $netdev.Type ) }} + [ethernet] mac-address={{ $netdev.Hwaddr }} -{{ if $netdev.MTU -}} +{{- if $netdev.MTU }} mtu={{ $netdev.MTU }} -{{ end -}} -{{ end -}} -{{ end -}} +{{- end }} +{{- end }} +{{- end }} +{{- if eq $netdev.Type "bond" }} -# bond -{{ if eq $netdev.Type "bond" -}} -[ethernet] -{{ if $netdev.MTU -}} -mtu={{ $netdev.MTU }} -{{ end -}} [bond] downdelay=0 miimon=100 mode=802.3ad xmit_hash_policy=layer2+3 updelay=0 -{{ end -}} +{{- end }} +{{- if eq $netdev.Type "infiniband" }} -{{ if eq $netdev.Type "infiniband" -}} [infiniband] transport-mode=datagram -{{ if $netdev.MTU -}} +{{- if $netdev.MTU }} mtu={{ $netdev.MTU }} -{{ end -}} -{{ end -}} +{{- end }} +{{- end }} +{{- if ne $netdev.Type "bond-slave" }} -{{ if and ($netdev.IpCIDR) (ne $netdev.Type "bond-slave") -}} [ipv4] +{{- if not (eq $netdev.IpCIDR nil) }} address={{ $netdev.IpCIDR }} -{{ if $netdev.Gateway -}} +{{- end }} +{{- if $netdev.Gateway }} gateway={{ $netdev.Gateway }} -{{ end -}} +{{- end }} method=manual {{- $dns := "" }} -{{range $tk, $tv := $netdev.Tags -}} -{{ $prefix := substr 0 3 $tk -}} -{{ if eq $prefix "DNS" -}} -{{ $dns = print $dns $tv ";" -}} -{{ end -}} -{{ end -}} -{{ if ne $dns "" -}} +{{- range $tk, $tv := $netdev.Tags }} +{{- if eq (substr 0 3 $tk) "DNS" }} +{{- $dns = print $dns $tv ";" }} +{{- else if eq (substr 0 5 $tk) "route" }} +{{$tk}}={{$tv}} +{{- end }} +{{- end }} +{{- if ne $dns "" }} dns={{$dns}} -{{ end -}} -{{ end -}} +{{- end }} +{{- end }} +{{- if eq $netdev.Type "vlan" }} + +[vlan] +interface-name={{ $netdev.Device }} +parent={{ $netdev.Tags.parent_device }} +id={{ $netdev.Tags.vlan_id }} +{{- end }} -{{/* always autoconfigure ipv6 */}} [ipv6] addr-gen-mode=stable-privacy method=ignore never-default=true {{ if $netdev.Ipaddr6 -}} ipaddr="{{ $netdev.Ipaddr6 }}" -{{ end -}} -{{ end -}} +{{- end }} +{{- end -}} diff --git a/overlays/debian.interfaces/internal/debian_interfaces_test.go b/overlays/debian.interfaces/internal/debian_interfaces_test.go index 9f47c1d6..ad0a3ade 100644 --- a/overlays/debian.interfaces/internal/debian_interfaces_test.go +++ b/overlays/debian.interfaces/internal/debian_interfaces_test.go @@ -13,23 +13,25 @@ import ( func Test_wickedOverlay(t *testing.T) { env := testenv.New(t) defer env.RemoveAll(t) - env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf") env.ImportFile(t, "var/lib/warewulf/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww", "../rootfs/etc/network/interfaces.d/default.ww") tests := []struct { - name string - args []string - log string + name string + nodes_conf string + args []string + log string }{ { - name: "debian.interfaces", - args: []string{"--render", "node1", "debian.interfaces", "etc/network/interfaces.d/default.ww"}, - log: debian_interfaces, + name: "debian.interfaces", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "debian.interfaces", "etc/network/interfaces.d/default.ww"}, + log: debian_interfaces, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf) cmd := show.GetCommand() cmd.SetArgs(tt.args) stdout := bytes.NewBufferString("") @@ -69,5 +71,5 @@ iface wwnet1 inet static netmask 255.255.255.0 gateway 192.168.3.1 mtu 9000 - up ifmetric wwnet1 30 + up ip route add 192.168.1.0/24 via 192.168.3.254 dev wwnet1 ` diff --git a/overlays/debian.interfaces/internal/nodes.conf b/overlays/debian.interfaces/internal/nodes.conf index df4f7439..3ff766da 100644 --- a/overlays/debian.interfaces/internal/nodes.conf +++ b/overlays/debian.interfaces/internal/nodes.conf @@ -15,3 +15,5 @@ nodes: netmask: 255.255.255.0 gateway: 192.168.3.1 mtu: 9000 + tags: + route1: "192.168.1.0/24,192.168.3.254" diff --git a/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww b/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww index a65ce140..178ec263 100644 --- a/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww +++ b/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww @@ -1,15 +1,18 @@ -{{range $devname, $netdev := .ThisNode.NetDevs -}} -{{- $filename := print $devname }} -{{- file $filename }} +{{- range $devname, $netdev := .ThisNode.NetDevs }} +{{- file $devname }} # This file is autogenerated by warewulf -{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}} -auto {{$netdev.Device}} +{{- if or $netdev.OnBoot (eq $netdev.OnBoot nil) }} +auto {{ $netdev.Device }} +{{- end }} +allow-hotplug {{ $netdev.Device }} +iface {{ $netdev.Device }} inet static + address {{ $netdev.Ipaddr }} + netmask {{ $netdev.Netmask }} + {{ if $netdev.Gateway }}gateway {{ $netdev.Gateway }}{{ end }} + {{ if $netdev.MTU }}mtu {{ $netdev.MTU }}{{ end }} + {{- range $tk, $tv := $netdev.Tags }} + {{- if eq (substr 0 5 $tk) "route" }} + up ip route add {{ index (splitList "," $tv) 0 }} via {{ index (splitList "," $tv) 1 }} dev {{ $netdev.Device }} + {{- end }} + {{- end }} {{ end -}} -allow-hotplug {{$netdev.Device}} -iface {{$netdev.Device}} inet static - address {{$netdev.Ipaddr}} - netmask {{$netdev.Netmask}} - {{ if $netdev.Gateway }}gateway {{$netdev.Gateway}}{{- end}} - {{ if $netdev.MTU }}mtu {{$netdev.MTU}}{{- end}} - up ifmetric {{$netdev.Device}} 30 -{{- end}} diff --git a/overlays/ifcfg/internal/ifcfg_test.go b/overlays/ifcfg/internal/ifcfg_test.go index 01542954..3725f4b6 100644 --- a/overlays/ifcfg/internal/ifcfg_test.go +++ b/overlays/ifcfg/internal/ifcfg_test.go @@ -13,29 +13,45 @@ import ( func Test_ifcfgOverlay(t *testing.T) { env := testenv.New(t) defer env.RemoveAll(t) - env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf") env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww", "../rootfs/etc/sysconfig/network-scripts/ifcfg.ww") + env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww", "../rootfs/etc/sysconfig/network-scripts/route.ww") env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network.ww", "../rootfs/etc/sysconfig/network.ww") tests := []struct { - name string - args []string - log string + name string + nodes_conf string + args []string + log string }{ { - name: "ifcfg:ifcfg.ww", - args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"}, - log: ifcfg, + name: "ifcfg:ifcfg.ww", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"}, + log: ifcfg, }, { - name: "ifcfg:network.ww", - args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network.ww"}, - log: ifcfg_network, + name: "ifcfg:network.ww", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network.ww"}, + log: ifcfg_network, + }, + { + name: "ifcfg:ifcfg.ww (vlan)", + nodes_conf: "nodes.conf-vlan", + args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"}, + log: ifcfg_vlan, + }, + { + name: "ifcfg:route.ww", + nodes_conf: "nodes.conf-vlan", + args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/route.ww"}, + log: ifcfg_routes, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf) cmd := show.GetCommand() cmd.SetArgs(tt.args) stdout := bytes.NewBufferString("") @@ -57,6 +73,7 @@ const ifcfg string = `backupFile: true writeFile: true Filename: ifcfg-default.conf # This file is autogenerated by warewulf + TYPE=ethernet DEVICE=wwnet0 NAME=default @@ -75,6 +92,7 @@ backupFile: true writeFile: true Filename: ifcfg-secondary.conf # This file is autogenerated by warewulf + TYPE=ethernet DEVICE=wwnet1 NAME=secondary @@ -99,3 +117,46 @@ Filename: etc/sysconfig/network NETWORKING=yes HOSTNAME=node1 ` + +const ifcfg_vlan string = `backupFile: true +writeFile: true +Filename: ifcfg-tagged.conf +# This file is autogenerated by warewulf + +VLAN=yes +DEVICE=eth0.902 +NAME=tagged +BOOTPROTO=static +DEVTIMEOUT=10 +ONBOOT=true +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +backupFile: true +writeFile: true +Filename: ifcfg-untagged.conf +# This file is autogenerated by warewulf + +TYPE=ethernet +DEVICE=eth0 +NAME=untagged +BOOTPROTO=static +DEVTIMEOUT=10 +ONBOOT=true +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +` + +const ifcfg_routes string = `backupFile: true +writeFile: true +Filename: route-tagged.conf +# This file is autogenerated by warewulf +192.168.1.0/24 via 192.168.2.254 +backupFile: true +writeFile: true +Filename: route-untagged.conf +# This file is autogenerated by warewulf +` diff --git a/overlays/ifcfg/internal/nodes.conf-vlan b/overlays/ifcfg/internal/nodes.conf-vlan new file mode 100644 index 00000000..1f418c08 --- /dev/null +++ b/overlays/ifcfg/internal/nodes.conf-vlan @@ -0,0 +1,11 @@ +nodes: + node1: + primary network: untagged + network devices: + untagged: + device: eth0 + tagged: + type: vlan + device: eth0.902 + tags: + route1: "192.168.1.0/24,192.168.2.254" diff --git a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww index d3ac924c..ffe040d5 100644 --- a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww +++ b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww @@ -1,41 +1,45 @@ -{{range $devname, $netdev := .NetDevs -}} +{{- range $devname, $netdev := .NetDevs }} {{- $filename := print "ifcfg-" $devname ".conf" }} {{- file $filename }} # This file is autogenerated by warewulf -{{ if $netdev.Type -}} -TYPE={{ $netdev.Type }} -{{ else -}} -TYPE=ethernet -{{ end -}} + +{{ if eq $netdev.Type "vlan" -}} +VLAN=yes +{{- else -}} +TYPE={{ default "ethernet" $netdev.Type }} +{{- end }} DEVICE={{ $netdev.Device }} NAME={{ $devname }} -{{ if $netdev.MTU -}} +{{- if $netdev.MTU }} MTU={{ $netdev.MTU }} -{{ end -}} +{{- end }} BOOTPROTO=static DEVTIMEOUT=10 +{{- if $netdev.Ipaddr }} IPADDR={{ $netdev.Ipaddr }} +{{- end }} +{{- if $netdev.Netmask }} NETMASK={{ $netdev.Netmask }} -{{ if $netdev.Gateway -}} +{{- end }} +{{- if $netdev.Gateway }} GATEWAY={{ $netdev.Gateway }} -{{ end -}} -{{ if $netdev.Hwaddr -}} +{{- end }} +{{- if $netdev.Hwaddr }} HWADDR={{ $netdev.Hwaddr }} -{{ end -}} +{{- end }} {{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}} ONBOOT=true -{{ end -}} +{{- end }} IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no -{{ if $netdev.Ipaddr6 -}} +{{- if $netdev.Ipaddr6 }} IPV6ADDR="{{ $netdev.Ipaddr6 }}" -{{ end -}} -{{range $tk, $tv := $netdev.Tags -}} -{{ $prefix := substr 0 3 $tk -}} -{{ if eq $prefix "DNS" -}} +{{- end }} +{{- range $tk, $tv := $netdev.Tags }} +{{- if eq (substr 0 3 $tk) "DNS" }} {{ $tk }}={{ $tv }} -{{ end -}} -{{ end -}} +{{- end }} +{{- end }} {{ end -}} diff --git a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww new file mode 100644 index 00000000..12127fcc --- /dev/null +++ b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww @@ -0,0 +1,10 @@ +{{- range $devname, $netdev := .NetDevs }} +{{- $filename := print "route-" $devname ".conf" }} +{{- file $filename }} +# This file is autogenerated by warewulf +{{- range $tk, $tv := $netdev.Tags }} +{{- if eq (substr 0 5 $tk) "route" }} +{{ index (splitList "," $tv) 0 }} via {{ index (splitList "," $tv) 1 }} +{{- end }} +{{- end }} +{{ end -}} diff --git a/overlays/wicked/internal/nodes.conf-vlan b/overlays/wicked/internal/nodes.conf-vlan new file mode 100644 index 00000000..3302207f --- /dev/null +++ b/overlays/wicked/internal/nodes.conf-vlan @@ -0,0 +1,13 @@ +nodes: + node1: + primary network: untagged + network devices: + untagged: + device: eth0 + tagged: + type: vlan + device: eth0.902 + tags: + vlan_id: 902 + parent_device: eth0 + route1: "192.168.1.0/24,192.168.2.254" diff --git a/overlays/wicked/internal/wicked_test.go b/overlays/wicked/internal/wicked_test.go index 845edb3c..7b835d07 100644 --- a/overlays/wicked/internal/wicked_test.go +++ b/overlays/wicked/internal/wicked_test.go @@ -13,23 +13,31 @@ import ( func Test_wickedOverlay(t *testing.T) { env := testenv.New(t) defer env.RemoveAll(t) - env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf") env.ImportFile(t, "var/lib/warewulf/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww", "../rootfs/etc/wicked/ifconfig/ifcfg.xml.ww") tests := []struct { - name string - args []string - log string + name string + nodes_conf string + args []string + log string }{ { - name: "wicked", - args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"}, - log: wicked, + name: "wicked", + nodes_conf: "nodes.conf", + args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"}, + log: wicked, + }, + { + name: "wicked-vlans", + nodes_conf: "nodes.conf-vlan", + args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"}, + log: wicked_vlans, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf) cmd := show.GetCommand() cmd.SetArgs(tt.args) stdout := bytes.NewBufferString("") @@ -69,12 +77,12 @@ This file is autogenerated by warewulf
192.168.3.21/24
- + 192.168.3.1 - + true prefer-public @@ -103,12 +111,83 @@ This file is autogenerated by warewulf
192.168.3.22/24
- + 192.168.3.1 - + + + true + prefer-public + false + + +` + +const wicked_vlans string = `backupFile: true +writeFile: true +Filename: ifcfg-tagged.xml + + + eth0.902 + vlan + + eth0 + 902 + ieee802-1Q + + + boot + + + + + true + true + + +
+ +
+ + 192.168.1.0/24 + + 192.168.2.254 + + +
+ + true + prefer-public + false + +
+backupFile: true +writeFile: true +Filename: ifcfg-untagged.xml + + + eth0 + ethernet + + boot + + + + + true + true + + +
+ +
+
true prefer-public diff --git a/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww b/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww index 5c8308cd..19012c0d 100644 --- a/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww +++ b/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww @@ -1,28 +1,22 @@ -{{ $NetDevs := .NetDevs -}}{{/* FIX: 1413 */ -}} -{{range $devname, $netdev := .ThisNode.NetDevs -}} -{{- $filename := print "ifcfg-" $devname ".xml" }} -{{- file $filename }} +{{- $NetDevs := .NetDevs }} +{{- range $devname, $netdev := .ThisNode.NetDevs }} +{{- file (print "ifcfg-" $devname ".xml") }} - {{$netdev.Device}} - {{ if $netdev.Type -}} - {{ if eq $netdev.Type "vlan" -}} + {{ $netdev.Device }} + {{ default "ethernet" $netdev.Type }} + {{- if eq $netdev.Type "vlan" }} - {{ $netdev.Tags.parent_device }} - {{ $netdev.Tags.vlan_id }} + {{ $netdev.Tags.parent_device }} + {{ $netdev.Tags.vlan_id }} ieee802-1Q - {{ else -}} - {{ $netdev.Type }} - {{ else -}} - ethernet - {{ end -}} - {{ end -}} - {{ if $netdev.MTU -}} + {{- end }} + {{- if $netdev.MTU }} {{ $netdev.MTU }} - {{ end -}} + {{- end }} {{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) }}boot{{ else }}manual{{end}} @@ -36,25 +30,35 @@ This file is autogenerated by warewulf
{{$netdev.IpCIDR}}
-{{ if $netdev.Gateway -}} + {{- if $netdev.Gateway }} {{$netdev.Gateway}} -{{ end -}} + {{- end }} + {{- range $tk, $tv := $netdev.Tags }} + {{- if eq (substr 0 5 $tk) "route" }} + + {{ index (splitList "," $tv) 0 }} + + {{ index (splitList "," $tv) 1 }} + + + {{- end }} + {{- end }} true prefer-public false -{{ if $netdev.Ipaddr6 -}} + {{- if $netdev.Ipaddr6 }}
{{ $netdev.Ipaddr6 }}
-{{ end -}} + {{- end }}
{{ end -}}