use netParseIP and ParseMAC
check also MAC addresses and common formating Signed-off-by: Christian Goll <cgoll@suse.de> reformat ipaddr for test coverage fixed processing of default values updated transformer tests correct behavior for tags add tests for tags new tests for primary network Signed-off-by: Christian Goll <cgoll@suse.de>
This commit is contained in:
@@ -2,7 +2,7 @@ package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"net"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -18,9 +18,11 @@ func (nodeConf *NodeConf) Check() (err error) {
|
||||
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
|
||||
//wwlog.Debug("checking field: %s type: %s", nodeInfoType.Elem().Field(i).Name, nodeInfoVal.Elem().Field(i).Type())
|
||||
if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.String {
|
||||
err = checker(nodeInfoVal.Elem().Field(i).Interface().(string), nodeInfoType.Elem().Field(i).Tag.Get("type"))
|
||||
newFmt, err := checker(nodeInfoVal.Elem().Field(i).Interface().(string), nodeInfoType.Elem().Field(i).Tag.Get("type"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("field: %s value:%s err: %s", nodeInfoType.Elem().Field(i).Name, nodeInfoVal.Elem().Field(i).String(), err)
|
||||
} else if newFmt != "" {
|
||||
nodeInfoVal.Elem().Field(i).SetString(newFmt)
|
||||
}
|
||||
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr && !nodeInfoVal.Elem().Field(i).IsNil() {
|
||||
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
@@ -28,9 +30,11 @@ func (nodeConf *NodeConf) Check() (err error) {
|
||||
for j := 0; j < nestType.Elem().NumField(); j++ {
|
||||
if nestType.Elem().Field(j).Type.Kind() == reflect.String {
|
||||
//wwlog.Debug("checking field: %s type: %s", nestType.Elem().Field(j).Name, nestType.Elem().Field(j).Tag.Get("type"))
|
||||
err = checker(nestVal.Elem().Field(j).Interface().(string), nestType.Elem().Field(j).Tag.Get("type"))
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,9 +44,11 @@ func (nodeConf *NodeConf) Check() (err error) {
|
||||
netType := reflect.TypeOf(val)
|
||||
netVal := reflect.ValueOf(val)
|
||||
for j := 0; j < netType.Elem().NumField(); j++ {
|
||||
err = checker(netVal.Elem().Field(j).String(), netType.Elem().Field(j).Tag.Get("type"))
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,26 +57,39 @@ func (nodeConf *NodeConf) Check() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checker(value string, valType string) (err error) {
|
||||
func checker(value string, valType string) (niceValue string, err error) {
|
||||
if valType == "" || value == "" {
|
||||
return nil
|
||||
return "", nil
|
||||
}
|
||||
//wwlog.Debug("checker: %s is %s", value, valType)
|
||||
switch valType {
|
||||
case "":
|
||||
return nil
|
||||
return "", nil
|
||||
case "bool":
|
||||
if strings.ToLower(value) == "yes" {
|
||||
return nil
|
||||
return "true", nil
|
||||
}
|
||||
if strings.ToLower(value) == "no" {
|
||||
return nil
|
||||
return "false", nil
|
||||
}
|
||||
_, err = strconv.ParseBool(value)
|
||||
return err
|
||||
myBool, err := strconv.ParseBool(value)
|
||||
return strconv.FormatBool(myBool), err
|
||||
case "IP":
|
||||
_, err = netip.ParseAddr(value)
|
||||
return err
|
||||
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
|
||||
return "", nil
|
||||
}
|
||||
|
||||
@@ -135,12 +135,13 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
|
||||
defData, err := os.ReadFile(DefaultConfig)
|
||||
if err != nil {
|
||||
wwlog.Verbose("Couldn't read DefaultConfig :%s\n", err)
|
||||
wwlog.Verbose("Using building defaults")
|
||||
defData = []byte(FallBackConf)
|
||||
}
|
||||
wwlog.Debug("Unmarshalling default config\n")
|
||||
err = yaml.Unmarshal(defData, &defConf)
|
||||
if err != nil {
|
||||
wwlog.Verbose("Couldn't unmarshall defaults from file :%s\n", err)
|
||||
wwlog.Verbose("Using building defaults")
|
||||
err = yaml.Unmarshal([]byte(FallBackConf), &defConf)
|
||||
if err != nil {
|
||||
wwlog.Warn("Could not get any defaults")
|
||||
|
||||
@@ -75,14 +75,14 @@ type NetDevs struct {
|
||||
Type string `yaml:"type,omitempty" lopt:"type" sopt:"T" comment:"Set device type of given network"`
|
||||
OnBoot string `yaml:"onboot,omitempty" lopt:"onboot" comment:"Enable/disable network device (true/false)" type:"bool"`
|
||||
Device string `yaml:"device,omitempty" lopt:"netdev" sopt:"N" comment:"Set the device for given network"`
|
||||
Hwaddr string `yaml:"hwaddr,omitempty" lopt:"hwaddr" sopt:"H" comment:"Set the device's HW address for given network"`
|
||||
Hwaddr string `yaml:"hwaddr,omitempty" lopt:"hwaddr" sopt:"H" comment:"Set the device's HW address for given network" type:"MAC"`
|
||||
Ipaddr string `yaml:"ipaddr,omitempty" comment:"IPv4 address in given network" sopt:"I" lopt:"ipaddr" type:"IP"`
|
||||
IpCIDR string `yaml:"ipcidr,omitempty"`
|
||||
Ipaddr6 string `yaml:"ip6addr,omitempty" lopt:"ipaddr6" comment:"IPv6 address" type:"IP"`
|
||||
Prefix string `yaml:"prefix,omitempty"`
|
||||
Netmask string `yaml:"netmask,omitempty" lopt:"netmask" sopt:"M" comment:"Set the networks netmask" type:"IP"`
|
||||
Gateway string `yaml:"gateway,omitempty" lopt:"gateway" sopt:"G" comment:"Set the node's network device gateway" type:"IP"`
|
||||
MTU string `yaml:"mtu,omitempty" lopt:"mtu" comment:"Set the mtu"`
|
||||
MTU string `yaml:"mtu,omitempty" lopt:"mtu" comment:"Set the mtu" type:"uint"`
|
||||
Primary string `yaml:"primary,omitempty" lopt:"primary" comment:"Enable/disable network device as primary (true/false)" type:"bool"`
|
||||
Default string `yaml:"default,omitempty"` /* backward compatibility */
|
||||
Tags map[string]string `yaml:"tags,omitempty" lopt:"nettagadd" comment:"network tags"`
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,7 @@ Create cmd line flags from the NodeConf fields. Returns a []func() where every f
|
||||
must be called, as the commandline parser returns e.g. netip.IP objects which must be parsedf
|
||||
back to strings.
|
||||
*/
|
||||
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) (converters []func()) {
|
||||
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) (converters []func() error) {
|
||||
nodeInfoType := reflect.TypeOf(nodeConf)
|
||||
nodeInfoVal := reflect.ValueOf(nodeConf)
|
||||
// now iterate of every field
|
||||
@@ -60,48 +59,54 @@ func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []stri
|
||||
Helper function to create the different PerisitantFlags() for different types.
|
||||
*/
|
||||
func createFlags(baseCmd *cobra.Command, excludeList []string,
|
||||
myType reflect.StructField, myVal *reflect.Value) (converters []func()) {
|
||||
myType reflect.StructField, myVal *reflect.Value) (converters []func() error) {
|
||||
if myType.Tag.Get("lopt") != "" {
|
||||
if myType.Type.Kind() == reflect.String {
|
||||
ptr := myVal.Addr().Interface().(*string)
|
||||
switch myType.Tag.Get("type") {
|
||||
case "uint":
|
||||
defaultConv, _ := strconv.ParseUint(myType.Tag.Get("default"), 10, 32)
|
||||
var valueRaw uint
|
||||
converters = append(converters, func() { *ptr = strconv.FormatUint(uint64(valueRaw), 10) })
|
||||
converters = append(converters, func() error {
|
||||
if !util.InSlice(GetUnsetVerbs(), *ptr) && *ptr != "" {
|
||||
_, err := strconv.ParseUint(myType.Tag.Get(*ptr), 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().UintVarP(&valueRaw,
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
uint(defaultConv),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().UintVar(&valueRaw,
|
||||
baseCmd.PersistentFlags().StringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
uint(defaultConv),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
case "bool":
|
||||
/*
|
||||
Can't use the bool var from pflag as we need the UNSET verbs to be passwd correctly
|
||||
*/
|
||||
converters = append(converters, func() {
|
||||
converters = append(converters, func() error {
|
||||
if !util.InSlice(GetUnsetVerbs(), *ptr) && *ptr != "" {
|
||||
if strings.ToLower(*ptr) != "yes" {
|
||||
*ptr = "true"
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if strings.ToLower(*ptr) != "no" {
|
||||
*ptr = "false"
|
||||
return
|
||||
return nil
|
||||
}
|
||||
val, err := strconv.ParseBool(*ptr)
|
||||
if err != nil {
|
||||
wwlog.Error("commandline option %s needs to be bool", myType.Tag.Get("lopt"))
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("commandline option %s needs to be bool", myType.Tag.Get("lopt"))
|
||||
}
|
||||
*ptr = strconv.FormatBool(val)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
@@ -119,10 +124,12 @@ func createFlags(baseCmd *cobra.Command, excludeList []string,
|
||||
case "IP":
|
||||
defaultConv := net.ParseIP(myType.Tag.Get("default"))
|
||||
var valueRaw net.IP
|
||||
converters = append(converters, func() {
|
||||
converters = append(converters, func() error {
|
||||
if valueRaw != nil {
|
||||
// will always get a IP, not a string
|
||||
*ptr = valueRaw.String()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().IPVarP(&valueRaw,
|
||||
@@ -139,7 +146,14 @@ func createFlags(baseCmd *cobra.Command, excludeList []string,
|
||||
case "IPMask":
|
||||
defaultConv := net.ParseIP(myType.Tag.Get("default")).DefaultMask()
|
||||
var valueRaw net.IPMask
|
||||
converters = append(converters, func() { *ptr = valueRaw.String() })
|
||||
converters = append(converters, func() error {
|
||||
if valueRaw != nil {
|
||||
*ptr = valueRaw.String()
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("could not parse %s to IP", valueRaw.String())
|
||||
}
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().IPMaskVarP(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
@@ -152,6 +166,27 @@ func createFlags(baseCmd *cobra.Command, excludeList []string,
|
||||
defaultConv,
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
case "MAC":
|
||||
converters = append(converters, func() error {
|
||||
myMac, err := net.ParseMAC(*ptr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*ptr = myMac.String()
|
||||
return nil
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
"",
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().StringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
"",
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
default:
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
|
||||
@@ -1,37 +1,223 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func NewTransformerTestNode() NodeYaml {
|
||||
var data = `
|
||||
nodeprofiles:
|
||||
default:
|
||||
comment: This profile is automatically included for each node
|
||||
ipmi:
|
||||
username: greg
|
||||
profile2:
|
||||
tags:
|
||||
foo: foo profile2
|
||||
comment: Comment profile2
|
||||
ipmi:
|
||||
tags:
|
||||
foo: foo ipmi profile
|
||||
nodes:
|
||||
test_node1:
|
||||
comment: Node Comment
|
||||
profiles:
|
||||
- default
|
||||
network devices:
|
||||
net0:
|
||||
device: eth1
|
||||
discoverable: true
|
||||
ipmi:
|
||||
username: chris
|
||||
tags:
|
||||
baar: baar node1
|
||||
test_node2:
|
||||
primary: net0
|
||||
profiles:
|
||||
- default
|
||||
- profile2
|
||||
network devices:
|
||||
net0:
|
||||
netmask: 1.1.1.1
|
||||
net1:
|
||||
ipaddr: 1.2.3.4
|
||||
tags:
|
||||
baar: baar node2
|
||||
test_node3:
|
||||
profiles:
|
||||
- profile2
|
||||
tags:
|
||||
foo: foo node3
|
||||
foobaar: foobaar node3
|
||||
ipmi:
|
||||
ipaddr: 1.1.1.1
|
||||
tags:
|
||||
foo: foo ipmi node3
|
||||
`
|
||||
var ret NodeYaml
|
||||
_ = yaml.Unmarshal([]byte(data), &ret)
|
||||
return ret
|
||||
}
|
||||
func Test_nodeYaml_SetFrom(t *testing.T) {
|
||||
c, _ := NewTestNode()
|
||||
singleNodeConf := c.Nodes["test_node"]
|
||||
singleNodeInfo := NewInfo()
|
||||
singleNodeInfo.SetFrom(singleNodeConf)
|
||||
tests := []struct {
|
||||
c := NewTransformerTestNode()
|
||||
nodes, _ := c.FindAllNodes()
|
||||
test_node1 := NewInfo()
|
||||
test_node2 := NewInfo()
|
||||
test_node3 := NewInfo()
|
||||
for _, n := range nodes {
|
||||
if n.Id.Get() == "test_node1" {
|
||||
test_node1 = n
|
||||
}
|
||||
if n.Id.Get() == "test_node2" {
|
||||
test_node2 = n
|
||||
}
|
||||
if n.Id.Get() == "test_node3" {
|
||||
test_node3 = n
|
||||
}
|
||||
}
|
||||
getByNametests := []struct {
|
||||
name string
|
||||
arg string
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{"Right comment", "Comment", "Node Comment", false},
|
||||
{"FieldName", "comment", "NodeComment", true},
|
||||
{"GetByName: FieldValue", "Comment", "Node Comment", false},
|
||||
{"GetByName: FieldName", "comment", "NodeComment", true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
for _, tt := range getByNametests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetByName(&singleNodeInfo, tt.arg)
|
||||
got, err := GetByName(&test_node1, tt.arg)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetByName(%s,%s) error = %v, wantErr %v",
|
||||
reflect.TypeOf(singleNodeConf), tt.arg, err, tt.wantErr)
|
||||
reflect.TypeOf(test_node1), tt.arg, err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if (got != tt.want) != tt.wantErr {
|
||||
t.Errorf("GetByName(%s,%s) got = %v, want = %v",
|
||||
reflect.TypeOf(singleNodeConf), tt.arg, got, tt.want)
|
||||
reflect.TypeOf(test_node1), tt.arg, got, tt.want)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
t.Run("Get() comment", func(t *testing.T) {
|
||||
comment := test_node1.Comment.Get()
|
||||
if comment != "Node Comment" {
|
||||
t.Errorf("Get() returned wrong comment: %s", comment)
|
||||
}
|
||||
})
|
||||
t.Run("Get() profile comment", func(t *testing.T) {
|
||||
comment := test_node2.Comment.Get()
|
||||
if comment != "Comment profile2" {
|
||||
t.Errorf("Get() returned wrong comment: %s", comment)
|
||||
}
|
||||
})
|
||||
t.Run("Get() default ipxe", func(t *testing.T) {
|
||||
value := test_node1.Ipxe.Get()
|
||||
if value != "default" {
|
||||
t.Errorf("Get() returned wrong ipxe template: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("GetSlice() default profile", func(t *testing.T) {
|
||||
value := test_node1.Profiles.GetSlice()[0]
|
||||
if value != "default" {
|
||||
t.Errorf("GetSlice() returned wrong profile: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() default kernel args", func(t *testing.T) {
|
||||
value := test_node1.Kernel.Args.Get()
|
||||
if value != "quiet crashkernel=no vga=791 net.naming-scheme=v238" {
|
||||
t.Errorf("Get() returned wrong kernel args: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() default network mask", func(t *testing.T) {
|
||||
value := test_node1.NetDevs["net0"].Netmask.Get()
|
||||
if value != "255.255.255.0" {
|
||||
t.Errorf("Get() returned wrong default netmask: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() default network mask", func(t *testing.T) {
|
||||
value := test_node2.NetDevs["net0"].Netmask.Get()
|
||||
if value != "1.1.1.1" {
|
||||
t.Errorf("Get() returned wrong default netmask: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("GetB() primary for single network", func(t *testing.T) {
|
||||
value := test_node1.NetDevs["net0"].Primary.GetB()
|
||||
if !value {
|
||||
t.Errorf("GetB() returned wrong: %s", strconv.FormatBool(value))
|
||||
}
|
||||
})
|
||||
t.Run("GetB() for primary with two networks", func(t *testing.T) {
|
||||
value := test_node2.NetDevs["net0"].Primary.GetB()
|
||||
if !value {
|
||||
t.Errorf("GetB() returned wrong: %s", strconv.FormatBool(value))
|
||||
}
|
||||
})
|
||||
t.Run("GetB() for primary with two networks, get secondary network", func(t *testing.T) {
|
||||
value := test_node2.NetDevs["net1"].Primary.GetB()
|
||||
if value {
|
||||
t.Errorf("GetB() returned wrong: %s", strconv.FormatBool(value))
|
||||
}
|
||||
})
|
||||
t.Run("GetB() default discoverable", func(t *testing.T) {
|
||||
value := test_node1.Discoverable.GetB()
|
||||
if !value {
|
||||
t.Errorf("GetB() returned wrong: %s", strconv.FormatBool(value))
|
||||
}
|
||||
})
|
||||
t.Run("GetB() default discoverable", func(t *testing.T) {
|
||||
value := test_node2.Discoverable.GetB()
|
||||
if value {
|
||||
t.Errorf("GetB() returned wrong: %s", strconv.FormatBool(value))
|
||||
}
|
||||
})
|
||||
t.Run("Get() ipmi user from profile", func(t *testing.T) {
|
||||
value := test_node2.Ipmi.UserName.Get()
|
||||
if value != "greg" {
|
||||
t.Errorf("Get() returned wrong ipmi username: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() ipmi user from node", func(t *testing.T) {
|
||||
value := test_node1.Ipmi.UserName.Get()
|
||||
if value != "chris" {
|
||||
t.Errorf("Get() returned wrong ipmi username: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() tag foo from profile, node does not have this tag", func(t *testing.T) {
|
||||
value := test_node2.Tags["foo"].Get()
|
||||
if value != "foo profile2" {
|
||||
t.Errorf("Get() returned wrong tag for foo: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() tag baar from node, node tag map is not overwritten", func(t *testing.T) {
|
||||
value := test_node2.Tags["baar"].Get()
|
||||
if value != "baar node2" {
|
||||
t.Errorf("Get() returned wrong tag for foo: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() tag foo from node, tag present in profile", func(t *testing.T) {
|
||||
value := test_node3.Tags["foo"].Get()
|
||||
if value != "foo node3" {
|
||||
t.Errorf("Get() returned wrong tag for foo: %s", value)
|
||||
}
|
||||
})
|
||||
t.Run("Get() tag foobaar from node", func(t *testing.T) {
|
||||
value := test_node3.Tags["foobaar"].Get()
|
||||
if value != "foobaar node3" {
|
||||
t.Errorf("Get() returned wrong tag for foo: %s", value)
|
||||
}
|
||||
})
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -266,24 +266,28 @@ func (node *NodeInfo) setterFrom(n *NodeConf, nameArg string,
|
||||
}
|
||||
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr && !valField.IsZero() {
|
||||
nestedInfoType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
netstedInfoVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
nestedInfoVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
nestedConfVal := reflect.ValueOf(valField.Interface())
|
||||
for j := 0; j < nestedInfoType.Elem().NumField(); j++ {
|
||||
nestedVal := nestedConfVal.Elem().FieldByName(nestedInfoType.Elem().Field(j).Name)
|
||||
if nestedVal.IsValid() {
|
||||
if netstedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) {
|
||||
setter(netstedInfoVal.Elem().Field(j).Addr().Interface().(*Entry), nestedVal.String(), nameArg)
|
||||
} else {
|
||||
if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) {
|
||||
setter(nestedInfoVal.Elem().Field(j).Addr().Interface().(*Entry), nestedVal.String(), nameArg)
|
||||
} else if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(map[string](*Entry){}) {
|
||||
confMap := nestedVal.Interface().(map[string]string)
|
||||
if netstedInfoVal.Elem().Field(j).IsNil() {
|
||||
newMap := make(map[string]*Entry)
|
||||
mapPtr := (netstedInfoVal.Elem().Field(j).Addr().Interface()).(*map[string](*Entry))
|
||||
*mapPtr = newMap
|
||||
if nestedInfoVal.Elem().Field(j).IsNil() {
|
||||
ptr := nestedInfoVal.Elem().Field(j).Addr().Interface().(*map[string](*Entry))
|
||||
*ptr = make(map[string]*Entry)
|
||||
}
|
||||
tagMap := nestedInfoVal.Elem().Field(j).Interface().(map[string](*Entry))
|
||||
for key, val := range confMap {
|
||||
entr := new(Entry)
|
||||
setter(entr, val, nameArg)
|
||||
(netstedInfoVal.Elem().Field(j).Interface()).(map[string](*Entry))[key] = entr
|
||||
if entr, ok := tagMap[key]; ok {
|
||||
setter(entr, val, nameArg)
|
||||
} else {
|
||||
entr := new(Entry)
|
||||
tagMap[key] = entr
|
||||
setter(entr, val, nameArg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,9 +295,17 @@ func (node *NodeInfo) setterFrom(n *NodeConf, nameArg string,
|
||||
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*Entry)(nil)) {
|
||||
confMap := valField.Interface().(map[string]string)
|
||||
for key, val := range confMap {
|
||||
entr := new(Entry)
|
||||
setter(entr, val, nameArg)
|
||||
(nodeInfoVal.Elem().Field(i).Interface()).(map[string](*Entry))[key] = entr
|
||||
tagMap := nodeInfoVal.Elem().Field(i).Interface().(map[string](*Entry))
|
||||
if nodeInfoVal.Elem().Field(i).IsNil() {
|
||||
tagMap = make(map[string]*Entry)
|
||||
}
|
||||
if entr, ok := tagMap[key]; ok {
|
||||
setter(entr, val, nameArg)
|
||||
} else {
|
||||
entr := new(Entry)
|
||||
tagMap[key] = entr
|
||||
setter(entr, val, nameArg)
|
||||
}
|
||||
}
|
||||
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*NetDevEntry)(nil)) {
|
||||
netValMap := valField.Interface().(map[string](*NetDevs))
|
||||
|
||||
@@ -27,10 +27,11 @@ func (config *NodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) {
|
||||
}
|
||||
|
||||
func (config *NodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) {
|
||||
if net.ParseIP(ipaddr) == nil {
|
||||
if addr := net.ParseIP(ipaddr); addr == nil {
|
||||
return NodeInfo{}, errors.New("invalid IP:" + ipaddr)
|
||||
} else {
|
||||
ipaddr = addr.String()
|
||||
}
|
||||
|
||||
var ret NodeInfo
|
||||
|
||||
n, _ := config.FindAllNodes()
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func NewTestNode() (NodeYaml, error) {
|
||||
func NewUtilTestNode() (NodeYaml, error) {
|
||||
var data = `
|
||||
nodeprofiles:
|
||||
default:
|
||||
@@ -49,7 +49,7 @@ nodes:
|
||||
}
|
||||
|
||||
func Test_nodeYaml_FindByHwaddr(t *testing.T) {
|
||||
c, _ := NewTestNode()
|
||||
c, _ := NewUtilTestNode()
|
||||
//type fields struct {
|
||||
// NodeProfiles map[string]*NodeConf
|
||||
// Nodes map[string]*NodeConf
|
||||
@@ -90,7 +90,7 @@ func Test_nodeYaml_FindByHwaddr(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_nodeYaml_FindByIpaddr(t *testing.T) {
|
||||
c, _ := NewTestNode()
|
||||
c, _ := NewUtilTestNode()
|
||||
type args struct {
|
||||
ipaddr string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user