VOL-2168 - add the ability to specify default formats and ordering
Change-Id: Ie867bbd8d055e34f26eb43466a92f1d1954e35d4
diff --git a/Makefile b/Makefile
index 62332d7..fc0ea52 100644
--- a/Makefile
+++ b/Makefile
@@ -155,7 +155,7 @@
endif
@rm -rf ./sca-report
@mkdir -p ./sca-report
- $(GOLANGCI_LINT_TOOL) run --out-format $(GOLANGCI_LINT_OUT_FORMAT) ./... 2>&1 | tee ./sca-report/sca-report.xml
+ $(GOLANGCI_LINT_TOOL) run --deadline 20m --out-format $(GOLANGCI_LINT_OUT_FORMAT) ./... 2>&1 | tee ./sca-report/sca-report.xml
test:
@mkdir -p ./tests/results
diff --git a/README.md b/README.md
index 1966af9..8e2ea55 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,15 @@
`--outputas` or `-o` command line option. Valid values for this options are
`table`, `json`, or `yaml`.
+## Overriding Default Command Format and Order
+The default format and ordering of commands can be overriden (specified) by
+the command line options, but they can also be set via a configuration file so
+that the overrides don't have to be specified on each invocation. By default
+the file `~/.volt/command_options` is loaded, but the file used can also be
+specified by the environment variable `VOLTCTL_COMMAND_OPTIONS` or via
+the command line arguments. A samle of this file is include in the
+repository as `voltctl_command_options.config`.
+
### Examples
```
voltctl adapter list
diff --git a/cmd/voltctl/voltctl.go b/cmd/voltctl/voltctl.go
index caa0f40..5b70bac 100644
--- a/cmd/voltctl/voltctl.go
+++ b/cmd/voltctl/voltctl.go
@@ -42,11 +42,12 @@
if len(compval) > 0 {
os.Unsetenv("GO_FLAGS_COMPLETION")
pp := flags.NewNamedParser(path.Base(os.Args[0]), flags.Default|flags.PassAfterNonOption)
- _, err := pp.AddGroup("Global Options", "", &commands.GlobalOptions)
- if err != nil {
- panic(err)
+ if _, err := pp.AddGroup("Global Options", "", &commands.GlobalOptions); err != nil {
+ commands.Error.Fatalf("Unable to set up global options for command completion: %s", err.Error())
}
- pp.Parse()
+ if _, err := pp.Parse(); err != nil {
+ commands.Error.Fatalf("Unable to parse command line options for command completion: %s", err.Error())
+ }
os.Setenv("GO_FLAGS_COMPLETION", compval)
}
diff --git a/internal/pkg/commands/adapter.go b/internal/pkg/commands/adapter.go
index 067b64c..b777889 100644
--- a/internal/pkg/commands/adapter.go
+++ b/internal/pkg/commands/adapter.go
@@ -22,7 +22,6 @@
"github.com/jhump/protoreflect/dynamic"
"github.com/opencord/voltctl/pkg/format"
"github.com/opencord/voltctl/pkg/model"
- "log"
)
const (
@@ -41,7 +40,7 @@
func RegisterAdapterCommands(parent *flags.Parser) {
if _, err := parent.AddCommand("adapter", "adapter commands", "Commands to query and manipulate VOLTHA adapters", &adapterOpts); err != nil {
- log.Fatalf("Unexpected error while attempting to register adapter commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register adapter commands : %s", err)
}
}
@@ -81,12 +80,15 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_OUTPUT_FORMAT
+ outputFormat = GetCommandOptionWithDefault("adapter-list", "format", DEFAULT_OUTPUT_FORMAT)
}
-
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("adapter-list", "order", "")
+ }
data := make([]model.Adapter, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
@@ -96,7 +98,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index 2331163..a4e298e 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -82,19 +82,27 @@
},
}
+ GlobalCommandOptions = make(map[string]map[string]string)
+
GlobalOptions struct {
Config string `short:"c" long:"config" env:"VOLTCONFIG" value-name:"FILE" default:"" description:"Location of client config file"`
Server string `short:"s" long:"server" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of VOLTHA"`
// Do not set the default for the API version here, else it will override the value read in the config
- ApiVersion string `short:"a" long:"apiversion" description:"API version" value-name:"VERSION" choice:"v1" choice:"v2"`
- Debug bool `short:"d" long:"debug" description:"Enable debug mode"`
- UseTLS bool `long:"tls" description:"Use TLS"`
- CACert string `long:"tlscacert" value-name:"CA_CERT_FILE" description:"Trust certs signed only by this CA"`
- Cert string `long:"tlscert" value-name:"CERT_FILE" description:"Path to TLS vertificate file"`
- Key string `long:"tlskey" value-name:"KEY_FILE" description:"Path to TLS key file"`
- Verify bool `long:"tlsverify" description:"Use TLS and verify the remote"`
- K8sConfig string `short:"8" long:"k8sconfig" env:"KUBECONFIG" value-name:"FILE" default:"" description:"Location of Kubernetes config file"`
+ ApiVersion string `short:"a" long:"apiversion" description:"API version" value-name:"VERSION" choice:"v1" choice:"v2"`
+ Debug bool `short:"d" long:"debug" description:"Enable debug mode"`
+ UseTLS bool `long:"tls" description:"Use TLS"`
+ CACert string `long:"tlscacert" value-name:"CA_CERT_FILE" description:"Trust certs signed only by this CA"`
+ Cert string `long:"tlscert" value-name:"CERT_FILE" description:"Path to TLS vertificate file"`
+ Key string `long:"tlskey" value-name:"KEY_FILE" description:"Path to TLS key file"`
+ Verify bool `long:"tlsverify" description:"Use TLS and verify the remote"`
+ K8sConfig string `short:"8" long:"k8sconfig" env:"KUBECONFIG" value-name:"FILE" default:"" description:"Location of Kubernetes config file"`
+ CommandOptions string `short:"o" long:"command-options" env:"VOLTCTL_COMMAND_OPTIONS" value-name:"FILE" default:"" description:"Location of command options default configuration file"`
}
+
+ Debug = log.New(os.Stdout, "DEBUG: ", 0)
+ Info = log.New(os.Stdout, "INFO: ", 0)
+ Warn = log.New(os.Stderr, "WARN: ", 0)
+ Error = log.New(os.Stderr, "ERROR: ", 0)
)
type OutputOptions struct {
@@ -145,25 +153,34 @@
Data interface{}
}
+func GetCommandOptionWithDefault(name, option, defaultValue string) string {
+ if cmd, ok := GlobalCommandOptions[name]; ok {
+ if val, ok := cmd[option]; ok {
+ return CharReplacer.Replace(val)
+ }
+ }
+ return defaultValue
+}
+
func ProcessGlobalOptions() {
if len(GlobalOptions.Config) == 0 {
home, err := os.UserHomeDir()
if err != nil {
- log.Printf("Unable to discover they users home directory: %s\n", err)
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
home = "~"
}
GlobalOptions.Config = filepath.Join(home, ".volt", "config")
}
- info, err := os.Stat(GlobalOptions.Config)
- if err == nil && !info.IsDir() {
+ if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
configFile, err := ioutil.ReadFile(GlobalOptions.Config)
if err != nil {
- log.Printf("configFile.Get err #%v ", err)
+ Error.Fatalf("Unable to read the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
}
- err = yaml.Unmarshal(configFile, &GlobalConfig)
- if err != nil {
- log.Fatalf("Unmarshal: %v", err)
+ if err = yaml.Unmarshal(configFile, &GlobalConfig); err != nil {
+ Error.Fatalf("Unable to parse the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
}
}
@@ -180,11 +197,32 @@
if len(GlobalOptions.K8sConfig) == 0 {
home, err := os.UserHomeDir()
if err != nil {
- log.Printf("Unable to discover the user's home directory: %s\n", err)
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
home = "~"
}
GlobalOptions.K8sConfig = filepath.Join(home, ".kube", "config")
}
+
+ if len(GlobalOptions.CommandOptions) == 0 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
+ home = "~"
+ }
+ GlobalOptions.CommandOptions = filepath.Join(home, ".volt", "command_options")
+ }
+
+ if info, err := os.Stat(GlobalOptions.CommandOptions); err == nil && !info.IsDir() {
+ optionsFile, err := ioutil.ReadFile(GlobalOptions.CommandOptions)
+ if err != nil {
+ Error.Fatalf("Unable to read command options configuration file '%s' : %s",
+ GlobalOptions.CommandOptions, err.Error())
+ }
+ if err = yaml.Unmarshal(optionsFile, &GlobalCommandOptions); err != nil {
+ Error.Fatalf("Unable to parse the command line options configuration file '%s': %s",
+ GlobalOptions.CommandOptions, err.Error())
+ }
+ }
}
func NewConnection() (*grpc.ClientConn, error) {
@@ -218,7 +256,7 @@
if result.OutputAs == OUTPUT_TABLE {
tableFormat := format.Format(result.Format)
if err := tableFormat.Execute(os.Stdout, true, result.NameLimit, data); err != nil {
- log.Fatalf("Unexpected error while attempting to format results as table : %s", err)
+ Error.Fatalf("Unexpected error while attempting to format results as table : %s", err)
}
} else if result.OutputAs == OUTPUT_JSON {
asJson, err := json.Marshal(&data)
diff --git a/internal/pkg/commands/completion.go b/internal/pkg/commands/completion.go
index 17de063..0052a10 100644
--- a/internal/pkg/commands/completion.go
+++ b/internal/pkg/commands/completion.go
@@ -19,7 +19,6 @@
"fmt"
flags "github.com/jessevdk/go-flags"
"github.com/opencord/voltctl/internal/pkg/completion"
- "log"
)
type BashOptions struct{}
@@ -30,7 +29,7 @@
func RegisterCompletionCommands(parent *flags.Parser) {
if _, err := parent.AddCommand("completion", "generate shell compleition", "Commands to generate shell compleition information", &CompletionOptions{}); err != nil {
- log.Fatalf("Unexpected error while attempting to register completion commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register completion commands : %s", err)
}
}
diff --git a/internal/pkg/commands/components.go b/internal/pkg/commands/components.go
index 95cbd80..4501f1f 100644
--- a/internal/pkg/commands/components.go
+++ b/internal/pkg/commands/components.go
@@ -23,7 +23,6 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
- "log"
)
const (
@@ -44,7 +43,7 @@
func RegisterComponentCommands(parser *flags.Parser) {
if _, err := parser.AddCommand("component", "component instance commands", "Commands to query and manipulate VOLTHA component instances", &componentOpts); err != nil {
- log.Fatalf("Unexpected error while attempting to register component commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register component commands : %s", err)
}
}
@@ -80,11 +79,16 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_COMPONENT_FORMAT
+ outputFormat = GetCommandOptionWithDefault("component-list", "format", DEFAULT_COMPONENT_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Metadata.Name}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("component-list", "order", "")
+ }
+
data := make([]model.ComponentInstance, len(pods.Items))
for i, item := range pods.Items {
data[i].PopulateFrom(item)
@@ -93,7 +97,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
diff --git a/internal/pkg/commands/config.go b/internal/pkg/commands/config.go
index aadc9d2..3ba4118 100644
--- a/internal/pkg/commands/config.go
+++ b/internal/pkg/commands/config.go
@@ -19,7 +19,6 @@
"fmt"
flags "github.com/jessevdk/go-flags"
"gopkg.in/yaml.v2"
- "log"
)
const copyrightNotice = `
@@ -39,12 +38,17 @@
#
`
+type CommandOptionsDump struct{}
+
type ConfigOptions struct {
+ Commands CommandOptionsDump `command:"commands"`
}
func RegisterConfigCommands(parent *flags.Parser) {
- if _, err := parent.AddCommand("config", "generate voltctl configuration", "Commands to generate voltctl configuration", &ConfigOptions{}); err != nil {
- log.Fatalf("Unexpected error while attempting to register config commands : %s", err)
+ if command, err := parent.AddCommand("config", "generate voltctl configuration", "Commands to generate voltctl configuration", &ConfigOptions{}); err != nil {
+ Error.Fatalf("Unexpected error while attempting to register config commands : %s", err)
+ } else {
+ command.SubcommandsOptional = true
}
}
@@ -59,3 +63,14 @@
fmt.Println(string(b))
return nil
}
+
+func (commands *CommandOptionsDump) Execute(args []string) error {
+ ProcessGlobalOptions()
+ b, err := yaml.Marshal(GlobalCommandOptions)
+ if err != nil {
+ return err
+ }
+ fmt.Println(copyrightNotice)
+ fmt.Println(string(b))
+ return nil
+}
diff --git a/internal/pkg/commands/devicegroups.go b/internal/pkg/commands/devicegroups.go
index 7314b0a..4d206c7 100644
--- a/internal/pkg/commands/devicegroups.go
+++ b/internal/pkg/commands/devicegroups.go
@@ -22,7 +22,6 @@
"github.com/jhump/protoreflect/dynamic"
"github.com/opencord/voltctl/pkg/format"
"github.com/opencord/voltctl/pkg/model"
- "log"
)
const (
@@ -42,7 +41,7 @@
func RegisterDeviceGroupCommands(parser *flags.Parser) {
if _, err := parser.AddCommand("devicegroup", "device group commands", "Commands to query and manipulate VOLTHA device groups",
&deviceGroupOpts); err != nil {
- log.Fatalf("Unexpected error while attempting to register device group commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register device group commands : %s", err)
}
}
@@ -54,7 +53,7 @@
}
defer conn.Close()
- descriptor, method, err := GetMethod("devicegroup-list")
+ descriptor, method, err := GetMethod("device-group-list")
if err != nil {
return err
}
@@ -84,11 +83,15 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_DEVICE_GROUP_FORMAT
+ outputFormat = GetCommandOptionWithDefault("device-group-list", "format", DEFAULT_DEVICE_GROUP_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("device-group-list", "order", "")
+ }
data := make([]model.DeviceGroup, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
@@ -99,7 +102,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index 78d1aca..ac6d508 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -23,7 +23,6 @@
"github.com/jhump/protoreflect/dynamic"
"github.com/opencord/voltctl/pkg/format"
"github.com/opencord/voltctl/pkg/model"
- "log"
"strings"
)
@@ -115,7 +114,7 @@
func RegisterDeviceCommands(parser *flags.Parser) {
if _, err := parser.AddCommand("device", "device commands", "Commands to query and manipulate VOLTHA devices", &deviceOpts); err != nil {
- log.Fatalf("Unexpected error while attempting to register device commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register device commands : %s", err)
}
}
@@ -204,12 +203,17 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_DEVICE_FORMAT
+ outputFormat = GetCommandOptionWithDefault("device-list", "format", DEFAULT_DEVICE_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("device-list", "order", "")
+ }
+
data := make([]model.Device, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
val := item.(*dynamic.Message)
@@ -219,7 +223,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
@@ -450,12 +454,17 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_DEVICE_PORTS_FORMAT
+ outputFormat = GetCommandOptionWithDefault("device-ports", "format", DEFAULT_DEVICE_PORTS_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("device-ports", "order", "")
+ }
+
data := make([]model.DevicePort, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
data[i].PopulateFrom(item.(*dynamic.Message))
@@ -464,7 +473,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
@@ -478,7 +487,7 @@
fl := &FlowList{}
fl.ListOutputOptions = options.ListOutputOptions
fl.Args.Id = string(options.Args.Id)
- fl.Method = "device-flow-list"
+ fl.Method = "device-flows"
return fl.Execute(args)
}
@@ -521,7 +530,7 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_DEVICE_INSPECT_FORMAT
+ outputFormat = GetCommandOptionWithDefault("device-inspect", "format", DEFAULT_DEVICE_INSPECT_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
diff --git a/internal/pkg/commands/flows.go b/internal/pkg/commands/flows.go
index d16abab..bfb82dc 100644
--- a/internal/pkg/commands/flows.go
+++ b/internal/pkg/commands/flows.go
@@ -114,8 +114,8 @@
defer conn.Close()
switch options.Method {
- case "device-flow-list":
- case "logical-device-flow-list":
+ case "device-flows":
+ case "logical-device-flows":
default:
panic(fmt.Errorf("Unknown method name: '%s'", options.Method))
}
@@ -165,13 +165,18 @@
if options.Quiet {
outputFormat = "{{.Id}}"
} else if outputFormat == "" {
- outputFormat = buildOutputFormat(fieldset, model.FLOW_FIELD_STATS)
+ outputFormat = GetCommandOptionWithDefault(options.Method, "format", buildOutputFormat(fieldset, model.FLOW_FIELD_STATS))
+ }
+
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault(options.Method, "order", "")
}
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
diff --git a/internal/pkg/commands/funcmap.go b/internal/pkg/commands/funcmap.go
index 7f479df..f60d297 100644
--- a/internal/pkg/commands/funcmap.go
+++ b/internal/pkg/commands/funcmap.go
@@ -102,7 +102,7 @@
"v1": "voltha.VolthaGlobalService/GetDevice",
"v2": "voltha.VolthaService/GetDevice",
},
- "device-flow-list": {
+ "device-flows": {
"v1": "voltha.VolthaGlobalService/ListDeviceFlows",
"v2": "voltha.VolthaService/ListDeviceFlows",
},
@@ -114,7 +114,7 @@
"v1": "voltha.VolthaGlobalService/ListLogicalDevicePorts",
"v2": "voltha.VolthaService/ListLogicalDevicePorts",
},
- "logical-device-flow-list": {
+ "logical-device-flows": {
"v1": "voltha.VolthaGlobalService/ListLogicalDeviceFlows",
"v2": "voltha.VolthaService/ListLogicalDeviceFlows",
},
@@ -122,7 +122,7 @@
"v1": "voltha.VolthaGlobalService/GetLogicalDevice",
"v2": "voltha.VolthaService/GetLogicalDevice",
},
- "devicegroup-list": {
+ "device-group-list": {
"v1": "voltha.VolthaGlobalService/ListDeviceGroups",
"v2": "voltha.VolthaService/ListDeviceGroups",
},
diff --git a/internal/pkg/commands/logicaldevices.go b/internal/pkg/commands/logicaldevices.go
index 16cd48a..cecd5ec 100644
--- a/internal/pkg/commands/logicaldevices.go
+++ b/internal/pkg/commands/logicaldevices.go
@@ -23,7 +23,6 @@
"github.com/jhump/protoreflect/dynamic"
"github.com/opencord/voltctl/pkg/format"
"github.com/opencord/voltctl/pkg/model"
- "log"
"strings"
)
@@ -74,7 +73,7 @@
func RegisterLogicalDeviceCommands(parser *flags.Parser) {
if _, err := parser.AddCommand("logicaldevice", "logical device commands", "Commands to query and manipulate VOLTHA logical devices", &logicalDeviceOpts); err != nil {
- log.Fatalf("Unexpected error while attempting to register logical device commands : %s", err)
+ Error.Fatalf("Unexpected error while attempting to register logical device commands : %s", err)
}
}
@@ -163,11 +162,15 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_LOGICAL_DEVICE_FORMAT
+ outputFormat = GetCommandOptionWithDefault("logical-device-list", "format", DEFAULT_LOGICAL_DEVICE_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("local-device-list", "order", "")
+ }
data := make([]model.LogicalDevice, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
@@ -177,7 +180,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
@@ -227,11 +230,15 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_LOGICAL_DEVICE_PORT_FORMAT
+ outputFormat = GetCommandOptionWithDefault("logical-device-ports", "format", DEFAULT_LOGICAL_DEVICE_PORT_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
}
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault("logical-device-ports", "order", "")
+ }
data := make([]model.LogicalPort, len(items.([]interface{})))
for i, item := range items.([]interface{}) {
@@ -241,7 +248,7 @@
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
@@ -255,7 +262,7 @@
fl := &FlowList{}
fl.ListOutputOptions = options.ListOutputOptions
fl.Args.Id = string(options.Args.Id)
- fl.Method = "logical-device-flow-list"
+ fl.Method = "logical-device-flows"
return fl.Execute(args)
}
@@ -298,7 +305,7 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_LOGICAL_DEVICE_INSPECT_FORMAT
+ outputFormat = GetCommandOptionWithDefault("logical-device-inspect", "format", DEFAULT_LOGICAL_DEVICE_INSPECT_FORMAT)
}
if options.Quiet {
outputFormat = "{{.Id}}"
diff --git a/internal/pkg/commands/loglevel.go b/internal/pkg/commands/loglevel.go
index 265ab8f..3bb7798 100644
--- a/internal/pkg/commands/loglevel.go
+++ b/internal/pkg/commands/loglevel.go
@@ -27,7 +27,6 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
- "log"
"strings"
)
@@ -198,12 +197,12 @@
case "rw-core":
affinity_group, ok := pod.Labels["affinity-group"]
if !ok {
- log.Printf("rwcore %s lacks affinity-group label", pod.Name)
+ Warn.Printf("rwcore %s lacks affinity-group label", pod.Name)
continue
}
affinity_group_core_id, ok := pod.Labels["affinity-group-core-id"]
if !ok {
- log.Printf("rwcore %s lacks affinity-group-core-id label", pod.Name)
+ Warn.Printf("rwcore %s lacks affinity-group-core-id label", pod.Name)
continue
}
arouter_name = "vcore" + affinity_group + ".vcore" + affinity_group + affinity_group_core_id
@@ -315,7 +314,7 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_SETLOGLEVEL_FORMAT
+ outputFormat = GetCommandOptionWithDefault("loglevel-set", "format", DEFAULT_SETLOGLEVEL_FORMAT)
}
result := CommandResult{
@@ -329,7 +328,7 @@
return nil
}
-func (options *GetLogLevelsOpts) Execute(args []string) error {
+func (options *GetLogLevelsOpts) getLogLevels(methodName string, args []string) error {
if len(options.Args.Component) == 0 {
return fmt.Errorf("Please specify at least one component")
}
@@ -409,13 +408,17 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DEFAULT_LOGLEVELS_FORMAT
+ outputFormat = GetCommandOptionWithDefault(methodName, "format", DEFAULT_LOGLEVELS_FORMAT)
+ }
+ orderBy := options.OrderBy
+ if orderBy == "" {
+ orderBy = GetCommandOptionWithDefault(methodName, "order", "")
}
result := CommandResult{
Format: format.Format(outputFormat),
Filter: options.Filter,
- OrderBy: options.OrderBy,
+ OrderBy: orderBy,
OutputAs: toOutputType(options.OutputAs),
NameLimit: options.NameLimit,
Data: data,
@@ -424,6 +427,10 @@
return nil
}
+func (options *GetLogLevelsOpts) Execute(args []string) error {
+ return options.getLogLevels("loglevel-get", args)
+}
+
func (options *ListLogLevelsOpts) Execute(args []string) error {
var getOptions GetLogLevelsOpts
var podNames []string
@@ -442,5 +449,5 @@
getOptions.ListOutputOptions = options.ListOutputOptions
getOptions.Args.Component = podNames
- return getOptions.Execute(args)
+ return getOptions.getLogLevels("loglevel-list", args)
}
diff --git a/internal/pkg/commands/version.go b/internal/pkg/commands/version.go
index 1ca0fbf..d68b633 100644
--- a/internal/pkg/commands/version.go
+++ b/internal/pkg/commands/version.go
@@ -105,7 +105,7 @@
func (options *VersionOpts) clientOnlyVersion(args []string) error {
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = ClientOnlyFormat
+ outputFormat = GetCommandOptionWithDefault("version", "format", ClientOnlyFormat)
}
if options.Quiet {
outputFormat = "{{.Version}}"
@@ -210,7 +210,7 @@
outputFormat := CharReplacer.Replace(options.Format)
if outputFormat == "" {
- outputFormat = DefaultFormat
+ outputFormat = GetCommandOptionWithDefault("version", "format", DefaultFormat)
}
if options.Quiet {
outputFormat = "{{.Client.Version}}"
diff --git a/voltctl.config b/voltctl.config
index 15c8a41..b52590f 100644
--- a/voltctl.config
+++ b/voltctl.config
@@ -1,5 +1,4 @@
-apiVersion: v1
+apiVersion: v2
server: voltha.voltha.svc.cluster.local:50555
grpc:
timeout: 10s
-
diff --git a/voltctl_command_options.config b/voltctl_command_options.config
new file mode 100644
index 0000000..6732777
--- /dev/null
+++ b/voltctl_command_options.config
@@ -0,0 +1,30 @@
+device-list:
+ format: table{{.Id}}\t{{.Type}}\t{{.Root}}\t{{.ParentId}}\t{{.SerialNumber}}\t{{.Vlan}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.ConnectStatus}}\t{{.Reason}}
+ order: -Root,SerialNumber
+
+device-ports:
+ order: PortNo
+
+device-flows:
+ order: Priority,EthType
+
+logical-device-list:
+ order: RootDeviceId,DataPathId
+
+logical-device-ports:
+ order: Id
+
+logical-device-flows:
+ order: Priority,EthType
+
+adapter-list:
+ order: Id
+
+component-list:
+ order: Component,Name,Id
+
+loglevel-get:
+ order: ComponentName,PackageName,Level
+
+loglevel-list:
+ order: ComponentName,PackageName,Level