removed optionStrMap in favor of NodeConf

openStrMap is a map[string]string which is sent arround. This is now
done by using a unmarshalled NodeConf instead.
This commit is contained in:
Christian Goll
2022-08-17 16:41:20 +02:00
parent 2016588f36
commit b485ea999f
18 changed files with 1161 additions and 875 deletions

View File

@@ -331,11 +331,12 @@ func (s *apiServer) Version(ctx context.Context, request *emptypb.Empty) (respon
func (s *apiServer) nodeListInternal(nodeNames []string) (response *wwapiv1.NodeListResponse, err error) {
var nodes []*wwapiv1.NodeInfo
nodes, err = apinode.NodeList(nodeNames)
if err != nil {
return
}
/*
nodes, err = apinode.NodeList(nodeNames)
if err != nil {
return
}
*/
response = &wwapiv1.NodeListResponse{
Nodes: nodes,
}

View File

@@ -1,26 +1,34 @@
package add
import (
"errors"
"os"
"gopkg.in/yaml.v2"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
if netWithoutName {
return errors.New("a netname must be given for any network related configuration")
}
realMap := make(map[string]string)
// OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
// if netWithoutName {
// return errors.New("a netname must be given for any network related configuration")
// }
// realMap := make(map[string]string)
for key, val := range OptionStrMap {
realMap[key] = *val
// for key, val := range OptionStrMap {
// realMap[key] = *val
// }
buffer, err := yaml.Marshal(nodeConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
set := wwapiv1.NodeAddParameter{
OptionsStrMap: realMap,
NodeNames: args,
NodeConfYaml: string(buffer[:]),
NodeNames: args,
}
return apinode.NodeAdd(&set)

View File

@@ -19,16 +19,12 @@ var (
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
}
OptionStrMap map[string]*string
nodeConf node.NodeConf
)
func init() {
// init empty helper structs, so that we know what's inside
myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf, []string{})
nodeConf := node.NewConf()
nodeConf.CreateFlags(baseCmd, []string{})
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()

View File

@@ -2,174 +2,29 @@ package list
import (
"fmt"
"sort"
"strings"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
nodeInfo, err := apinode.NodeList(args)
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
return
req := wwapiv1.GetNodeList{
Nodes: args,
Type: wwapiv1.GetNodeList_Simple,
}
nodeLopt := node.GetloptMap(node.NodeConf{})
ipmiLopt := node.GetloptMap(node.IpmiConf{})
kernelLopt := node.GetloptMap(node.KernelConf{})
netdevLopt := node.GetloptMap(node.NetDevs{})
if ShowAll {
for i := 0; i < len(nodeInfo); i++ {
ni := nodeInfo[i]
nodeName := `UNKNOWN`
if _, ok := ni.Fields["Id"]; ok {
nodeName = ni.Fields["Id"].Print
}
var nodeconfkeys, ipmiconfkeys, kernelconfkeys, netdevkys []string
for k := range ni.Fields {
subkeys := strings.Split(k, ":")
if len(subkeys) == 1 {
nodeconfkeys = append(nodeconfkeys, k)
}
if len(subkeys) >= 2 {
switch subkeys[0] {
case "IpmiEntry":
ipmiconfkeys = append(ipmiconfkeys, k)
case "KernelEntry":
kernelconfkeys = append(kernelconfkeys, k)
case "NetDevEntry":
netdevkys = append(netdevkys, k)
case "key":
nodeconfkeys = append(nodeconfkeys, k)
}
}
}
sort.Strings(nodeconfkeys)
sort.Strings(ipmiconfkeys)
sort.Strings(kernelconfkeys)
sort.Strings(netdevkys)
keyssorted := append(nodeconfkeys, kernelconfkeys...)
keyssorted = append(keyssorted, ipmiconfkeys...)
keyssorted = append(keyssorted, netdevkys...)
fmt.Printf("################################################################################\n")
fmt.Printf("%-20s %-18s %-12s %s\n", "NODE", "FIELD", "PROFILE", "VALUE")
for _, keys := range keyssorted {
fieldName := keys
subkeys := strings.Split(keys, ":")
if len(subkeys) == 1 {
if subkeys[0] == "Id" {
continue
}
fieldName = nodeLopt[subkeys[0]]
}
if len(subkeys) >= 2 {
switch subkeys[0] {
case "key":
fieldName = "tag:" + subkeys[1]
case "IpmiEntry":
fieldName = ipmiLopt[subkeys[1]]
if len(subkeys) == 3 {
fieldName = "ipmikey:" + subkeys[2]
}
case "KernelEntry":
fieldName = kernelLopt[subkeys[1]]
case "NetDevEntry":
if len(subkeys) == 3 {
fieldName = subkeys[1] + ":" + netdevLopt[subkeys[2]]
} else if len(subkeys) == 4 {
fieldName = subkeys[1] + ":keys:" + subkeys[3]
}
}
}
fmt.Printf("%-20s %-18s %-12s %s\n", nodeName, fieldName, ni.Fields[keys].Source, ni.Fields[keys].Print)
}
}
} else if ShowNet {
fmt.Printf("%-22s %-8s %-18s %-15s %-15s %-15s\n", "NODE NAME", "NAME", "HWADDR", "IPADDR", "GATEWAY", "DEVICE")
fmt.Println(strings.Repeat("=", 90))
for i := 0; i < len(nodeInfo); i++ {
ni := nodeInfo[i]
nodeName := `UNKNOWN`
if _, ok := ni.Fields["Id"]; ok {
nodeName = ni.Fields["Id"].Print
}
netNames := make(map[string]bool)
for k := range ni.Fields {
subkeys := strings.Split(k, ":")
if len(subkeys) == 3 && subkeys[0] == "NetDevEntry" {
netNames[subkeys[1]] = true
}
}
if len(netNames) > 0 {
for name := range netNames {
fmt.Printf("%-22s %-8s %-18s %-15s %-15s %-15s\n", nodeName, name,
ni.Fields["NetDevEntry:"+name+":Hwaddr"].Print,
ni.Fields["NetDevEntry:"+name+":Ipaddr"].Print,
ni.Fields["NetDevEntry:"+name+":Gateway"].Print,
ni.Fields["NetDevEntry:"+name+":Device"].Print)
}
} else {
fmt.Printf("%-22s %-6s %-18s %-15s %-15s\n", nodeName, "--", "--", "--", "--")
}
}
req.Type = wwapiv1.GetNodeList_All
} else if ShowIpmi {
fmt.Printf("%-22s %-16s %-10s %-20s %-14s\n", "NODE NAME", "IPMI IPADDR", "IPMI PORT", "IPMI USERNAME", "IPMI INTERFACE")
fmt.Println(strings.Repeat("=", 98))
for i := 0; i < len(nodeInfo); i++ {
ni := nodeInfo[i]
nodeName := `UNKNOWN`
if _, ok := ni.Fields["Id"]; ok {
nodeName = ni.Fields["Id"].Print
}
fmt.Printf("%-22s %-16s %-10s %-20s %-14s\n", nodeName,
ni.Fields["IpmiEntry:Ipaddr"].Print,
ni.Fields["IpmiEntry:Port"].Print,
ni.Fields["IpmiEntry:UserName"].Print,
ni.Fields["IpmiEntry:Interface"].Print)
}
req.Type = wwapiv1.GetNodeList_Ipmi
} else if ShowNet {
req.Type = wwapiv1.GetNodeList_Network
} else if ShowLong {
fmt.Printf("%-22s %-16s %-16s %s\n", "NODE NAME", "KERNEL OVERRIDE", "CONTAINER", "OVERLAYS (S/R)")
fmt.Println(strings.Repeat("=", 85))
for i := 0; i < len(nodeInfo); i++ {
ni := nodeInfo[i]
nodeName := `UNKNOWN`
if _, ok := ni.Fields["Id"]; ok {
nodeName = ni.Fields["Id"].Print
}
fmt.Printf("%-22s %-16s %-16s %s\n", nodeName,
ni.Fields["KernelEntry:Override"].Print,
ni.Fields["ContainerName"].Print,
ni.Fields["SystemOverlay"].Print+"/"+ni.Fields["RuntimeOverlay"].Print)
}
} else {
fmt.Printf("%-22s %-26s %s\n", "NODE NAME", "PROFILES", "NETWORK")
fmt.Println(strings.Repeat("=", 80))
for i := 0; i < len(nodeInfo); i++ {
ni := nodeInfo[i]
nodeName := `UNKNOWN`
if _, ok := ni.Fields["Id"]; ok {
nodeName = ni.Fields["Id"].Print
}
netNameMap := make(map[string]bool)
var netNames []string
for k := range ni.Fields {
subkeys := strings.Split(k, ":")
if len(subkeys) == 3 && subkeys[0] == "NetDevEntry" && !netNameMap[subkeys[1]] {
netNameMap[subkeys[1]] = true
netNames = append(netNames, subkeys[1])
}
}
fmt.Printf("%-22s %-26s %s\n", nodeName, ni.Fields["Profiles"].Print, strings.Join(netNames, ", "))
}
req.Type = wwapiv1.GetNodeList_Long
}
nodeInfo, err := apinode.NodeList(&req)
for _, str := range nodeInfo.Output {
fmt.Printf("%s\n", str)
}
return
}

View File

@@ -1,32 +1,39 @@
package set
import (
"errors"
"fmt"
"os"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
if netWithoutName {
return errors.New("a netname must be given for any network related configuration")
}
realMap := make(map[string]string)
// OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
// if netWithoutName {
// return errors.New("a netname must be given for any network related configuration")
// }
// realMap := make(map[string]string)
for key, val := range OptionStrMap {
realMap[key] = *val
// for key, val := range OptionStrMap {
// realMap[key] = *val
// }
buffer, err := yaml.Marshal(nodeConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
set := wwapiv1.NodeSetParameter{
OptionsStrMap: realMap,
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
}
if !SetYes {

View File

@@ -36,17 +36,12 @@ var (
SetNodeAll bool
SetYes bool
SetForce bool
OptionStrMap map[string]*string
nodeConf node.NodeConf
)
func init() {
// init empty helper structs, so that we know what's inside
myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf, []string{})
nodeConf := node.NewConf()
nodeConf.CreateFlags(baseCmd, []string{})
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")

View File

@@ -2,33 +2,38 @@ package add
import (
"fmt"
"os"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"gopkg.in/yaml.v2"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
if netWithoutName {
return errors.New("a netname must be given for any network related configuration")
}
realMap := make(map[string]string)
// OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
// if netWithoutName {
// return errors.New("a netname must be given for any network related configuration")
// }
// realMap := make(map[string]string)
for key, val := range OptionStrMap {
realMap[key] = *val
// for key, val := range OptionStrMap {
// realMap[key] = *val
// }
buffer, err := yaml.Marshal(profileConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
set := wwapiv1.NodeSetParameter{
OptionsStrMap: realMap,
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
}
if !SetYes {

View File

@@ -23,17 +23,13 @@ var (
SetNodeAll bool
SetYes bool
SetForce bool
OptionStrMap map[string]*string
profileConf node.NodeConf
)
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
// init empty helper structs, so that we know what's inside
myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf,
profileConf = node.NewConf()
profileConf.CreateFlags(baseCmd,
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

View File

@@ -2,32 +2,32 @@ package set
import (
"fmt"
"os"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/pkg/errors"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
if netWithoutName {
return errors.New("a netname must be given for any network related configuration")
// OptionStrMap, netWithoutName := apinode.AddNetname(OptionStrMap)
// if netWithoutName {
// return errors.New("a netname must be given for any network related configuration")
// }
buffer, err := yaml.Marshal(profileConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
realMap := make(map[string]string)
for key, val := range OptionStrMap {
realMap[key] = *val
}
set := wwapiv1.NodeSetParameter{
OptionsStrMap: realMap,
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
}
if !SetYes {

View File

@@ -36,18 +36,13 @@ var (
SetNodeAll bool
SetYes bool
SetForce bool
OptionStrMap map[string]*string
profileConf node.NodeConf
)
func init() {
// init empty helper structs, so that we know what's inside
myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf,
profileConf = node.NewConf()
profileConf.CreateFlags(baseCmd,
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")

View File

@@ -0,0 +1,178 @@
package apinode
import (
"fmt"
"reflect"
"sort"
"strings"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/pkg/hostlist"
)
/*
NodeList lists all to none of the nodes managed by Warewulf. Returns
a formated string slice, with each line as separate string
*/
func NodeList(nodeGet *wwapiv1.GetNodeList) (nodeList wwapiv1.NodeList, err error) {
// nil is okay for nodeNames
nodeDB, err := node.New()
if err != nil {
return
}
nodes, err := nodeDB.FindAllNodes()
if err != nil {
return
}
nodeGet.Nodes = hostlist.Expand(nodeGet.Nodes)
sort.Strings(nodeGet.Nodes)
if nodeGet.Type == wwapiv1.GetNodeList_Simple {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-26s %s", "NODE NAME", "PROFILES", "NETWORK"))
nodeList.Output = append(nodeList.Output, (strings.Repeat("=", 80)))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
var netNames []string
for k := range n.NetDevs {
netNames = append(netNames, k)
}
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-26s %s", n.Id.Print(), n.Profiles.Print(), strings.Join(netNames, ", ")))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Network {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-8s %-18s %-15s %-15s %-15s", "NODE NAME", "NAME", "HWADDR", "IPADDR", "GATEWAY", "DEVICE"),
strings.Repeat("=", 90))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
if len(n.NetDevs) > 0 {
for name := range n.NetDevs {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-8s %-18s %-15s %-15s %-15s", n.Id.Print(), name,
n.NetDevs[name].Hwaddr.Print(),
n.NetDevs[name].Ipaddr.Print(),
n.NetDevs[name].Gateway.Print(),
n.NetDevs[name].Device.Print()))
}
} else {
fmt.Printf("%-22s %-6s %-18s %-15s %-15s", n.Id.Print(), "--", "--", "--", "--")
}
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Ipmi {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-10s %-20s %-14s", "NODE NAME", "IPMI IPADDR", "IPMI PORT", "IPMI USERNAME", "IPMI INTERFACE"),
strings.Repeat("=", 98))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-10s %-20s %-14s", n.Id.Print(),
n.Ipmi.Ipaddr.Print(),
n.Ipmi.Port.Print(),
n.Ipmi.UserName.Print(),
n.Ipmi.Interface.Print()))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_Long {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-16s %s", "NODE NAME", "KERNEL OVERRIDE", "CONTAINER", "OVERLAYS (S/R)"),
strings.Repeat("=", 85))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-22s %-16s %-16s %s", n.Id.Print(),
n.Kernel.Override.Print(),
n.ContainerName.Print(),
n.SystemOverlay.Print()+"/"+n.RuntimeOverlay.Print()))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_All {
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", "NODE", "FIELD", "PROFILE", "VALUE"), strings.Repeat("=", 85))
nType := reflect.TypeOf(n)
nVal := reflect.ValueOf(n)
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()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.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 {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.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 {
fieldName = netName + ":" + netConfField.Tag.Get("lopt")
} 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") != "" {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.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) {
fieldName = fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, 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()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.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()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%-20s %-18s %-12s %s", n.Id.Print(), fieldName, fieldSource, fieldVal))
}
}
}
}
}
}
}
return
}

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"net/http"
"os"
"sort"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
@@ -14,6 +13,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/pkg/hostlist"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
)
@@ -31,6 +31,11 @@ func NodeAdd(nap *wwapiv1.NodeAddParameter) (err error) {
}
node_args := hostlist.Expand(nap.NodeNames)
var nodeConf node.NodeConf
err = yaml.Unmarshal([]byte(nap.NodeConfYaml), &nodeConf)
if err != nil {
return errors.Wrap(err, "Failed to decode nodeConf")
}
for _, a := range node_args {
var n node.NodeInfo
@@ -39,29 +44,24 @@ func NodeAdd(nap *wwapiv1.NodeAddParameter) (err error) {
return errors.Wrap(err, "failed to add node")
}
wwlog.Printf(wwlog.INFO, "Added node: %s\n", a)
netName := nap.OptionsStrMap["NetDevs"]
if nap.OptionsStrMap["NetDevs."+netName+".Ipaddr"] != "" {
var netName string
for netName = range nodeConf.NetDevs {
// as map should only have key this should give is the first and
// only key
}
// setting node from the received yaml
n.SetFrom(&nodeConf)
if netName != "" && nodeConf.NetDevs[netName].Ipaddr != "" {
// if more nodes are added increment IPv4 address
nap.OptionsStrMap["NetDevs."+netName+".Ipaddr"] = util.IncrementIPv4(nap.OptionsStrMap["NetDevs."+netName+".Ipaddr"], 1)
nodeConf.NetDevs[netName].Ipaddr = util.IncrementIPv4(nodeConf.NetDevs[netName].Ipaddr, 1)
wwlog.Verbose("Node: %s:%s, Setting Ipaddr to: %s\n",
n.Id.Get(), nap.OptionsStrMap["NetDevs"], nap.OptionsStrMap["NetDevs."+netName+".Ipaddr"])
wwlog.Verbose("Incremented IP addr to %s\n", nodeConf.NetDevs[netName].Ipaddr)
}
if nap.OptionsStrMap["Ipmi.Ipaddr"] != "" {
if nodeConf.Ipmi != nil && nodeConf.Ipmi.Ipaddr != "" {
// if more nodes are added increment IPv4 address
nap.OptionsStrMap["Ipmi.Ipaddr"] = util.IncrementIPv4(nap.OptionsStrMap["Ipmi.Ipaddr"], 1)
wwlog.Verbose("Node: %s:, Setting IPMIIpaddr to: %s\n",
n.Id.Get(), nap.OptionsStrMap["Ipmi.Ipaddr"])
nodeConf.Ipmi.Ipaddr = util.IncrementIPv4(nodeConf.Ipmi.Ipaddr, 1)
wwlog.Verbose("Incremented IP addr to %s\n", nodeConf.Ipmi.Ipaddr)
}
// Now set all the rest
for key, val := range nap.OptionsStrMap {
if val != "" {
wwlog.Verbose("node:%s setting %s to %s\n", n.Id.Get(), key, val)
n.SetField(key, val)
}
}
err = nodeDB.NodeUpdate(n)
if err != nil {
return errors.Wrap(err, "failed to update nodedb")
@@ -162,33 +162,6 @@ func NodeDeleteParameterCheck(ndp *wwapiv1.NodeDeleteParameter, console bool) (n
return
}
// NodeList lists all to none of the nodes managed by Warewulf.
func NodeList(nodeNames []string) (nodeInfo []*wwapiv1.NodeInfo, err error) {
// nil is okay for nodeNames
nodeDB, err := node.New()
if err != nil {
return
}
nodes, err := nodeDB.FindAllNodes()
if err != nil {
return
}
nodeNames = hostlist.Expand(nodeNames)
sort.Strings(nodeNames)
// Translate to the protobuf structure so wwapiv1 can use this across the wire.
// This is the same logic as was in wwctl.
for _, n := range node.FilterByName(nodes, nodeNames) {
var ni wwapiv1.NodeInfo
ni.Fields = GetFields(n)
nodeInfo = append(nodeInfo, &ni)
}
return
}
// NodeSet is the wwapiv1 implmentation for updating node fields.
func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
@@ -211,7 +184,7 @@ func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, nodeCount uint, err error) {
if set == nil {
err = fmt.Errorf("Node set parameter is nil")
err = fmt.Errorf("node set parameter is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -219,7 +192,7 @@ func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB
}
if set.NodeNames == nil {
err = fmt.Errorf("Node set parameter: NodeNames is nil")
err = fmt.Errorf("node set parameter: NodeNames is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -257,17 +230,17 @@ func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB
for _, n := range nodes {
wwlog.Printf(wwlog.VERBOSE, "Evaluating node: %s\n", n.Id.Get())
for key, val := range set.OptionsStrMap {
if val != "" {
wwlog.Verbose("node:%s setting %s to %s\n", n.Id.Get(), key, val)
n.SetField(key, val)
}
var nodeConf node.NodeConf
err = yaml.Unmarshal([]byte(set.NodeConfYaml), &nodeConf)
if err != nil {
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
n.SetFrom(&nodeConf)
if set.NetdevDelete != "" {
if _, ok := n.NetDevs[set.NetdevDelete]; !ok {
err = fmt.Errorf("Network device name doesn't exist: %s", set.NetdevDelete)
err = fmt.Errorf("network device name doesn't exist: %s", set.NetdevDelete)
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
@@ -313,7 +286,7 @@ func NodeStatus(nodeNames []string) (nodeStatusResponse *wwapiv1.NodeStatusRespo
}
if controller.Ipaddr == "" {
err = fmt.Errorf("The Warewulf Server IP Address is not properly configured")
err = fmt.Errorf("the Warewulf Server IP Address is not properly configured")
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
// NodeSet is the wwapiv1 implmentation for updating nodeinfo fields.
@@ -34,7 +35,7 @@ func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
if set == nil {
err = fmt.Errorf("Profile set parameter is nil")
err = fmt.Errorf("profile set parameter is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -42,7 +43,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
}
if set.NodeNames == nil {
err = fmt.Errorf("Profile set parameter: ProfileNames is nil")
err = fmt.Errorf("profile set parameter: ProfileNames is nil")
if console {
fmt.Printf("%v\n", err)
return
@@ -75,16 +76,17 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
}
return
}
var pConf node.NodeConf
err = yaml.Unmarshal([]byte(set.NodeConfYaml), &pConf)
if err != nil {
wwlog.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
for _, p := range profiles {
if util.InSlice(set.NodeNames, p.Id.Get()) {
wwlog.Printf(wwlog.VERBOSE, "Evaluating profile: %s\n", p.Id.Get())
for key, val := range set.OptionsStrMap {
if val != "" {
wwlog.Verbose("profile:%s setting %s to %s\n", p.Id.Get(), key, val)
p.SetField(key, val)
}
}
p.SetFrom(&pConf)
if set.NetdevDelete != "" {

View File

@@ -102,10 +102,27 @@ message NodeListResponse {
repeated NodeInfo nodes = 1;
}
// Request a node list
message GetNodeList {
enum ListType {
Simple = 0;
Ipmi = 1;
Network = 2;
Long = 3;
All = 4;
}
ListType type = 7;
repeated string Nodes = 8;
}
message NodeList {
repeated string Output = 1;
}
// NodeAddParameter contains all input for adding a node to be managed by
// Warewulf.
message NodeAddParameter {
map<string,string > optionsStrMap = 1;
string nodeConfYaml = 1;
repeated string nodeNames = 10;
}
@@ -119,7 +136,7 @@ message NodeDeleteParameter {
// NodeSetParameter contains all fields for updating aspects of nodes managed
// by Warewulf.
message NodeSetParameter {
map<string,string > optionsStrMap = 1;
string nodeConfYaml = 1;
string container = 2;
string netdevDelete = 14;
bool allNodes = 27;

View File

@@ -25,6 +25,61 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetNodeList_ListType int32
const (
GetNodeList_Simple GetNodeList_ListType = 0
GetNodeList_Ipmi GetNodeList_ListType = 1
GetNodeList_Network GetNodeList_ListType = 2
GetNodeList_Long GetNodeList_ListType = 3
GetNodeList_All GetNodeList_ListType = 4
)
// Enum value maps for GetNodeList_ListType.
var (
GetNodeList_ListType_name = map[int32]string{
0: "Simple",
1: "Ipmi",
2: "Network",
3: "Long",
4: "All",
}
GetNodeList_ListType_value = map[string]int32{
"Simple": 0,
"Ipmi": 1,
"Network": 2,
"Long": 3,
"All": 4,
}
)
func (x GetNodeList_ListType) Enum() *GetNodeList_ListType {
p := new(GetNodeList_ListType)
*p = x
return p
}
func (x GetNodeList_ListType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (GetNodeList_ListType) Descriptor() protoreflect.EnumDescriptor {
return file_routes_proto_enumTypes[0].Descriptor()
}
func (GetNodeList_ListType) Type() protoreflect.EnumType {
return &file_routes_proto_enumTypes[0]
}
func (x GetNodeList_ListType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use GetNodeList_ListType.Descriptor instead.
func (GetNodeList_ListType) EnumDescriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{13, 0}
}
// ContainerBuildParameter contains input for building zero or more containers.
type ContainerBuildParameter struct {
state protoimpl.MessageState
@@ -811,6 +866,109 @@ func (x *NodeListResponse) GetNodes() []*NodeInfo {
return nil
}
// Request a node list
type GetNodeList struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type GetNodeList_ListType `protobuf:"varint,7,opt,name=type,proto3,enum=wwapi.v1.GetNodeList_ListType" json:"type,omitempty"`
Nodes []string `protobuf:"bytes,8,rep,name=Nodes,proto3" json:"Nodes,omitempty"`
}
func (x *GetNodeList) Reset() {
*x = GetNodeList{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetNodeList) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetNodeList) ProtoMessage() {}
func (x *GetNodeList) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetNodeList.ProtoReflect.Descriptor instead.
func (*GetNodeList) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{13}
}
func (x *GetNodeList) GetType() GetNodeList_ListType {
if x != nil {
return x.Type
}
return GetNodeList_Simple
}
func (x *GetNodeList) GetNodes() []string {
if x != nil {
return x.Nodes
}
return nil
}
type NodeList struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Output []string `protobuf:"bytes,1,rep,name=Output,proto3" json:"Output,omitempty"`
}
func (x *NodeList) Reset() {
*x = NodeList{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NodeList) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NodeList) ProtoMessage() {}
func (x *NodeList) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NodeList.ProtoReflect.Descriptor instead.
func (*NodeList) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{14}
}
func (x *NodeList) GetOutput() []string {
if x != nil {
return x.Output
}
return nil
}
// NodeAddParameter contains all input for adding a node to be managed by
// Warewulf.
type NodeAddParameter struct {
@@ -818,14 +976,14 @@ type NodeAddParameter struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OptionsStrMap map[string]string `protobuf:"bytes,1,rep,name=optionsStrMap,proto3" json:"optionsStrMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
NodeNames []string `protobuf:"bytes,10,rep,name=nodeNames,proto3" json:"nodeNames,omitempty"`
NodeConfYaml string `protobuf:"bytes,1,opt,name=nodeConfYaml,proto3" json:"nodeConfYaml,omitempty"`
NodeNames []string `protobuf:"bytes,10,rep,name=nodeNames,proto3" json:"nodeNames,omitempty"`
}
func (x *NodeAddParameter) Reset() {
*x = NodeAddParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[13]
mi := &file_routes_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -838,7 +996,7 @@ func (x *NodeAddParameter) String() string {
func (*NodeAddParameter) ProtoMessage() {}
func (x *NodeAddParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[13]
mi := &file_routes_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -851,14 +1009,14 @@ func (x *NodeAddParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeAddParameter.ProtoReflect.Descriptor instead.
func (*NodeAddParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{13}
return file_routes_proto_rawDescGZIP(), []int{15}
}
func (x *NodeAddParameter) GetOptionsStrMap() map[string]string {
func (x *NodeAddParameter) GetNodeConfYaml() string {
if x != nil {
return x.OptionsStrMap
return x.NodeConfYaml
}
return nil
return ""
}
func (x *NodeAddParameter) GetNodeNames() []string {
@@ -882,7 +1040,7 @@ type NodeDeleteParameter struct {
func (x *NodeDeleteParameter) Reset() {
*x = NodeDeleteParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[14]
mi := &file_routes_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -895,7 +1053,7 @@ func (x *NodeDeleteParameter) String() string {
func (*NodeDeleteParameter) ProtoMessage() {}
func (x *NodeDeleteParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[14]
mi := &file_routes_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -908,7 +1066,7 @@ func (x *NodeDeleteParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeDeleteParameter.ProtoReflect.Descriptor instead.
func (*NodeDeleteParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{14}
return file_routes_proto_rawDescGZIP(), []int{16}
}
func (x *NodeDeleteParameter) GetForce() bool {
@@ -932,18 +1090,18 @@ type NodeSetParameter struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OptionsStrMap map[string]string `protobuf:"bytes,1,rep,name=optionsStrMap,proto3" json:"optionsStrMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Container string `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"`
NetdevDelete string `protobuf:"bytes,14,opt,name=netdevDelete,proto3" json:"netdevDelete,omitempty"`
AllNodes bool `protobuf:"varint,27,opt,name=allNodes,proto3" json:"allNodes,omitempty"`
Force bool `protobuf:"varint,31,opt,name=force,proto3" json:"force,omitempty"`
NodeNames []string `protobuf:"bytes,39,rep,name=nodeNames,proto3" json:"nodeNames,omitempty"`
NodeConfYaml string `protobuf:"bytes,1,opt,name=nodeConfYaml,proto3" json:"nodeConfYaml,omitempty"`
Container string `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"`
NetdevDelete string `protobuf:"bytes,14,opt,name=netdevDelete,proto3" json:"netdevDelete,omitempty"`
AllNodes bool `protobuf:"varint,27,opt,name=allNodes,proto3" json:"allNodes,omitempty"`
Force bool `protobuf:"varint,31,opt,name=force,proto3" json:"force,omitempty"`
NodeNames []string `protobuf:"bytes,39,rep,name=nodeNames,proto3" json:"nodeNames,omitempty"`
}
func (x *NodeSetParameter) Reset() {
*x = NodeSetParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[15]
mi := &file_routes_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -956,7 +1114,7 @@ func (x *NodeSetParameter) String() string {
func (*NodeSetParameter) ProtoMessage() {}
func (x *NodeSetParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[15]
mi := &file_routes_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -969,14 +1127,14 @@ func (x *NodeSetParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeSetParameter.ProtoReflect.Descriptor instead.
func (*NodeSetParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{15}
return file_routes_proto_rawDescGZIP(), []int{17}
}
func (x *NodeSetParameter) GetOptionsStrMap() map[string]string {
func (x *NodeSetParameter) GetNodeConfYaml() string {
if x != nil {
return x.OptionsStrMap
return x.NodeConfYaml
}
return nil
return ""
}
func (x *NodeSetParameter) GetContainer() string {
@@ -1030,7 +1188,7 @@ type NodeStatus struct {
func (x *NodeStatus) Reset() {
*x = NodeStatus{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[16]
mi := &file_routes_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1043,7 +1201,7 @@ func (x *NodeStatus) String() string {
func (*NodeStatus) ProtoMessage() {}
func (x *NodeStatus) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[16]
mi := &file_routes_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1056,7 +1214,7 @@ func (x *NodeStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatus.ProtoReflect.Descriptor instead.
func (*NodeStatus) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{16}
return file_routes_proto_rawDescGZIP(), []int{18}
}
func (x *NodeStatus) GetNodeName() string {
@@ -1106,7 +1264,7 @@ type NodeStatusResponse struct {
func (x *NodeStatusResponse) Reset() {
*x = NodeStatusResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[17]
mi := &file_routes_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1119,7 +1277,7 @@ func (x *NodeStatusResponse) String() string {
func (*NodeStatusResponse) ProtoMessage() {}
func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[17]
mi := &file_routes_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1132,7 +1290,7 @@ func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatusResponse.ProtoReflect.Descriptor instead.
func (*NodeStatusResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{17}
return file_routes_proto_rawDescGZIP(), []int{19}
}
func (x *NodeStatusResponse) GetNodeStatus() []*NodeStatus {
@@ -1156,7 +1314,7 @@ type VersionResponse struct {
func (x *VersionResponse) Reset() {
*x = VersionResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[18]
mi := &file_routes_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1169,7 +1327,7 @@ func (x *VersionResponse) String() string {
func (*VersionResponse) ProtoMessage() {}
func (x *VersionResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[18]
mi := &file_routes_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1182,7 +1340,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead.
func (*VersionResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{18}
return file_routes_proto_rawDescGZIP(), []int{20}
}
func (x *VersionResponse) GetApiPrefix() string {
@@ -1329,135 +1487,132 @@ var file_routes_proto_rawDesc = []byte{
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6e, 0x6f, 0x64,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x6e, 0x6f,
0x64, 0x65, 0x73, 0x22, 0xc7, 0x01, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x53, 0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x2d, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41,
0x64, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x4f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d,
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x12, 0x1c, 0x0a,
0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09,
0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x4f,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x49, 0x0a,
0x13, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f,
0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e,
0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xbb, 0x02, 0x0a, 0x10, 0x4e, 0x6f, 0x64,
0x65, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x53, 0x0a,
0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x4d,
0x61, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52,
0x64, 0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70,
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x40, 0x0a,
0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x69, 0x6d,
0x70, 0x6c, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x70, 0x6d, 0x69, 0x10, 0x01, 0x12,
0x0b, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04,
0x4c, 0x6f, 0x6e, 0x67, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6c, 0x6c, 0x10, 0x04, 0x22,
0x22, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x22, 0x54, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x50, 0x61,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43,
0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e,
0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e,
0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x13, 0x4e, 0x6f, 0x64,
0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61,
0x6d, 0x65, 0x73, 0x18, 0x27, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53,
0x74, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x86, 0x01, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69,
0x70, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x70, 0x61,
0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x18,
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x22,
0x4a, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x77, 0x77, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x61, 0x70, 0x69, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x61, 0x70, 0x69, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1e, 0x0a, 0x0a,
0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f,
0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0xa6, 0x08, 0x0a, 0x05, 0x57, 0x57, 0x41, 0x70, 0x69,
0x12, 0x73, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x75, 0x69,
0x6c, 0x64, 0x12, 0x21, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12,
0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x64, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x76,
0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x70, 0x0a, 0x0f, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x22,
0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64,
0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1c, 0x0a,
0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e,
0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28,
0x08, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66,
0x6f, 0x72, 0x63, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x27,
0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22,
0x86, 0x01, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a,
0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x73, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x70, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x70, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08,
0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x22, 0x4a, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34,
0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x14, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x50, 0x72,
0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x69, 0x50,
0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c,
0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32,
0xa6, 0x08, 0x0a, 0x05, 0x57, 0x57, 0x41, 0x70, 0x69, 0x12, 0x73, 0x0a, 0x0e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x21, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f,
0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31,
0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a,
0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12,
0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x6d,
0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x12,
0x20, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x56, 0x0a,
0x07, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x12, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f,
0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x55, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e,
0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x0a, 0x2a, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x08,
0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x1a, 0x2e,
0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x64,
0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x15, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x12, 0x70, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x6d, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f,
0x77, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53,
0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x56, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64,
0x64, 0x12, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64,
0x65, 0x41, 0x64, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x4e,
0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x12, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65,
0x73, 0x65, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x57, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12,
0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x4e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x1a, 0x19, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42,
0x29, 0x5a, 0x27, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x77, 0x77, 0x61, 0x70, 0x69,
0x76, 0x31, 0x3b, 0x77, 0x77, 0x61, 0x70, 0x69, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x55,
0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x2a, 0x08, 0x2f, 0x76, 0x31,
0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73,
0x74, 0x12, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64,
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x12,
0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53,
0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22,
0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x74, 0x3a, 0x01, 0x2a, 0x12,
0x57, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x73, 0x1a, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f,
0x64, 0x65, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08,
0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x29, 0x5a, 0x27, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x2f, 0x77, 0x77, 0x61, 0x70, 0x69, 0x76, 0x31, 0x3b, 0x77, 0x77, 0x61, 0x70,
0x69, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1472,82 +1627,83 @@ func file_routes_proto_rawDescGZIP() []byte {
return file_routes_proto_rawDescData
}
var file_routes_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
var file_routes_proto_goTypes = []interface{}{
(*ContainerBuildParameter)(nil), // 0: wwapi.v1.ContainerBuildParameter
(*ContainerDeleteParameter)(nil), // 1: wwapi.v1.ContainerDeleteParameter
(*ContainerImportParameter)(nil), // 2: wwapi.v1.ContainerImportParameter
(*ContainerInfo)(nil), // 3: wwapi.v1.ContainerInfo
(*ContainerListResponse)(nil), // 4: wwapi.v1.ContainerListResponse
(*ContainerShowParameter)(nil), // 5: wwapi.v1.ContainerShowParameter
(*ContainerShowResponse)(nil), // 6: wwapi.v1.ContainerShowResponse
(*ContainerSyncUserParameter)(nil), // 7: wwapi.v1.ContainerSyncUserParameter
(*NodeNames)(nil), // 8: wwapi.v1.NodeNames
(*NodeField)(nil), // 9: wwapi.v1.NodeField
(*NetDev)(nil), // 10: wwapi.v1.NetDev
(*NodeInfo)(nil), // 11: wwapi.v1.NodeInfo
(*NodeListResponse)(nil), // 12: wwapi.v1.NodeListResponse
(*NodeAddParameter)(nil), // 13: wwapi.v1.NodeAddParameter
(*NodeDeleteParameter)(nil), // 14: wwapi.v1.NodeDeleteParameter
(*NodeSetParameter)(nil), // 15: wwapi.v1.NodeSetParameter
(*NodeStatus)(nil), // 16: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 17: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 18: wwapi.v1.VersionResponse
nil, // 19: wwapi.v1.NetDev.FieldEntry
nil, // 20: wwapi.v1.NetDev.TagsEntry
nil, // 21: wwapi.v1.NodeInfo.FieldsEntry
nil, // 22: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 23: wwapi.v1.NodeInfo.TagsEntry
nil, // 24: wwapi.v1.NodeInfo.KeysEntry
nil, // 25: wwapi.v1.NodeAddParameter.OptionsStrMapEntry
nil, // 26: wwapi.v1.NodeSetParameter.OptionsStrMapEntry
(*empty.Empty)(nil), // 27: google.protobuf.Empty
(GetNodeList_ListType)(0), // 0: wwapi.v1.GetNodeList.ListType
(*ContainerBuildParameter)(nil), // 1: wwapi.v1.ContainerBuildParameter
(*ContainerDeleteParameter)(nil), // 2: wwapi.v1.ContainerDeleteParameter
(*ContainerImportParameter)(nil), // 3: wwapi.v1.ContainerImportParameter
(*ContainerInfo)(nil), // 4: wwapi.v1.ContainerInfo
(*ContainerListResponse)(nil), // 5: wwapi.v1.ContainerListResponse
(*ContainerShowParameter)(nil), // 6: wwapi.v1.ContainerShowParameter
(*ContainerShowResponse)(nil), // 7: wwapi.v1.ContainerShowResponse
(*ContainerSyncUserParameter)(nil), // 8: wwapi.v1.ContainerSyncUserParameter
(*NodeNames)(nil), // 9: wwapi.v1.NodeNames
(*NodeField)(nil), // 10: wwapi.v1.NodeField
(*NetDev)(nil), // 11: wwapi.v1.NetDev
(*NodeInfo)(nil), // 12: wwapi.v1.NodeInfo
(*NodeListResponse)(nil), // 13: wwapi.v1.NodeListResponse
(*GetNodeList)(nil), // 14: wwapi.v1.GetNodeList
(*NodeList)(nil), // 15: wwapi.v1.NodeList
(*NodeAddParameter)(nil), // 16: wwapi.v1.NodeAddParameter
(*NodeDeleteParameter)(nil), // 17: wwapi.v1.NodeDeleteParameter
(*NodeSetParameter)(nil), // 18: wwapi.v1.NodeSetParameter
(*NodeStatus)(nil), // 19: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 20: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 21: wwapi.v1.VersionResponse
nil, // 22: wwapi.v1.NetDev.FieldEntry
nil, // 23: wwapi.v1.NetDev.TagsEntry
nil, // 24: wwapi.v1.NodeInfo.FieldsEntry
nil, // 25: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 26: wwapi.v1.NodeInfo.TagsEntry
nil, // 27: wwapi.v1.NodeInfo.KeysEntry
(*empty.Empty)(nil), // 28: google.protobuf.Empty
}
var file_routes_proto_depIdxs = []int32{
3, // 0: wwapi.v1.ContainerListResponse.containers:type_name -> wwapi.v1.ContainerInfo
19, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
20, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
21, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
22, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
23, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
24, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
11, // 7: wwapi.v1.NodeListResponse.nodes:type_name -> wwapi.v1.NodeInfo
25, // 8: wwapi.v1.NodeAddParameter.optionsStrMap:type_name -> wwapi.v1.NodeAddParameter.OptionsStrMapEntry
26, // 9: wwapi.v1.NodeSetParameter.optionsStrMap:type_name -> wwapi.v1.NodeSetParameter.OptionsStrMapEntry
16, // 10: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
9, // 11: wwapi.v1.NetDev.FieldEntry.value:type_name -> wwapi.v1.NodeField
9, // 12: wwapi.v1.NetDev.TagsEntry.value:type_name -> wwapi.v1.NodeField
9, // 13: wwapi.v1.NodeInfo.FieldsEntry.value:type_name -> wwapi.v1.NodeField
10, // 14: wwapi.v1.NodeInfo.NetDevsEntry.value:type_name -> wwapi.v1.NetDev
9, // 15: wwapi.v1.NodeInfo.TagsEntry.value:type_name -> wwapi.v1.NodeField
9, // 16: wwapi.v1.NodeInfo.KeysEntry.value:type_name -> wwapi.v1.NodeField
0, // 17: wwapi.v1.WWApi.ContainerBuild:input_type -> wwapi.v1.ContainerBuildParameter
1, // 18: wwapi.v1.WWApi.ContainerDelete:input_type -> wwapi.v1.ContainerDeleteParameter
2, // 19: wwapi.v1.WWApi.ContainerImport:input_type -> wwapi.v1.ContainerImportParameter
27, // 20: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
5, // 21: wwapi.v1.WWApi.ContainerShow:input_type -> wwapi.v1.ContainerShowParameter
13, // 22: wwapi.v1.WWApi.NodeAdd:input_type -> wwapi.v1.NodeAddParameter
14, // 23: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter
8, // 24: wwapi.v1.WWApi.NodeList:input_type -> wwapi.v1.NodeNames
15, // 25: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.NodeSetParameter
8, // 26: wwapi.v1.WWApi.NodeStatus:input_type -> wwapi.v1.NodeNames
27, // 27: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
4, // 28: wwapi.v1.WWApi.ContainerBuild:output_type -> wwapi.v1.ContainerListResponse
27, // 29: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
4, // 30: wwapi.v1.WWApi.ContainerImport:output_type -> wwapi.v1.ContainerListResponse
4, // 31: wwapi.v1.WWApi.ContainerList:output_type -> wwapi.v1.ContainerListResponse
6, // 32: wwapi.v1.WWApi.ContainerShow:output_type -> wwapi.v1.ContainerShowResponse
12, // 33: wwapi.v1.WWApi.NodeAdd:output_type -> wwapi.v1.NodeListResponse
27, // 34: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
12, // 35: wwapi.v1.WWApi.NodeList:output_type -> wwapi.v1.NodeListResponse
12, // 36: wwapi.v1.WWApi.NodeSet:output_type -> wwapi.v1.NodeListResponse
17, // 37: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
18, // 38: wwapi.v1.WWApi.Version:output_type -> wwapi.v1.VersionResponse
28, // [28:39] is the sub-list for method output_type
17, // [17:28] is the sub-list for method input_type
17, // [17:17] is the sub-list for extension type_name
17, // [17:17] is the sub-list for extension extendee
0, // [0:17] is the sub-list for field type_name
4, // 0: wwapi.v1.ContainerListResponse.containers:type_name -> wwapi.v1.ContainerInfo
22, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
23, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
24, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
25, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
26, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
27, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
12, // 7: wwapi.v1.NodeListResponse.nodes:type_name -> wwapi.v1.NodeInfo
0, // 8: wwapi.v1.GetNodeList.type:type_name -> wwapi.v1.GetNodeList.ListType
19, // 9: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
10, // 10: wwapi.v1.NetDev.FieldEntry.value:type_name -> wwapi.v1.NodeField
10, // 11: wwapi.v1.NetDev.TagsEntry.value:type_name -> wwapi.v1.NodeField
10, // 12: wwapi.v1.NodeInfo.FieldsEntry.value:type_name -> wwapi.v1.NodeField
11, // 13: wwapi.v1.NodeInfo.NetDevsEntry.value:type_name -> wwapi.v1.NetDev
10, // 14: wwapi.v1.NodeInfo.TagsEntry.value:type_name -> wwapi.v1.NodeField
10, // 15: wwapi.v1.NodeInfo.KeysEntry.value:type_name -> wwapi.v1.NodeField
1, // 16: wwapi.v1.WWApi.ContainerBuild:input_type -> wwapi.v1.ContainerBuildParameter
2, // 17: wwapi.v1.WWApi.ContainerDelete:input_type -> wwapi.v1.ContainerDeleteParameter
3, // 18: wwapi.v1.WWApi.ContainerImport:input_type -> wwapi.v1.ContainerImportParameter
28, // 19: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
6, // 20: wwapi.v1.WWApi.ContainerShow:input_type -> wwapi.v1.ContainerShowParameter
16, // 21: wwapi.v1.WWApi.NodeAdd:input_type -> wwapi.v1.NodeAddParameter
17, // 22: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter
9, // 23: wwapi.v1.WWApi.NodeList:input_type -> wwapi.v1.NodeNames
18, // 24: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.NodeSetParameter
9, // 25: wwapi.v1.WWApi.NodeStatus:input_type -> wwapi.v1.NodeNames
28, // 26: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
5, // 27: wwapi.v1.WWApi.ContainerBuild:output_type -> wwapi.v1.ContainerListResponse
28, // 28: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
5, // 29: wwapi.v1.WWApi.ContainerImport:output_type -> wwapi.v1.ContainerListResponse
5, // 30: wwapi.v1.WWApi.ContainerList:output_type -> wwapi.v1.ContainerListResponse
7, // 31: wwapi.v1.WWApi.ContainerShow:output_type -> wwapi.v1.ContainerShowResponse
13, // 32: wwapi.v1.WWApi.NodeAdd:output_type -> wwapi.v1.NodeListResponse
28, // 33: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
13, // 34: wwapi.v1.WWApi.NodeList:output_type -> wwapi.v1.NodeListResponse
13, // 35: wwapi.v1.WWApi.NodeSet:output_type -> wwapi.v1.NodeListResponse
20, // 36: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
21, // 37: wwapi.v1.WWApi.Version:output_type -> wwapi.v1.VersionResponse
27, // [27:38] is the sub-list for method output_type
16, // [16:27] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
}
func init() { file_routes_proto_init() }
@@ -1713,7 +1869,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeAddParameter); i {
switch v := v.(*GetNodeList); i {
case 0:
return &v.state
case 1:
@@ -1725,7 +1881,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeDeleteParameter); i {
switch v := v.(*NodeList); i {
case 0:
return &v.state
case 1:
@@ -1737,7 +1893,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeSetParameter); i {
switch v := v.(*NodeAddParameter); i {
case 0:
return &v.state
case 1:
@@ -1749,7 +1905,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatus); i {
switch v := v.(*NodeDeleteParameter); i {
case 0:
return &v.state
case 1:
@@ -1761,7 +1917,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatusResponse); i {
switch v := v.(*NodeSetParameter); i {
case 0:
return &v.state
case 1:
@@ -1773,6 +1929,30 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatus); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_routes_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatusResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_routes_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*VersionResponse); i {
case 0:
return &v.state
@@ -1790,13 +1970,14 @@ func file_routes_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_routes_proto_rawDesc,
NumEnums: 0,
NumEnums: 1,
NumMessages: 27,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_routes_proto_goTypes,
DependencyIndexes: file_routes_proto_depIdxs,
EnumInfos: file_routes_proto_enumTypes,
MessageInfos: file_routes_proto_msgTypes,
}.Build()
File_routes_proto = out.File

View File

@@ -2,13 +2,11 @@ package node
import (
"fmt"
"reflect"
"regexp"
"strings"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
)
/**********
@@ -312,348 +310,356 @@ func (ent *Entry) Defined() bool {
}
/*
Set the Entry trough an interface by trying to cast the interface
Create an empty node NodeConf
*/
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)))
}
func NewConf() (nodeconf NodeConf) {
nodeconf.Ipmi = new(IpmiConf)
nodeconf.Kernel = new(KernelConf)
nodeconf.NetDevs = map[string]*NetDevs{}
return nodeconf
}
/*
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))
}
}
// /*
// 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)))
// }
/*
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))
}
// }
}
// /*
// 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))
// }
// }
/*
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))
}
}
// /*
// 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 (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 (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 (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))
}
}
}
// /*
// 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 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)
}
// 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
// }
}
return optionsMap
}
// } 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)
// }
type CobraCommand struct {
*cobra.Command
}
// } 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"))
/*
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 {
optionsMap := make(map[string]*string)
structVal := reflect.ValueOf(theStruct)
structTyp := structVal.Type()
for i := 0; i < structVal.NumField(); i++ {
field := structTyp.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)
}
// }
// return optionsMap
// }
} 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"))
// /*
// 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
}
}
// }
}
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
}
// /*
// 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

@@ -2,6 +2,9 @@ package node
import (
"reflect"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/spf13/cobra"
)
/*
@@ -132,6 +135,74 @@ func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo,
*/
}
}
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++ {
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
// }
// } 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") != "" {
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")) {
baseCmd.PersistentFlags().StringVar(ptr,
field.Tag.Get("lopt"),
field.Tag.Get("default"),
field.Tag.Get("comment"))
}
}
}
// return optionsMap
}
/*
Populates all fields of NodeInfo with Set from the