Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add PSC support to proxy #1863

Merged
merged 5 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ status code.`)
"(*) Enables Automatic IAM Authentication for all instances")
pflags.BoolVar(&c.conf.PrivateIP, "private-ip", false,
"(*) Connect to the private ip address for all instances")
pflags.BoolVar(&c.conf.PSC, "psc", false,
"(*) Connect to the PSC endpoint for all instances")

v := viper.NewWithOptions(viper.EnvKeyReplacer(strings.NewReplacer("-", "_")))
v.SetEnvPrefix(envPrefix)
Expand Down Expand Up @@ -509,6 +511,11 @@ func parseConfig(cmd *Command, conf *proxy.Config, args []string) error {
return newBadCommandError("cannot specify --private-ip and --auto-ip together")
}

// If more than one IP type is set, error.
if conf.PrivateIP && conf.PSC {
return newBadCommandError("cannot specify --private-ip and --psc flags at the same time")
}

// If more than one auth method is set, error.
if conf.Token != "" && conf.CredentialsFile != "" {
return newBadCommandError("cannot specify --token and --credentials-file flags at the same time")
Expand Down Expand Up @@ -666,6 +673,15 @@ and re-try with just --auto-iam-authn`)
return newBadCommandError("cannot use --auto-ip with private-ip")
}

ic.PSC, err = parseBoolOpt(q, "psc")
if err != nil {
return err
}

if ic.PrivateIP != nil && ic.PSC != nil {
return newBadCommandError("cannot specify both private-ip and psc query params")
}

}
ics = append(ics, ic)
}
Expand Down
108 changes: 108 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,22 @@ func TestNewCommandArguments(t *testing.T) {
}},
}),
},
{
desc: "using the psc flag",
args: []string{"--psc", "proj:region:inst"},
want: withDefaults(&proxy.Config{
PSC: true,
}),
},
{
desc: "using the psc flag query param",
args: []string{"proj:region:inst?psc=true"},
want: withDefaults(&proxy.Config{
Instances: []proxy.InstanceConnConfig{{
PSC: pointer(true),
}},
}),
},
{
desc: "using the quota project flag",
args: []string{"--quota-project", "proj", "proj:region:inst"},
Expand Down Expand Up @@ -638,6 +654,14 @@ func TestNewCommandWithEnvironmentConfig(t *testing.T) {
PrivateIP: true,
}),
},
{
desc: "using the psc envvar",
envName: "CSQL_PROXY_PSC",
envValue: "true",
want: withDefaults(&proxy.Config{
PSC: true,
}),
},
{
desc: "using the quota project envvar",
envName: "CSQL_PROXY_QUOTA_PROJECT",
Expand Down Expand Up @@ -905,6 +929,79 @@ func TestPrivateIPQueryParams(t *testing.T) {
}
}

func TestPSCQueryParams(t *testing.T) {
tcs := []struct {
desc string
args []string
want *bool
}{
{
desc: "when the query string is absent",
args: []string{"proj:region:inst"},
want: nil,
},
{
desc: "when the query string has no value",
args: []string{"proj:region:inst?psc"},
want: pointer(true),
},
{
desc: "when the query string is true",
args: []string{"proj:region:inst?psc=true"},
want: pointer(true),
},
{
desc: "when the query string is True",
args: []string{"proj:region:inst?psc=True"},
want: pointer(true),
},
{
desc: "when the query string is (short) T",
args: []string{"proj:region:inst?psc=T"},
want: pointer(true),
},
{
desc: "when the query string is (short) t",
args: []string{"proj:region:inst?psc=t"},
want: pointer(true),
},
{
desc: "when the query string is false",
args: []string{"proj:region:inst?psc=false"},
want: pointer(false),
},
{
desc: "when the query string is (short) f",
args: []string{"proj:region:inst?psc=f"},
want: pointer(false),
},
{
desc: "when the query string is False",
args: []string{"proj:region:inst?psc=False"},
want: pointer(false),
},
{
desc: "when the query string is (short) F",
args: []string{"proj:region:inst?psc=F"},
want: pointer(false),
},
}
for _, tc := range tcs {
t.Run(tc.desc, func(t *testing.T) {
c, err := invokeProxyCommand(tc.args)
if err != nil {
t.Fatalf("command.Execute: %v", err)
}
if tc.want == nil && c.conf.Instances[0].PSC == nil {
return
}
if got := c.conf.Instances[0].PSC; *got != *tc.want {
t.Errorf("args = %v, want = %v, got = %v", tc.args, *tc.want, *got)
}
})
}
}

func TestNewCommandWithErrors(t *testing.T) {
tcs := []struct {
desc string
Expand Down Expand Up @@ -1064,6 +1161,17 @@ func TestNewCommandWithErrors(t *testing.T) {
"p:r:i?private-ip=true",
},
},
{
desc: "using private IP and psc query params",
args: []string{"p:r:i?private-ip=true&psc=true"},
},
{
desc: "using --private-ip with --psc",
args: []string{
"--private-ip", "--psc",
"p:r:i",
},
},
{
desc: "run-connection-test with fuse",
args: []string{
Expand Down
12 changes: 12 additions & 0 deletions internal/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ type InstanceConnConfig struct {
// PrivateIP tells the proxy to attempt to connect to the db instance's
// private IP address instead of the public IP address
PrivateIP *bool

// PSC tells the proxy to attempt to connect to the db instance's
// private service connect endpoint
PSC *bool
}

// Config contains all the configuration provided by the caller.
Expand Down Expand Up @@ -168,6 +172,10 @@ type Config struct {
// for all instances.
PrivateIP bool

// PSC enables connections via the database server's private service connect
// endpoint for all instances
PSC bool

// AutoIP supports a legacy behavior where the Proxy will connect to
// the first IP address returned from the SQL ADmin API response. This
// setting should be avoided and used only to support legacy Proxy
Expand Down Expand Up @@ -253,6 +261,10 @@ func dialOptions(c Config, i InstanceConnConfig) []cloudsqlconn.DialOption {
// add the option.
case i.PrivateIP != nil && *i.PrivateIP || i.PrivateIP == nil && c.PrivateIP:
opts = append(opts, cloudsqlconn.WithPrivateIP())
// If PSC is enabled at the instance level, or PSC is enabled globally
// add the option.
case i.PSC != nil && *i.PSC || i.PSC == nil && c.PSC:
opts = append(opts, cloudsqlconn.WithPSC())
case c.AutoIP:
opts = append(opts, cloudsqlconn.WithAutoIP())
default:
Expand Down