This removes node-only attributes, like a profile list, from profile commands. Signed-off-by: Jonathon Anderson <janderson@ciq.com>
181 lines
6.5 KiB
Go
181 lines
6.5 KiB
Go
package node
|
|
|
|
import (
|
|
"net"
|
|
"reflect"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/warewulf/warewulf/internal/pkg/wwtype"
|
|
)
|
|
|
|
type NodeConfDel struct {
|
|
TagsDel []string `lopt:"tagdel" comment:"add tags"`
|
|
IpmiTagsDel []string `lopt:"ipmitagdel" comment:"delete ipmi tags"`
|
|
NetTagsDel []string `lopt:"nettagdel" comment:"delete network tags"`
|
|
NetDel string `lopt:"netdel" comment:"network to delete"`
|
|
DiskDel string `lopt:"diskdel" comment:"delete the disk from the configuration"`
|
|
PartDel string `lopt:"partdel" comment:"delete the partition from the configuration"`
|
|
FsDel string `lopt:"fsdel" comment:"delete the fs from the configuration"`
|
|
}
|
|
type NodeConfAdd struct {
|
|
TagsAdd map[string]string `lopt:"tagadd" comment:"add tags"`
|
|
IpmiTagsAdd map[string]string `lopt:"ipmitagadd" comment:"add ipmi tags"`
|
|
NetTagsAdd map[string]string `lopt:"nettagadd" comment:"add network tags"`
|
|
Net string `lopt:"netname" comment:"network which is modified"`
|
|
DiskName string `lopt:"diskname" comment:"set diskdevice name"`
|
|
PartName string `lopt:"partname" comment:"set the partition name so it can be used by a file system"`
|
|
FsName string `lopt:"fsname" comment:"set the file system name which must match a partition name"`
|
|
}
|
|
|
|
/*
|
|
Create cmd line flags from the NodeConf fields. Returns a []func() where every function must be called, as the command line parser returns e.g. netip.IP objects which must be parsed
|
|
back to strings.
|
|
*/
|
|
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command) {
|
|
recursiveCreateFlags(nodeConf, baseCmd)
|
|
}
|
|
|
|
func (profileConf *ProfileConf) CreateFlags(baseCmd *cobra.Command) {
|
|
recursiveCreateFlags(profileConf, baseCmd)
|
|
}
|
|
|
|
func (del *NodeConfDel) CreateDelFlags(baseCmd *cobra.Command) {
|
|
recursiveCreateFlags(del, baseCmd)
|
|
|
|
}
|
|
func (add *NodeConfAdd) CreateAddFlags(baseCmd *cobra.Command) {
|
|
recursiveCreateFlags(add, baseCmd)
|
|
|
|
}
|
|
|
|
func recursiveCreateFlags(obj interface{}, baseCmd *cobra.Command) {
|
|
// now iterate of every field
|
|
nodeInfoType := reflect.TypeOf(obj)
|
|
nodeInfoVal := reflect.ValueOf(obj)
|
|
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
|
|
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" {
|
|
field := nodeInfoVal.Elem().Field(i)
|
|
createFlags(baseCmd, nodeInfoType.Elem().Field(i), &field)
|
|
|
|
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
|
|
recursiveCreateFlags(nodeInfoVal.Elem().Field(i).Interface(), baseCmd)
|
|
|
|
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Map &&
|
|
nodeInfoType.Elem().Field(i).Type != reflect.TypeOf(map[string]string{}) {
|
|
// add a map with key UNDEF so that it can hold values N.B. UNDEF can never be added through command line
|
|
key := reflect.ValueOf("UNDEF")
|
|
if nodeInfoVal.Elem().Field(i).Len() == 0 {
|
|
if nodeInfoVal.Elem().Field(i).IsNil() {
|
|
nodeInfoVal.Elem().Field(i).Set(reflect.MakeMap(nodeInfoType.Elem().Field(i).Type))
|
|
}
|
|
newPtr := reflect.New(nodeInfoType.Elem().Field(i).Type.Elem().Elem())
|
|
nodeInfoVal.Elem().Field(i).SetMapIndex(key, newPtr)
|
|
} else {
|
|
key = nodeInfoVal.Elem().Field(i).MapKeys()[0]
|
|
}
|
|
recursiveCreateFlags(nodeInfoVal.Elem().Field(i).MapIndex(key).Interface(), baseCmd)
|
|
} else if nodeInfoType.Elem().Field(i).Anonymous {
|
|
recursiveCreateFlags(nodeInfoVal.Elem().Field(i).Addr().Interface(), baseCmd)
|
|
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Struct {
|
|
recursiveCreateFlags(nodeInfoVal.Elem().Field(i).Addr().Interface(), baseCmd)
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Helper function to create the different PersistentFlags() for different types.
|
|
*/
|
|
func createFlags(baseCmd *cobra.Command,
|
|
myType reflect.StructField, myVal *reflect.Value) {
|
|
var wwbool wwtype.WWbool
|
|
if myType.Tag.Get("lopt") != "" {
|
|
if myType.Type == reflect.TypeOf("") {
|
|
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 {
|
|
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("comment"))
|
|
} else {
|
|
baseCmd.PersistentFlags().StringSliceVar(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
[]string{},
|
|
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 {
|
|
baseCmd.PersistentFlags().StringToStringVar(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
map[string]string{}, // empty default!
|
|
myType.Tag.Get("comment"))
|
|
}
|
|
} else if myType.Type == reflect.TypeOf(true) {
|
|
ptr := myVal.Addr().Interface().(*bool)
|
|
if myType.Tag.Get("sopt") != "" {
|
|
baseCmd.PersistentFlags().BoolVarP(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
myType.Tag.Get("sopt"),
|
|
false, // empty default!
|
|
myType.Tag.Get("comment"))
|
|
} else {
|
|
baseCmd.PersistentFlags().BoolVar(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
false, // empty default!
|
|
myType.Tag.Get("comment"))
|
|
}
|
|
} else if myType.Type == reflect.TypeOf(net.IP{}) {
|
|
ptr := myVal.Addr().Interface().(*net.IP)
|
|
if myType.Tag.Get("sopt") != "" {
|
|
baseCmd.PersistentFlags().IPVarP(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
myType.Tag.Get("sopt"),
|
|
net.IP{}, // empty default!
|
|
myType.Tag.Get("comment"))
|
|
} else {
|
|
baseCmd.PersistentFlags().IPVar(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
net.IP{}, // empty default!
|
|
myType.Tag.Get("comment"))
|
|
}
|
|
} else if myType.Type == reflect.TypeOf(wwbool) {
|
|
ptr := myVal.Addr().Interface().(*wwtype.WWbool)
|
|
if myType.Tag.Get("sopt") != "" {
|
|
baseCmd.PersistentFlags().VarP(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
myType.Tag.Get("sopt"),
|
|
myType.Tag.Get("comment"))
|
|
baseCmd.Flag(myType.Tag.Get("lopt")).NoOptDefVal = "true"
|
|
} else {
|
|
baseCmd.PersistentFlags().Var(ptr,
|
|
myType.Tag.Get("lopt"),
|
|
myType.Tag.Get("comment"))
|
|
baseCmd.Flag(myType.Tag.Get("lopt")).NoOptDefVal = "true"
|
|
}
|
|
}
|
|
}
|
|
}
|