VOL-2170 add common method the output GRPC status error
Change-Id: Ibc48cb087cd73f981542bcb137bdb4f213fa7e8d
diff --git a/cmd/voltctl/voltctl.go b/cmd/voltctl/voltctl.go
index 5b70bac..8a342ca 100644
--- a/cmd/voltctl/voltctl.go
+++ b/cmd/voltctl/voltctl.go
@@ -41,7 +41,7 @@
compval := os.Getenv("GO_FLAGS_COMPLETION")
if len(compval) > 0 {
os.Unsetenv("GO_FLAGS_COMPLETION")
- pp := flags.NewNamedParser(path.Base(os.Args[0]), flags.Default|flags.PassAfterNonOption)
+ pp := flags.NewNamedParser(path.Base(os.Args[0]), flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption)
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())
}
@@ -51,10 +51,10 @@
os.Setenv("GO_FLAGS_COMPLETION", compval)
}
- parser := flags.NewNamedParser(path.Base(os.Args[0]), flags.Default|flags.PassAfterNonOption)
+ parser := flags.NewNamedParser(path.Base(os.Args[0]), flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption)
_, err := parser.AddGroup("Global Options", "", &commands.GlobalOptions)
if err != nil {
- panic(err)
+ commands.Error.Fatalf("Unable to parse global command options: %s", err.Error())
}
commands.RegisterAdapterCommands(parser)
commands.RegisterDeviceCommands(parser)
@@ -75,7 +75,7 @@
return
}
} else {
- panic(err)
+ commands.Error.Fatal(commands.ErrorToString(err))
}
os.Exit(1)
}
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index a4e298e..7972b8f 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -73,7 +73,7 @@
GlobalConfig = GlobalConfigSpec{
ApiVersion: "v2",
- Server: "localhost",
+ Server: "localhost:55555",
Tls: TlsConfigSpec{
UseTls: false,
},
@@ -236,38 +236,38 @@
if result.Filter != "" {
f, err := filter.Parse(result.Filter)
if err != nil {
- panic(err)
+ Error.Fatalf("Unable to parse specified output filter '%s': %s", result.Filter, err.Error())
}
data, err = f.Process(data)
if err != nil {
- panic(err)
+ Error.Fatalf("Unexpected error while filtering command results: %s", err.Error())
}
}
if result.OrderBy != "" {
s, err := order.Parse(result.OrderBy)
if err != nil {
- panic(err)
+ Error.Fatalf("Unable to parse specified sort specification '%s': %s", result.OrderBy, err.Error())
}
data, err = s.Process(data)
if err != nil {
- panic(err)
+ Error.Fatalf("Unexpected error while sorting command result: %s", err.Error())
}
}
if result.OutputAs == OUTPUT_TABLE {
tableFormat := format.Format(result.Format)
if err := tableFormat.Execute(os.Stdout, true, result.NameLimit, data); err != nil {
- Error.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.Error())
}
} else if result.OutputAs == OUTPUT_JSON {
asJson, err := json.Marshal(&data)
if err != nil {
- panic(err)
+ Error.Fatalf("Unexpected error while processing command results to JSON: %s", err.Error())
}
fmt.Printf("%s", asJson)
} else if result.OutputAs == OUTPUT_YAML {
asYaml, err := yaml.Marshal(&data)
if err != nil {
- panic(err)
+ Error.Fatalf("Unexpected error while processing command results to YAML: %s", err.Error())
}
fmt.Printf("%s", asYaml)
}
diff --git a/internal/pkg/commands/components.go b/internal/pkg/commands/components.go
index 4501f1f..203b64d 100644
--- a/internal/pkg/commands/components.go
+++ b/internal/pkg/commands/components.go
@@ -61,20 +61,20 @@
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", GlobalOptions.K8sConfig)
if err != nil {
- panic(err.Error())
+ Error.Fatalf("Unable to resolve Kubernetes configuration options: %s", err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
- panic(err.Error())
+ Error.Fatalf("Unable to create client context for Kubernetes API connection: %s", err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{
LabelSelector: "app.kubernetes.io/part-of=voltha",
})
if err != nil {
- panic(err.Error())
+ Error.Fatalf("Unexpected error while attempting to query PODs from Kubernetes: %s", err.Error())
}
outputFormat := CharReplacer.Replace(options.Format)
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index ac6d508..8b603f8 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -303,10 +303,10 @@
err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
if err != nil {
- fmt.Printf("Error while deleting '%s': %s\n", i, err)
+ Error.Printf("Error while deleting '%s': %s\n", i, err)
continue
} else if h.Status != nil && h.Status.Err() != nil {
- fmt.Printf("Error while deleting '%s': %s\n", i, h.Status.Err())
+ Error.Printf("Error while deleting '%s': %s\n", i, ErrorToString(h.Status.Err()))
continue
}
fmt.Printf("%s\n", i)
@@ -336,10 +336,10 @@
err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
if err != nil {
- fmt.Printf("Error while enabling '%s': %s\n", i, err)
+ Error.Printf("Error while enabling '%s': %s\n", i, err)
continue
} else if h.Status != nil && h.Status.Err() != nil {
- fmt.Printf("Error while enabling '%s': %s\n", i, h.Status.Err())
+ Error.Printf("Error while enabling '%s': %s\n", i, ErrorToString(h.Status.Err()))
continue
}
fmt.Printf("%s\n", i)
@@ -369,10 +369,10 @@
err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
if err != nil {
- fmt.Printf("Error while disabling '%s': %s\n", i, err)
+ Error.Printf("Error while disabling '%s': %s\n", i, err)
continue
} else if h.Status != nil && h.Status.Err() != nil {
- fmt.Printf("Error while disabling '%s': %s\n", i, h.Status.Err())
+ Error.Printf("Error while disabling '%s': %s\n", i, ErrorToString(h.Status.Err()))
continue
}
fmt.Printf("%s\n", i)
@@ -402,10 +402,10 @@
err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
if err != nil {
- fmt.Printf("Error while rebooting '%s': %s\n", i, err)
+ Error.Printf("Error while rebooting '%s': %s\n", i, err)
continue
} else if h.Status != nil && h.Status.Err() != nil {
- fmt.Printf("Error while rebooting '%s': %s\n", i, h.Status.Err())
+ Error.Printf("Error while rebooting '%s': %s\n", i, ErrorToString(h.Status.Err()))
continue
}
fmt.Printf("%s\n", i)
diff --git a/internal/pkg/commands/error.go b/internal/pkg/commands/error.go
new file mode 100644
index 0000000..ff641d3
--- /dev/null
+++ b/internal/pkg/commands/error.go
@@ -0,0 +1,51 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package commands
+
+import (
+ "fmt"
+ "google.golang.org/grpc/status"
+ "regexp"
+ "strings"
+)
+
+var (
+ descRE = regexp.MustCompile(`desc = "(.*)"`)
+ try2RE = regexp.MustCompile(`all SubConns are in TransientFailure, latest connection error: (.*)`)
+ try3RE = regexp.MustCompile(`all SubConns are in TransientFailure, (.*)`)
+)
+
+func ErrorToString(err error) string {
+ if err == nil {
+ return ""
+ }
+
+ if st, ok := status.FromError(err); ok {
+ msg := st.Message()
+ if match := descRE.FindAllStringSubmatch(msg, 1); match != nil {
+ msg = match[0][1]
+ } else if match = try2RE.FindAllStringSubmatch(msg, 1); match != nil {
+ msg = match[0][1]
+ } else if match = try3RE.FindAllStringSubmatch(msg, 1); match != nil {
+ msg = match[0][1]
+ }
+
+ return fmt.Sprintf("%s: %s", strings.ToUpper(st.Code().String()), msg)
+ }
+ return err.Error()
+}
diff --git a/internal/pkg/commands/flows.go b/internal/pkg/commands/flows.go
index bfb82dc..b8c2eb6 100644
--- a/internal/pkg/commands/flows.go
+++ b/internal/pkg/commands/flows.go
@@ -117,7 +117,7 @@
case "device-flows":
case "logical-device-flows":
default:
- panic(fmt.Errorf("Unknown method name: '%s'", options.Method))
+ Error.Fatalf("Unknown method name: '%s'", options.Method)
}
descriptor, method, err := GetMethod(options.Method)
diff --git a/internal/pkg/commands/handler.go b/internal/pkg/commands/handler.go
index 03e599e..0c6d32b 100644
--- a/internal/pkg/commands/handler.go
+++ b/internal/pkg/commands/handler.go
@@ -16,7 +16,6 @@
package commands
import (
- "fmt"
"github.com/golang/protobuf/proto"
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic"
@@ -67,8 +66,7 @@
for k, v := range fields {
err := dmsg.TrySetFieldByName(k, v)
if err != nil {
- fmt.Printf("Failed to set field %s in proto %s, err %v\n", k, dmsg.XXX_MessageName(), err)
- panic("GetParams failure")
+ Error.Fatalf("Failed to set field %s in proto %s, err %v\n", k, dmsg.XXX_MessageName(), err.Error())
}
}
delete(h.Fields, dmsg.XXX_MessageName())
diff --git a/internal/pkg/commands/loglevel.go b/internal/pkg/commands/loglevel.go
index e7723fd..5da4e12 100644
--- a/internal/pkg/commands/loglevel.go
+++ b/internal/pkg/commands/loglevel.go
@@ -72,7 +72,7 @@
func RegisterLogLevelCommands(parent *flags.Parser) {
_, err := parent.AddCommand("loglevel", "loglevel commands", "Get and set log levels", &logLevelOpts)
if err != nil {
- panic(err)
+ Error.Fatalf("Unable to register log level commands with voltctl command parser: %s", err.Error())
}
}
diff --git a/internal/pkg/commands/version.go b/internal/pkg/commands/version.go
index d68b633..05ddcc7 100644
--- a/internal/pkg/commands/version.go
+++ b/internal/pkg/commands/version.go
@@ -72,7 +72,7 @@
func RegisterVersionCommands(parent *flags.Parser) {
_, err := parent.AddCommand("version", "display version", "Display client and server version", &versionOpts)
if err != nil {
- panic(err)
+ Error.Fatalf("Unable to register version command: %s", err.Error())
}
}