[VOL-2312] Logging - Integrate voltctl with new etcd-based dynamic loglevel mechanism. Testing is in progress
Change-Id: I2e13bb79008c9a49ebb6f58e575f51efebe6dbfd
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index 1cae97b..8e3ced7 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -25,8 +25,10 @@
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
+ "net"
"os"
"path/filepath"
+ "strconv"
"strings"
"time"
)
@@ -37,12 +39,29 @@
OUTPUT_TABLE OutputType = iota
OUTPUT_JSON
OUTPUT_YAML
+
+ defaultApiHost = "localhost"
+ defaultApiPort = 55555
+
+ defaultKafkaHost = "localhost"
+ defaultKafkaPort = 9092
+
+ supportedKvStoreType = "etcd"
+ defaultKvHost = "localhost"
+ defaultKvPort = 2379
+ defaultKvTimeout = time.Second * 5
+
+ defaultGrpcTimeout = time.Minute * 5
)
type GrpcConfigSpec struct {
Timeout time.Duration `yaml:"timeout"`
}
+type KvStoreConfigSpec struct {
+ Timeout time.Duration `yaml:"timeout"`
+}
+
type TlsConfigSpec struct {
UseTls bool `yaml:"useTls"`
CACert string `yaml:"caCert"`
@@ -52,12 +71,14 @@
}
type GlobalConfigSpec struct {
- ApiVersion string `yaml:"apiVersion"`
- Server string `yaml:"server"`
- Kafka string `yaml:"kafka"`
- Tls TlsConfigSpec `yaml:"tls"`
- Grpc GrpcConfigSpec `yaml:"grpc"`
- K8sConfig string `yaml:"-"`
+ ApiVersion string `yaml:"apiVersion"`
+ Server string `yaml:"server"`
+ Kafka string `yaml:"kafka"`
+ KvStore string `yaml:"kvstore"`
+ Tls TlsConfigSpec `yaml:"tls"`
+ Grpc GrpcConfigSpec `yaml:"grpc"`
+ KvStoreConfig KvStoreConfigSpec `yaml:"kvstoreconfig"`
+ K8sConfig string `yaml:"-"`
}
var (
@@ -80,20 +101,26 @@
ApiVersion: "v3",
Server: "localhost:55555",
Kafka: "",
+ KvStore: "localhost:2379",
Tls: TlsConfigSpec{
UseTls: false,
},
Grpc: GrpcConfigSpec{
- Timeout: time.Minute * 5,
+ Timeout: defaultGrpcTimeout,
+ },
+ KvStoreConfig: KvStoreConfigSpec{
+ Timeout: defaultKvTimeout,
},
}
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"`
- Kafka string `short:"k" long:"kafka" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Kafka"`
+ 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"`
+ Kafka string `short:"k" long:"kafka" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Kafka"`
+ KvStore string `short:"e" long:"kvstore" env:"KVSTORE" value-name:"SERVER:PORT" description:"IP/Host and port of KV store (etcd)"`
+
// Do not set the default for the API version here, else it will override the value read in the config
// nolint: staticcheck
ApiVersion string `short:"a" long:"apiversion" description:"API version" value-name:"VERSION" choice:"v1" choice:"v2" choice:"v3"`
@@ -105,6 +132,7 @@
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"`
+ KvStoreTimeout string `long:"kvstoretimeout" env:"KVSTORE_TIMEOUT" value-name:"DURATION" default:"" description:"timeout for calls to KV store"`
CommandOptions string `short:"o" long:"command-options" env:"VOLTCTL_COMMAND_OPTIONS" value-name:"FILE" default:"" description:"Location of command options default configuration file"`
}
@@ -155,6 +183,31 @@
}
}
+func splitEndpoint(ep, defaultHost string, defaultPort int) (string, int, error) {
+ port := defaultPort
+ host, sPort, err := net.SplitHostPort(ep)
+ if err != nil {
+ if addrErr, ok := err.(*net.AddrError); ok {
+ if addrErr.Err != "missing port in address" {
+ return "", 0, err
+ }
+ host = ep
+ } else {
+ return "", 0, err
+ }
+ } else if len(strings.TrimSpace(sPort)) > 0 {
+ val, err := strconv.Atoi(sPort)
+ if err != nil {
+ return "", 0, err
+ }
+ port = val
+ }
+ if len(strings.TrimSpace(host)) == 0 {
+ host = defaultHost
+ }
+ return strings.Trim(host, "]["), port, nil
+}
+
type CommandResult struct {
Format format.Format
Filter string
@@ -199,13 +252,46 @@
if GlobalOptions.Server != "" {
GlobalConfig.Server = GlobalOptions.Server
}
+ host, port, err := splitEndpoint(GlobalConfig.Server, defaultApiHost, defaultApiPort)
+ if err != nil {
+ Error.Fatalf("voltha API endport incorrectly specified '%s':%s",
+ GlobalConfig.Server, err)
+ }
+ GlobalConfig.Server = net.JoinHostPort(host, strconv.Itoa(port))
+
if GlobalOptions.Kafka != "" {
GlobalConfig.Kafka = GlobalOptions.Kafka
}
+ host, port, err = splitEndpoint(GlobalConfig.Kafka, defaultKafkaHost, defaultKafkaPort)
+ if err != nil {
+ Error.Fatalf("Kafka endport incorrectly specified '%s':%s",
+ GlobalConfig.Kafka, err)
+ }
+ GlobalConfig.Kafka = net.JoinHostPort(host, strconv.Itoa(port))
+
+ if GlobalOptions.KvStore != "" {
+ GlobalConfig.KvStore = GlobalOptions.KvStore
+ }
+ host, port, err = splitEndpoint(GlobalConfig.KvStore, defaultKvHost, defaultKvPort)
+ if err != nil {
+ Error.Fatalf("KV store endport incorrectly specified '%s':%s",
+ GlobalConfig.KvStore, err)
+ }
+ GlobalConfig.KvStore = net.JoinHostPort(host, strconv.Itoa(port))
+
if GlobalOptions.ApiVersion != "" {
GlobalConfig.ApiVersion = GlobalOptions.ApiVersion
}
+ if GlobalOptions.KvStoreTimeout != "" {
+ timeout, err := time.ParseDuration(GlobalOptions.KvStoreTimeout)
+ if err != nil {
+ Error.Fatalf("Unable to parse specified KV strore timeout duration '%s': %s",
+ GlobalOptions.KvStoreTimeout, err.Error())
+ }
+ GlobalConfig.KvStoreConfig.Timeout = timeout
+ }
+
if GlobalOptions.Timeout != "" {
timeout, err := time.ParseDuration(GlobalOptions.Timeout)
if err != nil {