diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 9189168d..9afabd2c 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -87,7 +87,7 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) { node.Tags[keyname] = key delete(node.Keys, keyname) } - n.setFrom(node) + n.SetFrom(node) // set default/primary network is just one network exist if len(n.NetDevs) == 1 { // only way to get the key @@ -130,7 +130,7 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) { } // can't call setFrom() as we have to use SetAlt instead of Set for an Entry wwlog.Printf(wwlog.VERBOSE, "Merging profile into node: %s <- %s\n", nodename, profileName) - n.setAltFrom(config.NodeProfiles[profileName], profileName) + n.SetAltFrom(config.NodeProfiles[profileName], profileName) } ret = append(ret, n) } @@ -162,7 +162,7 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) { profile.Tags[keyname] = key delete(profile.Keys, keyname) } - p.setFrom(profile) + p.SetFrom(profile) p.Ipmi.Ipaddr.Set(profile.IpmiIpaddr) p.Ipmi.Netmask.Set(profile.IpmiNetmask) p.Ipmi.Port.Set(profile.IpmiPort) diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index b9e77ceb..02d26809 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -149,7 +149,7 @@ func (ent *Entry) SetDefaultSlice(val []string) { } /* -Remove a elemnt from a slice +Remove a element from a slice */ func (ent *Entry) SliceRemoveElement(val string) { util.SliceRemoveElement(ent.value, val) diff --git a/internal/pkg/node/transformers.go b/internal/pkg/node/transformers.go index 54f2bb05..5113d96d 100644 --- a/internal/pkg/node/transformers.go +++ b/internal/pkg/node/transformers.go @@ -11,6 +11,24 @@ the underlying entries using GetReal, so just the explicit values go do disk. */ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { + nodeConf.getterFrom(nodeInfo, (*Entry).GetReal, (*Entry).GetRealSlice) +} + +/* +Populates a NodeConf struct from a NodeInfo, with the combined +values from the underlying entries using Get. +*/ +func (nodeConf *NodeConf) GetFrom(nodeInfo NodeInfo) { + nodeConf.getterFrom(nodeInfo, (*Entry).Get, (*Entry).GetSlice) +} + +/* +Abstract function which populates a NodeConf form the given NodeInfo +via getter functions. +*/ +func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo, + getter func(*Entry) string, + getterSlice func(*Entry) []string) { nodeInfoType := reflect.TypeOf(nodeInfo) nodeInfoVal := reflect.ValueOf(nodeInfo) configVal := reflect.ValueOf(nodeConf) @@ -23,16 +41,16 @@ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { if confField.Type().Kind() == reflect.String { newValue := (confField.Addr().Interface()).(*string) entryVal := nodeInfoVal.Field(i).Interface().(Entry) - *newValue = entryVal.GetReal() + *newValue = getter(&entryVal) } else if confField.Type() == reflect.TypeOf([]string{}) { newValue := (confField.Addr().Interface()).(*[]string) entryVal := nodeInfoVal.Field(i).Interface().(Entry) - *newValue = entryVal.GetRealSlice() + *newValue = getterSlice(&entryVal) } } else if nodeInfoVal.Field(i).Type() == reflect.TypeOf(map[string]*Entry{}) { entryMap := nodeInfoVal.Field(i).Interface().(map[string]*Entry) for key, val := range entryMap { - confField.Interface().(map[string]string)[key] = val.GetReal() + confField.Interface().(map[string]string)[key] = getter(val) } } else if nodeInfoVal.Field(i).Type().Kind() == reflect.Ptr { if confField.Addr().Elem().IsZero() { @@ -56,11 +74,11 @@ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { if nestedVal.Type().Kind() == reflect.String { newValue := (nestedVal.Addr().Interface()).(*string) entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry) - *newValue = entryVal.GetReal() + *newValue = getter(&entryVal) } else if nestedVal.Type() == reflect.TypeOf([]string{}) { newValue := (nestedVal.Addr().Interface()).(*[]string) entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry) - *newValue = entryVal.GetRealSlice() + *newValue = getterSlice(&entryVal) } } else if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(map[string]*Entry{}) { @@ -70,7 +88,7 @@ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { } entryMap := nestedInfoVal.Elem().Field(j).Interface().(map[string]*Entry) for key, val := range entryMap { - nestedVal.Interface().(map[string]string)[key] = val.GetReal() + nestedVal.Interface().(map[string]string)[key] = getter(val) } } //} @@ -91,13 +109,10 @@ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { if netVal.IsValid() { if netVal.Type() == reflect.TypeOf(Entry{}) { newVal := netConfVal.Elem().Field(j).Addr().Interface().((*string)) - *newVal = (netVal.Addr().Interface()).(*Entry).GetReal() + *newVal = getter((netVal.Addr().Interface()).(*Entry)) } else if netVal.Type() == reflect.TypeOf(map[string]string{}) { - // normaly the map should be created here, but did not manage it - for key, val := range (netVal.Interface()).(map[string]string) { - var entr Entry - entr.Set(val) - netConfVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = &entr + for key, val := range (netVal.Interface()).(map[string]*string) { + *val = getter(netConfVal.Elem().Field(j).Interface().((map[string](*Entry)))[key]) } } } @@ -114,208 +129,18 @@ func (nodeConf *NodeConf) GetRealFrom(nodeInfo NodeInfo) { } } -/* -Populates a NodeConf struct from a NodeInfo, with the combined -values from the underlying entries using Get. -*/ -func (nodeConf *NodeConf) GetFrom(nodeInfo NodeInfo) { - nodeInfoType := reflect.TypeOf(nodeInfo) - nodeInfoVal := reflect.ValueOf(nodeInfo) - configVal := reflect.ValueOf(nodeConf) - // now iterate of every field - for i := 0; i < nodeInfoType.NumField(); i++ { - // found field with same name for Conf and Info - confField := configVal.Elem().FieldByName(nodeInfoType.Field(i).Name) - if confField.IsValid() { - if nodeInfoVal.Field(i).Type() == reflect.TypeOf(Entry{}) { - if confField.Type().Kind() == reflect.String { - newValue := (confField.Addr().Interface()).(*string) - entryVal := nodeInfoVal.Field(i).Interface().(Entry) - *newValue = entryVal.Get() - } else if confField.Type() == reflect.TypeOf([]string{}) { - newValue := (confField.Addr().Interface()).(*[]string) - entryVal := nodeInfoVal.Field(i).Interface().(Entry) - *newValue = entryVal.GetSlice() - } - } else if nodeInfoVal.Field(i).Type() == reflect.TypeOf(map[string]*Entry{}) { - if confField.IsNil() { - confFieldPtr := confField.Addr().Interface().(*map[string]string) - *confFieldPtr = make(map[string]string) - } - entryMap := nodeInfoVal.Field(i).Interface().(map[string]*Entry) - for key, val := range entryMap { - confField.Interface().(map[string]string)[key] = val.Get() - } - } else if nodeInfoVal.Field(i).Type().Kind() == reflect.Ptr { - if confField.Addr().Elem().IsZero() { - switch confField.Addr().Elem().Type() { - case reflect.TypeOf((*KernelConf)(nil)): - var newConf KernelConf - newConfPtr := (confField.Addr().Elem().Addr().Interface()).(**KernelConf) - *newConfPtr = &newConf - case reflect.TypeOf((*IpmiConf)(nil)): - var newConf IpmiConf - newConfPtr := (confField.Addr().Elem().Addr().Interface()).(**IpmiConf) - *newConfPtr = &newConf - } - } - nestedInfoType := reflect.TypeOf(nodeInfoVal.Field(i).Interface()) - nestedInfoVal := reflect.ValueOf(nodeInfoVal.Field(i).Interface()) - nestedConfVal := reflect.ValueOf(confField.Interface()) - for j := 0; j < nestedInfoType.Elem().NumField(); j++ { - nestedVal := nestedConfVal.Elem().FieldByName(nestedInfoType.Elem().Field(j).Name) - if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) { - if nestedVal.Type().Kind() == reflect.String { - newValue := (nestedVal.Addr().Interface()).(*string) - entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry) - *newValue = entryVal.Get() - } else if nestedVal.Type() == reflect.TypeOf([]string{}) { - newValue := (nestedVal.Addr().Interface()).(*[]string) - entryVal := nestedInfoVal.Elem().Field(j).Interface().(Entry) - *newValue = entryVal.GetSlice() - - } - } else if nestedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(map[string]*Entry{}) { - if nestedVal.IsNil() { - mapPtr := nestedVal.Addr().Interface().(*map[string]string) - *mapPtr = make(map[string]string) - } - entryMap := nestedInfoVal.Elem().Field(j).Interface().(map[string]*Entry) - for key, val := range entryMap { - nestedVal.Interface().(map[string]string)[key] = val.Get() - } - } - } - } else if nodeInfoVal.Field(i).Type() == reflect.TypeOf(map[string]*NetDevEntry{}) { - nestedMap := nodeInfoVal.Field(i).Interface().(map[string]*NetDevEntry) - for netName, netVal := range nestedMap { - netValsType := reflect.ValueOf(netVal) - if confField.IsNil() { - netMapPtr := confField.Addr().Interface().(*map[string](*NetDevs)) - *netMapPtr = make(map[string](*NetDevs)) - } - netMap := confField.Interface().(map[string](*NetDevs)) - var newNet NetDevs - newNet.Tags = make(map[string]string) - netMap[netName] = &newNet - netConfType := reflect.TypeOf(newNet) - netConfVal := reflect.ValueOf(&newNet) - for j := 0; j < netConfType.NumField(); j++ { - netVal := netValsType.Elem().FieldByName(netConfType.Field(j).Name) - if netVal.IsValid() { - if netVal.Type() == reflect.TypeOf(Entry{}) { - newVal := netConfVal.Elem().Field(j).Addr().Interface().((*string)) - *newVal = (netVal.Addr().Interface()).(*Entry).Get() - } else if netVal.Type() == reflect.TypeOf(map[string]string{}) { - // normaly the map should be created here, but did not manage it - for key, val := range (netVal.Interface()).(map[string]string) { - var entr Entry - entr.Set(val) - netConfVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = &entr - } - } - } - - } - } - } - } /*else { - // NodeInfo has the Id field, nodeConf not - fmt.Println("INVALID", nodeInfoType.Field(i).Name) - } */ - } -} - /* Populates all fields of NodeInfo with Set from the values of NodeConf. */ -func (node *NodeInfo) setFrom(n *NodeConf) { - // get the full memory, taking the shortcut and init Ipmi and Kernel directly - if node.Kernel == nil { - node.Kernel = new(KernelEntry) +func (node *NodeInfo) SetFrom(n *NodeConf) { + setWrap := func(entr *Entry, val string, nameArg string) { + entr.Set(val) } - if node.Ipmi == nil { - node.Ipmi = new(IpmiEntry) - } - nodeInfoVal := reflect.ValueOf(node) - nodeInfoType := reflect.TypeOf(node) - nodeConfVal := reflect.ValueOf(n) - // now iterate of every field - for i := 0; i < nodeInfoType.Elem().NumField(); i++ { - valField := nodeConfVal.Elem().FieldByName(nodeInfoType.Elem().Field(i).Name) - if valField.IsValid() { - // found field with same name for Conf and Info - if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(Entry{}) { - if valField.Type().Kind() == reflect.String { - (nodeInfoVal.Elem().Field(i).Addr().Interface()).(*Entry).Set(valField.String()) - } else if valField.Type() == reflect.TypeOf([]string{}) { - (nodeInfoVal.Elem().Field(i).Addr().Interface()).(*Entry).SetSlice(valField.Interface().([]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()) - 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{}) { - netstedInfoVal.Elem().Field(j).Addr().Interface().(*Entry).Set(nestedVal.String()) - } else { - 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 - } - for key, val := range confMap { - var entr Entry - entr.Set(val) - (netstedInfoVal.Elem().Field(j).Interface()).(map[string](*Entry))[key] = &entr - } - } - } - } - } else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*Entry)(nil)) { - confMap := valField.Interface().(map[string]string) - for key, val := range confMap { - var entr Entry - entr.Set(val) - (nodeInfoVal.Elem().Field(i).Interface()).(map[string](*Entry))[key] = &entr - } - } else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*NetDevEntry)(nil)) { - nestedMap := valField.Interface().(map[string](*NetDevs)) - for netName, netVals := range nestedMap { - netValsType := reflect.ValueOf(netVals) - netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string](*NetDevEntry)) - var newNet NetDevEntry - newNet.Tags = make(map[string]*Entry) - // This should be done a bit down, but didn't know how to do it - netMap[netName] = &newNet - netInfoType := reflect.TypeOf(newNet) - netInfoVal := reflect.ValueOf(&newNet) - for j := 0; j < netInfoType.NumField(); j++ { - netVal := netValsType.Elem().FieldByName(netInfoType.Field(j).Name) - if netVal.IsValid() { - if netVal.Type().Kind() == reflect.String { - netInfoVal.Elem().Field(j).Addr().Interface().((*Entry)).Set(netVal.String()) - if netInfoType.Field(j).Name == "Netmask" { - netInfoVal.Elem().Field(j).Addr().Interface().((*Entry)).SetDefault("255.255.255.0") - } - } else if netVal.Type() == reflect.TypeOf(map[string]string{}) { - // normaly the map should be created here, but did not manage it - for key, val := range (netVal.Interface()).(map[string]string) { - var entr Entry - entr.Set(val) - netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = &entr - } - } - } - } - } - } - } + setSliceWrap := func(entr *Entry, val []string, nameArg string) { + entr.SetSlice(val) } + node.setterFrom(n, "", setWrap, setSliceWrap) } /* @@ -324,7 +149,17 @@ values of NodeConf. The string profileName is used to destermine from which source/NodeInfo the entry came from. */ -func (node *NodeInfo) setAltFrom(n *NodeConf, profileName string) { +func (node *NodeInfo) SetAltFrom(n *NodeConf, profileName string) { + node.setterFrom(n, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice) +} + +/* +Abstract function which populates a NodeInfo from a NodeConf via +setter functionns. +*/ +func (node *NodeInfo) setterFrom(n *NodeConf, nameArg string, + setter func(*Entry, string, string), + setterSlice func(*Entry, []string, string)) { // get the full memory, taking the shortcut and init Ipmi and Kernel directly if node.Kernel == nil { node.Kernel = new(KernelEntry) @@ -342,9 +177,9 @@ func (node *NodeInfo) setAltFrom(n *NodeConf, profileName string) { // found field with same name for Conf and Info if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(Entry{}) { if valField.Type().Kind() == reflect.String { - (nodeInfoVal.Elem().Field(i).Addr().Interface()).(*Entry).SetAlt(valField.String(), profileName) + setter(nodeInfoVal.Elem().Field(i).Addr().Interface().(*Entry), valField.String(), nameArg) } else if valField.Type() == reflect.TypeOf([]string{}) { - (nodeInfoVal.Elem().Field(i).Addr().Interface()).(*Entry).SetAltSlice(valField.Interface().([]string), profileName) + setterSlice(nodeInfoVal.Elem().Field(i).Addr().Interface().(*Entry), valField.Interface().([]string), nameArg) } } else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr && !valField.IsZero() { nestedInfoType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface()) @@ -354,7 +189,7 @@ func (node *NodeInfo) setAltFrom(n *NodeConf, profileName string) { nestedVal := nestedConfVal.Elem().FieldByName(nestedInfoType.Elem().Field(j).Name) if nestedVal.IsValid() { if netstedInfoVal.Elem().Field(j).Type() == reflect.TypeOf(Entry{}) { - netstedInfoVal.Elem().Field(j).Addr().Interface().(*Entry).SetAlt(nestedVal.String(), profileName) + setter(netstedInfoVal.Elem().Field(j).Addr().Interface().(*Entry), nestedVal.String(), nameArg) } else { confMap := nestedVal.Interface().(map[string]string) if netstedInfoVal.Elem().Field(j).IsNil() { @@ -363,9 +198,9 @@ func (node *NodeInfo) setAltFrom(n *NodeConf, profileName string) { *mapPtr = newMap } for key, val := range confMap { - var entr Entry - entr.SetAlt(val, profileName) - (netstedInfoVal.Elem().Field(j).Interface()).(map[string](*Entry))[key] = &entr + entr := new(Entry) + setter(entr, val, nameArg) + (netstedInfoVal.Elem().Field(j).Interface()).(map[string](*Entry))[key] = entr } } } @@ -373,9 +208,9 @@ func (node *NodeInfo) setAltFrom(n *NodeConf, profileName 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 { - var entr Entry - entr.SetAlt(val, profileName) - (nodeInfoVal.Elem().Field(i).Interface()).(map[string](*Entry))[key] = &entr + entr := new(Entry) + setter(entr, val, nameArg) + (nodeInfoVal.Elem().Field(i).Interface()).(map[string](*Entry))[key] = entr } } else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string](*NetDevEntry)(nil)) { nestedMap := valField.Interface().(map[string](*NetDevs)) @@ -392,13 +227,13 @@ func (node *NodeInfo) setAltFrom(n *NodeConf, profileName string) { netVal := netValsType.Elem().FieldByName(netInfoType.Field(j).Name) if netVal.IsValid() { if netVal.Type().Kind() == reflect.String { - netInfoVal.Elem().Field(j).Addr().Interface().((*Entry)).SetAlt(netVal.String(), profileName) + setter(netInfoVal.Elem().Field(j).Addr().Interface().((*Entry)), netVal.String(), nameArg) } else if netVal.Type() == reflect.TypeOf(map[string]string{}) { // normaly the map should be created here, but did not manage it for key, val := range (netVal.Interface()).(map[string]string) { - var entr Entry - entr.SetAlt(val, profileName) - netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = &entr + entr := new(Entry) + setter(entr, val, nameArg) + netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = entr } } }