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:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
RunE needs a function of type func(*cobraCommand,[]string) err, but
|
||||
in order to avoid global variables which mess up testing a function of
|
||||
@@ -16,6 +17,10 @@ the required type is returned
|
||||
*/
|
||||
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) error {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
// run converters for different types
|
||||
for _, c := range Converters {
|
||||
c()
|
||||
}
|
||||
// remove the default network as all network values are assigned
|
||||
// to this network
|
||||
if _, ok := vars.nodeConf.NetDevs["default"]; ok && vars.netName != "" {
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
type variables struct {
|
||||
netName string
|
||||
nodeConf node.NodeConf
|
||||
converters []func()
|
||||
}
|
||||
|
||||
// Returns the newly created command
|
||||
@@ -28,9 +29,8 @@ func GetCommand() *cobra.Command {
|
||||
RunE: CobraRunE(&vars),
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
}
|
||||
vars.nodeConf.CreateFlags(baseCmd, []string{"tagdel", "nettagdel", "ipmitagdel"})
|
||||
vars.converters = vars.nodeConf.CreateFlags(baseCmd, []string{"tagdel", "nettagdel", "ipmitagdel"})
|
||||
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "", "Set network name for network options")
|
||||
|
||||
// register the command line completions
|
||||
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
list, _ := container.ListSources()
|
||||
|
||||
@@ -13,6 +13,10 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
// run converters for different types
|
||||
for _, c := range Converters {
|
||||
c()
|
||||
}
|
||||
// remove the default network as the all network values are assigned
|
||||
// to this network
|
||||
if NetName != "default" {
|
||||
|
||||
@@ -15,7 +15,7 @@ var (
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "set [OPTIONS] PATTERN [PATTERN ...]",
|
||||
Short: "Configure node properties",
|
||||
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET' to remove a configuration",
|
||||
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET'/'0.0.0.0' to remove a configuration",
|
||||
Args: cobra.MinimumNArgs(0),
|
||||
RunE: CobraRunE,
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
@@ -38,11 +38,12 @@ var (
|
||||
SetYes bool
|
||||
SetForce bool
|
||||
NodeConf node.NodeConf
|
||||
Converters []func()
|
||||
)
|
||||
|
||||
func init() {
|
||||
NodeConf = node.NewConf()
|
||||
NodeConf.CreateFlags(baseCmd, []string{})
|
||||
Converters = NodeConf.CreateFlags(baseCmd, []string{})
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
|
||||
baseCmd.PersistentFlags().StringVar(&NetName, "netname", "default", "Set network name for network options")
|
||||
baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes")
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
)
|
||||
|
||||
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
|
||||
// run converters for different types
|
||||
for _, c := range Converters {
|
||||
c()
|
||||
}
|
||||
// remove the default network as the all network values are assigned
|
||||
// to this network
|
||||
if NetName != "" {
|
||||
|
||||
@@ -25,12 +25,13 @@ var (
|
||||
SetForce bool
|
||||
NetName string
|
||||
ProfileConf node.NodeConf
|
||||
Converters []func()
|
||||
)
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
func GetCommand() *cobra.Command {
|
||||
ProfileConf = node.NewConf()
|
||||
ProfileConf.CreateFlags(baseCmd,
|
||||
Converters = ProfileConf.CreateFlags(baseCmd,
|
||||
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
|
||||
baseCmd.PersistentFlags().StringVar(&NetName, "netname", "", "Set network name for network options")
|
||||
// register the command line completions
|
||||
|
||||
@@ -15,7 +15,7 @@ var (
|
||||
Use: "set [OPTIONS] [PROFILE ...]",
|
||||
Short: "Configure node profile properties",
|
||||
Long: "This command sets configuration properties for the node PROFILE(s).\n\n" +
|
||||
"Note: use the string 'UNSET' to remove a configuration",
|
||||
"Note: use the string 'UNSET'/'0.0.0.0' to remove a configuration",
|
||||
Args: cobra.MinimumNArgs(0),
|
||||
RunE: CobraRunE,
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
@@ -38,11 +38,12 @@ var (
|
||||
SetForce bool
|
||||
NetName string
|
||||
ProfileConf node.NodeConf
|
||||
Converters []func()
|
||||
)
|
||||
|
||||
func init() {
|
||||
ProfileConf = node.NewConf()
|
||||
ProfileConf.CreateFlags(baseCmd,
|
||||
Converters = ProfileConf.CreateFlags(baseCmd,
|
||||
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
|
||||
baseCmd.PersistentFlags().StringVar(&NetName, "netname", "default", "Set network name for network options")
|
||||
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
|
||||
|
||||
@@ -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