Refactor the CreateFlags command
* added the additional type flag, which can be bool,IP * UNDEF is recognized for the bool flag * 0.0.0.0 must be used as UNDEF for IP flag Signed-off-by: Christian Goll <cgoll@suse.de>
This commit is contained in:
@@ -44,7 +44,7 @@ type NodeConf struct {
|
||||
Init string `yaml:"init,omitempty" lopt:"init" sopt:"i" comment:"Define the init process to boot the container"`
|
||||
Root string `yaml:"root,omitempty" lopt:"root" comment:"Define the rootfs" `
|
||||
AssetKey string `yaml:"asset key,omitempty" lopt:"asset" comment:"Set the node's Asset tag (key)"`
|
||||
Discoverable string `yaml:"discoverable,omitempty" lopt:"discoverable" comment:"Make discoverable in given network (yes/no)"`
|
||||
Discoverable string `yaml:"discoverable,omitempty" lopt:"discoverable" sopt:"e" comment:"Make discoverable in given network (true/false)" type:"bool"`
|
||||
Profiles []string `yaml:"profiles,omitempty" lopt:"profile" sopt:"P" comment:"Set the node's profile members (comma separated)"`
|
||||
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
|
||||
Tags map[string]string `yaml:"tags,omitempty" lopt:"tagadd" comment:"base key"`
|
||||
@@ -56,12 +56,12 @@ type NodeConf struct {
|
||||
type IpmiConf struct {
|
||||
UserName string `yaml:"username,omitempty" lopt:"ipmiuser" comment:"Set the IPMI username"`
|
||||
Password string `yaml:"password,omitempty" lopt:"ipmipass" comment:"Set the IPMI password"`
|
||||
Ipaddr string `yaml:"ipaddr,omitempty" lopt:"ipmiaddr" comment:"Set the IPMI IP address"`
|
||||
Netmask string `yaml:"netmask,omitempty" lopt:"ipminetmask" comment:"Set the IPMI netmask"`
|
||||
Ipaddr string `yaml:"ipaddr,omitempty" lopt:"ipmiaddr" comment:"Set the IPMI IP address" type:"IP"`
|
||||
Netmask string `yaml:"netmask,omitempty" lopt:"ipminetmask" comment:"Set the IPMI netmask" type:"IP"`
|
||||
Port string `yaml:"port,omitempty" lopt:"ipmiport" comment:"Set the IPMI port"`
|
||||
Gateway string `yaml:"gateway,omitempty" lopt:"ipmigateway" comment:"Set the IPMI gateway"`
|
||||
Gateway string `yaml:"gateway,omitempty" lopt:"ipmigateway" comment:"Set the IPMI gateway" type:"IP"`
|
||||
Interface string `yaml:"interface,omitempty" lopt:"ipmiinterface" comment:"Set the node's IPMI interface (defaults: 'lan')"`
|
||||
Write string `yaml:"write,omitempty" lopt:"ipmiwrite" comment:"Enable the write of impi configuration (yes/no)"`
|
||||
Write string `yaml:"write,omitempty" lopt:"ipmiwrite" comment:"Enable the write of impi configuration (true/false)" type:"bool"`
|
||||
Tags map[string]string `yaml:"tags,omitempty" lopt:"ipmitagadd" comment:"add ipmitags"`
|
||||
TagsDel []string `yaml:"tagsdel,omitempty" lopt:"ipmitagdel" comment:"remove ipmitags"` // should not go to disk only to wire
|
||||
}
|
||||
@@ -73,16 +73,18 @@ type KernelConf struct {
|
||||
|
||||
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 (yes/no)"`
|
||||
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"`
|
||||
Ipaddr string `yaml:"ipaddr,omitempty" comment:"IPv4 address in given network" sopt:"I" lopt:"ipaddr"`
|
||||
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"`
|
||||
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"`
|
||||
Gateway string `yaml:"gateway,omitempty" lopt:"gateway" sopt:"G" comment:"Set the node's network device gateway"`
|
||||
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"`
|
||||
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"`
|
||||
TagsDel []string `yaml:"tagsdel,omitempty" lopt:"nettagdel" comment:"delete network tags"` // should not go to disk only to wire
|
||||
}
|
||||
|
||||
200
internal/pkg/node/flags.go
Normal file
200
internal/pkg/node/flags.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
/*
|
||||
Create cmd line flags from the NodeConf fields
|
||||
*/
|
||||
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) (converters []func()) {
|
||||
nodeInfoType := reflect.TypeOf(nodeConf)
|
||||
nodeInfoVal := reflect.ValueOf(nodeConf)
|
||||
// now iterate of every field
|
||||
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
|
||||
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" &&
|
||||
!util.InSlice(excludeList, nodeInfoType.Elem().Field(i).Tag.Get("lopt")) {
|
||||
field := nodeInfoVal.Elem().Field(i)
|
||||
converters = append(converters, createFlags(baseCmd, excludeList, nodeInfoType.Elem().Field(i), &field)...)
|
||||
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
|
||||
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
nestVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
for j := 0; j < nestType.Elem().NumField(); j++ {
|
||||
field := nestVal.Elem().Field(j)
|
||||
converters = append(converters, createFlags(baseCmd, excludeList, nestType.Elem().Field(j), &field)...)
|
||||
}
|
||||
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
|
||||
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
|
||||
// add a default network so that it can hold values
|
||||
key := "default"
|
||||
if len(netMap) == 0 {
|
||||
netMap[key] = new(NetDevs)
|
||||
} else {
|
||||
for keyIt := range netMap {
|
||||
key = keyIt
|
||||
break
|
||||
}
|
||||
}
|
||||
netType := reflect.TypeOf(netMap[key])
|
||||
netVal := reflect.ValueOf(netMap[key])
|
||||
for j := 0; j < netType.Elem().NumField(); j++ {
|
||||
field := netVal.Elem().Field(j)
|
||||
converters = append(converters, createFlags(baseCmd, excludeList, netType.Elem().Field(j), &field)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return converters
|
||||
}
|
||||
|
||||
/*
|
||||
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()) {
|
||||
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) })
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().UintVarP(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
uint(defaultConv),
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().UintVar(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
uint(defaultConv),
|
||||
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() {
|
||||
if !util.InSlice(GetUnsetVerbs(), *ptr) && *ptr != "" {
|
||||
if strings.ToLower(*ptr) != "yes" {
|
||||
*ptr = "true"
|
||||
return
|
||||
}
|
||||
if strings.ToLower(*ptr) != "no" {
|
||||
*ptr = "false"
|
||||
return
|
||||
}
|
||||
val, err := strconv.ParseBool(*ptr)
|
||||
if err != nil {
|
||||
wwlog.Error("commandline option %s needs to be bool", myType.Tag.Get("lopt"))
|
||||
os.Exit(1)
|
||||
}
|
||||
*ptr = strconv.FormatBool(val)
|
||||
}
|
||||
})
|
||||
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"))
|
||||
}
|
||||
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() {
|
||||
if valueRaw != nil {
|
||||
*ptr = valueRaw.String()
|
||||
}
|
||||
})
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().IPVarP(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
defaultConv,
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().IPVar(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
defaultConv,
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
case "IPMask":
|
||||
defaultConv := net.ParseIP(myType.Tag.Get("default")).DefaultMask()
|
||||
var valueRaw net.IPMask
|
||||
converters = append(converters, func() { *ptr = valueRaw.String() })
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().IPMaskVarP(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
defaultConv,
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().IPMaskVar(&valueRaw,
|
||||
myType.Tag.Get("lopt"),
|
||||
defaultConv,
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
default:
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
} else {
|
||||
baseCmd.PersistentFlags().StringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
}
|
||||
}
|
||||
} else if myType.Type == reflect.TypeOf([]string{}) {
|
||||
ptr := myVal.Addr().Interface().(*[]string)
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringSliceVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
[]string{myType.Tag.Get("default")},
|
||||
myType.Tag.Get("comment"))
|
||||
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
|
||||
baseCmd.PersistentFlags().StringSliceVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
[]string{myType.Tag.Get("default")},
|
||||
myType.Tag.Get("comment"))
|
||||
|
||||
}
|
||||
} else if myType.Type == reflect.TypeOf(map[string]string{}) {
|
||||
ptr := myVal.Addr().Interface().(*map[string]string)
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringToStringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
map[string]string{}, // empty default!
|
||||
myType.Tag.Get("comment"))
|
||||
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
|
||||
baseCmd.PersistentFlags().StringToStringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
map[string]string{}, // empty default!
|
||||
myType.Tag.Get("comment"))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return converters
|
||||
}
|
||||
@@ -10,6 +10,10 @@ import (
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func GetUnsetVerbs() []string {
|
||||
return []string{"UNSET", "DELETE", "UNDEF", "undef", "--", "nil", "0.0.0.0"}
|
||||
}
|
||||
|
||||
/**********
|
||||
*
|
||||
* Filters
|
||||
@@ -77,7 +81,7 @@ func (ent *Entry) Set(val string) {
|
||||
return
|
||||
}
|
||||
|
||||
if val == "UNDEF" || val == "DELETE" || val == "UNSET" || val == "--" || val == "nil" {
|
||||
if util.InSlice(GetUnsetVerbs(), val) {
|
||||
wwlog.Debug("Removing value for %v", *ent)
|
||||
ent.value = []string{""}
|
||||
} else {
|
||||
@@ -102,7 +106,7 @@ func (ent *Entry) SetSlice(val []string) {
|
||||
} else if len(val) == 1 && val[0] == "" { // check also for an "empty" slice
|
||||
return
|
||||
}
|
||||
if val[0] == "UNDEF" || val[0] == "DELETE" || val[0] == "UNSET" || val[0] == "--" {
|
||||
if util.InSlice(GetUnsetVerbs(), val[0]) {
|
||||
ent.value = []string{}
|
||||
} else {
|
||||
ent.value = val
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -194,102 +193,6 @@ func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create cmd line flags from the NodeConf fields
|
||||
*/
|
||||
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) {
|
||||
nodeInfoType := reflect.TypeOf(nodeConf)
|
||||
nodeInfoVal := reflect.ValueOf(nodeConf)
|
||||
// now iterate of every field
|
||||
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
|
||||
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" &&
|
||||
!util.InSlice(excludeList, nodeInfoType.Elem().Field(i).Tag.Get("lopt")) {
|
||||
field := nodeInfoVal.Elem().Field(i)
|
||||
createFlags(baseCmd, excludeList, nodeInfoType.Elem().Field(i), &field)
|
||||
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
|
||||
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
nestVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
|
||||
for j := 0; j < nestType.Elem().NumField(); j++ {
|
||||
field := nestVal.Elem().Field(j)
|
||||
createFlags(baseCmd, excludeList, nestType.Elem().Field(j), &field)
|
||||
}
|
||||
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
|
||||
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
|
||||
// add a default network so that it can hold values
|
||||
key := "default"
|
||||
if len(netMap) == 0 {
|
||||
netMap[key] = new(NetDevs)
|
||||
} else {
|
||||
for keyIt := range netMap {
|
||||
key = keyIt
|
||||
break
|
||||
}
|
||||
}
|
||||
netType := reflect.TypeOf(netMap[key])
|
||||
netVal := reflect.ValueOf(netMap[key])
|
||||
for j := 0; j < netType.Elem().NumField(); j++ {
|
||||
field := netVal.Elem().Field(j)
|
||||
createFlags(baseCmd, excludeList, netType.Elem().Field(j), &field)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Helper function to create the different PerisitantFlags() for different types.
|
||||
*/
|
||||
func createFlags(baseCmd *cobra.Command, excludeList []string,
|
||||
myType reflect.StructField, myVal *reflect.Value) {
|
||||
if myType.Tag.Get("lopt") != "" {
|
||||
if myType.Type.Kind() == reflect.String {
|
||||
ptr := myVal.Addr().Interface().(*string)
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
|
||||
baseCmd.PersistentFlags().StringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("default"),
|
||||
myType.Tag.Get("comment"))
|
||||
|
||||
}
|
||||
} else if myType.Type == reflect.TypeOf([]string{}) {
|
||||
ptr := myVal.Addr().Interface().(*[]string)
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringSliceVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
[]string{myType.Tag.Get("default")},
|
||||
myType.Tag.Get("comment"))
|
||||
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
|
||||
baseCmd.PersistentFlags().StringSliceVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
[]string{myType.Tag.Get("default")},
|
||||
myType.Tag.Get("comment"))
|
||||
|
||||
}
|
||||
} else if myType.Type == reflect.TypeOf(map[string]string{}) {
|
||||
ptr := myVal.Addr().Interface().(*map[string]string)
|
||||
if myType.Tag.Get("sopt") != "" {
|
||||
baseCmd.PersistentFlags().StringToStringVarP(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
myType.Tag.Get("sopt"),
|
||||
map[string]string{}, // empty default!
|
||||
myType.Tag.Get("comment"))
|
||||
} else if !util.InSlice(excludeList, myType.Tag.Get("lopt")) {
|
||||
baseCmd.PersistentFlags().StringToStringVar(ptr,
|
||||
myType.Tag.Get("lopt"),
|
||||
map[string]string{}, // empty default!
|
||||
myType.Tag.Get("comment"))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Populates all fields of NodeInfo with Set from the
|
||||
values of NodeConf.
|
||||
|
||||
Reference in New Issue
Block a user