diff --git a/auth/internal/transport/cba.go b/auth/internal/transport/cba.go index f606888f1204..c879611a8d7f 100644 --- a/auth/internal/transport/cba.go +++ b/auth/internal/transport/cba.go @@ -51,17 +51,13 @@ const ( mtlsMDSKey = "/run/google-mds-mtls/client.key" ) -var ( - errUniverseNotSupportedMTLS = errors.New("mTLS is not supported in any universe other than googleapis.com") -) - // Options is a struct that is duplicated information from the individual // transport packages in order to avoid cyclic deps. It correlates 1:1 with // fields on httptransport.Options and grpctransport.Options. type Options struct { Endpoint string - DefaultMTLSEndpoint string DefaultEndpointTemplate string + DefaultMTLSEndpoint string ClientCertProvider cert.Provider Client *http.Client UniverseDomain string @@ -94,6 +90,16 @@ func (o *Options) defaultEndpoint() string { return strings.Replace(o.DefaultEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1) } +// defaultMTLSEndpoint returns the DefaultMTLSEndpointTemplate merged with the +// universe domain if the DefaultMTLSEndpointTemplate is set, otherwise returns an +// empty string. +func (o *Options) defaultMTLSEndpoint() string { + if o.DefaultMTLSEndpoint == "" { + return "" + } + return strings.Replace(o.DefaultMTLSEndpoint, universeDomainPlaceholder, o.getUniverseDomain(), 1) +} + // mergedEndpoint merges a user-provided Endpoint of format host[:port] with the // default endpoint. func (o *Options) mergedEndpoint() (string, error) { @@ -256,9 +262,6 @@ func getTransportConfig(opts *Options) (*transportConfig, error) { if !shouldUseS2A(clientCertSource, opts) { return &defaultTransportConfig, nil } - if !opts.isUniverseDomainGDU() { - return nil, errUniverseNotSupportedMTLS - } s2aAddress := GetS2AAddress() mtlsS2AAddress := GetMTLSS2AAddress() @@ -270,7 +273,7 @@ func getTransportConfig(opts *Options) (*transportConfig, error) { endpoint: endpoint, s2aAddress: s2aAddress, mtlsS2AAddress: mtlsS2AAddress, - s2aMTLSEndpoint: opts.DefaultMTLSEndpoint, + s2aMTLSEndpoint: opts.defaultMTLSEndpoint(), }, nil } @@ -316,24 +319,23 @@ type transportConfig struct { // getEndpoint returns the endpoint for the service, taking into account the // user-provided endpoint override "settings.Endpoint". // -// If no endpoint override is specified, we will either return the default endpoint or -// the default mTLS endpoint if a client certificate is available. +// If no endpoint override is specified, we will either return the default +// endpoint or the default mTLS endpoint if a client certificate is available. // -// You can override the default endpoint choice (mtls vs. regular) by setting the -// GOOGLE_API_USE_MTLS_ENDPOINT environment variable. +// You can override the default endpoint choice (mTLS vs. regular) by setting +// the GOOGLE_API_USE_MTLS_ENDPOINT environment variable. // // If the endpoint override is an address (host:port) rather than full base // URL (ex. https://...), then the user-provided address will be merged into // the default endpoint. For example, WithEndpoint("myhost:8000") and -// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return "https://myhost:8080/bar/baz" +// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return +// "https://myhost:8080/bar/baz". Note that this does not apply to the mTLS +// endpoint. func getEndpoint(opts *Options, clientCertSource cert.Provider) (string, error) { if opts.Endpoint == "" { mtlsMode := getMTLSMode() if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) { - if !opts.isUniverseDomainGDU() { - return "", errUniverseNotSupportedMTLS - } - return opts.DefaultMTLSEndpoint, nil + return opts.defaultMTLSEndpoint(), nil } return opts.defaultEndpoint(), nil } diff --git a/auth/internal/transport/cba_test.go b/auth/internal/transport/cba_test.go index 3c0a90269ac4..a28f57f639a7 100644 --- a/auth/internal/transport/cba_test.go +++ b/auth/internal/transport/cba_test.go @@ -26,12 +26,15 @@ import ( ) const ( - testMTLSEndpoint = "https://test.mtls.googleapis.com/" - testEndpointTemplate = "https://test.UNIVERSE_DOMAIN/" - testRegularEndpoint = "https://test.googleapis.com/" - testOverrideEndpoint = "https://test.override.example.com/" - testUniverseDomain = "example.com" - testUniverseDomainEndpoint = "https://test.example.com/" + testEndpointTemplate = "https://test.UNIVERSE_DOMAIN/" + testMTLSEndpoint = "https://test.mtls.googleapis.com/" + testMTLSEndpointTemplate = "https://test.mtls.UNIVERSE_DOMAIN/" + testDefaultUniverseEndpoint = "https://test.googleapis.com/" + testDefaultUniverseMTLSEndpoint = "https://test.mtls.googleapis.com/" + testOverrideEndpoint = "https://test.override.example.com/" + testUniverseDomain = "example.com" + testUniverseDomainEndpoint = "https://test.example.com/" + testUniverseDomainMTLSEndpoint = "https://test.mtls.example.com/" ) var ( @@ -287,56 +290,75 @@ func TestGetGRPCTransportConfigAndEndpoint_S2A(t *testing.T) { { name: "has client cert", opts: &Options{ + DefaultEndpointTemplate: testEndpointTemplate, DefaultMTLSEndpoint: testMTLSEndpoint, + ClientCertProvider: fakeClientCertSource, + }, + s2ARespFn: validConfigResp, + want: testDefaultUniverseMTLSEndpoint, + }, + { + name: "has client cert, MTLSEndpointTemplate", + opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, ClientCertProvider: fakeClientCertSource, }, s2ARespFn: validConfigResp, - want: testMTLSEndpoint, + want: testDefaultUniverseMTLSEndpoint, }, { name: "no client cert, S2A address not empty", opts: &Options{ + DefaultEndpointTemplate: testEndpointTemplate, DefaultMTLSEndpoint: testMTLSEndpoint, + }, + s2ARespFn: validConfigResp, + want: testDefaultUniverseMTLSEndpoint, + }, + { + name: "no client cert, S2A address not empty, MTLSEndpointTemplate", + opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: validConfigResp, - want: testMTLSEndpoint, + want: testDefaultUniverseMTLSEndpoint, }, { name: "no client cert, S2A address not empty, EnableDirectPath == true", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, EnableDirectPath: true, }, s2ARespFn: validConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, }, { name: "no client cert, S2A address not empty, EnableDirectPathXds == true", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, EnableDirectPathXds: true, }, s2ARespFn: validConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, }, { name: "no client cert, S2A address empty", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: invalidConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, }, { name: "no client cert, S2A address not empty, override endpoint", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, Endpoint: testOverrideEndpoint, }, s2ARespFn: validConfigResp, @@ -345,29 +367,38 @@ func TestGetGRPCTransportConfigAndEndpoint_S2A(t *testing.T) { { "no client cert, S2A address not empty, DefaultMTLSEndpoint not set", &Options{ - DefaultMTLSEndpoint: "", DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: "", }, validConfigResp, - testRegularEndpoint, + testDefaultUniverseEndpoint, }, { "no client cert, MTLS S2A address not empty, no MTLS MDS cert", &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, validConfigRespMTLSS2A, - testRegularEndpoint, + testDefaultUniverseEndpoint, }, { "no client cert, dual S2A addresses, no MTLS MDS cert", &Options{ + DefaultEndpointTemplate: testEndpointTemplate, DefaultMTLSEndpoint: testMTLSEndpoint, + }, + validConfigRespDualS2A, + testDefaultUniverseMTLSEndpoint, + }, + { + "no client cert, dual S2A addresses, no MTLS MDS cert, MTLSEndpointTemplate", + &Options{ DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, validConfigRespDualS2A, - testMTLSEndpoint, + testDefaultUniverseMTLSEndpoint, }, } defer setupTest(t)() @@ -399,38 +430,38 @@ func TestGetHTTPTransportConfig_S2A(t *testing.T) { { name: "has client cert", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, ClientCertProvider: fakeClientCertSource, }, s2ARespFn: validConfigResp, - want: testMTLSEndpoint, + want: testMTLSEndpointTemplate, isDialFnNil: true, }, { name: "no client cert, S2A address not empty", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: validConfigResp, - want: testMTLSEndpoint, + want: testMTLSEndpointTemplate, }, { name: "no client cert, S2A address empty", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: invalidConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, isDialFnNil: true, }, { name: "no client cert, S2A address not empty, override endpoint", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, Endpoint: testOverrideEndpoint, }, s2ARespFn: validConfigResp, @@ -440,42 +471,42 @@ func TestGetHTTPTransportConfig_S2A(t *testing.T) { { name: "no client cert, S2A address not empty, but DefaultMTLSEndpoint is not set", opts: &Options{ - DefaultMTLSEndpoint: "", DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: "", }, s2ARespFn: validConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, isDialFnNil: true, }, { name: "no client cert, S2A address not empty, custom HTTP client", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, Client: http.DefaultClient, }, s2ARespFn: validConfigResp, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, isDialFnNil: true, }, { name: "no client cert, MTLS S2A address not empty, no MTLS MDS cert", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: validConfigRespMTLSS2A, - want: testRegularEndpoint, + want: testDefaultUniverseEndpoint, isDialFnNil: true, }, { name: "no client cert, dual S2A addresses, no MTLS MDS cert", opts: &Options{ - DefaultMTLSEndpoint: testMTLSEndpoint, DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, s2ARespFn: validConfigRespDualS2A, - want: testMTLSEndpoint, + want: testMTLSEndpointTemplate, isDialFnNil: false, }, } @@ -556,23 +587,22 @@ func TestGetTransportConfig_UniverseDomain(t *testing.T) { name string opts *Options wantEndpoint string - wantErr error }{ { name: "google default universe (GDU), no client cert, template is regular endpoint", opts: &Options{ - DefaultEndpointTemplate: testRegularEndpoint, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultEndpointTemplate: testDefaultUniverseEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, - wantEndpoint: testRegularEndpoint, + wantEndpoint: testDefaultUniverseEndpoint, }, { name: "google default universe (GDU), no client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, - wantEndpoint: testRegularEndpoint, + wantEndpoint: testDefaultUniverseEndpoint, }, { name: "google default universe (GDU), client cert", @@ -581,13 +611,22 @@ func TestGetTransportConfig_UniverseDomain(t *testing.T) { DefaultMTLSEndpoint: testMTLSEndpoint, ClientCertProvider: fakeClientCertSource, }, - wantEndpoint: testMTLSEndpoint, + wantEndpoint: testDefaultUniverseMTLSEndpoint, + }, + { + name: "google default universe (GDU), client cert, MTLSEndpointTemplate", + opts: &Options{ + DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, + ClientCertProvider: fakeClientCertSource, + }, + wantEndpoint: testDefaultUniverseMTLSEndpoint, }, { name: "UniverseDomain, no client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, }, wantEndpoint: testUniverseDomainEndpoint, @@ -596,12 +635,11 @@ func TestGetTransportConfig_UniverseDomain(t *testing.T) { name: "UniverseDomain, client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, ClientCertProvider: fakeClientCertSource, }, - wantEndpoint: testUniverseDomainEndpoint, - wantErr: errUniverseNotSupportedMTLS, + wantEndpoint: testUniverseDomainMTLSEndpoint, }, } @@ -614,9 +652,7 @@ func TestGetTransportConfig_UniverseDomain(t *testing.T) { } config, err := getTransportConfig(tc.opts) if err != nil { - if err != tc.wantErr { - t.Fatalf("err: %v", err) - } + t.Fatalf("err: %v", err) } else { if tc.wantEndpoint != config.endpoint { t.Errorf("want endpoint: %s, got %s", tc.wantEndpoint, config.endpoint) @@ -631,21 +667,20 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { name string opts *Options wantEndpoint string - wantErr error }{ { name: "google default universe (GDU), no client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, }, - wantEndpoint: testRegularEndpoint, + wantEndpoint: testDefaultUniverseEndpoint, }, { name: "google default universe (GDU), no client cert, endpoint", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, Endpoint: testOverrideEndpoint, }, wantEndpoint: testOverrideEndpoint, @@ -657,13 +692,22 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { DefaultMTLSEndpoint: testMTLSEndpoint, ClientCertProvider: fakeClientCertSource, }, - wantEndpoint: testMTLSEndpoint, + wantEndpoint: testDefaultUniverseMTLSEndpoint, + }, + { + name: "google default universe (GDU), client cert, MTLSEndpointTemplate", + opts: &Options{ + DefaultEndpointTemplate: testEndpointTemplate, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, + ClientCertProvider: fakeClientCertSource, + }, + wantEndpoint: testDefaultUniverseMTLSEndpoint, }, { name: "google default universe (GDU), client cert, endpoint", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, ClientCertProvider: fakeClientCertSource, Endpoint: testOverrideEndpoint, }, @@ -673,7 +717,7 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { name: "UniverseDomain, no client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, }, wantEndpoint: testUniverseDomainEndpoint, @@ -682,7 +726,7 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { name: "UniverseDomain, no client cert, endpoint", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, Endpoint: testOverrideEndpoint, }, @@ -692,17 +736,17 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { name: "UniverseDomain, client cert", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, ClientCertProvider: fakeClientCertSource, }, - wantErr: errUniverseNotSupportedMTLS, + wantEndpoint: testUniverseDomainMTLSEndpoint, }, { name: "UniverseDomain, client cert, endpoint", opts: &Options{ DefaultEndpointTemplate: testEndpointTemplate, - DefaultMTLSEndpoint: testMTLSEndpoint, + DefaultMTLSEndpoint: testMTLSEndpointTemplate, UniverseDomain: testUniverseDomain, ClientCertProvider: fakeClientCertSource, Endpoint: testOverrideEndpoint, @@ -720,9 +764,7 @@ func TestGetGRPCTransportCredsAndEndpoint_UniverseDomain(t *testing.T) { } _, endpoint, err := GetGRPCTransportCredsAndEndpoint(tc.opts) if err != nil { - if err != tc.wantErr { - t.Fatalf("err: %v", err) - } + t.Fatalf("err: %v", err) } else { if tc.wantEndpoint != endpoint { t.Errorf("want endpoint: %s, got %s", tc.wantEndpoint, endpoint) @@ -745,7 +787,7 @@ func TestGetClientCertificateProvider(t *testing.T) { opts: &Options{ UniverseDomain: internal.DefaultUniverseDomain, ClientCertProvider: fakeClientCertSource, - Endpoint: testRegularEndpoint, + Endpoint: testDefaultUniverseEndpoint, }, useCertEnvVar: "false", wantCertProvider: nil, @@ -765,7 +807,7 @@ func TestGetClientCertificateProvider(t *testing.T) { opts: &Options{ UniverseDomain: internal.DefaultUniverseDomain, ClientCertProvider: fakeClientCertSource, - Endpoint: testRegularEndpoint, + Endpoint: testDefaultUniverseEndpoint, }, useCertEnvVar: "unset", wantCertProvider: fakeClientCertSource,