Repository: yorkie-team/yorkie
Pull request #548 (2023-06-13 06:00:15)

Add TLS Option & Insecure Flag in Admin CLI
<!--  Thanks for sending a pull request! -->

**What this PR does / why we need it**:

Add TLS option & insecure flag in admin CLI.

This is to set TLS connectivity between hosted server (`api.yorkie.dev`) and admin CLI.
Also, `--insecure` global flag is added to disable the TLS connection of the client when needed.

**Which issue(s) this PR fixes**:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
Fixes https://github.com/yorkie-team/devops/issues/43

**Special notes for your reviewer**:

**Does this PR introduce a user-facing change?**:
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note

```

**Additional documentation**:

<!--
This section can be blank if this pull request does not require a release note.

Please use the following format for linking documentation:
- [Usage]: <link>
- [Other doc]: <link>
-->
```docs

```

**Checklist**:
- [x] Added relevant tests or not required
- [x] Didn't break anything


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/yorkie-team/yorkie/pull/548?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) Report
> Merging [#548](https://app.codecov.io/gh/yorkie-team/yorkie/pull/548?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) (001ca09) into [main](https://app.codecov.io/gh/yorkie-team/yorkie/commit/0ce364b62d487aa1a6cc26f059f3eb6cfefb19eb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) (0ce364b) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main     #548   +/-   ##
=======================================
  Coverage   50.53%   50.53%           
=======================================
  Files          67       67           
  Lines        6678     6678           
=======================================
  Hits         3375     3375           
  Misses       2876     2876           
  Partials      427      427           
```





Patch:
diff --git a/admin/client.go b/admin/client.go
index b07821a7..eaabc071 100644
--- a/admin/client.go
+++ b/admin/client.go
@@ -19,11 +19,13 @@ package admin
 
 import (
 	"context"
+	"crypto/tls"
 	"fmt"
 	"strings"
 
 	"go.uber.org/zap"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/credentials/insecure"
 	"google.golang.org/grpc/metadata"
 
@@ -47,6 +49,11 @@ func WithLogger(logger *zap.Logger) Option {
 	return func(o *Options) { o.Logger = logger }
 }
 
+// WithInsecure configures insecure option of the client.
+func WithInsecure(isInsecure bool) Option {
+	return func(o *Options) { o.IsInsecure = isInsecure }
+}
+
 // Options configures how we set up the client.
 type Options struct {
 	// Token is the token of the user.
@@ -54,6 +61,9 @@ type Options struct {
 
 	// Logger is the Logger of the client.
 	Logger *zap.Logger
+
+	// IsInsecure is whether to disable the TLS connection of the client.
+	IsInsecure bool
 }
 
 // Client is a client for admin service.
@@ -72,8 +82,12 @@ func New(opts ...Option) (*Client, error) {
 		opt(&options)
 	}
 
-	credentials := grpc.WithTransportCredentials(insecure.NewCredentials())
-	dialOptions := []grpc.DialOption{credentials}
+	tlsConfig := credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})
+	credentialOptions := grpc.WithTransportCredentials(tlsConfig)
+	if options.IsInsecure {
+		credentialOptions = grpc.WithTransportCredentials(insecure.NewCredentials())
+	}
+	dialOptions := []grpc.DialOption{credentialOptions}
 
 	authInterceptor := NewAuthInterceptor(options.Token)
 	dialOptions = append(dialOptions, grpc.WithUnaryInterceptor(authInterceptor.Unary()))
diff --git a/cmd/yorkie/commands.go b/cmd/yorkie/commands.go
index 1aae40f2..2e340c78 100644
--- a/cmd/yorkie/commands.go
+++ b/cmd/yorkie/commands.go
@@ -45,4 +45,5 @@ func init() {
 	// TODO(chacha912): set rpcAddr from env using viper.
 	// https://github.com/spf13/cobra/blob/main/user_guide.md#bind-flags-with-config
 	rootCmd.PersistentFlags().StringVar(&config.RPCAddr, "rpc-addr", "localhost:11101", "Address of the rpc server")
+	rootCmd.PersistentFlags().BoolVar(&config.IsInsecure, "insecure", false, "Skip the TLS connection of the client")
 }
diff --git a/cmd/yorkie/config/config.go b/cmd/yorkie/config/config.go
index 6ec48562..358666f9 100644
--- a/cmd/yorkie/config/config.go
+++ b/cmd/yorkie/config/config.go
@@ -25,8 +25,12 @@ import (
 	"path/filepath"
 )
 
-// RPCAddr is the address of the rpc server.
-var RPCAddr string
+var (
+	// RPCAddr is the address of the rpc server.
+	RPCAddr string
+	// IsInsecure is whether to disable the TLS connection of the client.
+	IsInsecure bool
+)
 
 // ensureYorkieDir ensures that the directory of Yorkie exists.
 func ensureYorkieDir() (string, error) {
diff --git a/cmd/yorkie/document/list.go b/cmd/yorkie/document/list.go
index ac75c1ba..59ee3e6c 100644
--- a/cmd/yorkie/document/list.go
+++ b/cmd/yorkie/document/list.go
@@ -49,7 +49,7 @@ func newListCommand() *cobra.Command {
 			if err != nil {
 				return err
 			}
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/document/remove.go b/cmd/yorkie/document/remove.go
index 28439127..454f7d7b 100644
--- a/cmd/yorkie/document/remove.go
+++ b/cmd/yorkie/document/remove.go
@@ -41,7 +41,7 @@ func newRemoveCommand() *cobra.Command {
 			if err != nil {
 				return err
 			}
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/history.go b/cmd/yorkie/history.go
index 5ce130e7..f54aec71 100644
--- a/cmd/yorkie/history.go
+++ b/cmd/yorkie/history.go
@@ -48,7 +48,7 @@ func newHistoryCmd() *cobra.Command {
 				return err
 			}
 
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/login.go b/cmd/yorkie/login.go
index 1c3027d5..39c8a0ef 100644
--- a/cmd/yorkie/login.go
+++ b/cmd/yorkie/login.go
@@ -35,7 +35,7 @@ func newLoginCmd() *cobra.Command {
 		Use:   "login",
 		Short: "Log in to the Yorkie server",
 		RunE: func(cmd *cobra.Command, args []string) error {
-			cli, err := admin.Dial(config.RPCAddr)
+			cli, err := admin.Dial(config.RPCAddr, admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/project/create.go b/cmd/yorkie/project/create.go
index 668f845f..2a81cedf 100644
--- a/cmd/yorkie/project/create.go
+++ b/cmd/yorkie/project/create.go
@@ -45,7 +45,7 @@ func newCreateCommand() *cobra.Command {
 			if err != nil {
 				return err
 			}
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/project/list.go b/cmd/yorkie/project/list.go
index a96c4a08..6235a5d4 100644
--- a/cmd/yorkie/project/list.go
+++ b/cmd/yorkie/project/list.go
@@ -38,7 +38,7 @@ func newListCommand() *cobra.Command {
 				return err
 			}
 
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/yorkie/project/update.go b/cmd/yorkie/project/update.go
index 74ed310b..f480ac2c 100644
--- a/cmd/yorkie/project/update.go
+++ b/cmd/yorkie/project/update.go
@@ -54,7 +54,7 @@ func newUpdateCommand() *cobra.Command {
 				return err
 			}
 
-			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token))
+			cli, err := admin.Dial(config.RPCAddr, admin.WithToken(token), admin.WithInsecure(config.IsInsecure))
 			if err != nil {
 				return err
 			}


Test patch:
diff --git a/test/helper/helper.go b/test/helper/helper.go
index f3d5c24c..f0c9e610 100644
--- a/test/helper/helper.go
+++ b/test/helper/helper.go
@@ -87,7 +87,7 @@ func TestDBName() string {
 
 // CreateAdminCli returns a new instance of admin cli for testing.
 func CreateAdminCli(t assert.TestingT, rpcAddr string) *adminClient.Client {
-	adminCli, err := adminClient.Dial(rpcAddr)
+	adminCli, err := adminClient.Dial(rpcAddr, adminClient.WithInsecure(true))
 	assert.NoError(t, err)
 
 	_, err = adminCli.LogIn(context.Background(), server.DefaultAdminUser, server.DefaultAdminPassword)
diff --git a/test/integration/admin_test.go b/test/integration/admin_test.go
index d1664c26..75dbb087 100644
--- a/test/integration/admin_test.go
+++ b/test/integration/admin_test.go
@@ -38,7 +38,7 @@ import (
 func TestAdmin(t *testing.T) {
 	ctx := context.Background()
 
-	adminCli, err := admin.Dial(defaultServer.RPCAddr())
+	adminCli, err := admin.Dial(defaultServer.RPCAddr(), admin.WithInsecure(true))
 	assert.NoError(t, err)
 	_, err = adminCli.LogIn(ctx, "admin", "admin")
 	assert.NoError(t, err)