recreate CreateFlag based on NodeConf

This will always create the network named default,
so this has to be changed if a new netowk is set
This commit is contained in:
Christian Goll
2022-08-19 09:47:07 +02:00
parent b485ea999f
commit 063c781710
3 changed files with 76 additions and 405 deletions

View File

@@ -48,8 +48,9 @@ type NodeConf struct {
Discoverable string `yaml:"discoverable,omitempty" lopt:"discoverable" comment:"Make discoverable in given network (yes/no)"`
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:"tag" comment:"base key"`
Keys map[string]string `yaml:"keys,omitempty"` // Reverse compatibility
Tags map[string]string `yaml:"tags,omitempty" lopt:"tagadd" comment:"base key"`
TagsDel []string `lopt:"tagdel" comment:"remove this tags"` // does not go to disk only to wire
Keys map[string]string `yaml:"keys,omitempty"` // Reverse compatibility
}
type IpmiConf struct {
@@ -61,7 +62,8 @@ type IpmiConf struct {
Gateway string `yaml:"gateway,omitempty" lopt:"ipmigateway" comment:"Set the IPMI gateway"`
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)"`
Tags map[string]string `yaml:"tags,omitempty" lopt:"ipmitag" comment:"ipmi keys"`
Tags map[string]string `yaml:"tags,omitempty" lopt:"ipmitagadd" comment:"add ipmitags"`
TagsDel []string `lopt:"ipmitagdel" comment:"remove ipmitags"` // does not go to disk only to wire
}
type KernelConf struct {
Version string `yaml:"version,omitempty"`
@@ -82,7 +84,8 @@ type NetDevs struct {
Gateway string `yaml:"gateway,omitempty" lopt:"gateway" sopt:"G" comment:"Set the node's network device gateway"`
Primary string `yaml:"primary,omitempty" lopt:"primary" comment:"Enable/disable network device as primary (yes/no)"`
Default string `yaml:"default,omitempty"` /* backward compatibility */
Tags map[string]string `yaml:"tags,omitempty" lopt:"nettag" comment:"network keys"`
Tags map[string]string `yaml:"tags,omitempty" lopt:"nettagadd" comment:"network tags"`
TagsDel []string `lopt:"nettagdel" comment:"delete network tags"` // does not go to disk only to wire
}
/******

View File

@@ -318,348 +318,3 @@ func NewConf() (nodeconf NodeConf) {
nodeconf.NetDevs = map[string]*NetDevs{}
return nodeconf
}
// /*
// Set the Entry trough an interface by trying to cast the interface
// */
// func SetEntry(entryPtr interface{}, val interface{}) {
// valKind := reflect.TypeOf(val)
// if reflect.TypeOf(entryPtr) == reflect.TypeOf((*Entry)(nil)) {
// entry := entryPtr.(*Entry)
// if valKind.Kind() == reflect.String {
// entry.Set(val.(string))
// } else if valKind.Kind() == reflect.Slice {
// if valKind.Elem().Kind() == reflect.String {
// entry.SetSlice(val.([]string))
// } else {
// panic("Got unknown slice type")
// }
// }
// } else if reflect.TypeOf(entryPtr) == reflect.TypeOf((*[]string)(nil)) {
// entry := entryPtr.(*[]string)
// if valKind.Kind() == reflect.String {
// // most likely we got a comma seperated string slice
// *entry = strings.Split(val.(string), ",")
// } else if valKind.Kind() == reflect.Slice {
// if valKind.Elem().Kind() == reflect.String {
// *entry = val.([]string)
// } else {
// panic("Got unknown slice type")
// }
// }
// } else {
// panic(fmt.Sprintf("Can't convert %s to *node.Entry to call Set\n", reflect.TypeOf(entryPtr)))
// }
// }
// /*
// Add an entry in a map
// */
// func addEntry(entryMapInt interface{}, val interface{}) {
// if reflect.TypeOf(entryMapInt) == reflect.TypeOf((*map[string]*Entry)(nil)) {
// if reflect.ValueOf(entryMapInt).Elem().IsNil() {
// newMap := make(map[string]*Entry)
// entryMapInt = &newMap
// }
// entryMap := entryMapInt.(*map[string]*Entry)
// str, ok := (val).(string)
// if !ok {
// panic("AddEntry must be called with string value")
// }
// for _, token := range strings.Split(str, ",") {
// keyVal := strings.Split(token, "=")
// if len(keyVal) == 2 {
// _, mapOk := (*entryMap)[keyVal[0]]
// if !mapOk {
// (*entryMap)[keyVal[0]] = new(Entry)
// }
// (*entryMap)[keyVal[0]].Set(keyVal[1])
// }
// }
// } else {
// panic(fmt.Sprintf("Do not know how to add %v to %v\n", val, entryMapInt))
// }
// }
// /*
// Del an entry in a map
// */
// func delEntry(entryMapInt interface{}, val interface{}) {
// if reflect.TypeOf(entryMapInt) == reflect.TypeOf((*map[string]*Entry)(nil)) {
// entryMap := entryMapInt.(*map[string]*Entry)
// str, ok := (val).(string)
// if !ok {
// panic("DelEntry must be called with string value")
// }
// for _, token := range strings.Split(str, ",") {
// delete(*entryMap, token)
// }
// } else {
// panic(fmt.Sprintf("Do not know how to del %v to %v\n", val, entryMapInt))
// }
// }
// /*
// Call SetEntry for given field (NodeInfo).
// */
// func (node *NodeInfo) SetField(fieldName string, val interface{}) {
// field := reflect.ValueOf(node).Elem().FieldByName(fieldName)
// if field.IsValid() {
// if field.Addr().Type() == reflect.TypeOf((*Entry)(nil)) {
// SetEntry(field.Addr().Interface(), val)
// } else if field.Addr().Type() == reflect.TypeOf((*[]string)(nil)) {
// SetEntry(field.Addr().Interface(), val)
// }
// /*
// else if field.Addr().Kind() == reflect.Map {
// fmt.Println(field.Addr())
// } else {
// //fmt.Println("Not working field.Addr().Kind():", field.Addr().Type())
// // is most likely NetDevEntry, ignore it
// }
// */
// } else {
// fieldNames := strings.Split(fieldName, ".")
// if len(fieldNames) >= 2 {
// if fieldNames[0] == "del" || fieldNames[0] == "add" {
// fieldMap := reflect.ValueOf(node).Elem().FieldByName(fieldNames[1])
// if fieldMap.IsValid() {
// if fieldNames[0] == "del" {
// delEntry(fieldMap.Addr().Interface(), val)
// } else if fieldNames[0] == "add" {
// addEntry(fieldMap.Addr().Interface(), val)
// }
// } else {
// panic(fmt.Sprintf("invalid del/add operation with name %s called, field %s does not exists\n", fieldName, fieldNames[0]))
// }
// } else {
// nestedField := reflect.ValueOf(node).Elem().FieldByName(fieldNames[0])
// if nestedField.IsValid() {
// switch nestedField.Addr().Type() {
// case reflect.TypeOf((**KernelEntry)(nil)):
// entry := nestedField.Addr().Interface().(**KernelEntry)
// (*entry).SetField(strings.Join(fieldNames[1:], "."), val)
// case reflect.TypeOf((**IpmiEntry)(nil)):
// entry := nestedField.Addr().Interface().(**IpmiEntry)
// (*entry).SetField(strings.Join(fieldNames[1:], "."), val)
// case reflect.TypeOf((*map[string]*NetDevEntry)(nil)):
// if len(fieldNames) >= 3 {
// entryMap := nestedField.Addr().Interface().(*map[string]*NetDevEntry)
// if myVal, ok := (*entryMap)[fieldNames[1]]; ok {
// myVal.SetField(strings.Join(fieldNames[2:], "."), val)
// } else {
// var newEntry NetDevEntry
// (*entryMap)[fieldNames[1]] = &newEntry
// newEntry.SetField(strings.Join(fieldNames[2:], "."), val)
// }
// }
// default:
// panic(fmt.Sprintf("not implemented type %v\n", nestedField.Addr().Type()))
// }
// } else {
// panic(fmt.Sprintf("field %s is not a nested type of %s", fieldNames[0], fieldName))
// }
// }
// } else {
// panic(fmt.Sprintf("field %s does not exists in node.NodeInfo\n", fieldName))
// }
// }
// }
// /*
// Call SetEntry for given field (KernelEntry)
// */
// func (node *KernelEntry) SetField(fieldName string, val interface{}) {
// field := reflect.ValueOf(node).Elem().FieldByName(fieldName)
// if field.IsValid() {
// SetEntry(field.Addr().Interface(), val)
// } else {
// valFields := strings.Split(fieldName, ".")
// field = reflect.ValueOf(node).Elem().FieldByName(valFields[1])
// if field.IsValid() && len(valFields) == 2 && valFields[0] == "add" {
// addEntry(field.Addr().Interface(), val)
// } else if field.IsValid() && len(valFields) == 2 && valFields[0] == "del" {
// delEntry(field.Addr().Interface(), val)
// } else {
// panic(fmt.Sprintf("field %s does not exists in node.NetDevEntry\n", fieldName))
// }
// }
// }
// /*
// Call SetEntry for given field (ImpiEntry)
// */
// func (node *IpmiEntry) SetField(fieldName string, val interface{}) {
// field := reflect.ValueOf(node).Elem().FieldByName(fieldName)
// if field.IsValid() {
// SetEntry(field.Addr().Interface(), val)
// } else {
// valFields := strings.Split(fieldName, ".")
// field = reflect.ValueOf(node).Elem().FieldByName(valFields[1])
// if field.IsValid() && len(valFields) == 2 && valFields[0] == "add" {
// addEntry(field.Addr().Interface(), val)
// } else if field.IsValid() && len(valFields) == 2 && valFields[0] == "del" {
// delEntry(field.Addr().Interface(), val)
// } else {
// panic(fmt.Sprintf("field %s does not exists in node.NetDevEntry\n", fieldName))
// }
// }
// }
// /*
// Call SetEntry for given field (NetDevEntry)
// */
// func (node *NetDevEntry) SetField(fieldName string, val interface{}) {
// field := reflect.ValueOf(node).Elem().FieldByName(fieldName)
// if field.IsValid() {
// SetEntry(field.Addr().Interface(), val)
// } else {
// valFields := strings.Split(fieldName, ".")
// field = reflect.ValueOf(node).Elem().FieldByName(valFields[1])
// if field.IsValid() && len(valFields) == 2 && valFields[0] == "add" {
// addEntry(field.Addr().Interface(), val)
// } else if field.IsValid() && len(valFields) == 2 && valFields[0] == "del" {
// delEntry(field.Addr().Interface(), val)
// } else {
// panic(fmt.Sprintf("field %s does not exists in node.NetDevEntry\n", fieldName))
// }
// }
// }
// /*
// Get all names of the fields in the given struct (recursive)
// and create a map[name of struct field]*string if the the field
// of the struct bears the comment tag.
// */
// func GetOptionsMap(theStruct interface{}) map[string]*string {
// optionsMap := make(map[string]*string)
// structVal := reflect.ValueOf(theStruct)
// structTyp := structVal.Type()
// for i := 0; i < structVal.NumField(); i++ {
// field := structTyp.Field(i)
// if field.Type.Kind() == reflect.Struct {
// subStruct := GetOptionsMap(field)
// for key, val := range subStruct {
// optionsMap[key] = val
// }
// } else if field.Tag.Get("comment") != "" {
// optionsMap[field.Name] = new(string)
// }
// }
// return optionsMap
// }
// type CobraCommand struct {
// *cobra.Command
// }
/*
Get all names of the fields in the given struct (recursive)
and create a map[name of struct field]*string if the the field
of the struct bears the comment tag.
*/
// func (baseCmd *CobraCommand) CreateFlags(theStruct interface{}, excludeList []string) map[string]*string {
// structVal := reflect.ValueOf(theStruct)
// for i := 0; i < structVal.NumField(); i++ {
// field := structVal.Type().Field(i)
// //fmt.Printf("%s: field.Kind() == %s\n", field.Name, field.Type.Kind())
// if field.Type.Kind() == reflect.Ptr {
// a := structVal.Field(i).Elem().Interface()
// subStruct := baseCmd.CreateFlags(a, excludeList)
// for key, val := range subStruct {
// optionsMap[field.Name+"."+key] = val
// }
// } else if field.Type.Kind() == reflect.Map {
// // check the type of map
// mapType := field.Type.Elem()
// if mapType.Kind() == reflect.Ptr {
// //a := reflect.ValueOf((mapType.Elem())) node.NetDevs
// subMap := baseCmd.CreateFlags(reflect.New(mapType.Elem()).Elem().Interface(), excludeList)
// for key, val := range subMap {
// optionsMap[field.Name+"."+key] = val
// }
// if mapType == reflect.TypeOf((*NetDevs)(nil)) {
// // set the option for the network name here
// var netName string
// optionsMap[field.Name] = &netName
// baseCmd.PersistentFlags().StringVarP(&netName,
// "netname", "n", "", "Define the network name to configure")
// }
// } else if mapType.Kind() == reflect.String {
// if field.Tag.Get("lopt") != "" {
// var addPair string
// optionsMap["add"+"."+field.Name] = &addPair
// baseCmd.PersistentFlags().StringVarP(&addPair,
// field.Tag.Get("lopt")+"add", "", "", "Add key/value pair to "+field.Tag.Get("comment"))
// var delPair string
// optionsMap["del"+"."+field.Name] = &delPair
// baseCmd.PersistentFlags().StringVarP(&delPair,
// field.Tag.Get("lopt")+"del", "", "", "Delete key/value pair to "+field.Tag.Get("comment"))
// }
// } else {
// // TODO: implement handling of string maps
// wwlog.Warn("handling of %v not implemented\n", field.Type)
// }
// } else if field.Tag.Get("comment") != "" && !util.InSlice(excludeList, field.Tag.Get("lopt")) {
// var newStr string
// optionsMap[field.Name] = &newStr
// if field.Tag.Get("sopt") != "" {
// baseCmd.PersistentFlags().StringVarP(&newStr,
// field.Tag.Get("lopt"),
// field.Tag.Get("sopt"),
// field.Tag.Get("default"),
// field.Tag.Get("comment"))
// } else if !util.InSlice(excludeList, field.Tag.Get("lopt")) {
// baseCmd.PersistentFlags().StringVar(&newStr,
// field.Tag.Get("lopt"),
// field.Tag.Get("default"),
// field.Tag.Get("comment"))
// }
// }
// }
// return optionsMap
// }
// /*
// Helper function which gets the lopt of a given interface
// */
// func GetLoptOf(myStruct interface{}, name string) string {
// retStr := ""
// if reflect.TypeOf(myStruct).Kind() != reflect.Struct {
// return retStr
// }
// myType := reflect.TypeOf(myStruct)
// field, ok := myType.FieldByName(name)
// if ok {
// retStr = field.Tag.Get("lopt")
// }
// return retStr
// }
// /*
// Returns a translation map of field name and its associated lopt.
// */
// func GetloptMap(myStruct interface{}) map[string]string {
// retMap := make(map[string]string)
// if reflect.TypeOf(myStruct).Kind() != reflect.Struct {
// return retMap
// }
// structType := reflect.TypeOf(myStruct)
// for i := 0; i < structType.NumField(); i++ {
// retMap[structType.Field(i).Name] = structType.Field(i).Name
// lopt := structType.Field(i).Tag.Get("lopt")
// if lopt != "" {
// retMap[structType.Field(i).Name] = lopt
// }
// }
// return retMap
// }

View File

@@ -136,72 +136,85 @@ func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo,
}
}
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) {
// nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
// now iterate of every field
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
field := nodeInfoVal.Elem().Type().Field(i)
//fmt.Printf("%s: field.Kind() == %s\n", field.Name, field.Type.Kind())
// if field.Type.Kind() == reflect.Ptr {
// a := structVal.Field(i).Elem().Interface()
// subStruct := baseCmd.CreateFlags(a, excludeList)
// for key, val := range subStruct {
// optionsMap[field.Name+"."+key] = val
// }
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" &&
!util.InSlice(excludeList, nodeInfoType.Elem().Field(i).Tag.Get("lopt")) {
createFlags(baseCmd, excludeList, nodeInfoType.Elem().Field(i), nodeInfoVal.Elem().Field(i))
} 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++ {
createFlags(baseCmd, excludeList, nestType.Elem().Field(j), nestVal.Elem().Field(j))
}
} 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
netMap["default"] = new(NetDevs)
netType := reflect.TypeOf(netMap["default"])
netVal := reflect.ValueOf(netMap["default"])
for j := 0; j < netType.Elem().NumField(); j++ {
createFlags(baseCmd, excludeList, netType.Elem().Field(j), netVal.Elem().Field(j))
}
}
}
}
// } else if field.Type.Kind() == reflect.Map {
// // check the type of map
// mapType := field.Type.Elem()
// if mapType.Kind() == reflect.Ptr {
// //a := reflect.ValueOf((mapType.Elem())) node.NetDevs
// subMap := baseCmd.CreateFlags(reflect.New(mapType.Elem()).Elem().Interface(), excludeList)
// for key, val := range subMap {
// optionsMap[field.Name+"."+key] = val
// }
// if mapType == reflect.TypeOf((*NetDevs)(nil)) {
// // set the option for the network name here
// var netName string
// optionsMap[field.Name] = &netName
// baseCmd.PersistentFlags().StringVarP(&netName,
// "netname", "n", "", "Define the network name to configure")
// }
// } else
// if mapType.Kind() == reflect.String {
// if field.Tag.Get("lopt") != "" {
// baseCmd.PersistentFlags().StringVarP(nodeInfoVal.Field(i).Interface()(string),
// field.Tag.Get("lopt")+"add", "", "", "Add key/value pair to "+field.Tag.Get("comment"))
// var delPair string
// optionsMap["del"+"."+field.Name] = &delPair
// baseCmd.PersistentFlags().StringVarP(&delPair,
// field.Tag.Get("lopt")+"del", "", "", "Delete key/value pair to "+field.Tag.Get("comment"))
// }
// } else {
// // TODO: implement handling of string maps
// wwlog.Warn("handling of %v not implemented\n", field.Type)
// }
// } else
if field.Type.Kind() == reflect.String &&
field.Tag.Get("comment") != "" &&
!util.InSlice(excludeList, field.Tag.Get("lopt")) {
ptr := nodeInfoVal.Elem().Field(i).Addr().Interface().(*string)
if field.Tag.Get("sopt") != "" {
/*
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,
field.Tag.Get("lopt"),
field.Tag.Get("sopt"),
field.Tag.Get("default"),
field.Tag.Get("comment"))
} else if !util.InSlice(excludeList, field.Tag.Get("lopt")) {
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,
field.Tag.Get("lopt"),
field.Tag.Get("default"),
field.Tag.Get("comment"))
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 optionsMap
}
/*