Skip to content

Commit 89f4117

Browse files
committed
feat: Implement the instances-metadata flag in proxy v2 compatibility mode.
1 parent 064ffa8 commit 89f4117

3 files changed

Lines changed: 122 additions & 45 deletions

File tree

cmd/cloud_sql_proxy/cloud_sql_proxy.go

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -761,23 +761,50 @@ use the value from the flag, Not compatible with -fuse.`,
761761
}
762762

763763
func main() {
764-
translatedArgs, logDebugStdout, verbose, ok := translateV2Args()
765-
if !ok {
766-
code := runProxy()
767-
os.Exit(code)
764+
translatedArgs, logDebugStdout, verbose, unsupported, legacySet, v2Compat, v2Mode, ok := translateV2Args()
765+
766+
if v2Mode {
767+
v2cmd := proxyv2cmd.NewCommand()
768+
v2cmd.SetArgs(translatedArgs)
769+
proxyv2cmd.ExecuteCommand(v2cmd)
770+
return
768771
}
769772

770-
opts := []proxyv2cmd.Option{
771-
proxyv2cmd.WithProxyV1Compatibility(),
772-
proxyv2cmd.WithProxyV1Verbose(verbose),
773+
if ok {
774+
fmt.Fprintln(os.Stderr, "This proxy running Auth Proxy v2 in compatibility mode.")
775+
fmt.Fprintln(os.Stderr, "To use Proxy v1, add the -legacy-v1-proxy flag.")
776+
777+
opts := []proxyv2cmd.Option{
778+
proxyv2cmd.WithProxyV1Compatibility(),
779+
proxyv2cmd.WithProxyV1Verbose(verbose),
780+
}
781+
if logDebugStdout {
782+
opts = append(opts, proxyv2cmd.WithProxyV1LogDebugStdout())
783+
}
784+
785+
v2cmd := proxyv2cmd.NewCommand(opts...)
786+
v2cmd.SetArgs(translatedArgs)
787+
proxyv2cmd.ExecuteCommand(v2cmd)
788+
return
789+
}
790+
791+
// Translation failed
792+
if v2Compat && len(unsupported) > 0 {
793+
fmt.Fprintf(os.Stderr, "Error: -v2-compat flag is set, but the following flags are not supported in v2 compatibility mode: %s\n", strings.Join(unsupported, ", "))
794+
os.Exit(1)
773795
}
774-
if logDebugStdout {
775-
opts = append(opts, proxyv2cmd.WithProxyV1LogDebugStdout())
796+
797+
fmt.Fprintln(os.Stderr, "This proxy is using Auth Proxy v1 legacy mode.")
798+
if legacySet {
799+
fmt.Fprintln(os.Stderr, "This proxy is using Auth Proxy v1 legacy mode because the -legacy-v1-proxy flag is set")
800+
} else if len(unsupported) > 0 {
801+
fmt.Fprintln(os.Stderr, "This proxy is using Auth Proxy v1 legacy mode because it is using")
802+
fmt.Fprintln(os.Stderr, "flags that are not supported in v2 compatibility mode:")
803+
fmt.Fprintln(os.Stderr, strings.Join(unsupported, ", "))
776804
}
777805

778-
v2cmd := proxyv2cmd.NewCommand(opts...)
779-
v2cmd.SetArgs(translatedArgs)
780-
proxyv2cmd.ExecuteCommand(v2cmd)
806+
code := runProxy()
807+
os.Exit(code)
781808
}
782809

783810
// translateV2Args translates the v1 command line args to V2 args.
@@ -792,15 +819,41 @@ func main() {
792819
// - v2args the arguments translated for the v2 command
793820
// - logDebugStdout true if the v1 -log_debug_stdout flag was set
794821
// - verbose true if the v1 -verbose flag was set (default true)
822+
// - unsupported list of v1 flags that are not supported in v2
823+
// - legacySet true if -legacy-v1-proxy was set
824+
// - v2Compat true if -v2-compat was set
825+
// - v2Mode true if -v2 was set
795826
// - ok true when it is OK to use the v2 proxy command
796-
func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
797-
// Check for --legacy-v1-proxy before anything else
827+
func translateV2Args() (v2args []string, logDebugStdout, verbose bool, unsupported []string, legacySet, v2Compat, v2Mode, ok bool) {
828+
verbose = true // default
829+
830+
// Check for special flags before anything else
798831
for _, arg := range os.Args {
799832
if arg == "--legacy-v1-proxy" || arg == "-legacy-v1-proxy" {
800-
return nil, false, false, false
833+
legacySet = true
834+
}
835+
if arg == "--v2-compat" || arg == "-v2-compat" {
836+
v2Compat = true
837+
}
838+
if arg == "--v2" || arg == "-v2" {
839+
v2Mode = true
801840
}
802841
}
803842

843+
if v2Mode {
844+
// In v2 mode, we just pass all arguments except -v2 to the v2 parser
845+
for _, arg := range os.Args[1:] {
846+
if arg != "--v2" && arg != "-v2" {
847+
v2args = append(v2args, arg)
848+
}
849+
}
850+
return v2args, false, false, nil, false, false, true, true
851+
}
852+
853+
if legacySet {
854+
return nil, false, false, nil, true, v2Compat, false, false
855+
}
856+
804857
fs := flag.NewFlagSet("translate", flag.ContinueOnError)
805858
fs.SetOutput(io.Discard)
806859

@@ -824,37 +877,39 @@ func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
824877
version := fs.Bool("version", false, "")
825878
verboseFlag := fs.Bool("verbose", true, "")
826879
logDebugStdoutFlag := fs.Bool("log_debug_stdout", false, "")
880+
instancesMetadata := fs.String("instances_metadata", "", "")
827881

828882
// Untranslatable flags
829883
_ = fs.Bool("check_region", false, "")
830884
_ = fs.String("projects", "", "")
831-
_ = fs.String("instances_metadata", "", "")
832885
_ = fs.Duration("refresh_config_throttle", 0, "")
833886
_ = fs.Uint64("fd_rlimit", 0, "")
834887
_ = fs.Bool("legacy-v1-proxy", false, "")
888+
_ = fs.Bool("v2-compat", false, "")
835889

836890
var instances stringListValue
837891
fs.Var(&instances, "instances", "")
838892

839893
if err := fs.Parse(os.Args[1:]); err != nil {
840-
return nil, false, false, false
894+
return nil, false, false, nil, false, v2Compat, false, false
841895
}
842896

843897
// Check for unsupported flags being set
844-
unsupportedSet := false
845898
fs.Visit(func(f *flag.Flag) {
846899
switch f.Name {
847-
case "check_region", "projects", "instances_metadata", "legacy-v1-proxy":
848-
unsupportedSet = true
900+
case "check_region", "projects":
901+
unsupported = append(unsupported, "-"+f.Name)
849902
}
850903
})
851-
if unsupportedSet {
852-
return nil, false, false, false
904+
if len(unsupported) > 0 {
905+
return nil, false, false, unsupported, false, v2Compat, false, false
853906
}
854907

855908
var args []string
856909
fs.Visit(func(f *flag.Flag) {
857910
switch f.Name {
911+
case "instances_metadata":
912+
args = append(args, "--instances-metadata", *instancesMetadata)
858913
case "credential_file":
859914
args = append(args, "--credentials-file", *credentialFile)
860915
case "token":
@@ -928,7 +983,7 @@ func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
928983
hasPrivate = true
929984
default:
930985
// Unknown type, fallback to v1
931-
return nil, false, false, false
986+
return nil, false, false, []string{"-ip_address_types=" + *ipAddressTypes}, false, v2Compat, false, false
932987
}
933988
}
934989
if hasPublic && hasPrivate {
@@ -951,7 +1006,7 @@ func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
9511006

9521007
opts := strings.SplitN(parts[1], ":", 2)
9531008
if len(opts) != 2 {
954-
return nil, false, false, false // Invalid format
1009+
return nil, false, false, nil, false, v2Compat, false, false // Invalid format
9551010
}
9561011

9571012
netType := opts[0]
@@ -963,7 +1018,7 @@ func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
9631018
// host:port
9641019
h, p, err := net.SplitHostPort(netAddr)
9651020
if err != nil {
966-
return nil, false, false, false
1021+
return nil, false, false, nil, false, v2Compat, false, false
9671022
}
9681023
args = append(args, fmt.Sprintf("%s?address=%s&port=%s", connName, h, p))
9691024
} else {
@@ -977,14 +1032,14 @@ func translateV2Args() (v2args []string, logDebugStdout, verbose, ok bool) {
9771032
args = append(args, fmt.Sprintf("%s?unix-socket=%s", connName, netAddr))
9781033
}
9791034
default:
980-
return nil, false, false, false // Unsupported network
1035+
return nil, false, false, nil, false, v2Compat, false, false // Unsupported network
9811036
}
9821037
}
9831038

984-
// V2 requires at least one instance OR fuse mode OR version
985-
if len(instances) == 0 && !*useFuse && !*version {
986-
return nil, false, false, false
1039+
// V2 requires at least one instance OR fuse mode OR version OR instances_metadata
1040+
if len(instances) == 0 && !*useFuse && !*version && *instancesMetadata == "" {
1041+
return nil, false, false, nil, false, v2Compat, false, false
9871042
}
9881043

989-
return args, *logDebugStdoutFlag, *verboseFlag, true
1044+
return args, *logDebugStdoutFlag, *verboseFlag, nil, false, v2Compat, false, true
9901045
}

cmd/cloud_sql_proxy/translation_test.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,42 @@ func TestTranslateV2Args(t *testing.T) {
128128
wantOk: false,
129129
},
130130
{
131-
name: "fuse mode",
132-
args: []string{"cloud_sql_proxy", "-dir=/tmp", "-fuse"},
133-
wantArgs: []string{"--unix-socket", "/tmp", "--fuse", "/tmp", "--auto-ip"},
131+
name: "fuse mode",
132+
args: []string{"cloud_sql_proxy", "-dir=/tmp", "-fuse"},
133+
wantArgs: []string{"--unix-socket", "/tmp", "--fuse", "/tmp", "--auto-ip"},
134134
wantVerbose: true,
135135
wantOk: true,
136136
},
137-
}
137+
{
138+
name: "v2 flag",
139+
args: []string{"cloud_sql_proxy", "-v2", "--debug-logs", "p:r:i"},
140+
wantArgs: []string{"--debug-logs", "p:r:i"},
141+
wantOk: true,
142+
},
143+
{
144+
name: "v2-compat flag",
145+
args: []string{"cloud_sql_proxy", "-v2-compat", "-instances=i1"},
146+
wantArgs: []string{"--auto-ip", "i1"},
147+
wantVerbose: true,
148+
wantOk: true,
149+
},
150+
{
151+
name: "instances_metadata flag",
152+
args: []string{"cloud_sql_proxy", "-instances_metadata=path/to/attr"},
153+
wantArgs: []string{"--instances-metadata", "path/to/attr", "--auto-ip"},
154+
wantVerbose: true,
155+
wantOk: true,
156+
},
157+
}
158+
138159

139160
for _, tt := range tests {
140161
t.Run(tt.name, func(t *testing.T) {
141162
oldArgs := os.Args
142163
defer func() { os.Args = oldArgs }()
143164
os.Args = tt.args
144165

145-
gotArgs, gotLogDebug, gotVerbose, gotOk := translateV2Args()
166+
gotArgs, gotLogDebug, gotVerbose, _, _, _, gotV2Mode, gotOk := translateV2Args()
146167
if gotOk != tt.wantOk {
147168
t.Errorf("translateV2Args() ok = %v, want %v", gotOk, tt.wantOk)
148169
}
@@ -156,6 +177,9 @@ func TestTranslateV2Args(t *testing.T) {
156177
if gotVerbose != tt.wantVerbose {
157178
t.Errorf("translateV2Args() verbose = %v, want %v", gotVerbose, tt.wantVerbose)
158179
}
180+
if gotV2Mode != (tt.name == "v2 flag") {
181+
t.Errorf("translateV2Args() v2Mode = %v, want %v", gotV2Mode, tt.name == "v2 flag")
182+
}
159183
}
160184
})
161185
}

translatev2/translatev2_test.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ func TestModeComparison(t *testing.T) {
122122
args: []string{"-instances=p:r:i=tcp:3312", "-refresh_config_throttle=1m"},
123123
v2Expected: true,
124124
},
125+
{
126+
name: "instances_metadata flag stays in v2",
127+
args: []string{"-instances_metadata=path/to/attr"},
128+
v2Expected: true,
129+
},
125130
}
126131

127132
for _, tt := range tests {
@@ -149,8 +154,9 @@ func TestModeComparison(t *testing.T) {
149154
output := outBuf.String()
150155
if tt.v2Expected {
151156
// V2 indicators
152-
if strings.Contains(output, "The proxy has started successfully") &&
153-
strings.Contains(output, "Ready for new connections") {
157+
if (strings.Contains(output, "The proxy has started successfully") &&
158+
strings.Contains(output, "Ready for new connections")) ||
159+
strings.Contains(output, "This proxy running Auth Proxy v2 in compatibility mode.") {
154160
found = true
155161
goto end
156162
}
@@ -493,14 +499,6 @@ func TestE2EPostgres(t *testing.T) {
493499
testPostgres(t, binPath, connName, dbName, iamUser, "", true)
494500
})
495501
}
496-
497-
casConnName := os.Getenv("POSTGRES_CAS_CONNECTION_NAME")
498-
if casConnName != "" {
499-
casPass := os.Getenv("POSTGRES_CAS_PASS")
500-
t.Run("CASInstance", func(t *testing.T) {
501-
testPostgres(t, binPath, casConnName, dbName, user, casPass, false)
502-
})
503-
}
504502
}
505503

506504
func testSQLServer(t *testing.T, binPath, connName, dbName, user, pass string) {

0 commit comments

Comments
 (0)