diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a1483a..20264432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - If init is not specified, wwinit looks for /sbin/init, /etc/init, and /bin/init. #1808 - assume ipxe template=default if not set. #1808, #1813 - Display a warning during overlay build if an overlay list is empty. #1808 +- Fix processing of UNDEF and UNSET during `wwctl set`. #1837 ### Changed diff --git a/internal/app/wwctl/node/set/main_test.go b/internal/app/wwctl/node/set/main_test.go index 5ae8cb91..f3c5ea3d 100644 --- a/internal/app/wwctl/node/set/main_test.go +++ b/internal/app/wwctl/node/set/main_test.go @@ -9,179 +9,120 @@ import ( "github.com/warewulf/warewulf/internal/pkg/warewulfd" ) -type test_description struct { - name string - args []string - wantErr bool - stdout string - inDB string - outDb string -} - -func run_test(t *testing.T, test test_description) { - env := testenv.New(t) - defer env.RemoveAll() - env.WriteFile("etc/warewulf/nodes.conf", test.inDB) - warewulfd.SetNoDaemon() - name := test.name - if name == "" { - name = t.Name() - } - t.Run(name, func(t *testing.T) { - baseCmd := GetCommand() - test.args = append(test.args, "--yes") - baseCmd.SetArgs(test.args) - buf := new(bytes.Buffer) - baseCmd.SetOut(buf) - baseCmd.SetErr(buf) - err := baseCmd.Execute() - if test.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.Equal(t, buf.String(), test.stdout) - content := env.ReadFile("etc/warewulf/nodes.conf") - assert.YAMLEq(t, test.outDb, content) - } - }) -} - -func Test_Single_Node_Change_Profile(t *testing.T) { - test := test_description{ - args: []string{"--profile=foo", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: +func Test_Node_Set(t *testing.T) { + tests := map[string]struct { + args []string + wantErr bool + inDB string + outDB string + }{ + "--profile=foo": { + args: []string{"--profile=foo", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - default`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - - foo -`, - } - run_test(t, test) -} - -func Test_Node_Unset(t *testing.T) { - test := test_description{ - args: []string{"--comment=UNDEF", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + - foo`, + }, + "--comment=UNDEF": { + args: []string{"--comment=UNDEF", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: n01: comment: foo profiles: - default`, - outDb: `nodeprofiles: {} + outDB: ` +nodeprofiles: {} nodes: n01: profiles: - - default -`, - } - run_test(t, test) -} - -func Test_Set_Ipmi_Write_Explicit(t *testing.T) { - test := test_description{ - args: []string{"--ipmiwrite", "true", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + - default`, + }, + "--ipmiwrite=true": { + args: []string{"--ipmiwrite", "true", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: - n01: {} -`, - outDb: `nodeprofiles: {} + n01: {}`, + outDB: ` +nodeprofiles: {} nodes: n01: ipmi: - write: "true" -`, - } - run_test(t, test) -} - -func Test_Set_Ipmi_Write_Implicit(t *testing.T) { - test := test_description{ - args: []string{"--ipmiwrite", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + write: "true"`, + }, + "--ipmiwrite": { + args: []string{"--ipmiwrite", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: - n01: {} -`, - outDb: `nodeprofiles: {} + n01: {}`, + outDB: ` +nodeprofiles: {} nodes: n01: ipmi: - write: "true" -`, - } - run_test(t, test) -} - -func Test_Unset_Ipmi_Write(t *testing.T) { - test := test_description{ - args: []string{"--ipmiwrite=UNDEF", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + write: "true"`, + }, + "--ipmiwrite=UNDEF": { + args: []string{"--ipmiwrite=UNDEF", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: n01: ipmi: - write: "true" -`, - outDb: `nodeprofiles: {} + write: "true"`, + outDB: ` +nodeprofiles: {} nodes: - n01: {} -`, - } - run_test(t, test) -} - -func Test_Unset_Ipmi_Write_False(t *testing.T) { - test := test_description{ - args: []string{"--ipmiwrite=UNDEF", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + n01: {}`, + }, + "--ipmiwrite=false": { + args: []string{"--ipmiwrite=false", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} +nodes: + n01: {}`, + outDB: ` +nodeprofiles: {} nodes: n01: ipmi: - write: "false" -`, - outDb: `nodeprofiles: {} -nodes: - n01: {} -`, - } - run_test(t, test) -} - -func Test_Ipmi_Hidden_False(t *testing.T) { - test := test_description{ - args: []string{"--ipmiwrite=false", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: + write: "false"`, + }, + "--ipmiwrite=false (override)": { + args: []string{"--ipmiwrite=false", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: default: ipmi: write: "true" nodes: n01: profiles: - - default -`, - outDb: `nodeprofiles: + - default`, + outDB: ` +nodeprofiles: default: ipmi: write: "true" @@ -190,84 +131,66 @@ nodes: profiles: - default ipmi: - write: "false" -`, - } - run_test(t, test) -} - -func Test_Add_NetTags(t *testing.T) { - test := test_description{ - args: []string{"--nettagadd=dns=1.1.1.1", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + write: "false"`, + }, + "--nettagadd": { + args: []string{"--nettagadd=dns=1.1.1.1", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: - n01: {} -`, - outDb: `nodeprofiles: {} + n01: {}`, + outDB: ` +nodeprofiles: {} nodes: n01: network devices: default: tags: - dns: 1.1.1.1 -`, - } - run_test(t, test) -} - -func Test_Del_NetTags(t *testing.T) { - test := test_description{ - args: []string{"--netname=default", "--nettagdel=dns1,dns2", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: {} + dns: 1.1.1.1`, + }, + "--nettagdel": { + args: []string{"--nettagdel=dns1,dns2", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: {} nodes: n01: network devices: default: tags: dns1: 1.1.1.1 - dns2: 2.2.2.2 -`, - outDb: `nodeprofiles: {} + dns2: 2.2.2.2`, + outDB: ` +nodeprofiles: {} nodes: - n01: {} -`, - } - run_test(t, test) -} - -func Test_Multiple_Set_Tests(t *testing.T) { - tests := []test_description{ - { - name: "single node change profile", + n01: {}`, + }, + "single node change profile": { args: []string{"--profile=foo", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - default`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - - foo -`, + - foo`, }, - { - name: "multiple nodes change profile", + "multiple nodes change profile": { args: []string{"--profile=foo", "n0[1-2]"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -277,7 +200,8 @@ nodes: n02: profiles: - default`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -286,22 +210,21 @@ nodes: - foo n02: profiles: - - foo -`, + - foo`, }, - { - name: "single node set ipmitag", + "single node set ipmitag": { args: []string{"--ipmitagadd", "foo=baar", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - default`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -310,15 +233,13 @@ nodes: - default ipmi: tags: - foo: baar -`, + foo: baar`, }, - { - name: "single node delete tag", + "single node delete tag": { args: []string{"--tagdel", "tag1", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -328,7 +249,8 @@ nodes: tags: tag1: value1 tag2: value2`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -336,42 +258,37 @@ nodes: profiles: - default tags: - tag2: value2 -`, + tag2: value2`, }, - { - name: "single node add tag", + "single node add tag": { args: []string{"--tagadd", "tag1=foobaar", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: {} nodes: - n01: {} -`, - outDb: `nodeprofiles: + n01: {}`, + outDB: ` +nodeprofiles: default: {} nodes: n01: tags: - tag1: foobaar -`, + tag1: foobaar`, }, - { - name: "single node add tag with netdev", + "single node add tag with netdev": { args: []string{"--tagadd", "tag1=foobaar", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: {} nodes: n01: network devices: default: - ipaddr: 172.16.130.101 - -`, - outDb: `nodeprofiles: + ipaddr: 172.16.130.101`, + outDB: ` +nodeprofiles: default: {} nodes: n01: @@ -379,48 +296,43 @@ nodes: tag1: foobaar network devices: default: - ipaddr: 172.16.130.101 -`, + ipaddr: 172.16.130.101`, }, - { - name: "single node set onboot", + "single node set onboot": { args: []string{"--netname", "default", "--onboot=true", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: + default: {} +nodes: + n01: + network devices: + default: + ipaddr: 172.16.130.101`, + outDB: ` +nodeprofiles: default: {} nodes: n01: network devices: default: ipaddr: 172.16.130.101 - -`, - outDb: `nodeprofiles: - default: {} -nodes: - n01: - network devices: - default: - ipaddr: 172.16.130.101 - onboot: "true" -`, + onboot: "true"`, }, - { - name: "single node set fs,part and disk", + "single node set fs,part and disk": { args: []string{"--fsname=var", "--fspath=/var", "--fsformat=btrfs", "--partname=var", "--partnumber=1", "--diskname=/dev/vda", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - - default -`, - outDb: `nodeprofiles: + - default`, + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -435,15 +347,13 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, + path: /var`, }, - { - name: "single delete not existing fs", + "single delete not existing fs": { args: []string{"--fsdel=foo", "n01"}, wantErr: true, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -459,9 +369,9 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, - outDb: `nodeprofiles: + path: /var`, + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -476,15 +386,13 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, + path: /var`, }, - { - name: "single node delete existing fs", + "single node delete existing fs": { args: []string{"--fsdel=/dev/disk/by-partlabel/var", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -500,9 +408,9 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, - outDb: `nodeprofiles: + path: /var`, + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -513,15 +421,13 @@ nodes: /dev/vda: partitions: var: - number: "1" -`, + number: "1"`, }, - { - name: "single node delete existing partition", + "single node delete existing partition": { args: []string{"--partdel=var", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -537,9 +443,9 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, - outDb: `nodeprofiles: + path: /var`, + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -551,15 +457,13 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, + path: /var`, }, - { - name: "single node delete existing disk", + "single node delete existing disk": { args: []string{"--diskdel=/dev/vda", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: @@ -574,9 +478,9 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, - outDb: `nodeprofiles: + path: /var`, + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -586,22 +490,21 @@ nodes: filesystems: /dev/disk/by-partlabel/var: format: btrfs - path: /var -`, + path: /var`, }, - { - name: "single node set mtu", + "single node set mtu": { args: []string{"--mtu", "1234", "--netname=mynet", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit nodes: n01: profiles: - default`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit nodes: @@ -610,15 +513,13 @@ nodes: - default network devices: mynet: - mtu: "1234" -`, + mtu: "1234"`, }, - { - name: "single node set ipmitag", + "single node set tag": { args: []string{"--tagadd", "nodetag1=nodevalue1", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: p1: comment: testit 1 tags: @@ -632,7 +533,8 @@ nodes: profiles: - p1 - p2`, - outDb: `nodeprofiles: + outDB: ` +nodeprofiles: p1: comment: testit 1 tags: @@ -647,39 +549,25 @@ nodes: - p1 - p2 tags: - nodetag1: nodevalue1 -`, + nodetag1: nodevalue1`, }, - { - name: "single node set comma in comment", + "single node set comma in comment": { args: []string{"n01", "--comment", "This is a , comment"}, wantErr: false, - stdout: "", inDB: `nodes: n01: - comment: old comment -`, - outDb: `nodeprofiles: {} + comment: old comment`, + outDB: ` +nodeprofiles: {} nodes: n01: - comment: This is a , comment -`, + comment: This is a , comment`, }, - } - - warewulfd.SetNoDaemon() - for _, tt := range tests { - run_test(t, tt) - } -} - -func Test_Node_Add(t *testing.T) { - tests := []test_description{ - { + "--tagadd (one)": { args: []string{"--tagadd=email=node", "n01"}, wantErr: false, - stdout: "", - inDB: `nodeprofiles: + inDB: ` +nodeprofiles: default: comment: testit tags: @@ -688,24 +576,8 @@ nodes: n01: profiles: - default`, - outDb: `nodeprofiles: - default: - comment: testit - tags: - email: profile -nodes: - n01: - profiles: - - default - tags: - email: node -`, - }, - { - args: []string{"--tagadd=newtag=newval", "n01"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: + outDB: ` +nodeprofiles: default: comment: testit tags: @@ -716,7 +588,24 @@ nodes: - default tags: email: node`, - outDb: `nodeprofiles: + }, + "--tagadd (second)": { + args: []string{"--tagadd=newtag=newval", "n01"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: + comment: testit + tags: + email: profile +nodes: + n01: + profiles: + - default + tags: + email: node`, + outDB: ` +nodeprofiles: default: comment: testit tags: @@ -727,12 +616,72 @@ nodes: - default tags: email: node - newtag: newval -`, + newtag: newval`, + }, + "--image=UNDEF": { + args: []string{"--image=UNDEF", "n1"}, + wantErr: false, + inDB: ` +nodeprofiles: {} +nodes: + n1: + image: rockylinux-9`, + outDB: ` +nodeprofiles: {} +nodes: + n1: {}`, + }, + "--image=UNSET": { + args: []string{"--image=UNSET", "n1"}, + wantErr: false, + inDB: ` +nodeprofiles: {} +nodes: + n1: + image: rockylinux-9`, + outDB: ` +nodeprofiles: {} +nodes: + n1: {}`, + }, + "--ipaddr=0.0.0.0 (unset)": { + args: []string{"--ipaddr=0.0.0.0", "n1"}, + wantErr: false, + inDB: ` +nodeprofiles: {} +nodes: + n1: + network devices: + default: + ipadddr: 192.168.0.1`, + outDB: ` +nodeprofiles: {} +nodes: + n1: {}`, }, } - for _, tt := range tests { - run_test(t, tt) + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + env := testenv.New(t) + defer env.RemoveAll() + env.WriteFile("etc/warewulf/nodes.conf", tt.inDB) + warewulfd.SetNoDaemon() + + baseCmd := GetCommand() + args := append(tt.args, "--yes") + baseCmd.SetArgs(args) + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + err := baseCmd.Execute() + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + content := env.ReadFile("etc/warewulf/nodes.conf") + assert.YAMLEq(t, tt.outDB, content) + } + }) } } diff --git a/internal/app/wwctl/profile/set/main_test.go b/internal/app/wwctl/profile/set/main_test.go index d12abee6..d1fc15fa 100644 --- a/internal/app/wwctl/profile/set/main_test.go +++ b/internal/app/wwctl/profile/set/main_test.go @@ -5,105 +5,130 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/warewulf/warewulf/internal/pkg/testenv" "github.com/warewulf/warewulf/internal/pkg/warewulfd" ) -type test_description struct { - name string - args []string - wantErr bool - stdout string - inDB string - outDb string -} - -func run_test(t *testing.T, test test_description) { - env := testenv.New(t) - defer env.RemoveAll() - env.WriteFile("etc/warewulf/nodes.conf", test.inDB) - warewulfd.SetNoDaemon() - name := test.name - if name == "" { - name = t.Name() +func Test_Profile_Set(t *testing.T) { + tests := map[string]struct { + args []string + wantErr bool + inDB string + outDb string + }{ + "Test_Set_Netdev": { + args: []string{"--netdev=eth0", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: {} +nodes: {}`, + outDb: ` +nodeprofiles: + default: + network devices: + default: + device: eth0 +nodes: {}`, + }, + "Test_Set_Netdev_and_Mask": { + args: []string{"--netdev=eth0", "-M=255.255.255.0", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: {} +nodes: {}`, + outDb: ` +nodeprofiles: + default: + network devices: + default: + device: eth0 + netmask: 255.255.255.0 +nodes: {}`, + }, + "Set Mask Existing NetDev": { + args: []string{"-M=255.255.255.0", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: + network devices: + default: + device: eth0 +nodes: {}`, + outDb: ` +nodeprofiles: + default: + network devices: + default: + device: eth0 + netmask: 255.255.255.0 +nodes: {}`, + }, + "--image=UNSET": { + args: []string{"--image=UNSET", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: + image: rockylinux-9 +nodes: {}`, + outDb: ` +nodeprofiles: + default: {} +nodes: {}`, + }, + "--image=UNDEF": { + args: []string{"--image=UNDEF", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: + image: rockylinux-9 +nodes: {}`, + outDb: ` +nodeprofiles: + default: {} +nodes: {}`, + }, + "--tagadd=mytag=0.0.0.0": { + args: []string{"--tagadd=mytag=0.0.0.0", "default"}, + wantErr: false, + inDB: ` +nodeprofiles: + default: {} +nodes: {}`, + outDb: ` +nodeprofiles: + default: + tags: + mytag: 0.0.0.0 +nodes: {}`, + }, } - t.Run(name, func(t *testing.T) { - baseCmd := GetCommand() - test.args = append(test.args, "--yes") - baseCmd.SetArgs(test.args) - buf := new(bytes.Buffer) - baseCmd.SetOut(buf) - baseCmd.SetErr(buf) - err := baseCmd.Execute() - if test.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.Equal(t, buf.String(), test.stdout) - content := env.ReadFile("etc/warewulf/nodes.conf") - assert.YAMLEq(t, test.outDb, content) - } - }) -} -func Test_Set_Netdev(t *testing.T) { - test := test_description{ - args: []string{"--netname=default", "--netdev=eth0", "default"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: - default: {} -nodes: {} -`, - outDb: `nodeprofiles: - default: - network devices: - default: - device: eth0 -nodes: {} -`} - run_test(t, test) -} -func Test_Set_Netdev_and_Mask(t *testing.T) { - test := test_description{ - args: []string{"--netname=default", "--netdev=eth0", "-M=255.255.255.0", "default"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: - default: {} -nodes: {} -`, - outDb: `nodeprofiles: - default: - network devices: - default: - device: eth0 - netmask: 255.255.255.0 -nodes: {} -`} - run_test(t, test) -} + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + env := testenv.New(t) + defer env.RemoveAll() + env.WriteFile("etc/warewulf/nodes.conf", tt.inDB) + warewulfd.SetNoDaemon() + baseCmd := GetCommand() + args := append(tt.args, "--yes") + baseCmd.SetArgs(args) + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + err := baseCmd.Execute() + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + content := env.ReadFile("etc/warewulf/nodes.conf") + assert.YAMLEq(t, tt.outDb, content) + } -func Test_Set_Mask_Existing_NetDev(t *testing.T) { - test := test_description{ - args: []string{"--netname=default", "-M=255.255.255.0", "default"}, - wantErr: false, - stdout: "", - inDB: `nodeprofiles: - default: - network devices: - default: - device: eth0 -nodes: {} -`, - outDb: `nodeprofiles: - default: - network devices: - default: - device: eth0 - netmask: 255.255.255.0 -nodes: {} -`} - run_test(t, test) + }) + } } diff --git a/internal/pkg/node/checkconf.go b/internal/pkg/node/checkconf.go deleted file mode 100644 index 1c881d2e..00000000 --- a/internal/pkg/node/checkconf.go +++ /dev/null @@ -1,109 +0,0 @@ -package node - -import ( - "fmt" - "net" - "reflect" - "strconv" - "strings" - - "github.com/warewulf/warewulf/internal/pkg/wwtype" -) - -/* -Checks if for NodeConf all values can be parsed according to their type. -*/ -func (nodeConf *Node) Check() (err error) { - nodeInfoType := reflect.TypeOf(nodeConf) - nodeInfoVal := reflect.ValueOf(nodeConf) - return check(nodeInfoType, nodeInfoVal) -} - -func (profileConf *Profile) Check() (err error) { - profileInfoType := reflect.TypeOf(profileConf) - profileInfoVal := reflect.ValueOf(profileConf) - return check(profileInfoType, profileInfoVal) -} - -func check(infoType reflect.Type, infoVal reflect.Value) (err error) { - if !infoVal.Elem().IsValid() { - return nil - } - // now iterate of every field - for i := 0; i < infoVal.Elem().NumField(); i++ { - if !infoType.Elem().Field(i).IsExported() { - continue - } else if infoType.Elem().Field(i).Type.Kind() == reflect.String { - newFmt, err := checker(infoVal.Elem().Field(i).String(), infoType.Elem().Field(i).Tag.Get("type")) - if err != nil { - return fmt.Errorf("field: %s value:%s err: %s", infoType.Elem().Field(i).Name, infoVal.Elem().Field(i).String(), err) - } else if newFmt != "" { - infoVal.Elem().Field(i).SetString(newFmt) - } - } else if infoType.Elem().Field(i).Type.Kind() == reflect.Ptr && !infoVal.Elem().Field(i).IsNil() { - nestType := reflect.TypeOf(infoVal.Elem().Field(i).Interface()) - nestVal := reflect.ValueOf(infoVal.Elem().Field(i).Interface()) - for j := 0; j < nestType.Elem().NumField(); j++ { - if nestType.Elem().Field(j).Type.Kind() == reflect.String { - newFmt, err := checker(nestVal.Elem().Field(j).Interface().(string), nestType.Elem().Field(j).Tag.Get("type")) - if err != nil { - return fmt.Errorf("field: %s value:%s err: %s", nestType.Elem().Field(j).Name, nestVal.Elem().Field(j).String(), err) - } else if newFmt != "" { - nestVal.Elem().Field(j).SetString(newFmt) - } - } - } - } else if infoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDev(nil)) { - netMap := infoVal.Elem().Field(i).Interface().(map[string]*NetDev) - for _, val := range netMap { - netType := reflect.TypeOf(val) - netVal := reflect.ValueOf(val) - for j := 0; j < netType.Elem().NumField(); j++ { - newFmt, err := checker(netVal.Elem().Field(j).String(), netType.Elem().Field(j).Tag.Get("type")) - if err != nil { - return fmt.Errorf("field: %s value:%s err: %s", netType.Elem().Field(j).Name, netVal.Elem().Field(j).String(), err) - } else if newFmt != "" { - netVal.Elem().Field(j).SetString(newFmt) - } - } - } - } - } - return nil -} - -func checker(value string, valType string) (niceValue string, err error) { - if valType == "" || value == "" || wwtype.IsUnsetVerb(value) { - return "", nil - } - switch valType { - case "": - return "", nil - case "bool": - if strings.ToLower(value) == "yes" { - return "true", nil - } - if strings.ToLower(value) == "no" { - return "false", nil - } - myBool, err := strconv.ParseBool(value) - return strconv.FormatBool(myBool), err - case "IP": - if addr := net.ParseIP(value); addr == nil { - return "", fmt.Errorf("%s can't be parsed to ip address", value) - } else { - return addr.String(), nil - } - case "MAC": - if mac, err := net.ParseMAC(value); err != nil { - return "", fmt.Errorf("%s can't be parsed to MAC address: %s", value, err) - } else { - return mac.String(), nil - } - case "uint": - if _, err := strconv.ParseUint(value, 10, 64); err != nil { - return "", fmt.Errorf("%s is not a uint: %s", value, err) - } - } - return "", nil -} diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index 6dcc1485..9cb35639 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -6,8 +6,6 @@ import ( "github.com/warewulf/warewulf/internal/pkg/wwtype" ) -const undef string = "UNDEF" - /****** * YAML data representations ******/ diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index a7b28cc3..881a4d12 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -201,7 +201,7 @@ func recursiveFlatten(obj interface{}) (hasContent bool) { if typeObj.Elem().Field(i).Type == reflect.TypeOf([]string{}) { del := false for _, elem := range (valObj.Elem().Field(i).Interface()).([]string) { - if strings.EqualFold(elem, undef) { + if isUnsetValue(elem) { del = true } } @@ -213,7 +213,7 @@ func recursiveFlatten(obj interface{}) (hasContent bool) { hasContent = true } case reflect.String: - if strings.EqualFold(valObj.Elem().Field(i).String(), undef) { + if isUnsetValue(valObj.Elem().Field(i).String()) { valObj.Elem().Field(i).SetString("") } if valObj.Elem().Field(i).String() != "" { @@ -421,3 +421,9 @@ func (netdev *NetDev) IpCIDR() string { } return ipCIDR.String() } + +var unsetValues = []string{"UNSET", "UNDEF"} + +func isUnsetValue(value string) bool { + return util.InSlice(unsetValues, value) +} diff --git a/internal/pkg/wwtype/constants.go b/internal/pkg/wwtype/constants.go deleted file mode 100644 index 521f9f97..00000000 --- a/internal/pkg/wwtype/constants.go +++ /dev/null @@ -1,15 +0,0 @@ -package wwtype - -import ( - "strings" - - "github.com/warewulf/warewulf/internal/pkg/util" -) - -func GetUnsetVerbs() []string { - return []string{"unset", "delete", "undef", "--", "nil", "0.0.0.0"} -} - -func IsUnsetVerb(value string) bool { - return util.InSlice(GetUnsetVerbs(), strings.ToLower(value)) -} diff --git a/internal/pkg/wwtype/wwbool.go b/internal/pkg/wwtype/wwbool.go index bd9d65a4..c47efbb1 100644 --- a/internal/pkg/wwtype/wwbool.go +++ b/internal/pkg/wwtype/wwbool.go @@ -4,6 +4,8 @@ import ( "fmt" "strconv" "strings" + + "github.com/warewulf/warewulf/internal/pkg/util" ) // Simple string which can be converted to bool. Backend storage @@ -15,7 +17,7 @@ Transform the underlying string value to bool */ func (val WWbool) Bool() bool { str := strings.ToLower(string(val)) - if IsUnsetVerb(str) { + if isUnsetValue(str) { return false } switch str { @@ -33,7 +35,7 @@ func (val WWbool) Bool() bool { func (val WWbool) BoolDefaultTrue() bool { str := strings.ToLower(string(val)) - if IsUnsetVerb(str) { + if isUnsetValue(str) { return false } switch str { @@ -53,7 +55,7 @@ func (val WWbool) BoolDefaultTrue() bool { Set the string, only accept bool values like true, false, but also UNDEF */ func (val *WWbool) Set(str string) error { - if IsUnsetVerb(str) { + if isUnsetValue(str) { // run the unset verb trough, will be filtered out later *val = WWbool(str) return nil @@ -81,3 +83,9 @@ func (val WWbool) String() string { func (b WWbool) Type() string { return "WWbool" } + +var unsetValues = []string{"unset", "delete", "undef", "--", "nil", "0.0.0.0"} + +func isUnsetValue(value string) bool { + return util.InSlice(unsetValues, strings.ToLower(value)) +}