From 05bb4b27475aeee05e103657a9448f9e15771625 Mon Sep 17 00:00:00 2001 From: hessjc Date: Tue, 2 Jun 2026 18:19:56 +0000 Subject: [PATCH 1/6] feat: Support AI Developer Edition connections through the Cloud SQL Auth Proxy Cloud SQL AI Developer Edition instances allow connections through the SqlDataService. With this change and the corresponding chagnes in the Cloud SQL Go Connector, the Auth Proxy will allow users to connect to AIDE instances. Set the --sql-data flag to enable this support. --- .gitignore | 1 + build.sh | 62 +++++++++++++++++--- cmd/root.go | 18 ++++++ cmd/root_test.go | 95 ++++++++++++++++++++++++++++++ docs/cmd/cloud-sql-proxy.md | 2 + internal/proxy/proxy.go | 39 +++++++++++-- internal/proxy/proxy_test.go | 109 +++++++++++++++++++++++++++++++++++ 7 files changed, 314 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index de8224085..958b50e44 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /logs/ .tools test_results.txt +test-results diff --git a/build.sh b/build.sh index efdd6d303..5ad0c43c7 100755 --- a/build.sh +++ b/build.sh @@ -33,12 +33,25 @@ function clean() { ## build - Builds the project without running tests. function build() { - go build -o ./cloud-sql-proxy main.go + local metadata="${1:-}" + local ldflags="" + if [[ -n "$metadata" ]] ; then + ldflags="-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=$metadata" + fi + go build -ldflags "$ldflags" -o ./cloud-sql-proxy main.go } ## test - Runs local unit tests. function test() { - go test -v -race -cover -short ./... + get_golang_tool 'go-junit-report' 'jstemmer/go-junit-report' 'github.com/jstemmer/go-junit-report/v2' + mkdir -p test-results + local args=( "./..." ) + if [[ "$#" -gt 0 ]] ; then + args=( "$@" ) + fi + go test -v -race -cover -short "${args[@]}" -json \ + | .tools/go-junit-report -iocopy -parser gojson -out test-results/unit.xml \ + | jq -j 'select(.Output) | .Output ' } ## e2e - Runs end-to-end integration tests. @@ -53,7 +66,11 @@ function e2e() { # e2e_ci - Run end-to-end integration tests in the CI system. # This assumes that the secrets in the env vars are already set. function e2e_ci() { - go test -race -v ./... | tee test_results.txt + get_golang_tool 'go-junit-report' 'jstemmer/go-junit-report' 'github.com/jstemmer/go-junit-report/v2' + mkdir -p test-results + go test -race -v ./... -json \ + | .tools/go-junit-report -iocopy -parser gojson -out test-results/e2e.xml \ + | jq -j 'select(.Output) | .Output ' } function get_golang_tool() { @@ -227,16 +244,47 @@ function write_e2e_env(){ done # Set IAM User env vars to the local gcloud user - echo "export MYSQL_IAM_USER='${local_user%%@*}'" - echo "export POSTGRES_USER_IAM='$local_user'" + echo "export MYSQL_IAM_USER='$(iam_user_mysql)'" + echo "export POSTGRES_USER_IAM='$(iam_user_pg)'" } > "$1" } +function iam_user_pg() { + # Truncate the suffix `.iam.gserviceaccount.com` if it exists. Otherwise return the email. + local email + local pguser + + email="$(iam_user_email)" + pguser="${email%%.iam.gserviceaccount.com}" + if [[ -n "$pguser" ]] ; then + echo "$pguser" + else + echo "$email" + fi + +} + +function iam_user_mysql() { + # Truncate the part after the @ + local email + local pguser + + email=$(iam_user_email) + mysqluser="${email%%@*}" + echo "$mysqluser" +} + +function iam_user_email() { + gcloud auth list --format json | jq -r '.[] | select (.status == "ACTIVE") | .account' +} + + ## build_image - Builds and pushes the proxy container image using local source. -## Usage: ./build.sh build_image [image-url] +## Usage: ./build.sh build_image [image-url] [metadata] function build_image() { local image_url="${1:-}" + local metadata="${2:-container}" local push_arg="" if [[ -n "$image_url" ]]; then @@ -254,7 +302,7 @@ function build_image() { trap cleanup_build EXIT echo "Building binary locally..." - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=container" -o cloud-sql-proxy + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=$metadata" -o cloud-sql-proxy echo "Creating temporary Dockerfile..." cat > Dockerfile.local < 0 && c.conf.Instances[0].SQLDataEnabled != nil { + t.Fatalf("args = %v, want nil, got = %v", tc.args, *c.conf.Instances[0].SQLDataEnabled) + } + return + } + if len(c.conf.Instances) == 0 { + t.Fatal("expected at least one instance") + } + got := c.conf.Instances[0].SQLDataEnabled + if got == nil { + t.Fatalf("args = %v, want = %v, got = nil", tc.args, *tc.want) + } + if *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 @@ -1152,6 +1239,14 @@ func TestNewCommandWithErrors(t *testing.T) { desc: "when the iam authn login query param contains multiple values", args: []string{"proj:region:inst?auto-iam-authn=true&auto-iam-authn=false"}, }, + { + desc: "when the sql-data query param contains multiple values", + args: []string{"proj:region:inst?sql-data=true&sql-data=false"}, + }, + { + desc: "when the sql-data query param is bogus", + args: []string{"proj:region:inst?sql-data=nope"}, + }, { desc: "when the iam authn login query param is bogus", args: []string{"proj:region:inst?auto-iam-authn=nope"}, diff --git a/docs/cmd/cloud-sql-proxy.md b/docs/cmd/cloud-sql-proxy.md index 6454113ec..ab5260df2 100644 --- a/docs/cmd/cloud-sql-proxy.md +++ b/docs/cmd/cloud-sql-proxy.md @@ -279,7 +279,9 @@ cloud-sql-proxy INSTANCE_CONNECTION_NAME... [flags] status code. --skip-failed-instance-config If set, the Proxy will skip any instances that are invalid/unreachable ( only applicable to Unix sockets) + --sql-data Enable SQL Data to tunnel through the Cloud SQL Admin API without needing network access to your public or private IP --sqladmin-api-endpoint string API endpoint for all Cloud SQL Admin API requests. (default: https://sqladmin.googleapis.com) + --sqldata-api-endpoint string Override the SQL Data API endpoint -l, --structured-logs Enable structured logging with LogEntry format --telemetry-prefix string Prefix for Cloud Monitoring metrics. --telemetry-project string Enable Cloud Monitoring and Cloud Trace with the provided project ID. diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index ff58c552a..5c0043197 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -95,6 +95,8 @@ type InstanceConnConfig struct { // necessary. If set, UnixSocketPath takes precedence over UnixSocket, Addr // and Port. UnixSocketPath string + // SQLDataEnabled enables connections through the SqlDataService for this connection. + SQLDataEnabled *bool // IAMAuthN enables automatic IAM DB Authentication for the instance. // MySQL and Postgres only. If it is nil, the value was not specified. IAMAuthN *bool @@ -200,6 +202,11 @@ type Config struct { // of a request context, e.g., Cloud Run. LazyRefresh bool + // SQLDataEnabled configures the dialer to use the SQL Data API. + SQLDataEnabled bool + // SQLDataEndpoint configures the endpoint of the SQL Data service. + SQLDataEndpoint string + // Instances are configuration for individual instances. Instance // configuration takes precedence over global configuration. Instances []InstanceConnConfig @@ -282,6 +289,9 @@ func dialOptions(c Config, i InstanceConnConfig) []cloudsqlconn.DialOption { if i.IAMAuthN != nil { opts = append(opts, cloudsqlconn.WithDialIAMAuthN(*i.IAMAuthN)) } + if i.SQLDataEnabled != nil && *i.SQLDataEnabled || c.SQLDataEnabled { + opts = append(opts, cloudsqlconn.WithSQLData()) + } switch { // If private IP is enabled at the instance level, or private IP is enabled globally @@ -469,6 +479,10 @@ func (c *Config) DialerOptions(l cloudsql.Logger) ([]cloudsqlconn.Option, error) opts = append(opts, cloudsqlconn.WithLazyRefresh()) } + if c.SQLDataEndpoint != "" { + opts = append(opts, cloudsqlconn.WithSQLDataEndpoint(c.SQLDataEndpoint)) + } + return opts, nil } @@ -564,8 +578,12 @@ func NewClient(ctx context.Context, d cloudsql.Dialer, l cloudsql.Logger, conf * return configureFUSE(c, conf) } + // unless the proxy is in SqlDataEnabled mode, initiate a refresh operation to warm the cache for _, inst := range conf.Instances { - // Initiate refresh operation and warm the cache. + // Skip instances with SqlDataEnabled + if conf.SQLDataEnabled || inst.SQLDataEnabled != nil && *inst.SQLDataEnabled { + continue + } go func(name string) { _, _ = d.EngineVersion(ctx, name) }(inst.Name) } @@ -859,6 +877,10 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi np = inst.Port case conf.Port != 0: np = pc.nextPort() + case conf.SQLDataEnabled || inst.SQLDataEnabled != nil && *inst.SQLDataEnabled: + // Only Postgres is supported by the SqlDataService + // when more engines are supported, this code will need to change. + np = pc.nextDBPort("POSTGRES") default: version, err := c.dialer.EngineVersion(ctx, inst.Name) // Exit if the port is not specified for inactive instance @@ -873,10 +895,17 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi } else { network = "unix" - version, err := c.dialer.EngineVersion(ctx, inst.Name) - if err != nil { - c.logger.Errorf("[%v] could not resolve instance version: %v", inst.Name, err) - return nil, err + var version string + switch { + case conf.SQLDataEnabled || inst.SQLDataEnabled != nil && *inst.SQLDataEnabled: + version = "POSTGRES" + default: + var err error + version, err = c.dialer.EngineVersion(ctx, inst.Name) + if err != nil { + c.logger.Errorf("[%v] could not resolve instance version: %v", inst.Name, err) + return nil, err + } } address, err = newUnixSocketMount(inst, conf.UnixSocket, strings.HasPrefix(version, "POSTGRES")) diff --git a/internal/proxy/proxy_test.go b/internal/proxy/proxy_test.go index 2de5421f5..c529d6a84 100644 --- a/internal/proxy/proxy_test.go +++ b/internal/proxy/proxy_test.go @@ -33,6 +33,11 @@ import ( "github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/internal/proxy" ) +var ( + sd = "proj:region:sd" + sd2 = "proj:region:sd2" +) + var testLogger = log.NewStdLogger(os.Stdout, os.Stdout) type fakeDialer struct { @@ -114,6 +119,12 @@ func createTempDir(t *testing.T) (string, func()) { } } +// pointer returns the address of v and makes it easy to take the address of a +// predeclared identifier. +func pointer[T any](v T) *T { + return &v +} + func TestClientInitialization(t *testing.T) { ctx := context.Background() testDir, cleanup := createTempDir(t) @@ -213,6 +224,47 @@ func TestClientInitialization(t *testing.T) { "127.0.0.1:1434", }, }, + { + desc: "with SQL Data enabled globally defaulting to Postgres port", + in: &proxy.Config{ + Addr: "127.0.0.1", + SQLDataEnabled: true, + Instances: []proxy.InstanceConnConfig{ + {Name: sd}, + {Name: sd2}, + }, + }, + wantTCPAddrs: []string{ + "127.0.0.1:5432", + "127.0.0.1:5433", + }, + }, + { + desc: "with SQL Data enabled per-instance defaulting to Postgres port", + in: &proxy.Config{ + Addr: "127.0.0.1", + Instances: []proxy.InstanceConnConfig{ + {Name: sd, SQLDataEnabled: pointer(true)}, + {Name: sd2, SQLDataEnabled: pointer(true)}, + }, + }, + wantTCPAddrs: []string{ + "127.0.0.1:5432", + "127.0.0.1:5433", + }, + }, + { + desc: "with SQL Data enabled but explicit port", + in: &proxy.Config{ + Addr: "127.0.0.1", + Instances: []proxy.InstanceConnConfig{ + {Name: sd, SQLDataEnabled: pointer(true), Port: 60000}, + }, + }, + wantTCPAddrs: []string{ + "127.0.0.1:60000", + }, + }, { desc: "with a Unix socket", in: &proxy.Config{ @@ -589,6 +641,7 @@ func TestClientNotifiesCallerOnServe(t *testing.T) { if err != nil { t.Fatalf("want error = nil, got = %v", err) } + defer c.Close() done := make(chan struct{}) notify := func() { close(done) } @@ -650,6 +703,62 @@ func TestClientConnCount(t *testing.T) { verifyOpen(t, 1) } +func TestSQLDataWarmup(t *testing.T) { + tcs := []struct { + desc string + in *proxy.Config + want int + }{ + { + desc: "standard warmup", + in: &proxy.Config{ + Instances: []proxy.InstanceConnConfig{{Name: "proj:reg:inst", Port: 30104}}, + }, + want: 1, + }, + { + desc: "warmup skipped globally", + in: &proxy.Config{ + SQLDataEnabled: true, + Instances: []proxy.InstanceConnConfig{{Name: "proj:reg:inst", Port: 30105}}, + }, + want: 0, + }, + { + desc: "warmup skipped per-instance", + in: &proxy.Config{ + Instances: []proxy.InstanceConnConfig{{ + Name: "proj:reg:inst", + Port: 30106, + SQLDataEnabled: pointer(true), + }}, + }, + want: 0, + }, + } + + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + d := &fakeDialer{} + c, err := proxy.NewClient(context.Background(), d, testLogger, tc.in, nil) + if err != nil { + t.Fatalf("proxy.NewClient error: %v", err) + } + defer c.Close() + + var got int + for i := 0; i < 10; i++ { + got = d.engineVersionAttempts() + if got == tc.want { + return + } + time.Sleep(100 * time.Millisecond) + } + t.Fatalf("warmup attempts, want = %v, got = %v", tc.want, got) + }) + } +} + func TestCheckConnections(t *testing.T) { in := &proxy.Config{ Addr: "127.0.0.1", From beb3eeb02d5968b123ed94d04838c8ce1ef2ef04 Mon Sep 17 00:00:00 2001 From: hessjc Date: Tue, 2 Jun 2026 18:19:56 +0000 Subject: [PATCH 2/6] Internal changes to skip fuse on Kokoro tests. --- internal/proxy/fuse_test.go | 30 ++++++++++++++++++++++++++++++ tests/connection_test.go | 2 +- tests/fuse_test.go | 3 +++ tests/postgres_test.go | 3 +++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/internal/proxy/fuse_test.go b/internal/proxy/fuse_test.go index 02face315..1048d27ba 100644 --- a/internal/proxy/fuse_test.go +++ b/internal/proxy/fuse_test.go @@ -80,6 +80,9 @@ func TestFUSEREADME(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } dir := randTmpDir(t) d := &fakeDialer{} _, _, cleanup := newTestClient(t, d, dir, randTmpDir(t)) @@ -143,6 +146,9 @@ func TestFUSEDialInstance(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) fuseTempDir := randTmpDir(t) tcs := []struct { @@ -201,6 +207,9 @@ func TestFUSEAcceptErrorReturnedFromServe(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) fuseTempDir := randTmpDir(t) @@ -255,6 +264,9 @@ func TestFUSEReadDir(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) _, _, cleanup := newTestClient(t, &fakeDialer{}, fuseDir, randTmpDir(t)) defer cleanup() @@ -284,6 +296,9 @@ func TestLookupIgnoresContext(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } // create context and cancel it immediately ctx, cancel := context.WithCancel(context.Background()) cancel() @@ -305,6 +320,9 @@ func TestFUSEErrors(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } ctx := context.Background() d := &fakeDialer{} c, _, _ := newTestClient(t, d, randTmpDir(t), randTmpDir(t)) @@ -345,6 +363,9 @@ func TestFUSEWithBadInstanceName(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) d := &fakeDialer{} _, _, cleanup := newTestClient(t, d, fuseDir, randTmpDir(t)) @@ -364,6 +385,9 @@ func TestFUSECheckConnections(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) d := &fakeDialer{} c, _, cleanup := newTestClient(t, d, fuseDir, randTmpDir(t)) @@ -399,6 +423,9 @@ func TestFUSEClose(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } fuseDir := randTmpDir(t) d := &fakeDialer{} c, _, _ := newTestClient(t, d, fuseDir, randTmpDir(t)) @@ -422,6 +449,9 @@ func TestFUSEWithBadDir(t *testing.T) { if testing.Short() { t.Skip("skipping fuse tests in short mode.") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } conf := &proxy.Config{FUSEDir: "/not/a/dir", FUSETempDir: randTmpDir(t)} _, err := proxy.NewClient(context.Background(), &fakeDialer{}, testLogger, conf, nil) if err == nil { diff --git a/tests/connection_test.go b/tests/connection_test.go index 84f7e7bd1..accf27975 100644 --- a/tests/connection_test.go +++ b/tests/connection_test.go @@ -61,7 +61,7 @@ func removeAuthEnvVar(t *testing.T) (*oauth2.Token, string, func()) { func keyfile(t *testing.T) string { path := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") if path == "" { - t.Fatal("GOOGLE_APPLICATION_CREDENTIALS not set") + t.Skip("GOOGLE_APPLICATION_CREDENTIALS not set") } creds, err := os.ReadFile(path) if err != nil { diff --git a/tests/fuse_test.go b/tests/fuse_test.go index a1b57368f..7898979a8 100644 --- a/tests/fuse_test.go +++ b/tests/fuse_test.go @@ -32,6 +32,9 @@ func TestPostgresFUSEConnect(t *testing.T) { if testing.Short() { t.Skip("skipping Postgres integration tests") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } tmpDir, cleanup := createTempDir(t) defer cleanup() diff --git a/tests/postgres_test.go b/tests/postgres_test.go index fe6400d02..341c47414 100644 --- a/tests/postgres_test.go +++ b/tests/postgres_test.go @@ -247,6 +247,9 @@ func TestPostgresIAMDBAuthn(t *testing.T) { if testing.Short() { t.Skip("skipping Postgres integration tests") } + if os.Getenv("SKIP_FUSE_E2E_TESTS") == "true" { + t.Skip("skipping Postgres FUSE integration tests because SKIP_FUSE_E2E_TESTS is set") + } requirePostgresVars(t) if *postgresIAMUser == "" { t.Fatal("'postgres_user_iam' not set") From 5c2146ac507359b1af9e850fe2cccb19afc7cc13 Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Mon, 22 Jun 2026 23:28:20 +0000 Subject: [PATCH 3/6] fix: force tcp4/tcp6 based on IP address type This avoids binding to IPv6 wildcard [::] when 0.0.0.0 is requested, which can cause connection refused errors for IPv4 loopback (127.0.0.1) clients in environments where bindv6only is enabled. --- internal/proxy/proxy.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 5c0043197..4d192a7f0 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -870,6 +870,13 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi if inst.Addr != "" { a = inst.Addr } + if ip := net.ParseIP(a); ip != nil { + if ip.To4() != nil { + network = "tcp4" + } else { + network = "tcp6" + } + } var np int switch { From 1d9967a188d16540cd4f449d732ea4604f911e84 Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Tue, 23 Jun 2026 00:07:55 +0000 Subject: [PATCH 4/6] fix: add -buildvcs=false to go build in build.sh --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 5ad0c43c7..0b0cc65c6 100755 --- a/build.sh +++ b/build.sh @@ -38,7 +38,7 @@ function build() { if [[ -n "$metadata" ]] ; then ldflags="-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=$metadata" fi - go build -ldflags "$ldflags" -o ./cloud-sql-proxy main.go + go build -buildvcs=false -ldflags "$ldflags" -o ./cloud-sql-proxy main.go } ## test - Runs local unit tests. @@ -302,7 +302,7 @@ function build_image() { trap cleanup_build EXIT echo "Building binary locally..." - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=$metadata" -o cloud-sql-proxy + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs=false -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=$metadata" -o cloud-sql-proxy echo "Creating temporary Dockerfile..." cat > Dockerfile.local < Date: Tue, 23 Jun 2026 20:50:23 +0000 Subject: [PATCH 5/6] Update cloud-sql-go-connector to v1.22.0 and add --sql-data-endpoint alias Update cloud-sql-go-connector dependency to v1.22.0 in go.mod. Create --sql-data-endpoint as a hidden alias for --sqldata-api-endpoint, supporting both CLI flags and environment variables. TAG=agy CONV=9333d162-5ca9-4d37-8cf4-47ce7a321b70 --- Dockerfile.alpine | 2 +- Dockerfile.bookworm | 2 +- cmd/root.go | 17 ++++++++++++++--- cmd/root_test.go | 15 +++++++++++++++ go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 6 files changed, 58 insertions(+), 32 deletions(-) diff --git a/Dockerfile.alpine b/Dockerfile.alpine index b31b9a6f4..04f900640 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -26,7 +26,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=container.alpine" # Final stage -FROM alpine:3@sha256:4d889c14e7d5a73929ab00be2ef8ff22437e7cbc545931e52554a7b00e123d8b +FROM alpine:3@sha256:79ff19e9084a00eece421b2523fb93e22d730e2c0e525905de047e848e56d95f LABEL org.opencontainers.image.source="https://github.com/GoogleCloudPlatform/cloud-sql-proxy" diff --git a/Dockerfile.bookworm b/Dockerfile.bookworm index 12fbf5799..22536a1e3 100644 --- a/Dockerfile.bookworm +++ b/Dockerfile.bookworm @@ -26,7 +26,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=container.bookworm" # Final stage -FROM gcr.io/cloud-marketplace-containers/google/debian12@sha256:d10f3a95f20cdf7e3d9d7cfbdcbdcc6ab26643714dab2d286e3030971d768188 +FROM gcr.io/cloud-marketplace-containers/google/debian12@sha256:7f782ace3172c0380383b12f11855931c181cf8128710314229fd21cc77d2bf1 LABEL org.opencontainers.image.source="https://github.com/GoogleCloudPlatform/cloud-sql-proxy" diff --git a/cmd/root.go b/cmd/root.go index 01bdf1ef2..7904b458c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -494,6 +494,12 @@ func NewCommand(opts ...Option) *Command { // Flags that apply only to the root command localFlags := rootCmd.Flags() + localFlags.SetNormalizeFunc(func(_ *pflag.FlagSet, name string) pflag.NormalizedName { + if name == "sql-data-endpoint" { + return pflag.NormalizedName("sqldata-api-endpoint") + } + return pflag.NormalizedName(name) + }) // Flags that apply to all sub-commands globalFlags := rootCmd.PersistentFlags() @@ -626,9 +632,14 @@ func loadConfig(c *Command, args []string, opts []Option) error { c.Flags().VisitAll(func(f *pflag.Flag) { // Override any unset flags with Viper values to use the pflags // object as a single source of truth. - if !f.Changed && v.IsSet(f.Name) { - val := v.Get(f.Name) - _ = c.Flags().Set(f.Name, fmt.Sprintf("%v", val)) + if !f.Changed { + if v.IsSet(f.Name) { + val := v.Get(f.Name) + _ = c.Flags().Set(f.Name, fmt.Sprintf("%v", val)) + } else if f.Name == "sqldata-api-endpoint" && v.IsSet("sql-data-endpoint") { + val := v.Get("sql-data-endpoint") + _ = c.Flags().Set(f.Name, fmt.Sprintf("%v", val)) + } } }) diff --git a/cmd/root_test.go b/cmd/root_test.go index fc0b1c1c4..3479fc15b 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -480,6 +480,13 @@ func TestNewCommandArguments(t *testing.T) { SQLDataEndpoint: "https://test.googleapis.com", }), }, + { + desc: "using the sql-data-endpoint flag alias", + args: []string{"--sql-data-endpoint", "https://test.googleapis.com", "proj:region:inst"}, + want: withDefaults(&proxy.Config{ + SQLDataEndpoint: "https://test.googleapis.com", + }), + }, { desc: "using the sql-data query param", args: []string{"proj:region:inst?sql-data=true"}, @@ -860,6 +867,14 @@ func TestNewCommandWithEnvironmentConfig(t *testing.T) { SQLDataEndpoint: "https://test.googleapis.com", }), }, + { + desc: "using the sql-data-endpoint envvar alias", + envName: "CSQL_PROXY_SQL_DATA_ENDPOINT", + envValue: "https://test.googleapis.com", + want: withDefaults(&proxy.Config{ + SQLDataEndpoint: "https://test.googleapis.com", + }), + }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { diff --git a/go.mod b/go.mod index bdda07c1d..68d08a3ee 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/GoogleCloudPlatform/cloud-sql-proxy/v2 go 1.25.8 require ( - cloud.google.com/go/cloudsqlconn v1.21.2 + cloud.google.com/go/cloudsqlconn v1.22.0 contrib.go.opencensus.io/exporter/prometheus v0.4.2 contrib.go.opencensus.io/exporter/stackdriver v0.13.14 github.com/coreos/go-systemd/v22 v22.7.0 @@ -18,7 +18,7 @@ require ( go.opencensus.io v0.24.0 golang.org/x/oauth2 v0.36.0 golang.org/x/sys v0.46.0 - google.golang.org/api v0.284.0 + google.golang.org/api v0.286.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -34,7 +34,7 @@ require ( github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -53,10 +53,10 @@ require ( github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.3.1 // indirect + github.com/pelletier/go-toml/v2 v2.4.1 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.68.1 // indirect + github.com/prometheus/common v0.69.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect github.com/prometheus/prometheus v0.312.0 // indirect github.com/prometheus/statsd_exporter v0.30.0 // indirect @@ -75,13 +75,13 @@ require ( go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.53.0 // indirect - golang.org/x/net v0.55.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/sync v0.21.0 // indirect golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto v0.0.0-20260608224507-4308a22a1bab // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260608224507-4308a22a1bab // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260608224507-4308a22a1bab // indirect + google.golang.org/genproto v0.0.0-20260622175928-b703f567277d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260622175928-b703f567277d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260622175928-b703f567277d // indirect google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/go.sum b/go.sum index d68b5c98f..758347e2f 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/cloudsqlconn v1.21.2 h1:Iw/3W+6eIB9AChWFF2wlqLwpgaZ+DOX2DBUKKfsSDMI= -cloud.google.com/go/cloudsqlconn v1.21.2/go.mod h1:AXcbXAjdud2Hl6JLe80VHCaOjAsvh8O/JgQnhrRvJl8= +cloud.google.com/go/cloudsqlconn v1.22.0 h1:4+uh5gGbjmFzitCD9owKZhwjBN2U+4sWxD9gJjcpOeE= +cloud.google.com/go/cloudsqlconn v1.22.0/go.mod h1:AXcbXAjdud2Hl6JLe80VHCaOjAsvh8O/JgQnhrRvJl8= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -107,8 +107,8 @@ github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= +github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= @@ -268,8 +268,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc= -github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pelletier/go-toml/v2 v2.4.1 h1:j5OMOImsH+j2k7GJ5YO+RxfWwohNiH6t5zB/+h3bagc= +github.com/pelletier/go-toml/v2 v2.4.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -301,8 +301,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.68.1 h1:omjRRl4QP4komogpXuhfeOiisQg7xdy8VM1UY+pStaY= -github.com/prometheus/common v0.68.1/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= +github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= +github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -459,8 +459,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -603,8 +603,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.284.0 h1:i+cKTgeQRcRySkP7QTl5PDO7/pAm8EcMFIUMlNbk4Vc= -google.golang.org/api v0.284.0/go.mod h1:AU44fU+XVZOCcd8uLaBIa/ZgzgPf/0qqY3+m7lQaado= +google.golang.org/api v0.286.0 h1:TdTXMvzYKnWV1/lPbCdbXRqBrkDqjPto22H2xeZZ8LI= +google.golang.org/api v0.286.0/go.mod h1:NlOlUIr8MPoIhT9Bb/oUnRuHbJOLwxb6JSYJM8Yz+jQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -640,12 +640,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20260608224507-4308a22a1bab h1:bG8JpL3dfsvJKRgrh7yMkswdxzBqQDRYqkLDHo3+708= -google.golang.org/genproto v0.0.0-20260608224507-4308a22a1bab/go.mod h1:cVHIikDNAdx8ISZeW+2rYkEMf3xn0GSaBYmVnWXQBUo= -google.golang.org/genproto/googleapis/api v0.0.0-20260608224507-4308a22a1bab h1:Foefixyu0l973HSYkX8Etw/fPxAmKRhyMGwuqXFiVI0= -google.golang.org/genproto/googleapis/api v0.0.0-20260608224507-4308a22a1bab/go.mod h1:KdNqO+rCIWgFumrNBSEDlDNrkrQnpkax7Tv1WxNY8V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260608224507-4308a22a1bab h1:cY0oV1VnAqvaim8VsR8ZyEKAudzbRJMRGwD3W/L7yOw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260608224507-4308a22a1bab/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto v0.0.0-20260622175928-b703f567277d h1:CP5omUq8AJTiWMrPKM1WRLJ7zZeXd9OPcQD3TbBNAyY= +google.golang.org/genproto v0.0.0-20260622175928-b703f567277d/go.mod h1:DrwuGJgFSEVNpv3S5Q5VxhRTvdnjauw9GtvwVOEARfA= +google.golang.org/genproto/googleapis/api v0.0.0-20260622175928-b703f567277d h1:xr2lwHI91bn3UiXcnyzRMQjp2LRiM8wEHzwUaE0YhTs= +google.golang.org/genproto/googleapis/api v0.0.0-20260622175928-b703f567277d/go.mod h1:O0ZOWSrfWfJ+Z5HbwZ+wNtHsg/vk1k2C/w67eww8PfQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260622175928-b703f567277d h1:mpAgMyM9vQHxycBlDq50y1VHpfSfVwzXvrQKtYbXuUY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260622175928-b703f567277d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= From dd3178785da2c9850ee52fdd0d520792d9e9805f Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Thu, 25 Jun 2026 21:30:17 +0000 Subject: [PATCH 6/6] Fix code review issues. --- Dockerfile.bookworm | 2 +- build.sh | 2 +- cmd/root.go | 14 ++++++++++++-- cmd/root_test.go | 7 +++++++ go.mod | 6 +++--- go.sum | 12 ++++++------ internal/proxy/proxy.go | 2 +- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Dockerfile.bookworm b/Dockerfile.bookworm index 22536a1e3..bfa66e7a6 100644 --- a/Dockerfile.bookworm +++ b/Dockerfile.bookworm @@ -26,7 +26,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -ldflags "-X github.com/GoogleCloudPlatform/cloud-sql-proxy/v2/cmd.metadataString=container.bookworm" # Final stage -FROM gcr.io/cloud-marketplace-containers/google/debian12@sha256:7f782ace3172c0380383b12f11855931c181cf8128710314229fd21cc77d2bf1 +FROM gcr.io/cloud-marketplace-containers/google/debian12@sha256:8705219e4580f8c36633a84b491d35a66c3e788e81161d6b5f370daa948b9402 LABEL org.opencontainers.image.source="https://github.com/GoogleCloudPlatform/cloud-sql-proxy" diff --git a/build.sh b/build.sh index 0b0cc65c6..eae421672 100755 --- a/build.sh +++ b/build.sh @@ -268,7 +268,7 @@ function iam_user_pg() { function iam_user_mysql() { # Truncate the part after the @ local email - local pguser + local mysqluser email=$(iam_user_email) mysqluser="${email%%@*}" diff --git a/cmd/root.go b/cmd/root.go index 7904b458c..a876e3004 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -823,8 +823,18 @@ func parseConfig(cmd *Command, conf *proxy.Config, args []string) error { } // 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") + var ipTypes int + if conf.PrivateIP { + ipTypes++ + } + if conf.PSC { + ipTypes++ + } + if conf.SQLDataEnabled { + ipTypes++ + } + if ipTypes > 1 { + return newBadCommandError("cannot specify --private-ip, --psc, and --sql-data flags at the same time") } // If more than one auth method is set, error. diff --git a/cmd/root_test.go b/cmd/root_test.go index 3479fc15b..5641e6ca2 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -1295,6 +1295,13 @@ func TestNewCommandWithErrors(t *testing.T) { "p:r:i", }, }, + { + desc: "using --private-ip with --sql-data", + args: []string{ + "--private-ip", "--sql-data", + "p:r:i", + }, + }, { desc: "using private-ip query param with --auto-ip", args: []string{ diff --git a/go.mod b/go.mod index 68d08a3ee..9c1d9712b 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/GoogleCloudPlatform/cloud-sql-proxy/v2 go 1.25.8 require ( - cloud.google.com/go/cloudsqlconn v1.22.0 + cloud.google.com/go/cloudsqlconn v1.22.1 contrib.go.opencensus.io/exporter/prometheus v0.4.2 contrib.go.opencensus.io/exporter/stackdriver v0.13.14 github.com/coreos/go-systemd/v22 v22.7.0 @@ -45,7 +45,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.16 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.17 // indirect github.com/googleapis/gax-go/v2 v2.22.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -53,7 +53,7 @@ require ( github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.4.1 // indirect + github.com/pelletier/go-toml/v2 v2.4.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.69.0 // indirect diff --git a/go.sum b/go.sum index 758347e2f..2e3a45611 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/cloudsqlconn v1.22.0 h1:4+uh5gGbjmFzitCD9owKZhwjBN2U+4sWxD9gJjcpOeE= -cloud.google.com/go/cloudsqlconn v1.22.0/go.mod h1:AXcbXAjdud2Hl6JLe80VHCaOjAsvh8O/JgQnhrRvJl8= +cloud.google.com/go/cloudsqlconn v1.22.1 h1:c4HkWMSV4pDL8kJid+nIuF+6iE07pR5Mn/sRVY17wf4= +cloud.google.com/go/cloudsqlconn v1.22.1/go.mod h1:p7l+u0ThOzSvC5a4fkywi1hEyD8S709X1zEqux9tsq0= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -205,8 +205,8 @@ github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.16 h1:F/VPrx0YPBdksZJQdCAp0WUsqnNmZpUZszzfYt0M5Dw= -github.com/googleapis/enterprise-certificate-proxy v0.3.16/go.mod h1:9Yb0eAkH/Xqhvv3zbeKf/+wMJqCeocWc6KIhDvEAuYE= +github.com/googleapis/enterprise-certificate-proxy v0.3.17 h1:73NfMHdiqo9JFU9+7a5ExpVa10/R29pXfZIaW559nrg= +github.com/googleapis/enterprise-certificate-proxy v0.3.17/go.mod h1:rSEsBUemEBZEexP2y6jPp16LUmUbjmSbcPMQizR0o4k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4= @@ -268,8 +268,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pelletier/go-toml/v2 v2.4.1 h1:j5OMOImsH+j2k7GJ5YO+RxfWwohNiH6t5zB/+h3bagc= -github.com/pelletier/go-toml/v2 v2.4.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pelletier/go-toml/v2 v2.4.2 h1:M2fKKbmyvI+hGId/D0W64qDBMVhJnNR10O5gIbMc//Q= +github.com/pelletier/go-toml/v2 v2.4.2/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 4d192a7f0..af8f3e768 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -885,7 +885,7 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi case conf.Port != 0: np = pc.nextPort() case conf.SQLDataEnabled || inst.SQLDataEnabled != nil && *inst.SQLDataEnabled: - // Only Postgres is supported by the SqlDataService + // TODO: Only Postgres is supported by the SqlDataService // when more engines are supported, this code will need to change. np = pc.nextDBPort("POSTGRES") default: