all, transport/http: read default mTLS endpoint from Discovery Doc (#541)
Read default mTLS endpoint from Discovery Doc instead of generating it via regex. This is achieved by introducing a new internaloption "DefaultMTLSEndpoint". The generator is updated to include mtlsBasePath. Testdata is updated to include mtlsRootUrl.
diff --git a/google-api-go-generator/gen.go b/google-api-go-generator/gen.go
index 8d137b5..33aeaf4 100644
--- a/google-api-go-generator/gen.go
+++ b/google-api-go-generator/gen.go
@@ -495,6 +495,13 @@
return resolveRelative(base, rel)
}
+func (a *API) mtlsAPIBaseURL() string {
+ if a.doc.MTLSRootURL != "" {
+ return resolveRelative(a.doc.MTLSRootURL, a.doc.ServicePath)
+ }
+ return ""
+}
+
func (a *API) needsDataWrapper() bool {
for _, feature := range a.doc.Features {
if feature == "dataWrapper" {
@@ -719,6 +726,9 @@
pn("const apiName = %q", a.doc.Name)
pn("const apiVersion = %q", a.doc.Version)
pn("const basePath = %q", a.apiBaseURL())
+ if mtlsBase := a.mtlsAPIBaseURL(); mtlsBase != "" {
+ pn("const mtlsBasePath = %q", mtlsBase)
+ }
a.generateScopeConstants()
a.PopulateSchemas()
@@ -741,6 +751,9 @@
pn("opts = append([]option.ClientOption{scopesOption}, opts...)")
}
pn("opts = append(opts, internaloption.WithDefaultEndpoint(basePath))")
+ if a.mtlsAPIBaseURL() != "" {
+ pn("opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))")
+ }
pn("client, endpoint, err := htransport.NewClient(ctx, opts...)")
pn("if err != nil { return nil, err }")
pn("s, err := New(client)")
diff --git a/google-api-go-generator/internal/disco/disco.go b/google-api-go-generator/internal/disco/disco.go
index 0dee96a..b43d6ed 100644
--- a/google-api-go-generator/internal/disco/disco.go
+++ b/google-api-go-generator/internal/disco/disco.go
@@ -20,6 +20,7 @@
Version string `json:"version"`
Title string `json:"title"`
RootURL string `json:"rootUrl"`
+ MTLSRootURL string `json:"mtlsRootUrl"`
ServicePath string `json:"servicePath"`
BasePath string `json:"basePath"`
DocumentationLink string `json:"documentationLink"`
diff --git a/google-api-go-generator/testdata/any.json b/google-api-go-generator/testdata/any.json
index 405109a..a577208 100644
--- a/google-api-go-generator/testdata/any.json
+++ b/google-api-go-generator/testdata/any.json
@@ -19,6 +19,7 @@
"baseUrl": "https://logging.googleapis.com/",
"basePath": "",
"rootUrl": "https://logging.googleapis.com/",
+ "mtlsRootUrl": "https://logging.mtls.googleapis.com/",
"servicePath": "",
"batchPath": "batch",
"parameters": {
diff --git a/google-api-go-generator/testdata/any.want b/google-api-go-generator/testdata/any.want
index 34a1ae7..cb3b10c 100644
--- a/google-api-go-generator/testdata/any.want
+++ b/google-api-go-generator/testdata/any.want
@@ -75,6 +75,7 @@
const apiName = "logging"
const apiVersion = "v1beta3"
const basePath = "https://logging.googleapis.com/"
+const mtlsBasePath = "https://logging.mtls.googleapis.com/"
// OAuth2 scopes used by this API.
const (
@@ -90,6 +91,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/blogger-3.json b/google-api-go-generator/testdata/blogger-3.json
index 53caa83..ca0ae7e 100644
--- a/google-api-go-generator/testdata/blogger-3.json
+++ b/google-api-go-generator/testdata/blogger-3.json
@@ -21,6 +21,7 @@
"baseUrl": "https://www.googleapis.com/blogger/v3/",
"basePath": "/blogger/v3/",
"rootUrl": "https://www.googleapis.com/",
+ "mtlsRootUrl": "https://www.mtls.googleapis.com/",
"servicePath": "blogger/v3/",
"batchPath": "batch",
"parameters": {
diff --git a/google-api-go-generator/testdata/blogger-3.want b/google-api-go-generator/testdata/blogger-3.want
index 7492d2c..3ee1a52 100644
--- a/google-api-go-generator/testdata/blogger-3.want
+++ b/google-api-go-generator/testdata/blogger-3.want
@@ -79,6 +79,7 @@
const apiName = "blogger"
const apiVersion = "v3"
const basePath = "https://www.googleapis.com/blogger/v3/"
+const mtlsBasePath = "https://www.mtls.googleapis.com/blogger/v3/"
// OAuth2 scopes used by this API.
const (
@@ -98,6 +99,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/floats.json b/google-api-go-generator/testdata/floats.json
index 0973308..7b74fce 100644
--- a/google-api-go-generator/testdata/floats.json
+++ b/google-api-go-generator/testdata/floats.json
@@ -9,6 +9,7 @@
"baseUrl": "https://appengine.googleapis.com/",
"basePath": "",
"rootUrl": "https://appengine.googleapis.com/",
+ "mtlsRootUrl": "https://appengine.mtls.googleapis.com/",
"servicePath": "",
"batchPath": "batch",
"schemas": {
diff --git a/google-api-go-generator/testdata/floats.want b/google-api-go-generator/testdata/floats.want
index b01d096..8fae5dd 100644
--- a/google-api-go-generator/testdata/floats.want
+++ b/google-api-go-generator/testdata/floats.want
@@ -75,10 +75,12 @@
const apiName = "X"
const apiVersion = "v1"
const basePath = "https://appengine.googleapis.com/"
+const mtlsBasePath = "https://appengine.mtls.googleapis.com/"
// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/http-body.json b/google-api-go-generator/testdata/http-body.json
index ce638f6..534cd9d 100644
--- a/google-api-go-generator/testdata/http-body.json
+++ b/google-api-go-generator/testdata/http-body.json
@@ -164,6 +164,7 @@
},
"version": "v1beta1",
"baseUrl": "https://healthcare.googleapis.com/",
+ "mtlsRootUrl": "https://healthcare.mtls.googleapis.com/",
"kind": "discovery#restDescription",
"description": "Manage, store, and access healthcare data in Google Cloud Platform.",
"servicePath": "",
diff --git a/google-api-go-generator/testdata/http-body.want b/google-api-go-generator/testdata/http-body.want
index e32ebcf..a53e58a 100644
--- a/google-api-go-generator/testdata/http-body.want
+++ b/google-api-go-generator/testdata/http-body.want
@@ -75,6 +75,7 @@
const apiName = "healthcare"
const apiVersion = "v1beta1"
const basePath = "https://healthcare.googleapis.com/"
+const mtlsBasePath = "https://healthcare.mtls.googleapis.com/"
// OAuth2 scopes used by this API.
const (
@@ -90,6 +91,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/json-body.json b/google-api-go-generator/testdata/json-body.json
index 3ec0391..a78e9b6 100644
--- a/google-api-go-generator/testdata/json-body.json
+++ b/google-api-go-generator/testdata/json-body.json
@@ -10,6 +10,7 @@
},
"basePath": "",
"baseUrl": "https://ml.googleapis.com/",
+ "mtlsRootUrl": "https://ml.mtls.googleapis.com/",
"batchPath": "batch",
"canonicalName": "Cloud Machine Learning Engine",
"description": "An API to enable creating and using machine learning models.",
diff --git a/google-api-go-generator/testdata/json-body.want b/google-api-go-generator/testdata/json-body.want
index 270814d..0a4810c 100644
--- a/google-api-go-generator/testdata/json-body.want
+++ b/google-api-go-generator/testdata/json-body.want
@@ -75,6 +75,7 @@
const apiName = "ml"
const apiVersion = "v1"
const basePath = "https://ml.googleapis.com/"
+const mtlsBasePath = "https://ml.mtls.googleapis.com/"
// OAuth2 scopes used by this API.
const (
@@ -90,6 +91,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/quotednum.json b/google-api-go-generator/testdata/quotednum.json
index 738555e..c49b0cd 100644
--- a/google-api-go-generator/testdata/quotednum.json
+++ b/google-api-go-generator/testdata/quotednum.json
@@ -18,6 +18,7 @@
"baseUrl": "https://www.googleapis.com/adexchangebuyer/v1.1/",
"basePath": "/adexchangebuyer/v1.1/",
"rootUrl": "https://www.googleapis.com/",
+ "mtlsRootUrl": "https://www.mtls.googleapis.com/",
"servicePath": "adexchangebuyer/v1.1/",
"batchPath": "batch",
"parameters": {
diff --git a/google-api-go-generator/testdata/quotednum.want b/google-api-go-generator/testdata/quotednum.want
index 54ac67b..56c9fc7 100644
--- a/google-api-go-generator/testdata/quotednum.want
+++ b/google-api-go-generator/testdata/quotednum.want
@@ -75,6 +75,7 @@
const apiName = "adexchangebuyer"
const apiVersion = "v1.1"
const basePath = "https://www.googleapis.com/adexchangebuyer/v1.1/"
+const mtlsBasePath = "https://www.mtls.googleapis.com/adexchangebuyer/v1.1/"
// OAuth2 scopes used by this API.
const (
@@ -90,6 +91,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/google-api-go-generator/testdata/resource-named-service.json b/google-api-go-generator/testdata/resource-named-service.json
index 936867d..2c1ae24 100644
--- a/google-api-go-generator/testdata/resource-named-service.json
+++ b/google-api-go-generator/testdata/resource-named-service.json
@@ -19,6 +19,7 @@
"baseUrl": "https://appengine.googleapis.com/",
"basePath": "",
"rootUrl": "https://appengine.googleapis.com/",
+ "mtlsRootUrl": "https://appengine.mtls.googleapis.com/",
"servicePath": "",
"batchPath": "batch",
"version_module": true,
diff --git a/google-api-go-generator/testdata/resource-named-service.want b/google-api-go-generator/testdata/resource-named-service.want
index 9eaedf8..9fd5d31 100644
--- a/google-api-go-generator/testdata/resource-named-service.want
+++ b/google-api-go-generator/testdata/resource-named-service.want
@@ -75,6 +75,7 @@
const apiName = "appengine"
const apiVersion = "v1"
const basePath = "https://appengine.googleapis.com/"
+const mtlsBasePath = "https://appengine.mtls.googleapis.com/"
// OAuth2 scopes used by this API.
const (
@@ -90,6 +91,7 @@
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
+ opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
diff --git a/internal/settings.go b/internal/settings.go
index 0d8210b..f435519 100644
--- a/internal/settings.go
+++ b/internal/settings.go
@@ -18,25 +18,26 @@
// DialSettings holds information needed to establish a connection with a
// Google API service.
type DialSettings struct {
- Endpoint string
- DefaultEndpoint string
- Scopes []string
- TokenSource oauth2.TokenSource
- Credentials *google.Credentials
- CredentialsFile string // if set, Token Source is ignored.
- CredentialsJSON []byte
- UserAgent string
- APIKey string
- Audiences []string
- HTTPClient *http.Client
- GRPCDialOpts []grpc.DialOption
- GRPCConn *grpc.ClientConn
- GRPCConnPool ConnPool
- GRPCConnPoolSize int
- NoAuth bool
- TelemetryDisabled bool
- ClientCertSource func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
- CustomClaims map[string]interface{}
+ Endpoint string
+ DefaultEndpoint string
+ DefaultMTLSEndpoint string
+ Scopes []string
+ TokenSource oauth2.TokenSource
+ Credentials *google.Credentials
+ CredentialsFile string // if set, Token Source is ignored.
+ CredentialsJSON []byte
+ UserAgent string
+ APIKey string
+ Audiences []string
+ HTTPClient *http.Client
+ GRPCDialOpts []grpc.DialOption
+ GRPCConn *grpc.ClientConn
+ GRPCConnPool ConnPool
+ GRPCConnPoolSize int
+ NoAuth bool
+ TelemetryDisabled bool
+ ClientCertSource func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
+ CustomClaims map[string]interface{}
// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
diff --git a/option/internaloption/internaloption.go b/option/internaloption/internaloption.go
index 48121e4..ff5b530 100644
--- a/option/internaloption/internaloption.go
+++ b/option/internaloption/internaloption.go
@@ -24,3 +24,17 @@
func WithDefaultEndpoint(url string) option.ClientOption {
return defaultEndpointOption(url)
}
+
+type defaultMTLSEndpointOption string
+
+func (o defaultMTLSEndpointOption) Apply(settings *internal.DialSettings) {
+ settings.DefaultMTLSEndpoint = string(o)
+}
+
+// WithDefaultMTLSEndpoint is an option that indicates the default mTLS endpoint.
+//
+// It should only be used internally by generated clients.
+//
+func WithDefaultMTLSEndpoint(url string) option.ClientOption {
+ return defaultMTLSEndpointOption(url)
+}
diff --git a/transport/http/dial.go b/transport/http/dial.go
index 19a4c9a..4450301 100644
--- a/transport/http/dial.go
+++ b/transport/http/dial.go
@@ -269,7 +269,7 @@
if settings.Endpoint == "" {
mtlsMode := getMTLSMode()
if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) {
- return generateDefaultMtlsEndpoint(settings.DefaultEndpoint), nil
+ return settings.DefaultMTLSEndpoint, nil
}
return settings.DefaultEndpoint, nil
}
@@ -302,26 +302,3 @@
u.Host = newHost
return u.String(), nil
}
-
-// generateDefaultMtlsEndpoint attempts to derive the mTLS version of the
-// defaultEndpoint via regex, and returns defaultEndpoint if unsuccessful.
-//
-// We need to applying the following 2 transformations:
-// 1. pubsub.googleapis.com to pubsub.mtls.googleapis.com
-// 2. pubsub.sandbox.googleapis.com to pubsub.mtls.sandbox.googleapis.com
-//
-// TODO(andyzhao): In the future, the mTLS endpoint will be read from the Discovery Document
-// and passed in as defaultMtlsEndpoint instead of generated from defaultEndpoint,
-// and this function will be removed.
-func generateDefaultMtlsEndpoint(defaultEndpoint string) string {
- var domains = []string{
- ".sandbox.googleapis.com", // must come first because .googleapis.com is a substring
- ".googleapis.com",
- }
- for _, domain := range domains {
- if strings.Contains(defaultEndpoint, domain) {
- return strings.Replace(defaultEndpoint, domain, ".mtls"+domain, -1)
- }
- }
- return defaultEndpoint
-}
diff --git a/transport/http/dial_test.go b/transport/http/dial_test.go
index 0dfab10..ddbdc6e 100644
--- a/transport/http/dial_test.go
+++ b/transport/http/dial_test.go
@@ -9,7 +9,6 @@
"crypto/tls"
- "github.com/google/go-cmp/cmp"
"google.golang.org/api/internal"
)
@@ -111,27 +110,3 @@
}
}
}
-
-func TestGenerateDefaultMtlsEndpoint(t *testing.T) {
- mtlsEndpoint := generateDefaultMtlsEndpoint("pubsub.googleapis.com")
- wantMtlsEndpoint := "pubsub.mtls.googleapis.com"
- if !cmp.Equal(mtlsEndpoint, wantMtlsEndpoint) {
- t.Error(cmp.Diff(wantMtlsEndpoint, wantMtlsEndpoint))
- }
-}
-
-func TestGenerateDefaultMtlsEndpointSandbox(t *testing.T) {
- mtlsEndpoint := generateDefaultMtlsEndpoint("staging-pubsub.sandbox.googleapis.com")
- wantMtlsEndpoint := "staging-pubsub.mtls.sandbox.googleapis.com"
- if !cmp.Equal(mtlsEndpoint, wantMtlsEndpoint) {
- t.Error(cmp.Diff(wantMtlsEndpoint, wantMtlsEndpoint))
- }
-}
-
-func TestGenerateDefaultMtlsEndpointUnsupported(t *testing.T) {
- mtlsEndpoint := generateDefaultMtlsEndpoint("unsupported.google.com")
- wantMtlsEndpoint := "unsupported.google.com"
- if !cmp.Equal(mtlsEndpoint, wantMtlsEndpoint) {
- t.Error(cmp.Diff(wantMtlsEndpoint, wantMtlsEndpoint))
- }
-}