allow UNSET for IP addresses

added more tests for GetFrom
allow UNSET and handle empty hwaddr

Signed-off-by: Christian Goll <cgoll@suse.de>
This commit is contained in:
Christian Goll
2023-02-24 16:16:21 +01:00
parent b0602133ec
commit 96644be621
7 changed files with 166 additions and 19 deletions

View File

@@ -15,7 +15,7 @@ var (
DisableFlagsInUseLine: true,
Use: "set [OPTIONS] PATTERN [PATTERN ...]",
Short: "Configure node properties",
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET'/'0.0.0.0' to remove a configuration",
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(0),
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

View File

@@ -15,7 +15,7 @@ var (
Use: "set [OPTIONS] [PROFILE ...]",
Short: "Configure node profile properties",
Long: "This command sets configuration properties for the node PROFILE(s).\n\n" +
"Note: use the string 'UNSET'/'0.0.0.0' to remove a configuration",
"Note: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(0),
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

View File

@@ -6,6 +6,8 @@ import (
"reflect"
"strconv"
"strings"
"github.com/hpcng/warewulf/internal/pkg/util"
)
/*
@@ -58,7 +60,7 @@ func (nodeConf *NodeConf) Check() (err error) {
}
func checker(value string, valType string) (niceValue string, err error) {
if valType == "" || value == "" {
if valType == "" || value == "" || util.InSlice(GetUnsetVerbs(), value) {
return "", nil
}
//wwlog.Debug("checker: %s is %s", value, valType)

View File

@@ -122,25 +122,26 @@ func createFlags(baseCmd *cobra.Command, excludeList []string,
}
baseCmd.PersistentFlags().Lookup(myType.Tag.Get("lopt")).NoOptDefVal = "true"
case "IP":
defaultConv := net.ParseIP(myType.Tag.Get("default"))
var valueRaw net.IP
converters = append(converters, func() error {
if valueRaw != nil {
// will always get a IP, not a string
*ptr = valueRaw.String()
if !util.InSlice(GetUnsetVerbs(), *ptr) && *ptr != "" {
ipval := net.ParseIP(*ptr)
if ipval == nil {
return fmt.Errorf("commandline option %s needs to be an IP address", myType.Tag.Get("lopt"))
}
*ptr = ipval.String()
}
return nil
})
if myType.Tag.Get("sopt") != "" {
baseCmd.PersistentFlags().IPVarP(&valueRaw,
baseCmd.PersistentFlags().StringVarP(ptr,
myType.Tag.Get("lopt"),
myType.Tag.Get("sopt"),
defaultConv,
myType.Tag.Get("default"),
myType.Tag.Get("comment"))
} else {
baseCmd.PersistentFlags().IPVar(&valueRaw,
baseCmd.PersistentFlags().StringVar(ptr,
myType.Tag.Get("lopt"),
defaultConv,
myType.Tag.Get("default"),
myType.Tag.Get("comment"))
}
case "IPMask":
@@ -168,11 +169,13 @@ func createFlags(baseCmd *cobra.Command, excludeList []string,
}
case "MAC":
converters = append(converters, func() error {
myMac, err := net.ParseMAC(*ptr)
if err != nil {
return err
if !util.InSlice(GetUnsetVerbs(), *ptr) && *ptr != "" {
myMac, err := net.ParseMAC(*ptr)
if err != nil {
return err
}
*ptr = myMac.String()
}
*ptr = myMac.String()
return nil
})
if myType.Tag.Get("sopt") != "" {

View File

@@ -356,8 +356,10 @@ Create an empty node NodeConf
*/
func NewConf() (nodeconf NodeConf) {
nodeconf.Ipmi = new(IpmiConf)
nodeconf.Ipmi.Tags = map[string]string{}
nodeconf.Kernel = new(KernelConf)
nodeconf.NetDevs = make(map[string]*NetDevs)
nodeconf.Tags = map[string]string{}
return nodeconf
}
@@ -366,11 +368,18 @@ Create an empty node NodeInfo
*/
func NewInfo() (nodeInfo NodeInfo) {
nodeInfo.Ipmi = new(IpmiEntry)
nodeInfo.Ipmi.Tags = map[string]*Entry{}
nodeInfo.Kernel = new(KernelEntry)
nodeInfo.NetDevs = make(map[string]*NetDevEntry)
nodeInfo.Tags = make(map[string]*Entry)
return nodeInfo
}
func NewNetDevEntry() (netdev NetDevEntry) {
netdev.Tags = make(map[string]*Entry)
return
}
/*
Get a entry by its name
*/

View File

@@ -1,7 +1,6 @@
package node
import (
"fmt"
"reflect"
"strconv"
"testing"
@@ -69,6 +68,7 @@ func Test_nodeYaml_SetFrom(t *testing.T) {
test_node1 := NewInfo()
test_node2 := NewInfo()
test_node3 := NewInfo()
test_node4 := NewInfo()
for _, n := range nodes {
if n.Id.Get() == "test_node1" {
test_node1 = n
@@ -213,11 +213,140 @@ func Test_nodeYaml_SetFrom(t *testing.T) {
}
})
t.Run("Get() ipmitag foo from profile, node does not have this tag", func(t *testing.T) {
fmt.Println("ipmi tags", test_node3.Ipmi.Tags)
fmt.Println(c.Nodes["test_node3"].Ipmi)
value := test_node3.Ipmi.Tags["foo"].Get()
if value != "foo ipmi node3" {
t.Errorf("Get() returned wrong tag for foo: %s", value)
}
})
t.Run("Set() comment foo for empty node", func(t *testing.T) {
test_node4.Comment.Set("foo")
nodeConf := NewConf()
nodeConf.GetFrom(test_node4)
ymlByte, _ := yaml.Marshal(nodeConf)
wanted := `comment: foo
kernel: {}
ipmi: {}
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
// have to remove the comment for further tests, as vscode
// can test single functions
test_node4.Comment.Set("UNDEF")
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ = yaml.Marshal(nodeConf)
wanted = `{}
`
if string(ymlByte) != wanted {
t.Errorf("Couldn't unset comment:\n'%s'\nwanted:\n'%s'", string(ymlByte), wanted)
}
})
t.Run("Set() ipmiuser foo for flattened empty node", func(t *testing.T) {
test_node4.Ipmi.UserName.Set("foo")
nodeConf := NewConf()
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ := yaml.Marshal(nodeConf)
wanted := `ipmi:
username: foo
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
test_node4.Ipmi.Tags["foo"] = &Entry{}
test_node4.Ipmi.Tags["foo"].Set("baar")
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ = yaml.Marshal(nodeConf)
wanted = `ipmi:
username: foo
tags:
foo: baar
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
test_node4.Ipmi.UserName.Set("UNSET")
delete(test_node4.Ipmi.Tags, "foo")
})
t.Run("Set() kernelargs foo for flattened empty node", func(t *testing.T) {
test_node4.Kernel.Args.Set("foo")
nodeConf := NewConf()
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ := yaml.Marshal(nodeConf)
wanted := `kernel:
args: foo
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
test_node4.Kernel.Args.Set("--")
})
t.Run("Set() tag foo to bar for flattened empty node", func(t *testing.T) {
test_node4.Tags["foo"] = &Entry{}
test_node4.Tags["foo"].Set("baar")
nodeConf := NewConf()
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ := yaml.Marshal(nodeConf)
wanted := `tags:
foo: baar
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
delete(test_node4.Tags, "foo")
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ = yaml.Marshal(nodeConf)
wanted = `{}
`
if string(ymlByte) != wanted {
t.Errorf("Couldn't remove tag'%s'", string(ymlByte))
}
})
t.Run("Set() netdev foo with device name baar for flattened empty node", func(t *testing.T) {
netdev := NewNetDevEntry()
test_node4.NetDevs["foo"] = &netdev
test_node4.NetDevs["foo"].Device.Set("baar")
nodeConf := NewConf()
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ := yaml.Marshal(nodeConf)
wanted := `network devices:
foo:
device: baar
`
if !(wanted == string(ymlByte)) {
t.Errorf("Got wrong yml, wanted:\n'%s'\nGot:\n'%s'", wanted, string(ymlByte))
}
test_node4.NetDevs["foo"].Tags["netfoo"] = &Entry{}
test_node4.NetDevs["foo"].Tags["netfoo"].Set("netbaar")
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
wanted = `network devices:
foo:
device: baar
tags:
netfoo: netbaar
`
ymlByte, _ = yaml.Marshal(nodeConf)
if string(ymlByte) != wanted {
t.Errorf("Couldn set nettag: '%s' got: '%s'", wanted, string(ymlByte))
}
delete(test_node4.NetDevs, "foo")
nodeConf.GetFrom(test_node4)
nodeConf.Flatten()
ymlByte, _ = yaml.Marshal(nodeConf)
wanted = `{}
`
if string(ymlByte) != wanted {
t.Errorf("Couldn't remove tag'%s'", string(ymlByte))
}
})
}