Recursive handling for command line flags
Every struct in a NodeConf with `lopt:"foo" set is now added as a command-line flag with the RecursiveCreateFlags call. For maps a struct with the key UNDEF is added so that it can be parsed out. As the flags for the command-line need variables which hold the values, for every map an element map[UNDEF] is added. When now calling the internal add, these map element can be filtered out and replace by the given name. (e.g., --netname) * rewrote node/profile add for recursive functions * rewrote node/profile set for recursive functions * rewrote node/profile list for recursive functions Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
committed by
Jonathon Anderson
parent
c55c5a2ac4
commit
45539a0d1f
@@ -2,7 +2,6 @@ package apiprofile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
|
||||
@@ -30,99 +29,14 @@ func ProfileList(ShowOpt *wwapiv1.GetProfileList) (profileList wwapiv1.ProfileLi
|
||||
sort.Slice(profiles, func(i, j int) bool {
|
||||
return profiles[i].Id.Get() < profiles[j].Id.Get()
|
||||
})
|
||||
if ShowOpt.ShowAll {
|
||||
if ShowOpt.ShowAll || ShowOpt.ShowFullAll {
|
||||
for _, p := range profiles {
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", "PROFILE", "FIELD", "PROFILE", "VALUE"))
|
||||
nType := reflect.TypeOf(p)
|
||||
nVal := reflect.ValueOf(p)
|
||||
nConfType := reflect.TypeOf(node.NodeConf{})
|
||||
for i := 0; i < nType.NumField(); i++ {
|
||||
var fieldName, fieldSource, fieldVal string
|
||||
nConfField, ok := nConfType.FieldByName(nType.Field(i).Name)
|
||||
if ok {
|
||||
fieldName = nConfField.Tag.Get("lopt")
|
||||
} else {
|
||||
fieldName = nType.Field(i).Name
|
||||
}
|
||||
if nType.Field(i).Type == reflect.TypeOf(node.Entry{}) {
|
||||
entr := nVal.Field(i).Interface().(node.Entry)
|
||||
fieldSource = entr.Source()
|
||||
fieldVal = entr.Print()
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
|
||||
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.Entry{}) {
|
||||
entrMap := nVal.Field(i).Interface().(map[string]*node.Entry)
|
||||
for key, val := range entrMap {
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), key, val.Source(), val.Print()))
|
||||
}
|
||||
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.NetDevEntry{}) {
|
||||
netDevs := nVal.Field(i).Interface().(map[string]*node.NetDevEntry)
|
||||
for netName, netWork := range netDevs {
|
||||
netInfoType := reflect.TypeOf(*netWork)
|
||||
netInfoVal := reflect.ValueOf(*netWork)
|
||||
netConfType := reflect.TypeOf(node.NetDevs{})
|
||||
for j := 0; j < netInfoType.NumField(); j++ {
|
||||
netConfField, ok := netConfType.FieldByName(netInfoType.Field(j).Name)
|
||||
if ok {
|
||||
if netConfField.Tag.Get("lopt") != "nettagadd" {
|
||||
fieldName = netName + ":" + netConfField.Tag.Get("lopt")
|
||||
} else {
|
||||
fieldName = netName + ":tag"
|
||||
}
|
||||
} else {
|
||||
fieldName = netName + ":" + netInfoType.Field(j).Name
|
||||
}
|
||||
if netInfoType.Field(j).Type == reflect.TypeOf(node.Entry{}) {
|
||||
entr := netInfoVal.Field(j).Interface().(node.Entry)
|
||||
fieldSource = entr.Source()
|
||||
fieldVal = entr.Print()
|
||||
// only print fields with lopt
|
||||
if netConfField.Tag.Get("lopt") != "" {
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
|
||||
}
|
||||
} else if netInfoType.Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
|
||||
for key, val := range netInfoVal.Field(j).Interface().(map[string]*node.Entry) {
|
||||
keyfieldName := fieldName + ":" + key
|
||||
fieldSource = val.Source()
|
||||
fieldVal = val.Print()
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), keyfieldName, fieldSource, fieldVal))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else if nType.Field(i).Type.Kind() == reflect.Ptr {
|
||||
nestInfoType := reflect.TypeOf(nVal.Field(i).Interface())
|
||||
nestInfoVal := reflect.ValueOf(nVal.Field(i).Interface())
|
||||
// nestConfType := reflect.TypeOf(nConfField.Type.Elem().FieldByName())
|
||||
for j := 0; j < nestInfoType.Elem().NumField(); j++ {
|
||||
nestConfField, ok := nConfField.Type.Elem().FieldByName(nestInfoType.Elem().Field(j).Name)
|
||||
if ok {
|
||||
fieldName = nestConfField.Tag.Get("lopt")
|
||||
} else {
|
||||
fieldName = nestInfoType.Elem().Field(j).Name
|
||||
}
|
||||
if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(node.Entry{}) {
|
||||
entr := nestInfoVal.Elem().Field(j).Interface().(node.Entry)
|
||||
fieldSource = entr.Source()
|
||||
fieldVal = entr.Print()
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
|
||||
} else if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
|
||||
for key, val := range nestInfoVal.Elem().Field(j).Interface().(map[string]*node.Entry) {
|
||||
fieldName = fieldName + ":" + key
|
||||
fieldSource = val.Source()
|
||||
fieldVal = val.Print()
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fields := p.GetFields(ShowOpt.ShowFullAll)
|
||||
for _, f := range fields {
|
||||
profileList.Output = append(profileList.Output,
|
||||
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), f.Field, f.Source, f.Value))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// NodeSet is the wwapiv1 implmentation for updating nodeinfo fields.
|
||||
func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
|
||||
func ProfileSet(set *wwapiv1.ProfileSetParameter) (err error) {
|
||||
if set == nil {
|
||||
return fmt.Errorf("NodeAddParameter is nil")
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
|
||||
// Output to the console if console is true.
|
||||
// TODO: Determine if the console switch does wwlog or not.
|
||||
// - console may end up being textOutput?
|
||||
func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
|
||||
func ProfileSetParameterCheck(set *wwapiv1.ProfileSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
|
||||
if set == nil {
|
||||
err = fmt.Errorf("profile set parameter is nil")
|
||||
if console {
|
||||
@@ -40,7 +40,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
|
||||
}
|
||||
}
|
||||
|
||||
if set.NodeNames == nil {
|
||||
if set.ProfileNames == nil {
|
||||
err = fmt.Errorf("profile set parameter: ProfileNames is nil")
|
||||
if console {
|
||||
fmt.Printf("%v\n", err)
|
||||
@@ -62,7 +62,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
|
||||
|
||||
// Note: This does not do expansion on the nodes.
|
||||
|
||||
if set.AllNodes || (len(set.NodeNames) == 0) {
|
||||
if set.AllProfiles || (len(set.ProfileNames) == 0) {
|
||||
if console {
|
||||
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n")
|
||||
}
|
||||
@@ -82,12 +82,8 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
|
||||
}
|
||||
|
||||
for _, p := range profiles {
|
||||
if util.InSlice(set.NodeNames, p.Id.Get()) {
|
||||
if util.InSlice(set.ProfileNames, p.Id.Get()) {
|
||||
wwlog.Verbose("Evaluating profile: %s", p.Id.Get())
|
||||
// Fix issue: https://github.com/hpcng/warewulf/issues/661
|
||||
if p.Id.Get() == "default" && len(p.NetDevs) == 0 {
|
||||
set.NetdevDelete = p.Id.Get()
|
||||
}
|
||||
p.SetFrom(&pConf)
|
||||
if set.NetdevDelete != "" {
|
||||
if _, ok := p.NetDevs[set.NetdevDelete]; !ok {
|
||||
@@ -98,6 +94,40 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
|
||||
wwlog.Verbose("Profile: %s, Deleting network device: %s", p.Id.Get(), set.NetdevDelete)
|
||||
delete(p.NetDevs, set.NetdevDelete)
|
||||
}
|
||||
if set.PartitionDelete != "" {
|
||||
deletedPart := false
|
||||
for diskname, disk := range p.Disks {
|
||||
if _, ok := disk.Partitions[set.PartitionDelete]; ok {
|
||||
wwlog.Verbose("Node: %s, on disk %, deleting partition: %s", p.Id.Get(), diskname, set.PartitionDelete)
|
||||
deletedPart = true
|
||||
delete(disk.Partitions, set.PartitionDelete)
|
||||
}
|
||||
if !deletedPart {
|
||||
wwlog.Error(fmt.Sprintf("%v", err.Error()))
|
||||
err = fmt.Errorf("partition doesn't exist: %s", set.PartitionDelete)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if set.DiskDelete != "" {
|
||||
if _, ok := p.Disks[set.DiskDelete]; !ok {
|
||||
err = fmt.Errorf("disk doesn't exist: %s", set.DiskDelete)
|
||||
wwlog.Error(fmt.Sprintf("%v", err.Error()))
|
||||
return
|
||||
}
|
||||
wwlog.Verbose("Node: %s, deleting disk: %s", p.Id.Get(), set.DiskDelete)
|
||||
delete(p.Disks, set.DiskDelete)
|
||||
}
|
||||
if set.FilesystemDelete != "" {
|
||||
if _, ok := p.FileSystems[set.FilesystemDelete]; !ok {
|
||||
err = fmt.Errorf("disk doesn't exist: %s", set.FilesystemDelete)
|
||||
wwlog.Error(fmt.Sprintf("%v", err.Error()))
|
||||
return
|
||||
}
|
||||
wwlog.Verbose("Node: %s, deleting filesystem: %s", p.Id.Get(), set.FilesystemDelete)
|
||||
delete(p.FileSystems, set.FilesystemDelete)
|
||||
}
|
||||
|
||||
for _, key := range pConf.TagsDel {
|
||||
delete(p.Tags, key)
|
||||
}
|
||||
@@ -127,7 +157,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
|
||||
Adds a new profile with the given name
|
||||
*/
|
||||
|
||||
func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
|
||||
func AddProfile(nsp *wwapiv1.ProfileSetParameter) error {
|
||||
if nsp == nil {
|
||||
return fmt.Errorf("NodeSetParameter is nill")
|
||||
}
|
||||
@@ -137,8 +167,8 @@ func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
|
||||
return errors.Wrap(err, "Could not open database")
|
||||
}
|
||||
|
||||
if util.InSlice(nodeDB.ListAllProfiles(), nsp.NodeNames[0]) {
|
||||
return errors.New(fmt.Sprintf("profile with name %s allready exists", nsp.NodeNames[0]))
|
||||
if util.InSlice(nodeDB.ListAllProfiles(), nsp.ProfileNames[0]) {
|
||||
return errors.New(fmt.Sprintf("profile with name %s allready exists", nsp.ProfileNames[0]))
|
||||
}
|
||||
|
||||
var nodeConf node.NodeConf
|
||||
@@ -147,7 +177,7 @@ func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
|
||||
return errors.Wrap(err, "failed to decode nodeConf")
|
||||
}
|
||||
|
||||
n, err := nodeDB.AddProfile(nsp.NodeNames[0])
|
||||
n, err := nodeDB.AddProfile(nsp.ProfileNames[0])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to add node")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user