diff --git a/internal/app/api/wwapid/wwapid.go b/internal/app/api/wwapid/wwapid.go index 0d19e29d..7d6a1de4 100644 --- a/internal/app/api/wwapid/wwapid.go +++ b/internal/app/api/wwapid/wwapid.go @@ -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, } diff --git a/internal/app/wwctl/node/add/main.go b/internal/app/wwctl/node/add/main.go index 2b63ad94..4837809d 100644 --- a/internal/app/wwctl/node/add/main.go +++ b/internal/app/wwctl/node/add/main.go @@ -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) diff --git a/internal/app/wwctl/node/add/root.go b/internal/app/wwctl/node/add/root.go index b0e6af19..18dee9ae 100644 --- a/internal/app/wwctl/node/add/root.go +++ b/internal/app/wwctl/node/add/root.go @@ -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() diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index 1a5d8515..0bbad793 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -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 } diff --git a/internal/app/wwctl/node/set/main.go b/internal/app/wwctl/node/set/main.go index 83187b24..c7c6be47 100644 --- a/internal/app/wwctl/node/set/main.go +++ b/internal/app/wwctl/node/set/main.go @@ -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 { diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 32c58292..3e0a4675 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -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") diff --git a/internal/app/wwctl/profile/add/main.go b/internal/app/wwctl/profile/add/main.go index 6871520b..3e689a3d 100644 --- a/internal/app/wwctl/profile/add/main.go +++ b/internal/app/wwctl/profile/add/main.go @@ -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 { diff --git a/internal/app/wwctl/profile/add/root.go b/internal/app/wwctl/profile/add/root.go index 7380dec4..a7e60b26 100644 --- a/internal/app/wwctl/profile/add/root.go +++ b/internal/app/wwctl/profile/add/root.go @@ -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) { diff --git a/internal/app/wwctl/profile/set/main.go b/internal/app/wwctl/profile/set/main.go index b177a6b5..43e0446a 100644 --- a/internal/app/wwctl/profile/set/main.go +++ b/internal/app/wwctl/profile/set/main.go @@ -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 { diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 9bb96d6f..577e0312 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -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") diff --git a/internal/pkg/api/apiconfig/container/container.go b/internal/pkg/api/apiconfig/container/container.go index e4242e7d..d0e4ab3a 100644 --- a/internal/pkg/api/apiconfig/container/container.go +++ b/internal/pkg/api/apiconfig/container/container.go @@ -376,4 +376,4 @@ func getSystemContext() (sCtx *types.SystemContext, err error) { } return sCtx, nil -} \ No newline at end of file +} diff --git a/internal/pkg/api/node/list.go b/internal/pkg/api/node/list.go new file mode 100644 index 00000000..f31b8604 --- /dev/null +++ b/internal/pkg/api/node/list.go @@ -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 +} diff --git a/internal/pkg/api/node/node.go b/internal/pkg/api/node/node.go index df1c64f3..e3c7d890 100644 --- a/internal/pkg/api/node/node.go +++ b/internal/pkg/api/node/node.go @@ -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 } diff --git a/internal/pkg/api/profile/profile.go b/internal/pkg/api/profile/profile.go index 24ebff8f..1f25b897 100644 --- a/internal/pkg/api/profile/profile.go +++ b/internal/pkg/api/profile/profile.go @@ -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 != "" { diff --git a/internal/pkg/api/routes/v1/routes.proto b/internal/pkg/api/routes/v1/routes.proto index d3b3de2f..eb2fcb44 100644 --- a/internal/pkg/api/routes/v1/routes.proto +++ b/internal/pkg/api/routes/v1/routes.proto @@ -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 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 optionsStrMap = 1; + string nodeConfYaml = 1; string container = 2; string netdevDelete = 14; bool allNodes = 27; diff --git a/internal/pkg/api/routes/wwapiv1/routes.pb.go b/internal/pkg/api/routes/wwapiv1/routes.pb.go index 30d23083..5d38b99e 100644 --- a/internal/pkg/api/routes/wwapiv1/routes.pb.go +++ b/internal/pkg/api/routes/wwapiv1/routes.pb.go @@ -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 diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index 02d26809..5780937e 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -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 +// } diff --git a/internal/pkg/node/transformers.go b/internal/pkg/node/transformers.go index aac784b3..8653a78a 100644 --- a/internal/pkg/node/transformers.go +++ b/internal/pkg/node/transformers.go @@ -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