Recursive handling for command line flags

Every struct in a NodeConf with `lopt:"foo" set is now added as a
command-line flag with the RecursiveCreateFlags call. For maps a struct
with the key UNDEF is added so that it can be parsed out.

As the flags for the command-line need variables which hold the values,
for every map an element map[UNDEF] is added.  When now calling the
internal add, these map element can be filtered out and replace by the
given name. (e.g., --netname)

* rewrote node/profile add for recursive functions
* rewrote node/profile set for recursive functions
* rewrote node/profile list for recursive functions

Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
Christian Goll
2023-08-11 10:31:29 -06:00
committed by Jonathon Anderson
parent c55c5a2ac4
commit 45539a0d1f
29 changed files with 1346 additions and 714 deletions

View File

@@ -1,10 +1,14 @@
package add
import (
"fmt"
"strings"
"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/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
)
@@ -22,17 +26,36 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) error {
return err
}
}
// remove the default network as all network values are assigned
// remove the UNDEF network as all network values are assigned
// to this network
if _, ok := vars.nodeConf.NetDevs["default"]; ok && vars.netName != "" {
netDev := *vars.nodeConf.NetDevs["default"]
if !node.ObjectIsEmpty(vars.nodeConf.NetDevs["UNDEF"]) {
netDev := *vars.nodeConf.NetDevs["UNDEF"]
vars.nodeConf.NetDevs[vars.netName] = &netDev
delete(vars.nodeConf.NetDevs, "default")
}
delete(vars.nodeConf.NetDevs, "UNDEF")
if vars.fsName != "" {
if !strings.HasPrefix(vars.fsName, "/dev") {
if vars.fsName == vars.partName {
vars.fsName = "/dev/disk/by-partlabel/" + vars.partName
} else {
if vars.nodeConf.NetDevs["default"].Empty() {
delete(vars.nodeConf.NetDevs, "default")
return fmt.Errorf("filesystems need to have a underlying blockdev")
}
}
fs := *vars.nodeConf.FileSystems["UNDEF"]
vars.nodeConf.FileSystems[vars.fsName] = &fs
}
delete(vars.nodeConf.FileSystems, "UNDEF")
if vars.diskName != "" && vars.partName != "" {
prt := *vars.nodeConf.Disks["UNDEF"].Partitions["UNDEF"]
vars.nodeConf.Disks["UNDEF"].Partitions[vars.partName] = &prt
delete(vars.nodeConf.Disks["UNDEF"].Partitions, "UNDEF")
dsk := *vars.nodeConf.Disks["UNDEF"]
vars.nodeConf.Disks[vars.diskName] = &dsk
}
if (vars.diskName != "") != (vars.partName != "") {
return fmt.Errorf("partition and disk must be specified")
}
delete(vars.nodeConf.Disks, "UNDEF")
buffer, err := yaml.Marshal(vars.nodeConf)
if err != nil {
wwlog.Error("Can't marshall nodeInfo", err)

View File

@@ -5,8 +5,8 @@ import (
"os"
"testing"
"github.com/hpcng/warewulf/internal/pkg/node"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/stretchr/testify/assert"
)
@@ -234,6 +234,65 @@ nodes:
network devices:
foo:
ipaddr: 10.10.0.3
`},
{name: "one node with filesystem",
args: []string{"--fsname=/dev/vda1", "--fspath=/var", "n01"},
wantErr: false,
stdout: "",
outDb: `WW_INTERNAL: 43
nodeprofiles: {}
nodes:
n01:
profiles:
- default
filesystems:
/dev/vda1:
path: /var
`},
{name: "one node with filesystem",
args: []string{"--fsname=dev/vda1", "--fspath=/var", "n01"},
wantErr: true,
stdout: "",
outDb: `WW_INTERNAL: 43
nodeprofiles: {}
nodes: {}
`},
{name: "one node with filesystem and partition ",
args: []string{"--fsname=var", "--fspath=/var", "--partname=var", "--diskname=/dev/vda", "n01"},
wantErr: false,
stdout: "",
outDb: `WW_INTERNAL: 43
nodeprofiles: {}
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
filesystems:
/dev/disk/by-partlabel/var:
path: /var
`},
{name: "one node with filesystem with btrfs and partition ",
args: []string{"--fsname=var", "--fspath=/var", "--fsformat=btrfs", "--partname=var", "--diskname=/dev/vda", "n01"},
wantErr: false,
stdout: "",
outDb: `WW_INTERNAL: 43
nodeprofiles: {}
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`},
}
conf_yml := `WW_INTERNAL: 0`

View File

@@ -13,6 +13,9 @@ import (
// Holds the variables which are needed in CobraRunE
type variables struct {
netName string
fsName string
partName string
diskName string
nodeConf node.NodeConf
converters []func() error
}
@@ -30,7 +33,10 @@ func GetCommand() *cobra.Command {
Args: cobra.MinimumNArgs(1),
}
vars.converters = vars.nodeConf.CreateFlags(baseCmd, []string{"tagdel", "nettagdel", "ipmitagdel"})
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "", "Set network name for network options")
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "default", "Set network name for network options")
baseCmd.PersistentFlags().StringVar(&vars.fsName, "fsname", "", "set the file system name which must match a partition name")
baseCmd.PersistentFlags().StringVar(&vars.partName, "partname", "", "set the partition name so it can be used by a file system")
baseCmd.PersistentFlags().StringVar(&vars.diskName, "diskname", "", "set disk device name for the partition")
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()

View File

@@ -45,8 +45,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
wwlog.Error("Could not create temp file:%s \n", err)
}
defer os.Remove(file.Name())
nodeConf := node.NewConf()
yamlTemplate := nodeConf.UnmarshalConf([]string{"tagsdel", "default", "profiles"})
yamlTemplate := node.UnmarshalConf(node.NodeConf{}, []string{"tagsdel", "default", "profiles"})
for {
_ = file.Truncate(0)
_, _ = file.Seek(0, 0)

View File

@@ -26,6 +26,8 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err err
req.Type = wwapiv1.GetNodeList_Network
} else if vars.showLong {
req.Type = wwapiv1.GetNodeList_Long
} else if vars.showFullAll {
req.Type = wwapiv1.GetNodeList_FullAll
}
nodeInfo, err := apinode.NodeList(&req)
if len(nodeInfo.Output) > 0 {

View File

@@ -10,6 +10,7 @@ type variables struct {
showIpmi bool
showAll bool
showLong bool
showFullAll bool
}
func GetCommand() *cobra.Command {
@@ -39,6 +40,7 @@ func GetCommand() *cobra.Command {
baseCmd.PersistentFlags().BoolVarP(&vars.showNet, "net", "n", false, "Show node network configurations")
baseCmd.PersistentFlags().BoolVarP(&vars.showIpmi, "ipmi", "i", false, "Show node IPMI configurations")
baseCmd.PersistentFlags().BoolVarP(&vars.showAll, "all", "a", false, "Show all node configurations")
baseCmd.PersistentFlags().BoolVarP(&vars.showFullAll, "fullall", "A", false, "Show all node configurations inclusive empty entries")
baseCmd.PersistentFlags().BoolVarP(&vars.showLong, "long", "l", false, "Show long or wide format")
return baseCmd

View File

@@ -3,54 +3,86 @@ package set
import (
"fmt"
"os"
"strings"
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/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) {
return func(cmd *cobra.Command, args []string) error {
// run converters for different types
for _, c := range Converters {
for _, c := range vars.converters {
if err := c(); err != nil {
return err
}
}
// remove the default network as the all network values are assigned
// to this network
if NetName != "default" {
NodeConf.NetDevs[NetName] = NodeConf.NetDevs["default"]
delete(NodeConf.NetDevs, "default")
if !node.ObjectIsEmpty(vars.nodeConf.NetDevs["UNDEF"]) {
netDev := *vars.nodeConf.NetDevs["UNDEF"]
vars.nodeConf.NetDevs[vars.netName] = &netDev
}
buffer, err := yaml.Marshal(NodeConf)
delete(vars.nodeConf.NetDevs, "UNDEF")
if vars.fsName != "" {
if !strings.HasPrefix(vars.fsName, "/dev") {
if vars.fsName == vars.partName {
vars.fsName = "/dev/disk/by-partlabel/" + vars.partName
} else {
return fmt.Errorf("filesystems need to have a underlying blockdev")
}
}
fs := *vars.nodeConf.FileSystems["UNDEF"]
vars.nodeConf.FileSystems[vars.fsName] = &fs
}
delete(vars.nodeConf.FileSystems, "UNDEF")
if vars.diskName != "" && vars.partName != "" {
prt := *vars.nodeConf.Disks["UNDEF"].Partitions["UNDEF"]
vars.nodeConf.Disks["UNDEF"].Partitions[vars.partName] = &prt
delete(vars.nodeConf.Disks["UNDEF"].Partitions, "UNDEF")
dsk := *vars.nodeConf.Disks["UNDEF"]
vars.nodeConf.Disks[vars.diskName] = &dsk
}
if (vars.diskName != "") != (vars.partName != "") {
return fmt.Errorf("partition and disk must be specified")
}
delete(vars.nodeConf.Disks, "UNDEF")
buffer, err := yaml.Marshal(vars.nodeConf)
if err != nil {
wwlog.Error("Can't marshall nodeInfo", err)
os.Exit(1)
}
wwlog.Debug("sending following values: %s", string(buffer))
set := wwapiv1.NodeSetParameter{
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NetdevDelete: vars.setNetDevDel,
PartitionDelete: vars.setPartDel,
DiskDelete: vars.setDiskDel,
FilesystemDelete: vars.setFsDel,
AllNodes: vars.setNodeAll,
Force: vars.setForce,
NodeNames: args,
}
if !SetYes {
if !vars.setYes {
var nodeCount uint
// The checks run twice in the prompt case.
// Avoiding putting in a blocking prompt in an API.
_, nodeCount, err = apinode.NodeSetParameterCheck(&set, false)
if err != nil {
return
return nil
}
yes := util.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d nodes(s)", nodeCount))
if !yes {
return
return nil
}
}
return apinode.NodeSet(&set)
}
}

View File

@@ -0,0 +1,348 @@
package set
import (
"bytes"
"os"
"testing"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/stretchr/testify/assert"
)
func Test_Add(t *testing.T) {
tests := []struct {
name string
args []string
wantErr bool
stdout string
chkout bool
outDb string
inDB string
}{
{name: "single node change profile",
args: []string{"--profile=foo", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- foo
`},
{name: "multiple nodes change profile",
args: []string{"--profile=foo", "n0[1-2]"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
n02:
profiles:
- default`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- foo
n02:
profiles:
- foo
`},
{name: "single node set ipmitag",
args: []string{"--ipmitagadd", "foo=baar", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
ipmi:
tags:
foo: baar
profiles:
- default
`},
{name: "single node delete tag",
args: []string{"--tagdel", "tag1", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
tags:
tag1: value1
tag2: value2`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
tags:
tag2: value2
`},
{name: "single node set fs,part and disk",
args: []string{"--fsname=var", "--fspath=/var", "--fsformat=btrfs", "--partname=var", "--diskname=/dev/vda", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`},
{name: "single delete not existing fs",
args: []string{"--fsdel=var", "n01"},
wantErr: true,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
path: /var
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`},
{name: "single node delete existing fs",
args: []string{"--fsdel=/dev/disk/by-partlabel/var", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
path: /var
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
`},
{name: "single node delete existing partition",
args: []string{"--partdel=var", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
path: /var
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda: {}
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`},
{name: "single node delete existing disk",
args: []string{"--diskdel=/dev/vda", "n01"},
wantErr: false,
stdout: "",
inDB: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
disks:
/dev/vda:
partitions:
var: {}
path: /var
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`,
outDb: `WW_INTERNAL: 43
nodeprofiles:
default:
comment: testit
nodes:
n01:
profiles:
- default
filesystems:
/dev/disk/by-partlabel/var:
format: btrfs
path: /var
`},
}
conf_yml := `WW_INTERNAL: 0`
tempWarewulfConf, warewulfConfErr := os.CreateTemp("", "warewulf.conf-")
assert.NoError(t, warewulfConfErr)
defer os.Remove(tempWarewulfConf.Name())
_, warewulfConfErr = tempWarewulfConf.Write([]byte(conf_yml))
assert.NoError(t, warewulfConfErr)
assert.NoError(t, tempWarewulfConf.Sync())
assert.NoError(t, warewulfconf.New().Read(tempWarewulfConf.Name()))
tempNodeConf, nodesConfErr := os.CreateTemp("", "nodes.conf-")
assert.NoError(t, nodesConfErr)
defer os.Remove(tempNodeConf.Name())
node.ConfigFile = tempNodeConf.Name()
warewulfd.SetNoDaemon()
for _, tt := range tests {
var err error
_, err = tempNodeConf.Seek(0, 0)
assert.NoError(t, err)
assert.NoError(t, tempNodeConf.Truncate(0))
_, err = tempNodeConf.Write([]byte(tt.inDB))
assert.NoError(t, err)
assert.NoError(t, tempNodeConf.Sync())
t.Logf("Running test: %s\n", tt.name)
t.Run(tt.name, func(t *testing.T) {
baseCmd := GetCommand()
tt.args = append(tt.args, "--yes")
baseCmd.SetArgs(tt.args)
buf := new(bytes.Buffer)
baseCmd.SetOut(buf)
baseCmd.SetErr(buf)
err = baseCmd.Execute()
if (err != nil) != tt.wantErr {
t.Errorf("Got unwanted error: %s", err)
t.FailNow()
}
config, configErr := node.New()
assert.NoError(t, configErr)
dumpBytes, _ := config.Dump()
dump := string(dumpBytes)
if dump != tt.outDb {
t.Errorf("DB dump is wrong, got:'%s'\nwant:'%s'", dump, tt.outDb)
t.FailNow()
}
if tt.chkout && buf.String() != tt.stdout {
t.Errorf("Got wrong output, got:'%s'\nwant:'%s'", buf.String(), tt.stdout)
t.FailNow()
}
})
}
}

View File

@@ -10,14 +10,32 @@ import (
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
type variables struct {
setNetDevDel string
setDiskDel string
setPartDel string
setFsDel string
netName string
partName string
diskName string
fsName string
setNodeAll bool
setYes bool
setForce bool
nodeConf node.NodeConf
converters []func() error
}
func GetCommand() *cobra.Command {
vars := variables{}
vars.nodeConf = node.NewConf()
baseCmd := &cobra.Command{
DisableFlagsInUseLine: true,
Use: "set [OPTIONS] PATTERN [PATTERN ...]",
Short: "Configure node properties",
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(0),
RunE: CobraRunE,
RunE: CobraRunE(&vars),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
@@ -32,23 +50,19 @@ var (
return node_names, cobra.ShellCompDirectiveNoFileComp
},
}
SetNetDevDel string
NetName string
SetNodeAll bool
SetYes bool
SetForce bool
NodeConf node.NodeConf
Converters []func() error
)
func init() {
NodeConf = node.NewConf()
Converters = NodeConf.CreateFlags(baseCmd, []string{})
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().StringVar(&NetName, "netname", "default", "Set network name for network options")
baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)")
vars.converters = vars.nodeConf.CreateFlags(baseCmd, []string{})
baseCmd.PersistentFlags().StringVarP(&vars.setNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "default", "Set network name for network options")
baseCmd.PersistentFlags().BoolVarP(&vars.setNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().StringVar(&vars.fsName, "fsname", "", "set the file system name which must match a partition name")
baseCmd.PersistentFlags().StringVar(&vars.partName, "partname", "", "set the partition name so it can be used by a file system")
baseCmd.PersistentFlags().StringVar(&vars.diskName, "diskname", "", "set disk device name for the partition")
baseCmd.PersistentFlags().StringVar(&vars.setDiskDel, "diskdel", "", "delete the disk from the configuration")
baseCmd.PersistentFlags().StringVar(&vars.setPartDel, "partdel", "", "delete the partition from the configuration")
baseCmd.PersistentFlags().StringVar(&vars.setFsDel, "fsdel", "", "delete the partition from the configuration")
baseCmd.PersistentFlags().BoolVarP(&vars.setYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVarP(&vars.setForce, "force", "f", false, "Force configuration (even on error)")
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()
@@ -86,9 +100,5 @@ func init() {
log.Println(err)
}
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}

View File

@@ -3,8 +3,10 @@ package add
import (
"fmt"
"os"
"strings"
apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"gopkg.in/yaml.v2"
@@ -16,7 +18,7 @@ import (
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) {
return func(cmd *cobra.Command, args []string) (err error) {
// run converters for different types
for _, c := range Converters {
for _, c := range vars.Converters {
if err := c(); err != nil {
return err
}
@@ -24,25 +26,55 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err err
// remove the default network as the all network values are assigned
// to this network
if vars.netName != "" {
netDev := *vars.profileConf.NetDevs["default"]
netDev := *vars.profileConf.NetDevs["UNDEF"]
vars.profileConf.NetDevs[vars.netName] = &netDev
delete(vars.profileConf.NetDevs, "default")
delete(vars.profileConf.NetDevs, "UNDEF")
}
// remove the UNDEF network as all network values are assigned
// to this network
if !node.ObjectIsEmpty(vars.profileConf.NetDevs["UNDEF"]) {
netDev := *vars.profileConf.NetDevs["UNDEF"]
vars.profileConf.NetDevs[vars.netName] = &netDev
}
delete(vars.profileConf.NetDevs, "UNDEF")
if vars.fsName != "" {
if !strings.HasPrefix(vars.fsName, "/dev") {
if vars.fsName == vars.partName {
vars.fsName = "/dev/disk/by-partlabel/" + vars.partName
} else {
return fmt.Errorf("filesystems need to have a underlying blockdev")
}
}
fs := *vars.profileConf.FileSystems["UNDEF"]
vars.profileConf.FileSystems[vars.fsName] = &fs
}
delete(vars.profileConf.FileSystems, "UNDEF")
if vars.diskName != "" && vars.partName != "" {
prt := *vars.profileConf.Disks["UNDEF"].Partitions["UNDEF"]
vars.profileConf.Disks["UNDEF"].Partitions[vars.partName] = &prt
delete(vars.profileConf.Disks["UNDEF"].Partitions, "UNDEF")
dsk := *vars.profileConf.Disks["UNDEF"]
vars.profileConf.Disks[vars.diskName] = &dsk
}
if (vars.diskName != "") != (vars.partName != "") {
return fmt.Errorf("partition and disk must be specified")
}
delete(vars.profileConf.Disks, "UNDEF")
buffer, err := yaml.Marshal(vars.profileConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
set := wwapiv1.NodeSetParameter{
set := wwapiv1.ProfileSetParameter{
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
NetdevDelete: vars.SetNetDevDel,
AllProfiles: vars.SetNodeAll,
Force: vars.SetForce,
ProfileNames: args,
}
if !SetYes {
if !vars.SetYes {
// The checks run twice in the prompt case.
// Avoiding putting in a blocking prompt in an API.
_, _, err = apiprofile.ProfileSetParameterCheck(&set, false)

View File

@@ -5,8 +5,8 @@ import (
"os"
"testing"
"github.com/hpcng/warewulf/internal/pkg/node"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/stretchr/testify/assert"
)
@@ -26,9 +26,7 @@ func Test_Add(t *testing.T) {
stdout: "",
outDb: `WW_INTERNAL: 43
nodeprofiles:
p01:
network devices:
default: {}
p01: {}
nodes: {}
`,
},

View File

@@ -13,17 +13,16 @@ import (
type variables struct {
netName string
profileConf node.NodeConf
}
var (
SetNetDevDel string
SetNodeAll bool
SetYes bool
SetForce bool
NetName string
fsName string
partName string
diskName string
ProfileConf node.NodeConf
Converters []func() error
)
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
@@ -37,9 +36,12 @@ func GetCommand() *cobra.Command {
RunE: CobraRunE(&vars),
Args: cobra.ExactArgs(1),
}
Converters = vars.profileConf.CreateFlags(baseCmd,
vars.Converters = vars.profileConf.CreateFlags(baseCmd,
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "", "Set network name for network options")
baseCmd.PersistentFlags().StringVar(&vars.fsName, "fsname", "", "set the file system name which must match a partition name")
baseCmd.PersistentFlags().StringVar(&vars.partName, "partname", "", "set the partition name so it can be used by a file system")
baseCmd.PersistentFlags().StringVar(&vars.diskName, "diskname", "", "set disk device name for the partition")
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()
@@ -65,7 +67,6 @@ func GetCommand() *cobra.Command {
}); err != nil {
log.Println(err)
}
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVarP(&vars.SetYes, "yes", "y", false, "Set 'yes' to all questions asked")
return baseCmd
}

View File

@@ -45,8 +45,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
wwlog.Error("Could not create temp file:%s \n", err)
}
defer os.Remove(file.Name())
nodeConf := node.NewConf()
yamlTemplate := nodeConf.UnmarshalConf([]string{"tagsdel"})
yamlTemplate := node.UnmarshalConf(node.NodeConf{}, []string{"tagsdel"})
for {
_ = file.Truncate(0)
_, _ = file.Seek(0, 0)
@@ -112,7 +111,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
if yes {
err = apiprofile.ProfileDelete(&wwapiv1.NodeDeleteParameter{NodeNames: pList, Force: true})
if err != nil {
wwlog.Verbose("Problem deleting nodes before modification %s")
}

View File

@@ -17,6 +17,7 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err err
}
req := wwapiv1.GetProfileList{
ShowAll: vars.showAll,
ShowFullAll: vars.showFullAll,
Profiles: args,
}
profileInfo, err := apiprofile.ProfileList(&req)

View File

@@ -4,6 +4,7 @@ import "github.com/spf13/cobra"
type variables struct {
showAll bool
showFullAll bool
}
// GetRootCommand returns the root cobra.Command for the application.
@@ -17,7 +18,8 @@ func GetCommand() *cobra.Command {
RunE: CobraRunE(&vars),
Aliases: []string{"ls"},
}
baseCmd.PersistentFlags().BoolVarP(&vars.showAll, "all", "a", false, "Show all node configurations")
baseCmd.PersistentFlags().BoolVarP(&vars.showAll, "all", "a", false, "Show all profile configurations")
baseCmd.PersistentFlags().BoolVarP(&vars.showFullAll, "fullall", "A", false, "Show all profile configurations inclusive empty entries")
return baseCmd
}

View File

@@ -3,48 +3,80 @@ package set
import (
"fmt"
"os"
"strings"
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/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) {
return func(cmd *cobra.Command, args []string) error {
// remove the default network as the all network values are assigned
// to this network
if NetName != "default" {
ProfileConf.NetDevs[NetName] = ProfileConf.NetDevs["default"]
delete(ProfileConf.NetDevs, "default")
if !node.ObjectIsEmpty(vars.profileConf.NetDevs["UNDEF"]) {
netDev := *vars.profileConf.NetDevs["UNDEF"]
vars.profileConf.NetDevs[vars.netName] = &netDev
}
buffer, err := yaml.Marshal(ProfileConf)
delete(vars.profileConf.NetDevs, "UNDEF")
if vars.fsName != "" {
if !strings.HasPrefix(vars.fsName, "/dev") {
if vars.fsName == vars.partName {
vars.fsName = "/dev/disk/by-partlabel/" + vars.partName
} else {
return fmt.Errorf("filesystems need to have a underlying blockdev")
}
}
fs := *vars.profileConf.FileSystems["UNDEF"]
vars.profileConf.FileSystems[vars.fsName] = &fs
}
delete(vars.profileConf.FileSystems, "UNDEF")
if vars.diskName != "" && vars.partName != "" {
prt := *vars.profileConf.Disks["UNDEF"].Partitions["UNDEF"]
vars.profileConf.Disks["UNDEF"].Partitions[vars.partName] = &prt
delete(vars.profileConf.Disks["UNDEF"].Partitions, "UNDEF")
dsk := *vars.profileConf.Disks["UNDEF"]
vars.profileConf.Disks[vars.diskName] = &dsk
}
if (vars.diskName != "") != (vars.partName != "") {
return fmt.Errorf("partition and disk must be specified")
}
delete(vars.profileConf.Disks, "UNDEF")
buffer, err := yaml.Marshal(vars.profileConf)
if err != nil {
wwlog.Error("Cant marshall nodeInfo", err)
os.Exit(1)
}
set := wwapiv1.NodeSetParameter{
wwlog.Debug("sending following values: %s", string(buffer))
set := wwapiv1.ProfileSetParameter{
NodeConfYaml: string(buffer[:]),
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
NetdevDelete: vars.setNetDevDel,
PartitionDelete: vars.setPartDel,
DiskDelete: vars.setDiskDel,
FilesystemDelete: vars.setFsDel,
AllProfiles: vars.setNodeAll,
Force: vars.setForce,
ProfileNames: args,
}
if !SetYes {
if !vars.setYes {
var profileCount uint
// The checks run twice in the prompt case.
// Avoiding putting in a blocking prompt in an API.
_, profileCount, err = apiprofile.ProfileSetParameterCheck(&set, false)
if err != nil {
return
return err
}
yes := util.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d profile(s)", profileCount))
if !yes {
return
return err
}
}
return apiprofile.ProfileSet(&set)
}
}

View File

@@ -10,14 +10,33 @@ import (
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
type variables struct {
setNetDevDel string
setDiskDel string
setPartDel string
setFsDel string
setNodeAll bool
setYes bool
setForce bool
netName string
partName string
diskName string
fsName string
profileConf node.NodeConf
converters []func() error
}
func GetCommand() *cobra.Command {
vars := variables{}
vars.profileConf = node.NewConf()
baseCmd := &cobra.Command{
Use: "set [OPTIONS] [PROFILE ...]",
Short: "Configure node profile properties",
Long: "This command sets configuration properties for the node PROFILE(s).\n\n" +
"Note: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(0),
RunE: CobraRunE,
RunE: CobraRunE(&vars),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
@@ -32,24 +51,20 @@ var (
return p_names, cobra.ShellCompDirectiveNoFileComp
},
}
SetNetDevDel string
SetNodeAll bool
SetYes bool
SetForce bool
NetName string
ProfileConf node.NodeConf
Converters []func() error
)
func init() {
ProfileConf = node.NewConf()
Converters = ProfileConf.CreateFlags(baseCmd,
vars.profileConf = node.NewConf()
vars.converters = vars.profileConf.CreateFlags(baseCmd,
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
baseCmd.PersistentFlags().StringVar(&NetName, "netname", "default", "Set network name for network options")
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")
baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)")
baseCmd.PersistentFlags().StringVar(&vars.netName, "netname", "default", "Set network name for network options")
baseCmd.PersistentFlags().StringVarP(&vars.setNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().BoolVarP(&vars.setNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().BoolVarP(&vars.setYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVarP(&vars.setForce, "force", "f", false, "Force configuration (even on error)")
baseCmd.PersistentFlags().StringVar(&vars.fsName, "fsname", "", "set the file system name which must match a partition name")
baseCmd.PersistentFlags().StringVar(&vars.partName, "partname", "", "set the partition name so it can be used by a file system")
baseCmd.PersistentFlags().StringVar(&vars.diskName, "diskname", "", "set disk device name for the partition")
baseCmd.PersistentFlags().StringVar(&vars.setDiskDel, "diskdel", "", "delete the disk from the configuration")
baseCmd.PersistentFlags().StringVar(&vars.setPartDel, "partdel", "", "delete the partition from the configuration")
baseCmd.PersistentFlags().StringVar(&vars.setFsDel, "fsdel", "", "delete the from the configuration")
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()
@@ -75,10 +90,5 @@ func init() {
}); err != nil {
log.Println(err)
}
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}

View File

@@ -2,7 +2,6 @@ package apinode
import (
"fmt"
"reflect"
"sort"
"strings"
@@ -77,100 +76,14 @@ func NodeList(nodeGet *wwapiv1.GetNodeList) (nodeList wwapiv1.NodeList, err erro
n.ContainerName.Print(),
n.SystemOverlay.Print()+"/"+n.RuntimeOverlay.Print()))
}
} else if nodeGet.Type == wwapiv1.GetNodeList_All {
} else if nodeGet.Type == wwapiv1.GetNodeList_All || nodeGet.Type == wwapiv1.GetNodeList_FullAll {
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%s:=:%s:=:%s:=:%s", "NODE", "FIELD", "PROFILE", "VALUE"))
for _, n := range node.FilterByName(nodes, nodeGet.Nodes) {
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()
fields := n.GetFields(wwapiv1.GetNodeList_FullAll == nodeGet.Type)
for _, f := range fields {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%s:=:%s:=:%s:=:%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("%s:=:%s:=:%s:=:%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 {
if netConfField.Tag.Get("lopt") != "nettagadd" {
fieldName = netName + ":" + netConfField.Tag.Get("lopt")
} else {
fieldName = netName + ":tag"
}
} else {
fieldName = netName + ":" + netInfoType.Field(j).Name
}
if netInfoType.Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := netInfoVal.Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
// only print fields with lopt
if netConfField.Tag.Get("lopt") != "" {
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%s:=:%s:=:%s:=:%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) {
keyfieldName := fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%s:=:%s:=:%s:=:%s", n.Id.Print(), keyfieldName, fieldSource, fieldVal))
}
}
}
}
} else if nType.Field(i).Type.Kind() == reflect.Ptr {
nestInfoType := reflect.TypeOf(nVal.Field(i).Interface())
nestInfoVal := reflect.ValueOf(nVal.Field(i).Interface())
// nestConfType := reflect.TypeOf(nConfField.Type.Elem().FieldByName())
for j := 0; j < nestInfoType.Elem().NumField(); j++ {
nestConfField, ok := nConfField.Type.Elem().FieldByName(nestInfoType.Elem().Field(j).Name)
if ok {
fieldName = nestConfField.Tag.Get("lopt")
} else {
fieldName = nestInfoType.Elem().Field(j).Name
}
if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := nestInfoVal.Elem().Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
nodeList.Output = append(nodeList.Output,
fmt.Sprintf("%s:=:%s:=:%s:=:%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("%s:=:%s:=:%s:=:%s", n.Id.Print(), fieldName, fieldSource, fieldVal))
}
}
}
}
fmt.Sprintf("%s:=:%s:=:%s:=:%s", n.Id.Print(), f.Field, f.Source, f.Value))
}
}
}

View File

@@ -1,79 +0,0 @@
package apinode
import (
"fmt"
"reflect"
"strings"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
)
/*
Get the all the fields of a NodeInfo, keys are the lopt of NodeConf.
func GetFields(n interface{}) map[string]*wwapiv1.NodeField {
return getFieldsOf(n, node.NodeConf{})
}
*/
func GetFields(n interface{}) map[string]*wwapiv1.NodeField {
nodeType := reflect.TypeOf(n)
nodeVal := reflect.ValueOf(n)
fieldMap := make(map[string]*wwapiv1.NodeField)
for i := 0; i < nodeType.NumField(); i++ {
switch nodeType.Field(i).Type {
case reflect.TypeOf(node.Entry{}):
var myField wwapiv1.NodeField
entry := nodeVal.Field(i).Interface().(node.Entry)
myField.Source = entry.Source()
myField.Value = entry.Get()
myField.Print = entry.Print()
fieldMap[nodeType.Field(i).Name] = &myField
case reflect.TypeOf([]string{}):
var myField wwapiv1.NodeField
entry := nodeVal.Field(i).Interface().([]string)
if len(entry) == 0 {
myField.Value = node.NoValue
myField.Print = node.NoValue
myField.Source = node.NoValue
} else {
myField.Value = strings.Join(entry, ",")
myField.Print = strings.Join(entry, ",")
myField.Source = node.NoValue
fieldMap[nodeType.Field(i).Name] = &myField
}
case reflect.TypeOf((*node.KernelEntry)(nil)):
entry := nodeVal.Field(i).Elem().Interface().(node.KernelEntry)
kernelMap := GetFields(entry)
for key, val := range kernelMap {
fieldMap["KernelEntry:"+key] = val
}
case reflect.TypeOf((*node.IpmiEntry)(nil)):
entry := nodeVal.Field(i).Elem().Interface().(node.IpmiEntry)
kernelMap := GetFields(entry)
for key, val := range kernelMap {
fieldMap["IpmiEntry:"+key] = val
}
case reflect.TypeOf(map[string]*node.Entry(nil)):
keyMap := nodeVal.Field(i).Interface().(map[string]*node.Entry)
for key, entr := range keyMap {
var myField wwapiv1.NodeField
myField.Source = entr.Source()
myField.Value = entr.Get()
myField.Print = entr.Print()
fieldMap["key:"+key] = &myField
}
case reflect.TypeOf(map[string]*node.NetDevEntry(nil)):
netMap := nodeVal.Field(i).Interface().(map[string]*node.NetDevEntry)
for net, netdev := range netMap {
netMapEntr := GetFields(*netdev)
for key, val := range netMapEntr {
fieldMap["NetDevEntry:"+net+":"+key] = val
}
}
default:
panic(fmt.Sprintf("Can't handle: %s\n", nodeType.Field(i).Type))
}
}
return fieldMap
}

View File

@@ -8,9 +8,9 @@ import (
"os"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/pkg/hostlist"
"github.com/pkg/errors"
@@ -270,16 +270,52 @@ func NodeSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
wwlog.Verbose("Node: %s, Deleting network device: %s", n.Id.Get(), set.NetdevDelete)
delete(n.NetDevs, set.NetdevDelete)
}
if set.PartitionDelete != "" {
deletedPart := false
for diskname, disk := range n.Disks {
if _, ok := disk.Partitions[set.PartitionDelete]; ok {
wwlog.Verbose("Node: %s, on disk %, deleting partition: %s", n.Id.Get(), diskname, set.PartitionDelete)
deletedPart = true
delete(disk.Partitions, set.PartitionDelete)
}
if !deletedPart {
wwlog.Error(fmt.Sprintf("%v", err.Error()))
err = fmt.Errorf("partition doesn't exist: %s", set.PartitionDelete)
return
}
}
}
if set.DiskDelete != "" {
if _, ok := n.Disks[set.DiskDelete]; !ok {
err = fmt.Errorf("disk doesn't exist: %s", set.DiskDelete)
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
wwlog.Verbose("Node: %s, deleting disk: %s", n.Id.Get(), set.DiskDelete)
delete(n.Disks, set.DiskDelete)
}
if set.FilesystemDelete != "" {
if _, ok := n.FileSystems[set.FilesystemDelete]; !ok {
err = fmt.Errorf("filesystem doesn't exist: %s", set.FilesystemDelete)
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
wwlog.Verbose("Node: %s, deleting filesystem: %s", n.Id.Get(), set.FilesystemDelete)
delete(n.FileSystems, set.FilesystemDelete)
}
for _, key := range nodeConf.TagsDel {
wwlog.Debug("deleting tag %s", key)
delete(n.Tags, key)
}
if nodeConf.Ipmi != nil {
for _, key := range nodeConf.Ipmi.TagsDel {
wwlog.Debug("deleting Ipmi tag %s", key)
delete(n.Ipmi.Tags, key)
}
}
for net := range nodeConf.NetDevs {
for _, key := range nodeConf.NetDevs[net].TagsDel {
if _, ok := n.NetDevs[net]; ok {

View File

@@ -2,7 +2,6 @@ package apiprofile
import (
"fmt"
"reflect"
"sort"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
@@ -30,99 +29,14 @@ func ProfileList(ShowOpt *wwapiv1.GetProfileList) (profileList wwapiv1.ProfileLi
sort.Slice(profiles, func(i, j int) bool {
return profiles[i].Id.Get() < profiles[j].Id.Get()
})
if ShowOpt.ShowAll {
if ShowOpt.ShowAll || ShowOpt.ShowFullAll {
for _, p := range profiles {
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", "PROFILE", "FIELD", "PROFILE", "VALUE"))
nType := reflect.TypeOf(p)
nVal := reflect.ValueOf(p)
nConfType := reflect.TypeOf(node.NodeConf{})
for i := 0; i < nType.NumField(); i++ {
var fieldName, fieldSource, fieldVal string
nConfField, ok := nConfType.FieldByName(nType.Field(i).Name)
if ok {
fieldName = nConfField.Tag.Get("lopt")
} else {
fieldName = nType.Field(i).Name
}
if nType.Field(i).Type == reflect.TypeOf(node.Entry{}) {
entr := nVal.Field(i).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
fields := p.GetFields(ShowOpt.ShowFullAll)
for _, f := range fields {
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.Entry{}) {
entrMap := nVal.Field(i).Interface().(map[string]*node.Entry)
for key, val := range entrMap {
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), key, val.Source(), val.Print()))
}
} else if nType.Field(i).Type == reflect.TypeOf(map[string]*node.NetDevEntry{}) {
netDevs := nVal.Field(i).Interface().(map[string]*node.NetDevEntry)
for netName, netWork := range netDevs {
netInfoType := reflect.TypeOf(*netWork)
netInfoVal := reflect.ValueOf(*netWork)
netConfType := reflect.TypeOf(node.NetDevs{})
for j := 0; j < netInfoType.NumField(); j++ {
netConfField, ok := netConfType.FieldByName(netInfoType.Field(j).Name)
if ok {
if netConfField.Tag.Get("lopt") != "nettagadd" {
fieldName = netName + ":" + netConfField.Tag.Get("lopt")
} else {
fieldName = netName + ":tag"
}
} else {
fieldName = netName + ":" + netInfoType.Field(j).Name
}
if netInfoType.Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := netInfoVal.Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
// only print fields with lopt
if netConfField.Tag.Get("lopt") != "" {
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
}
} else if netInfoType.Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
for key, val := range netInfoVal.Field(j).Interface().(map[string]*node.Entry) {
keyfieldName := fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), keyfieldName, fieldSource, fieldVal))
}
}
}
}
} else if nType.Field(i).Type.Kind() == reflect.Ptr {
nestInfoType := reflect.TypeOf(nVal.Field(i).Interface())
nestInfoVal := reflect.ValueOf(nVal.Field(i).Interface())
// nestConfType := reflect.TypeOf(nConfField.Type.Elem().FieldByName())
for j := 0; j < nestInfoType.Elem().NumField(); j++ {
nestConfField, ok := nConfField.Type.Elem().FieldByName(nestInfoType.Elem().Field(j).Name)
if ok {
fieldName = nestConfField.Tag.Get("lopt")
} else {
fieldName = nestInfoType.Elem().Field(j).Name
}
if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(node.Entry{}) {
entr := nestInfoVal.Elem().Field(j).Interface().(node.Entry)
fieldSource = entr.Source()
fieldVal = entr.Print()
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
} else if nestInfoType.Elem().Field(j).Type == reflect.TypeOf(map[string]*node.Entry{}) {
for key, val := range nestInfoVal.Elem().Field(j).Interface().(map[string]*node.Entry) {
fieldName = fieldName + ":" + key
fieldSource = val.Source()
fieldVal = val.Print()
profileList.Output = append(profileList.Output,
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), fieldName, fieldSource, fieldVal))
}
}
}
}
fmt.Sprintf("%s=%s=%s=%s", p.Id.Print(), f.Field, f.Source, f.Value))
}
}
} else {

View File

@@ -14,7 +14,7 @@ import (
)
// NodeSet is the wwapiv1 implmentation for updating nodeinfo fields.
func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
func ProfileSet(set *wwapiv1.ProfileSetParameter) (err error) {
if set == nil {
return fmt.Errorf("NodeAddParameter is nil")
}
@@ -31,7 +31,7 @@ func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
// Output to the console if console is true.
// TODO: Determine if the console switch does wwlog or not.
// - console may end up being textOutput?
func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
func ProfileSetParameterCheck(set *wwapiv1.ProfileSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
if set == nil {
err = fmt.Errorf("profile set parameter is nil")
if console {
@@ -40,7 +40,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
}
}
if set.NodeNames == nil {
if set.ProfileNames == nil {
err = fmt.Errorf("profile set parameter: ProfileNames is nil")
if console {
fmt.Printf("%v\n", err)
@@ -62,7 +62,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
// Note: This does not do expansion on the nodes.
if set.AllNodes || (len(set.NodeNames) == 0) {
if set.AllProfiles || (len(set.ProfileNames) == 0) {
if console {
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n")
}
@@ -82,12 +82,8 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
}
for _, p := range profiles {
if util.InSlice(set.NodeNames, p.Id.Get()) {
if util.InSlice(set.ProfileNames, p.Id.Get()) {
wwlog.Verbose("Evaluating profile: %s", p.Id.Get())
// Fix issue: https://github.com/hpcng/warewulf/issues/661
if p.Id.Get() == "default" && len(p.NetDevs) == 0 {
set.NetdevDelete = p.Id.Get()
}
p.SetFrom(&pConf)
if set.NetdevDelete != "" {
if _, ok := p.NetDevs[set.NetdevDelete]; !ok {
@@ -98,6 +94,40 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
wwlog.Verbose("Profile: %s, Deleting network device: %s", p.Id.Get(), set.NetdevDelete)
delete(p.NetDevs, set.NetdevDelete)
}
if set.PartitionDelete != "" {
deletedPart := false
for diskname, disk := range p.Disks {
if _, ok := disk.Partitions[set.PartitionDelete]; ok {
wwlog.Verbose("Node: %s, on disk %, deleting partition: %s", p.Id.Get(), diskname, set.PartitionDelete)
deletedPart = true
delete(disk.Partitions, set.PartitionDelete)
}
if !deletedPart {
wwlog.Error(fmt.Sprintf("%v", err.Error()))
err = fmt.Errorf("partition doesn't exist: %s", set.PartitionDelete)
return
}
}
}
if set.DiskDelete != "" {
if _, ok := p.Disks[set.DiskDelete]; !ok {
err = fmt.Errorf("disk doesn't exist: %s", set.DiskDelete)
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
wwlog.Verbose("Node: %s, deleting disk: %s", p.Id.Get(), set.DiskDelete)
delete(p.Disks, set.DiskDelete)
}
if set.FilesystemDelete != "" {
if _, ok := p.FileSystems[set.FilesystemDelete]; !ok {
err = fmt.Errorf("disk doesn't exist: %s", set.FilesystemDelete)
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
wwlog.Verbose("Node: %s, deleting filesystem: %s", p.Id.Get(), set.FilesystemDelete)
delete(p.FileSystems, set.FilesystemDelete)
}
for _, key := range pConf.TagsDel {
delete(p.Tags, key)
}
@@ -127,7 +157,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
Adds a new profile with the given name
*/
func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
func AddProfile(nsp *wwapiv1.ProfileSetParameter) error {
if nsp == nil {
return fmt.Errorf("NodeSetParameter is nill")
}
@@ -137,8 +167,8 @@ func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
return errors.Wrap(err, "Could not open database")
}
if util.InSlice(nodeDB.ListAllProfiles(), nsp.NodeNames[0]) {
return errors.New(fmt.Sprintf("profile with name %s allready exists", nsp.NodeNames[0]))
if util.InSlice(nodeDB.ListAllProfiles(), nsp.ProfileNames[0]) {
return errors.New(fmt.Sprintf("profile with name %s allready exists", nsp.ProfileNames[0]))
}
var nodeConf node.NodeConf
@@ -147,7 +177,7 @@ func AddProfile(nsp *wwapiv1.NodeSetParameter) error {
return errors.Wrap(err, "failed to decode nodeConf")
}
n, err := nodeDB.AddProfile(nsp.NodeNames[0])
n, err := nodeDB.AddProfile(nsp.ProfileNames[0])
if err != nil {
return errors.Wrap(err, "failed to add node")
}

View File

@@ -118,6 +118,7 @@ message GetNodeList {
Network = 2;
Long = 3;
All = 4;
FullAll = 5;
}
ListType type = 7;
repeated string Nodes = 8;
@@ -131,7 +132,8 @@ message NodeList {
// Request a profile list view
message GetProfileList {
bool ShowAll = 1;
repeated string Profiles = 2;
bool ShowFullAll = 2;
repeated string Profiles = 3;
}
// Get the formated output as string
message ProfileList {
@@ -169,13 +171,26 @@ message NodeDeleteParameter {
// by Warewulf.
message NodeSetParameter {
string nodeConfYaml = 1;
string container = 2;
string netdevDelete = 14;
bool allNodes = 27;
bool force = 31;
repeated string nodeNames = 39;
string netdevDelete = 2;
string diskDelete = 3;
string partitionDelete = 4;
string filesystemDelete = 5;
bool allNodes = 6;
bool force = 7;
repeated string nodeNames = 8;
}
// ProfileSetParameter contains all fields for updating aspects of profiles managed. Basically a copy of NodeSetParameters
// by Warewulf.
message ProfileSetParameter {
string nodeConfYaml = 1;
string netdevDelete = 2;
string diskDelete = 3;
string partitionDelete = 4;
string filesystemDelete = 5;
bool allProfiles = 6;
bool force = 7;
repeated string profileNames = 8;
}
// NodeStatus contains information about the imaging status per node.
message NodeStatus {
string nodeName = 1; // Name (Id) of the node.

View File

@@ -33,6 +33,7 @@ const (
GetNodeList_Network GetNodeList_ListType = 2
GetNodeList_Long GetNodeList_ListType = 3
GetNodeList_All GetNodeList_ListType = 4
GetNodeList_FullAll GetNodeList_ListType = 5
)
// Enum value maps for GetNodeList_ListType.
@@ -43,6 +44,7 @@ var (
2: "Network",
3: "Long",
4: "All",
5: "FullAll",
}
GetNodeList_ListType_value = map[string]int32{
"Simple": 0,
@@ -50,6 +52,7 @@ var (
"Network": 2,
"Long": 3,
"All": 4,
"FullAll": 5,
}
)
@@ -1048,7 +1051,8 @@ type GetProfileList struct {
unknownFields protoimpl.UnknownFields
ShowAll bool `protobuf:"varint,1,opt,name=ShowAll,proto3" json:"ShowAll,omitempty"`
Profiles []string `protobuf:"bytes,2,rep,name=Profiles,proto3" json:"Profiles,omitempty"`
ShowFullAll bool `protobuf:"varint,2,opt,name=ShowFullAll,proto3" json:"ShowFullAll,omitempty"`
Profiles []string `protobuf:"bytes,3,rep,name=Profiles,proto3" json:"Profiles,omitempty"`
}
func (x *GetProfileList) Reset() {
@@ -1090,6 +1094,13 @@ func (x *GetProfileList) GetShowAll() bool {
return false
}
func (x *GetProfileList) GetShowFullAll() bool {
if x != nil {
return x.ShowFullAll
}
return false
}
func (x *GetProfileList) GetProfiles() []string {
if x != nil {
return x.Profiles
@@ -1351,11 +1362,13 @@ type NodeSetParameter struct {
unknownFields protoimpl.UnknownFields
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"`
NetdevDelete string `protobuf:"bytes,2,opt,name=netdevDelete,proto3" json:"netdevDelete,omitempty"`
DiskDelete string `protobuf:"bytes,3,opt,name=diskDelete,proto3" json:"diskDelete,omitempty"`
PartitionDelete string `protobuf:"bytes,4,opt,name=partitionDelete,proto3" json:"partitionDelete,omitempty"`
FilesystemDelete string `protobuf:"bytes,5,opt,name=filesystemDelete,proto3" json:"filesystemDelete,omitempty"`
AllNodes bool `protobuf:"varint,6,opt,name=allNodes,proto3" json:"allNodes,omitempty"`
Force bool `protobuf:"varint,7,opt,name=force,proto3" json:"force,omitempty"`
NodeNames []string `protobuf:"bytes,8,rep,name=nodeNames,proto3" json:"nodeNames,omitempty"`
}
func (x *NodeSetParameter) Reset() {
@@ -1397,16 +1410,30 @@ func (x *NodeSetParameter) GetNodeConfYaml() string {
return ""
}
func (x *NodeSetParameter) GetContainer() string {
func (x *NodeSetParameter) GetNetdevDelete() string {
if x != nil {
return x.Container
return x.NetdevDelete
}
return ""
}
func (x *NodeSetParameter) GetNetdevDelete() string {
func (x *NodeSetParameter) GetDiskDelete() string {
if x != nil {
return x.NetdevDelete
return x.DiskDelete
}
return ""
}
func (x *NodeSetParameter) GetPartitionDelete() string {
if x != nil {
return x.PartitionDelete
}
return ""
}
func (x *NodeSetParameter) GetFilesystemDelete() string {
if x != nil {
return x.FilesystemDelete
}
return ""
}
@@ -1432,6 +1459,111 @@ func (x *NodeSetParameter) GetNodeNames() []string {
return nil
}
// ProfileSetParameter contains all fields for updating aspects of profiles managed. Basically a copy of NodeSetParameters
// by Warewulf.
type ProfileSetParameter struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
NodeConfYaml string `protobuf:"bytes,1,opt,name=nodeConfYaml,proto3" json:"nodeConfYaml,omitempty"`
NetdevDelete string `protobuf:"bytes,2,opt,name=netdevDelete,proto3" json:"netdevDelete,omitempty"`
DiskDelete string `protobuf:"bytes,3,opt,name=diskDelete,proto3" json:"diskDelete,omitempty"`
PartitionDelete string `protobuf:"bytes,4,opt,name=partitionDelete,proto3" json:"partitionDelete,omitempty"`
FilesystemDelete string `protobuf:"bytes,5,opt,name=filesystemDelete,proto3" json:"filesystemDelete,omitempty"`
AllProfiles bool `protobuf:"varint,6,opt,name=allProfiles,proto3" json:"allProfiles,omitempty"`
Force bool `protobuf:"varint,7,opt,name=force,proto3" json:"force,omitempty"`
ProfileNames []string `protobuf:"bytes,8,rep,name=profileNames,proto3" json:"profileNames,omitempty"`
}
func (x *ProfileSetParameter) Reset() {
*x = ProfileSetParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ProfileSetParameter) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ProfileSetParameter) ProtoMessage() {}
func (x *ProfileSetParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[22]
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 ProfileSetParameter.ProtoReflect.Descriptor instead.
func (*ProfileSetParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{22}
}
func (x *ProfileSetParameter) GetNodeConfYaml() string {
if x != nil {
return x.NodeConfYaml
}
return ""
}
func (x *ProfileSetParameter) GetNetdevDelete() string {
if x != nil {
return x.NetdevDelete
}
return ""
}
func (x *ProfileSetParameter) GetDiskDelete() string {
if x != nil {
return x.DiskDelete
}
return ""
}
func (x *ProfileSetParameter) GetPartitionDelete() string {
if x != nil {
return x.PartitionDelete
}
return ""
}
func (x *ProfileSetParameter) GetFilesystemDelete() string {
if x != nil {
return x.FilesystemDelete
}
return ""
}
func (x *ProfileSetParameter) GetAllProfiles() bool {
if x != nil {
return x.AllProfiles
}
return false
}
func (x *ProfileSetParameter) GetForce() bool {
if x != nil {
return x.Force
}
return false
}
func (x *ProfileSetParameter) GetProfileNames() []string {
if x != nil {
return x.ProfileNames
}
return nil
}
// NodeStatus contains information about the imaging status per node.
type NodeStatus struct {
state protoimpl.MessageState
@@ -1448,7 +1580,7 @@ type NodeStatus struct {
func (x *NodeStatus) Reset() {
*x = NodeStatus{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[22]
mi := &file_routes_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1461,7 +1593,7 @@ func (x *NodeStatus) String() string {
func (*NodeStatus) ProtoMessage() {}
func (x *NodeStatus) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[22]
mi := &file_routes_proto_msgTypes[23]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1474,7 +1606,7 @@ func (x *NodeStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatus.ProtoReflect.Descriptor instead.
func (*NodeStatus) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{22}
return file_routes_proto_rawDescGZIP(), []int{23}
}
func (x *NodeStatus) GetNodeName() string {
@@ -1524,7 +1656,7 @@ type NodeStatusResponse struct {
func (x *NodeStatusResponse) Reset() {
*x = NodeStatusResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[23]
mi := &file_routes_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1537,7 +1669,7 @@ func (x *NodeStatusResponse) String() string {
func (*NodeStatusResponse) ProtoMessage() {}
func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[23]
mi := &file_routes_proto_msgTypes[24]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1550,7 +1682,7 @@ func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatusResponse.ProtoReflect.Descriptor instead.
func (*NodeStatusResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{23}
return file_routes_proto_rawDescGZIP(), []int{24}
}
func (x *NodeStatusResponse) GetNodeStatus() []*NodeStatus {
@@ -1574,7 +1706,7 @@ type VersionResponse struct {
func (x *VersionResponse) Reset() {
*x = VersionResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[24]
mi := &file_routes_proto_msgTypes[25]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1587,7 +1719,7 @@ func (x *VersionResponse) String() string {
func (*VersionResponse) ProtoMessage() {}
func (x *VersionResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[24]
mi := &file_routes_proto_msgTypes[25]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1600,7 +1732,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead.
func (*VersionResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{24}
return file_routes_proto_rawDescGZIP(), []int{25}
}
func (x *VersionResponse) GetApiPrefix() string {
@@ -1636,7 +1768,7 @@ type CanWriteConfig struct {
func (x *CanWriteConfig) Reset() {
*x = CanWriteConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[25]
mi := &file_routes_proto_msgTypes[26]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1649,7 +1781,7 @@ func (x *CanWriteConfig) String() string {
func (*CanWriteConfig) ProtoMessage() {}
func (x *CanWriteConfig) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[25]
mi := &file_routes_proto_msgTypes[26]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1662,7 +1794,7 @@ func (x *CanWriteConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use CanWriteConfig.ProtoReflect.Descriptor instead.
func (*CanWriteConfig) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{25}
return file_routes_proto_rawDescGZIP(), []int{26}
}
func (x *CanWriteConfig) GetCanWriteConfig() bool {
@@ -1802,151 +1934,179 @@ var file_routes_proto_rawDesc = []byte{
0x73, 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, 0x99, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65,
0x6f, 0x64, 0x65, 0x73, 0x22, 0xa6, 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,
0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x4d,
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, 0x46, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69,
0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x6c,
0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x6c, 0x6c,
0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x25, 0x0a, 0x0b,
0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 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, 0x7e, 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, 0x14, 0x0a, 0x05, 0x66,
0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x68, 0x61, 0x73, 0x68, 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, 0x48, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x59, 0x61, 0x6d, 0x6c, 0x12,
0x28, 0x0a, 0x0f, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x4d, 0x61, 0x70, 0x59, 0x61,
0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
0x6e, 0x66, 0x4d, 0x61, 0x70, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73,
0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x5d, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 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,
0x12, 0x0b, 0x0a, 0x07, 0x46, 0x75, 0x6c, 0x6c, 0x41, 0x6c, 0x6c, 0x10, 0x05, 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, 0x68, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x6c, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x6c, 0x6c, 0x12, 0x20, 0x0a,
0x0b, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x75, 0x6c, 0x6c, 0x41, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x52, 0x0b, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x75, 0x6c, 0x6c, 0x41, 0x6c, 0x6c, 0x12,
0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x25, 0x0a, 0x0b, 0x50,
0x72, 0x6f, 0x66, 0x69, 0x6c, 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, 0x7e, 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, 0x14, 0x0a, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x68, 0x61, 0x73, 0x68, 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, 0x48, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x28,
0x0a, 0x0f, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x4d, 0x61, 0x70, 0x59, 0x61, 0x6d,
0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e,
0x66, 0x4d, 0x61, 0x70, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x5d, 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, 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,
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f,
0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xa0, 0x02, 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, 0x22, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64,
0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x73, 0x6b,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69,
0x73, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x69,
0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a,
0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
0x52, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x18, 0x07, 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, 0x08, 0x20,
0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xaf,
0x02, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 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, 0x22, 0x0a, 0x0c, 0x6e, 0x65,
0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1e,
0x0a, 0x0a, 0x64, 0x69, 0x73, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x73, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x28,
0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65,
0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x66, 0x69,
0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x50, 0x72,
0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18,
0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 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,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x38, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x57, 0x72,
0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x61, 0x6e,
0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0e, 0x63, 0x61, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 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, 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,
0x22, 0x38, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x63, 0x61, 0x6e, 0x57,
0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 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, 0x77, 0x77, 0x61, 0x70, 0x69,
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,
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 (
@@ -1962,7 +2122,7 @@ func file_routes_proto_rawDescGZIP() []byte {
}
var file_routes_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 32)
var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
var file_routes_proto_goTypes = []interface{}{
(GetNodeList_ListType)(0), // 0: wwapi.v1.GetNodeList.ListType
(*NodeDBHash)(nil), // 1: wwapi.v1.NodeDBHash
@@ -1987,29 +2147,30 @@ var file_routes_proto_goTypes = []interface{}{
(*NodeYaml)(nil), // 20: wwapi.v1.NodeYaml
(*NodeDeleteParameter)(nil), // 21: wwapi.v1.NodeDeleteParameter
(*NodeSetParameter)(nil), // 22: wwapi.v1.NodeSetParameter
(*NodeStatus)(nil), // 23: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 24: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 25: wwapi.v1.VersionResponse
(*CanWriteConfig)(nil), // 26: wwapi.v1.CanWriteConfig
nil, // 27: wwapi.v1.NetDev.FieldEntry
nil, // 28: wwapi.v1.NetDev.TagsEntry
nil, // 29: wwapi.v1.NodeInfo.FieldsEntry
nil, // 30: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 31: wwapi.v1.NodeInfo.TagsEntry
nil, // 32: wwapi.v1.NodeInfo.KeysEntry
(*empty.Empty)(nil), // 33: google.protobuf.Empty
(*ProfileSetParameter)(nil), // 23: wwapi.v1.ProfileSetParameter
(*NodeStatus)(nil), // 24: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 25: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 26: wwapi.v1.VersionResponse
(*CanWriteConfig)(nil), // 27: wwapi.v1.CanWriteConfig
nil, // 28: wwapi.v1.NetDev.FieldEntry
nil, // 29: wwapi.v1.NetDev.TagsEntry
nil, // 30: wwapi.v1.NodeInfo.FieldsEntry
nil, // 31: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 32: wwapi.v1.NodeInfo.TagsEntry
nil, // 33: wwapi.v1.NodeInfo.KeysEntry
(*empty.Empty)(nil), // 34: google.protobuf.Empty
}
var file_routes_proto_depIdxs = []int32{
5, // 0: wwapi.v1.ContainerListResponse.containers:type_name -> wwapi.v1.ContainerInfo
27, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
28, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
29, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
30, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
31, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
32, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
28, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
29, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
30, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
31, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
32, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
33, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
13, // 7: wwapi.v1.NodeListResponse.nodes:type_name -> wwapi.v1.NodeInfo
0, // 8: wwapi.v1.GetNodeList.type:type_name -> wwapi.v1.GetNodeList.ListType
23, // 9: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
24, // 9: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
11, // 10: wwapi.v1.NetDev.FieldEntry.value:type_name -> wwapi.v1.NodeField
11, // 11: wwapi.v1.NetDev.TagsEntry.value:type_name -> wwapi.v1.NodeField
11, // 12: wwapi.v1.NodeInfo.FieldsEntry.value:type_name -> wwapi.v1.NodeField
@@ -2019,25 +2180,25 @@ var file_routes_proto_depIdxs = []int32{
2, // 16: wwapi.v1.WWApi.ContainerBuild:input_type -> wwapi.v1.ContainerBuildParameter
3, // 17: wwapi.v1.WWApi.ContainerDelete:input_type -> wwapi.v1.ContainerDeleteParameter
4, // 18: wwapi.v1.WWApi.ContainerImport:input_type -> wwapi.v1.ContainerImportParameter
33, // 19: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
34, // 19: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
7, // 20: wwapi.v1.WWApi.ContainerShow:input_type -> wwapi.v1.ContainerShowParameter
19, // 21: wwapi.v1.WWApi.NodeAdd:input_type -> wwapi.v1.NodeAddParameter
21, // 22: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter
10, // 23: wwapi.v1.WWApi.NodeList:input_type -> wwapi.v1.NodeNames
22, // 24: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.NodeSetParameter
10, // 25: wwapi.v1.WWApi.NodeStatus:input_type -> wwapi.v1.NodeNames
33, // 26: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
34, // 26: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
6, // 27: wwapi.v1.WWApi.ContainerBuild:output_type -> wwapi.v1.ContainerListResponse
33, // 28: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
34, // 28: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
6, // 29: wwapi.v1.WWApi.ContainerImport:output_type -> wwapi.v1.ContainerListResponse
6, // 30: wwapi.v1.WWApi.ContainerList:output_type -> wwapi.v1.ContainerListResponse
8, // 31: wwapi.v1.WWApi.ContainerShow:output_type -> wwapi.v1.ContainerShowResponse
14, // 32: wwapi.v1.WWApi.NodeAdd:output_type -> wwapi.v1.NodeListResponse
33, // 33: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
34, // 33: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
14, // 34: wwapi.v1.WWApi.NodeList:output_type -> wwapi.v1.NodeListResponse
14, // 35: wwapi.v1.WWApi.NodeSet:output_type -> wwapi.v1.NodeListResponse
24, // 36: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
25, // 37: wwapi.v1.WWApi.Version:output_type -> wwapi.v1.VersionResponse
25, // 36: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
26, // 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
@@ -2316,7 +2477,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatus); i {
switch v := v.(*ProfileSetParameter); i {
case 0:
return &v.state
case 1:
@@ -2328,7 +2489,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatusResponse); i {
switch v := v.(*NodeStatus); i {
case 0:
return &v.state
case 1:
@@ -2340,7 +2501,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*VersionResponse); i {
switch v := v.(*NodeStatusResponse); i {
case 0:
return &v.state
case 1:
@@ -2352,6 +2513,18 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*VersionResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_routes_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CanWriteConfig); i {
case 0:
return &v.state
@@ -2370,7 +2543,7 @@ func file_routes_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_routes_proto_rawDesc,
NumEnums: 1,
NumMessages: 32,
NumMessages: 33,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -17,46 +17,48 @@ must be called, as the commandline parser returns e.g. netip.IP objects which mu
back to strings.
*/
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) (converters []func() error) {
/*
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
*/
return RecursiveCreateFlags(nodeConf, baseCmd, excludeList)
}
func RecursiveCreateFlags(obj interface{}, baseCmd *cobra.Command, excludeList []string) (converters []func() error) {
// now iterate of every field
nodeInfoType := reflect.TypeOf(obj)
nodeInfoVal := reflect.ValueOf(obj)
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
if nodeInfoType.Elem().Field(i).Tag.Get("comment") != "" &&
!util.InSlice(excludeList, nodeInfoType.Elem().Field(i).Tag.Get("lopt")) {
field := nodeInfoVal.Elem().Field(i)
converters = append(converters, createFlags(baseCmd, excludeList, nodeInfoType.Elem().Field(i), &field)...)
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
nestVal := reflect.ValueOf(nodeInfoVal.Elem().Field(i).Interface())
for j := 0; j < nestType.Elem().NumField(); j++ {
field := nestVal.Elem().Field(j)
converters = append(converters, createFlags(baseCmd, excludeList, nestType.Elem().Field(j), &field)...)
newConv := RecursiveCreateFlags(nodeInfoVal.Elem().Field(i).Interface(), baseCmd, excludeList)
converters = append(converters, newConv...)
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Map &&
nodeInfoType.Elem().Field(i).Type != reflect.TypeOf(map[string]string{}) {
// add a map with key UNDEF so that it can hold values N.B. UNDEF can never be added through command line
key := reflect.ValueOf("UNDEF")
if nodeInfoVal.Elem().Field(i).Len() == 0 {
if nodeInfoVal.Elem().Field(i).IsNil() {
nodeInfoVal.Elem().Field(i).Set(reflect.MakeMap(nodeInfoType.Elem().Field(i).Type))
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
// add a default network so that it can hold values
key := "default"
if len(netMap) == 0 {
netMap[key] = new(NetDevs)
newPtr := reflect.New(nodeInfoType.Elem().Field(i).Type.Elem().Elem())
nodeInfoVal.Elem().Field(i).SetMapIndex(key, newPtr)
} else {
for keyIt := range netMap {
key = keyIt
break
}
}
netType := reflect.TypeOf(netMap[key])
netVal := reflect.ValueOf(netMap[key])
for j := 0; j < netType.Elem().NumField(); j++ {
field := netVal.Elem().Field(j)
converters = append(converters, createFlags(baseCmd, excludeList, netType.Elem().Field(j), &field)...)
key = nodeInfoVal.Elem().Field(i).MapKeys()[0]
}
newConv := RecursiveCreateFlags(nodeInfoVal.Elem().Field(i).MapIndex(key).Interface(), baseCmd, excludeList)
converters = append(converters, newConv...)
}
}
return converters
}
/*
Helper function to create the different PerisitantFlags() for different types.
Helper function to create the different PersistentFlags() for different types.
*/
func createFlags(baseCmd *cobra.Command, excludeList []string,
myType reflect.StructField, myVal *reflect.Value) (converters []func() error) {

79
internal/pkg/node/list.go Normal file
View File

@@ -0,0 +1,79 @@
package node
import (
"reflect"
)
/*
struct to hold the fields of GetFields
*/
type NodeFields struct {
Field string
Source string
Value string
}
/*
Get all the info out of NodeInfo. If emptyFields is set true, all fields
are shown not only the ones with effective values
*/
func (node *NodeInfo) GetFields(emptyFields bool) (output []NodeFields) {
return recursiveFields(node, emptyFields, "")
}
/*
Internal function which travels through all fields of a NodeInfo and for this
reason needs tb called via interface{}
*/
func recursiveFields(obj interface{}, emptyFields bool, prefix string) (output []NodeFields) {
valObj := reflect.ValueOf(obj)
typeObj := reflect.TypeOf(obj)
for i := 0; i < typeObj.Elem().NumField(); i++ {
if typeObj.Elem().Field(i).Type == reflect.TypeOf(Entry{}) {
myField := valObj.Elem().Field(i).Interface().(Entry)
if emptyFields || myField.Get() != "" {
output = append(output, NodeFields{
Field: prefix + typeObj.Elem().Field(i).Name,
Source: myField.Source(),
Value: myField.Print(),
})
}
} else if typeObj.Elem().Field(i).Type == reflect.TypeOf(map[string]*Entry{}) {
for key, val := range valObj.Elem().Field(i).Interface().(map[string]*Entry) {
if emptyFields || val.Get() != "" {
output = append(output, NodeFields{
Field: prefix + typeObj.Elem().Field(i).Name + "[" + key + "]",
Source: val.Source(),
Value: val.Print(),
})
}
}
if valObj.Elem().Field(i).Len() == 0 && emptyFields {
output = append(output, NodeFields{
Field: prefix + typeObj.Elem().Field(i).Name + "[]",
})
}
} else if typeObj.Elem().Field(i).Type.Kind() == reflect.Map {
mapIter := valObj.Elem().Field(i).MapRange()
for mapIter.Next() {
nestedOut := recursiveFields(mapIter.Value().Interface(), emptyFields, prefix+typeObj.Elem().Field(i).Name+"["+mapIter.Key().String()+"].")
if len(nestedOut) == 0 {
output = append(output, NodeFields{
Field: prefix + typeObj.Elem().Field(i).Name + "[" + mapIter.Key().String() + "]",
})
} else {
output = append(output, nestedOut...)
}
}
if valObj.Elem().Field(i).Len() == 0 && emptyFields {
output = append(output, NodeFields{
Field: prefix + typeObj.Elem().Field(i).Name + "[]",
})
}
} else if typeObj.Elem().Field(i).Type.Kind() == reflect.Ptr {
nestedOut := recursiveFields(valObj.Elem().Field(i).Interface(), emptyFields, prefix+typeObj.Elem().Field(i).Name+".")
output = append(output, nestedOut...)
}
}
return
}

View File

@@ -399,12 +399,15 @@ func GetByName(node interface{}, name string) (string, error) {
/*
Check if the Netdev is empty, so has no values set
*/
func (dev *NetDevs) Empty() bool {
if dev == nil {
func ObjectIsEmpty(obj interface{}) bool {
if obj == nil {
return true
}
varType := reflect.TypeOf(*dev)
varVal := reflect.ValueOf(*dev)
varType := reflect.TypeOf(obj)
varVal := reflect.ValueOf(obj)
if varType.Kind() == reflect.Ptr && !varVal.IsNil() {
return ObjectIsEmpty(varVal.Elem().Interface())
}
if varVal.IsZero() {
return true
}
@@ -418,6 +421,10 @@ func (dev *NetDevs) Empty() bool {
if len(varVal.Field(i).Interface().(map[string]string)) != 0 {
return false
}
} else if varType.Field(i).Type.Kind() == reflect.Ptr {
if !ObjectIsEmpty(varVal.Field(i).Interface()) {
return false
}
}
}
return true

View File

@@ -7,25 +7,25 @@ func Test_Empty(t *testing.T) {
var netdevPtr *NetDevs
t.Run("test for empty", func(t *testing.T) {
if netdev.Empty() != true {
if ObjectIsEmpty(netdev) != true {
t.Errorf("netdev must be empty")
}
})
t.Run("test for non empty", func(t *testing.T) {
netdev.Device = "foo"
if netdev.Empty() == true {
if ObjectIsEmpty(netdev) == true {
t.Errorf("netdev must be non empty")
}
})
t.Run("test for nil pointer", func(t *testing.T) {
if netdevPtr.Empty() != true {
if ObjectIsEmpty(netdevPtr) != true {
t.Errorf("netdev must be empty")
}
})
t.Run("test for pointer assigned", func(t *testing.T) {
netdev.Ipaddr = "10.10.10.1"
netdevPtr = &netdev
if netdevPtr.Empty() == true {
if ObjectIsEmpty(netdevPtr) == true {
t.Errorf("netdev must be empty")
}
})

View File

@@ -256,63 +256,47 @@ func recursiveFlatten(strct interface{}) {
}
/*
Create a string slice, where every element represents a yaml entry
Create a string slice, where every element represents a yaml entry, used for node/profile edit
in order to get a summary of all available elements
*/
func (nodeConf *NodeConf) UnmarshalConf(excludeList []string) (lines []string) {
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
func UnmarshalConf(obj interface{}, excludeList []string) (lines []string) {
objType := reflect.TypeOf(obj)
// now iterate of every field
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
if nodeInfoType.Elem().Field(i).Tag.Get("lopt") != "" {
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
for i := 0; i < objType.NumField(); i++ {
if objType.Field(i).Tag.Get("comment") != "" {
if ymlStr, ok := getYamlString(objType.Field(i), excludeList); ok {
lines = append(lines, ymlStr...)
}
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
lines = append(lines, ymlStr...)
}
for j := 0; j < nestType.Elem().NumField(); j++ {
if nestType.Elem().Field(j).Tag.Get("lopt") != "" &&
!util.InSlice(excludeList, nestType.Elem().Field(j).Tag.Get("lopt")) {
if ymlStr, ok := getYamlString(nestType.Elem().Field(j), excludeList); ok {
for _, str := range ymlStr {
lines = append(lines, " "+str)
if objType.Field(i).Type.Kind() == reflect.Ptr && objType.Field(i).Tag.Get("yaml") != "" {
typeLine := objType.Field(i).Tag.Get("yaml")
if len(strings.Split(typeLine, ",")) > 1 {
typeLine = strings.Split(typeLine, ",")[0] + ":"
}
lines = append(lines, typeLine)
nestedLine := UnmarshalConf(reflect.New(objType.Field(i).Type.Elem()).Elem().Interface(), excludeList)
for _, ln := range nestedLine {
lines = append(lines, " "+ln)
}
} else if objType.Field(i).Type.Kind() == reflect.Map && objType.Field(i).Type.Elem().Kind() == reflect.Ptr {
typeLine := objType.Field(i).Tag.Get("yaml")
if len(strings.Split(typeLine, ",")) > 1 {
typeLine = strings.Split(typeLine, ",")[0] + ":"
}
lines = append(lines, typeLine, " element:")
nestedLine := UnmarshalConf(reflect.New(objType.Field(i).Type.Elem().Elem()).Elem().Interface(), excludeList)
for _, ln := range nestedLine {
lines = append(lines, " "+ln)
}
}
}
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
// add a default network so that it can hold values
key := "default"
if len(netMap) == 0 {
netMap[key] = new(NetDevs)
} else {
for keyIt := range netMap {
key = keyIt
break
}
}
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
lines = append(lines, ymlStr[0]+":", " "+key+":")
netType := reflect.TypeOf(netMap[key])
for j := 0; j < netType.Elem().NumField(); j++ {
if ymlStr, ok := getYamlString(netType.Elem().Field(j), excludeList); ok {
for _, str := range ymlStr {
lines = append(lines, " "+str)
}
}
} // lines
} // this
} //not
} //do
return lines
}
/*
Get the string of the yaml tag
*/
func getYamlString(myType reflect.StructField, excludeList []string) ([]string, bool) {
ymlStr := myType.Tag.Get("yaml")
if len(strings.Split(ymlStr, ",")) > 1 {
@@ -320,11 +304,15 @@ func getYamlString(myType reflect.StructField, excludeList []string) ([]string,
}
if util.InSlice(excludeList, ymlStr) {
return []string{""}, false
} else if myType.Tag.Get("lopt") == "" && myType.Type.Kind() == reflect.String {
} else if myType.Tag.Get("comment") == "" && myType.Type.Kind() == reflect.String {
return []string{""}, false
}
if myType.Type.Kind() == reflect.String {
ymlStr += ": string"
fieldType := myType.Tag.Get("type")
if fieldType == "" {
fieldType = "string"
}
ymlStr += ": " + fieldType
return []string{ymlStr}, true
} else if myType.Type == reflect.TypeOf([]string{}) {
return []string{ymlStr + ":", " - string"}, true
@@ -347,7 +335,6 @@ func (nodeConf *NodeConf) SetLopt(lopt string, value string) (found bool) {
nodeInfoVal := reflect.ValueOf(nodeConf)
// try to find the normal fields, networks come later
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
//fmt.Println(nodeInfoType.Elem().Field(i).Tag.Get("lopt"), lopt)
if nodeInfoType.Elem().Field(i).Tag.Get("lopt") == lopt {
if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.String {
wwlog.Verbose("Found lopt %s mapping to %s, setting to %s\n",