diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index ed9d6320..8f7ae7dc 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -2,6 +2,7 @@ package node import ( "fmt" + "reflect" "regexp" "strings" @@ -347,3 +348,19 @@ func NewInfo() (nodeInfo NodeInfo) { nodeInfo.NetDevs = make(map[string]*NetDevEntry) return nodeInfo } + +/* +Get a entry by its name +*/ +func GetByName(node interface{}, name string) (string, error) { + valEntry := reflect.ValueOf(node) + entryField := valEntry.Elem().FieldByName(name) + if entryField == (reflect.Value{}) { + return "", fmt.Errorf("couldn't find field with name: %s", name) + } + if entryField.Type() != reflect.TypeOf(Entry{}) { + return "", fmt.Errorf("field %s is not of type node.Entry", name) + } + myEntry := entryField.Interface().(Entry) + return myEntry.Get(), nil +} diff --git a/internal/pkg/node/transformer_test.go b/internal/pkg/node/transformer_test.go new file mode 100644 index 00000000..8742f2a3 --- /dev/null +++ b/internal/pkg/node/transformer_test.go @@ -0,0 +1,37 @@ +package node + +import ( + "reflect" + "testing" +) + +func Test_nodeYaml_SetFrom(t *testing.T) { + c, _ := NewTestNode() + singleNodeConf := c.Nodes["test_node"] + singleNodeInfo := NewInfo() + singleNodeInfo.SetFrom(singleNodeConf) + tests := []struct { + name string + arg string + want string + wantErr bool + }{ + {"Right comment", "Comment", "Node Comment", false}, + {"FieldName", "comment", "NodeComment", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetByName(&singleNodeInfo, tt.arg) + if (err != nil) != tt.wantErr { + t.Errorf("GetByName(%s,%s) error = %v, wantErr %v", + reflect.TypeOf(singleNodeConf), 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) + return + } + }) + } +} diff --git a/internal/pkg/node/transformers.go b/internal/pkg/node/transformers.go index 18a1649a..177d7d49 100644 --- a/internal/pkg/node/transformers.go +++ b/internal/pkg/node/transformers.go @@ -72,7 +72,8 @@ func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo, for key, val := range entryMap { confMap[key] = getter(val) } - } else if nodeInfoVal.Field(i).Type().Kind() == reflect.Ptr { + } else if nodeInfoVal.Field(i).Type().Kind() == reflect.Ptr && !nodeInfoVal.Field(i).IsNil() { + // initialize the nested NodeConf structs, but only if these will be set if confField.Addr().Elem().IsZero() { switch confField.Addr().Elem().Type() { case reflect.TypeOf((*KernelConf)(nil)): @@ -341,6 +342,11 @@ func (node *NodeInfo) setterFrom(n *NodeConf, nameArg string, if node.Ipmi == nil { node.Ipmi = new(IpmiEntry) } + // also n could be nil + if n == nil { + myn := NewConf() + n = &myn + } nodeInfoVal := reflect.ValueOf(node) nodeInfoType := reflect.TypeOf(node) nodeConfVal := reflect.ValueOf(n) @@ -509,6 +515,10 @@ Abstract function for setting a NetDevEntry from a NetDevs func (netDev *NetDevEntry) setterFrom(netYaml *NetDevs, nameArg string, setter func(*Entry, string, string), setterSlice func(*Entry, []string, string)) { + // check if netYaml is empty + if netYaml == nil { + netYaml = new(NetDevs) + } netValues := reflect.ValueOf(netDev) netInfoType := reflect.TypeOf(*netYaml) netInfoVal := reflect.ValueOf(*netYaml) diff --git a/internal/pkg/node/util_test.go b/internal/pkg/node/util_test.go index fd8c8323..bdce3bf7 100644 --- a/internal/pkg/node/util_test.go +++ b/internal/pkg/node/util_test.go @@ -13,6 +13,7 @@ nodeprofiles: comment: This profile is automatically included for each node nodes: test_node: + comment: Node Comment profiles: - default network devices: