Files
warewulf/internal/pkg/node/checkconf.go
Jonathon Anderson 0665d5dc88 Refactor node
Signed-off-by: Jonathon Anderson <janderson@ciq.com>
2024-11-11 00:08:47 -07:00

106 lines
3.4 KiB
Go

package node
import (
"fmt"
"net"
"reflect"
"strconv"
"strings"
"github.com/warewulf/warewulf/internal/pkg/util"
"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) {
// now iterate of every field
for i := 0; i < infoVal.Elem().NumField(); i++ {
if infoType.Elem().Field(i).Type.Kind() == reflect.String {
newFmt, err := checker(infoVal.Elem().Field(i).Interface().(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 == "" || util.InSlice(wwtype.GetUnsetVerbs(), 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
}