Add maxCallRecvMsgSize parameter and read it from the configuration
GRPC client max msg receive size
file. It allows to set if the incoming message is bigger than the
default 4K size.
Change-Id: I5b5113264066b84b5b055faf7d4bc02a3f11ec89
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index 9b2afd0..d5a2785 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -19,6 +19,17 @@
"encoding/json"
"errors"
"fmt"
+ "io/ioutil"
+ "log"
+ "net"
+ "os"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"github.com/opencord/voltctl/pkg/filter"
@@ -26,15 +37,6 @@
"github.com/opencord/voltctl/pkg/order"
"google.golang.org/grpc"
"gopkg.in/yaml.v2"
- "io/ioutil"
- "log"
- "net"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
- "time"
)
type OutputType uint8
@@ -55,11 +57,13 @@
defaultKvPort = 2379
defaultKvTimeout = time.Second * 5
- defaultGrpcTimeout = time.Minute * 5
+ defaultGrpcTimeout = time.Minute * 5
+ defaultGrpcMaxCallRecvMsgSize = "4MB"
)
type GrpcConfigSpec struct {
- Timeout time.Duration `yaml:"timeout"`
+ Timeout time.Duration `yaml:"timeout"`
+ MaxCallRecvMsgSize string `yaml:"maxCallRecvMsgSize"`
}
type KvStoreConfigSpec struct {
@@ -109,7 +113,8 @@
UseTls: false,
},
Grpc: GrpcConfigSpec{
- Timeout: defaultGrpcTimeout,
+ Timeout: defaultGrpcTimeout,
+ MaxCallRecvMsgSize: defaultGrpcMaxCallRecvMsgSize,
},
KvStoreConfig: KvStoreConfigSpec{
Timeout: defaultKvTimeout,
@@ -125,16 +130,17 @@
KvStore string `short:"e" long:"kvstore" env:"KVSTORE" value-name:"SERVER:PORT" description:"IP/Host and port of KV store (etcd)"`
// nolint: staticcheck
- Debug bool `short:"d" long:"debug" description:"Enable debug mode"`
- Timeout string `short:"t" long:"timeout" description:"API call timeout duration" value-name:"DURATION" default:""`
- 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"`
- 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"`
+ Debug bool `short:"d" long:"debug" description:"Enable debug mode"`
+ Timeout string `short:"t" long:"timeout" description:"API call timeout duration" value-name:"DURATION" default:""`
+ 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"`
+ 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"`
+ MaxCallRecvMsgSize string `short:"m" long:"maxcallrecvmsgsize" description:"Max GRPC Client request size limit in bytes (eg: 4MB)" value-name:"SIZE" default:"4M"`
}
Debug = log.New(os.Stdout, "DEBUG: ", 0)
@@ -227,6 +233,36 @@
return defaultValue
}
+var sizeParser = regexp.MustCompile(`^([0-9]+)([PETGMK]?)I?B?$`)
+
+func parseSize(size string) (uint64, error) {
+
+ parts := sizeParser.FindAllStringSubmatch(strings.ToUpper(size), -1)
+ if len(parts) == 0 {
+ return 0, fmt.Errorf("size: invalid size '%s'", size)
+ }
+ value, err := strconv.ParseUint(parts[0][1], 10, 64)
+ if err != nil {
+ return 0, fmt.Errorf("size: invalid size '%s'", size)
+ }
+ switch parts[0][2] {
+ case "E":
+ value = value * 1024 * 1024 * 1024 * 1024 * 1024 * 1024
+ case "P":
+ value = value * 1024 * 1024 * 1024 * 1024 * 1024
+ case "T":
+ value = value * 1024 * 1024 * 1024 * 1024
+ case "G":
+ value = value * 1024 * 1024 * 1024
+ case "M":
+ value = value * 1024 * 1024
+ case "K":
+ value = value * 1024
+ default:
+ }
+ return value, nil
+}
+
func ProcessGlobalOptions() {
if len(GlobalOptions.Config) == 0 {
home, err := os.UserHomeDir()
@@ -298,6 +334,10 @@
GlobalConfig.Grpc.Timeout = timeout
}
+ if GlobalOptions.MaxCallRecvMsgSize != "" {
+ GlobalConfig.Grpc.MaxCallRecvMsgSize = GlobalOptions.MaxCallRecvMsgSize
+ }
+
// If a k8s cert/key were not specified, then attempt to read it from
// any $HOME/.kube/config if it exists
if len(GlobalOptions.K8sConfig) == 0 {
@@ -333,7 +373,14 @@
func NewConnection() (*grpc.ClientConn, error) {
ProcessGlobalOptions()
- return grpc.Dial(GlobalConfig.Server, grpc.WithInsecure())
+
+ // convert grpc.msgSize into bytes
+ n, err := parseSize(GlobalConfig.Grpc.MaxCallRecvMsgSize)
+ if err != nil {
+ Error.Fatalf("Cannot convert msgSize %s to bytes", GlobalConfig.Grpc.MaxCallRecvMsgSize)
+ }
+
+ return grpc.Dial(GlobalConfig.Server, grpc.WithInsecure(), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(int(n))))
}
func ConvertJsonProtobufArray(data_in interface{}) (string, error) {