grpc client default in plaintext mode (#19412)

* grpc client default in plaintext mode

* renaming and fix linter

* update the description and remove the context

* trim tests
This commit is contained in:
wangxinyi7 2023-11-28 10:58:57 -08:00 committed by GitHub
parent 419677cc9e
commit 9dc24448ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 193 additions and 11 deletions

View File

@ -19,10 +19,11 @@ import (
"sync"
"time"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-rootcerts"
"github.com/hashicorp/consul/api"
)
// NOTE: This client is copied from the api module to temporarily facilitate the resource cli commands
@ -72,12 +73,6 @@ const (
// whether or not to disable certificate checking.
HTTPSSLVerifyEnvName = "CONSUL_HTTP_SSL_VERIFY"
// GRPCAddrEnvName defines an environment variable name which sets the gRPC
// address for consul connect envoy. Note this isn't actually used by the api
// client in this package but is defined here for consistency with all the
// other ENV names we use.
GRPCAddrEnvName = "CONSUL_GRPC_ADDR"
// GRPCCAFileEnvName defines an environment variable name which sets the
// CA file to use for talking to Consul gRPC over TLS.
GRPCCAFileEnvName = "CONSUL_GRPC_CACERT"

View File

@ -0,0 +1,39 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/hashicorp/consul/proto-public/pbresource"
)
type GRPCClient struct {
Client pbresource.ResourceServiceClient
Config *GRPCConfig
Conn *grpc.ClientConn
}
func NewGRPCClient(config *GRPCConfig) (*GRPCClient, error) {
conn, err := dial(config)
if err != nil {
return nil, fmt.Errorf("**** error dialing grpc: %+v", err)
}
return &GRPCClient{
Client: pbresource.NewResourceServiceClient(conn),
Config: config,
Conn: conn,
}, nil
}
func dial(c *GRPCConfig) (*grpc.ClientConn, error) {
// TODO: decide if we use TLS mode based on the config
dialOpts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
}
return grpc.Dial(c.Address, dialOpts...)
}

View File

@ -0,0 +1,51 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/internal/resource/demo"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/testrpc"
)
func TestResourceRead(t *testing.T) {
t.Parallel()
a := agent.NewTestAgent(t, "ports { grpc = 8502 }")
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
grpcConfig := GetDefaultGRPCConfig()
gRPCClient, err := NewGRPCClient(grpcConfig)
t.Cleanup(func() {
a.Shutdown()
gRPCClient.Conn.Close()
})
t.Run("test", func(t *testing.T) {
if err != nil {
fmt.Println("error when create new grpc client")
}
v2Artist, err := demo.GenerateV2Artist()
require.NoError(t, err)
writeRsp, err := gRPCClient.Client.Write(testutil.TestContext(t), &pbresource.WriteRequest{Resource: v2Artist})
require.NoError(t, err)
readRsp, err := gRPCClient.Client.Read(context.Background(), &pbresource.ReadRequest{Id: v2Artist.Id})
require.NoError(t, err)
require.Equal(t, proto.Equal(readRsp.Resource.Id.Type, demo.TypeV2Artist), true)
prototest.AssertDeepEqual(t, writeRsp.Resource, readRsp.Resource)
})
}

View File

@ -0,0 +1,43 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"os"
)
const (
// GRPCAddrEnvName defines an environment variable name which sets the gRPC
// server address for the consul CLI.
GRPCAddrEnvName = "CONSUL_GRPC_ADDR"
)
type GRPCConfig struct {
Address string
}
func GetDefaultGRPCConfig() *GRPCConfig {
return &GRPCConfig{
Address: "localhost:8502",
}
}
func LoadGRPCConfig(defaultConfig *GRPCConfig) *GRPCConfig {
if defaultConfig == nil {
defaultConfig = GetDefaultGRPCConfig()
}
overwrittenConfig := loadEnvToDefaultConfig(defaultConfig)
return overwrittenConfig
}
func loadEnvToDefaultConfig(config *GRPCConfig) *GRPCConfig {
if addr := os.Getenv(GRPCAddrEnvName); addr != "" {
config.Address = addr
}
return config
}

View File

@ -0,0 +1,58 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"flag"
)
type GRPCFlags struct {
address StringValue
}
// mergeFlagsIntoGRPCConfig merges flag values into grpc config
// caller has to parse the CLI args before loading them into flag values
func (f *GRPCFlags) mergeFlagsIntoGRPCConfig(c *GRPCConfig) {
f.address.Merge(&c.Address)
}
func (f *GRPCFlags) ClientFlags() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Var(&f.address, "grpc-addr",
"The `address` and port of the Consul GRPC agent. The value can be an IP "+
"address or DNS address, but it must also include the port. This can "+
"also be specified via the CONSUL_GRPC_ADDR environment variable. The "+
"default value is 127.0.0.1:8502. It supports TLS communication "+
"by setting the environment variable CONSUL_GRPC_TLS=true.")
return fs
}
type StringValue struct {
v *string
}
// Set implements the flag.Value interface.
func (s *StringValue) Set(v string) error {
if s.v == nil {
s.v = new(string)
}
*(s.v) = v
return nil
}
// String implements the flag.Value interface.
func (s *StringValue) String() string {
var current string
if s.v != nil {
current = *(s.v)
}
return current
}
// Merge will overlay this value if it has been set.
func (s *StringValue) Merge(onto *string) {
if s.v != nil {
*onto = *(s.v)
}
}

View File

@ -86,10 +86,6 @@ func (c *cmd) Run(args []string) int {
return 1
}
} else {
if len(args) < 2 {
c.UI.Error("Incorrect argument format: Must specify two arguments: resource type and resource name")
return 1
}
var err error
gvk, resourceName, err = resource.GetTypeAndResourceName(args)
if err != nil {