Skip to content

Commit dd056dc

Browse files
authored
Add CLI flag --skip-tls-verify (#194)
* Add CLI flag `--skip-tls-verify` * Update README for `--skip-tls-verify`
1 parent 73f1bc3 commit dd056dc

3 files changed

Lines changed: 64 additions & 53 deletions

File tree

README.md

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,24 @@ Usage:
3737
spanner-cli [OPTIONS]
3838
3939
spanner:
40-
-p, --project= (required) GCP Project ID. [$SPANNER_PROJECT_ID]
41-
-i, --instance= (required) Cloud Spanner Instance ID [$SPANNER_INSTANCE_ID]
42-
-d, --database= (required) Cloud Spanner Database ID. [$SPANNER_DATABASE_ID]
43-
-e, --execute= Execute SQL statement and quit.
44-
-f, --file= Execute SQL statement from file and quit.
45-
-t, --table Display output in table format for batch mode.
46-
-v, --verbose Display verbose output.
47-
--credential= Use the specific credential file
48-
--prompt= Set the prompt to the specified format
49-
--history= Set the history file to the specified path
50-
--priority= Set default request priority (HIGH|MEDIUM|LOW)
51-
--role= Use the specific database role
52-
--directed-read= Directed read option (replica_location:replica_type).
53-
The replicat_type is optional and either READ_ONLY or READ_WRITE.
40+
-p, --project= (required) GCP Project ID. [$SPANNER_PROJECT_ID]
41+
-i, --instance= (required) Cloud Spanner Instance ID [$SPANNER_INSTANCE_ID]
42+
-d, --database= (required) Cloud Spanner Database ID. [$SPANNER_DATABASE_ID]
43+
-e, --execute= Execute SQL statement and quit.
44+
-f, --file= Execute SQL statement from file and quit.
45+
-t, --table Display output in table format for batch mode.
46+
-v, --verbose Display verbose output.
47+
--credential= Use the specific credential file
48+
--prompt= Set the prompt to the specified format
49+
--history= Set the history file to the specified path
50+
--priority= Set default request priority (HIGH|MEDIUM|LOW)
51+
--role= Use the specific database role
52+
--endpoint= Set the Spanner API endpoint (host:port)
53+
--directed-read= Directed read option (replica_location:replica_type). The replicat_type is optional and either READ_ONLY or READ_WRITE
54+
--skip-tls-verify Insecurely skip TLS verify
5455
5556
Help Options:
56-
-h, --help Show this help message
57+
-h, --help Show this help message
5758
```
5859

5960
### Authentication

cli.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package main
1919
import (
2020
"bufio"
2121
"context"
22+
"crypto/tls"
2223
"errors"
2324
"fmt"
2425
"io"
@@ -33,7 +34,9 @@ import (
3334
"github.com/chzyer/readline"
3435
"github.com/olekukonko/tablewriter"
3536
"google.golang.org/api/option"
37+
"google.golang.org/grpc"
3638
"google.golang.org/grpc/codes"
39+
"google.golang.org/grpc/credentials"
3740
)
3841

3942
type DisplayMode int
@@ -58,25 +61,26 @@ var (
5861
)
5962

6063
type Cli struct {
61-
Session *Session
62-
Prompt string
63-
HistoryFile string
64-
Credential []byte
65-
InStream io.ReadCloser
66-
OutStream io.Writer
67-
ErrStream io.Writer
68-
Verbose bool
69-
Priority pb.RequestOptions_Priority
70-
Endpoint string
64+
Session *Session
65+
Prompt string
66+
HistoryFile string
67+
Credential []byte
68+
InStream io.ReadCloser
69+
OutStream io.Writer
70+
ErrStream io.Writer
71+
Verbose bool
72+
Priority pb.RequestOptions_Priority
73+
Endpoint string
74+
SkipTLSVerify bool
7175
}
7276

7377
type command struct {
7478
Stmt Statement
7579
Vertical bool
7680
}
7781

78-
func NewCli(projectId, instanceId, databaseId, prompt, historyFile string, credential []byte, inStream io.ReadCloser, outStream io.Writer, errStream io.Writer, verbose bool, priority pb.RequestOptions_Priority, role string, endpoint string, directedRead *pb.DirectedReadOptions) (*Cli, error) {
79-
session, err := createSession(projectId, instanceId, databaseId, credential, priority, role, endpoint, directedRead)
82+
func NewCli(projectId, instanceId, databaseId, prompt, historyFile string, credential []byte, inStream io.ReadCloser, outStream io.Writer, errStream io.Writer, verbose bool, priority pb.RequestOptions_Priority, role string, endpoint string, directedRead *pb.DirectedReadOptions, skipTLSVerify bool) (*Cli, error) {
83+
session, err := createSession(projectId, instanceId, databaseId, credential, priority, role, endpoint, directedRead, skipTLSVerify)
8084
if err != nil {
8185
return nil, err
8286
}
@@ -90,15 +94,16 @@ func NewCli(projectId, instanceId, databaseId, prompt, historyFile string, crede
9094
}
9195

9296
return &Cli{
93-
Session: session,
94-
Prompt: prompt,
95-
HistoryFile: historyFile,
96-
Credential: credential,
97-
InStream: inStream,
98-
OutStream: outStream,
99-
ErrStream: errStream,
100-
Verbose: verbose,
101-
Endpoint: endpoint,
97+
Session: session,
98+
Prompt: prompt,
99+
HistoryFile: historyFile,
100+
Credential: credential,
101+
InStream: inStream,
102+
OutStream: outStream,
103+
ErrStream: errStream,
104+
Verbose: verbose,
105+
Endpoint: endpoint,
106+
SkipTLSVerify: skipTLSVerify,
102107
}, nil
103108
}
104109

@@ -148,7 +153,7 @@ func (c *Cli) RunInteractive() int {
148153
}
149154

150155
if s, ok := stmt.(*UseStatement); ok {
151-
newSession, err := createSession(c.Session.projectId, c.Session.instanceId, s.Database, c.Credential, c.Priority, s.Role, c.Endpoint, c.Session.directedRead)
156+
newSession, err := createSession(c.Session.projectId, c.Session.instanceId, s.Database, c.Credential, c.Priority, s.Role, c.Endpoint, c.Session.directedRead, c.SkipTLSVerify)
152157
if err != nil {
153158
c.PrintInteractiveError(err)
154159
continue
@@ -310,14 +315,18 @@ func (c *Cli) getInterpolatedPrompt() string {
310315
return prompt
311316
}
312317

313-
func createSession(projectId string, instanceId string, databaseId string, credential []byte, priority pb.RequestOptions_Priority, role string, endpoint string, directedRead *pb.DirectedReadOptions) (*Session, error) {
318+
func createSession(projectId string, instanceId string, databaseId string, credential []byte, priority pb.RequestOptions_Priority, role string, endpoint string, directedRead *pb.DirectedReadOptions, skipTLSVerify bool) (*Session, error) {
314319
var opts []option.ClientOption
315320
if credential != nil {
316321
opts = append(opts, option.WithCredentialsJSON(credential))
317322
}
318323
if endpoint != "" {
319324
opts = append(opts, option.WithEndpoint(endpoint))
320325
}
326+
if skipTLSVerify {
327+
creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
328+
opts = append(opts, option.WithGRPCDialOption(grpc.WithTransportCredentials(creds)))
329+
}
321330
return NewSession(projectId, instanceId, databaseId, priority, role, directedRead, opts...)
322331
}
323332

main.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,21 @@ type globalOptions struct {
3333
}
3434

3535
type spannerOptions struct {
36-
ProjectId string `short:"p" long:"project" env:"SPANNER_PROJECT_ID" description:"(required) GCP Project ID."`
37-
InstanceId string `short:"i" long:"instance" env:"SPANNER_INSTANCE_ID" description:"(required) Cloud Spanner Instance ID"`
38-
DatabaseId string `short:"d" long:"database" env:"SPANNER_DATABASE_ID" description:"(required) Cloud Spanner Database ID."`
39-
Execute string `short:"e" long:"execute" description:"Execute SQL statement and quit."`
40-
File string `short:"f" long:"file" description:"Execute SQL statement from file and quit."`
41-
Table bool `short:"t" long:"table" description:"Display output in table format for batch mode."`
42-
Verbose bool `short:"v" long:"verbose" description:"Display verbose output."`
43-
Credential string `long:"credential" description:"Use the specific credential file"`
44-
Prompt string `long:"prompt" description:"Set the prompt to the specified format"`
45-
HistoryFile string `long:"history" description:"Set the history file to the specified path"`
46-
Priority string `long:"priority" description:"Set default request priority (HIGH|MEDIUM|LOW)"`
47-
Role string `long:"role" description:"Use the specific database role"`
48-
Endpoint string `long:"endpoint" description:"Set the Spanner API endpoint (host:port)"`
49-
DirectedRead string `long:"directed-read" description:"Directed read option (replica_location:replica_type). The replicat_type is optional and either READ_ONLY or READ_WRITE"`
36+
ProjectId string `short:"p" long:"project" env:"SPANNER_PROJECT_ID" description:"(required) GCP Project ID."`
37+
InstanceId string `short:"i" long:"instance" env:"SPANNER_INSTANCE_ID" description:"(required) Cloud Spanner Instance ID"`
38+
DatabaseId string `short:"d" long:"database" env:"SPANNER_DATABASE_ID" description:"(required) Cloud Spanner Database ID."`
39+
Execute string `short:"e" long:"execute" description:"Execute SQL statement and quit."`
40+
File string `short:"f" long:"file" description:"Execute SQL statement from file and quit."`
41+
Table bool `short:"t" long:"table" description:"Display output in table format for batch mode."`
42+
Verbose bool `short:"v" long:"verbose" description:"Display verbose output."`
43+
Credential string `long:"credential" description:"Use the specific credential file"`
44+
Prompt string `long:"prompt" description:"Set the prompt to the specified format"`
45+
HistoryFile string `long:"history" description:"Set the history file to the specified path"`
46+
Priority string `long:"priority" description:"Set default request priority (HIGH|MEDIUM|LOW)"`
47+
Role string `long:"role" description:"Use the specific database role"`
48+
Endpoint string `long:"endpoint" description:"Set the Spanner API endpoint (host:port)"`
49+
DirectedRead string `long:"directed-read" description:"Directed read option (replica_location:replica_type). The replicat_type is optional and either READ_ONLY or READ_WRITE"`
50+
SkipTLSVerify bool `long:"skip-tls-verify" description:"Insecurely skip TLS verify"`
5051
}
5152

5253
func main() {
@@ -96,7 +97,7 @@ func main() {
9697
}
9798
}
9899

99-
cli, err := NewCli(opts.ProjectId, opts.InstanceId, opts.DatabaseId, opts.Prompt, opts.HistoryFile, cred, os.Stdin, os.Stdout, os.Stderr, opts.Verbose, priority, opts.Role, opts.Endpoint, directedRead)
100+
cli, err := NewCli(opts.ProjectId, opts.InstanceId, opts.DatabaseId, opts.Prompt, opts.HistoryFile, cred, os.Stdin, os.Stdout, os.Stderr, opts.Verbose, priority, opts.Role, opts.Endpoint, directedRead, opts.SkipTLSVerify)
100101
if err != nil {
101102
exitf("Failed to connect to Spanner: %v", err)
102103
}

0 commit comments

Comments
 (0)