1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

Update modules (#691)

* go get -u github.com/aws/aws-sdk-go
* get -u github.com/tiramiseb/go-gandi
* go get -u google.golang.org/api

Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
Tom Limoncelli
2020-03-10 16:26:06 -04:00
committed by GitHub
parent e6390c67d7
commit bbbb0c8c95
38 changed files with 1155 additions and 254 deletions

View File

@ -56,6 +56,7 @@ import (
googleapi "google.golang.org/api/googleapi"
gensupport "google.golang.org/api/internal/gensupport"
option "google.golang.org/api/option"
internaloption "google.golang.org/api/option/internaloption"
htransport "google.golang.org/api/transport/http"
)
@ -72,6 +73,7 @@ var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint
const apiId = "dns:v1"
const apiName = "dns"
@ -103,6 +105,7 @@ func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, err
)
// NOTE: prepend, so we don't override user-specified scopes.
opts = append([]option.ClientOption{scopesOption}, opts...)
opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
client, endpoint, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
@ -1754,7 +1757,7 @@ func (c *ChangesCreateCall) Header() http.Header {
func (c *ChangesCreateCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -1928,7 +1931,7 @@ func (c *ChangesGetCall) Header() http.Header {
func (c *ChangesGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -2129,7 +2132,7 @@ func (c *ChangesListCall) Header() http.Header {
func (c *ChangesListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -2353,7 +2356,7 @@ func (c *DnsKeysGetCall) Header() http.Header {
func (c *DnsKeysGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -2551,7 +2554,7 @@ func (c *DnsKeysListCall) Header() http.Header {
func (c *DnsKeysListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -2754,7 +2757,7 @@ func (c *ManagedZoneOperationsGetCall) Header() http.Header {
func (c *ManagedZoneOperationsGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -2949,7 +2952,7 @@ func (c *ManagedZoneOperationsListCall) Header() http.Header {
func (c *ManagedZoneOperationsListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3149,7 +3152,7 @@ func (c *ManagedZonesCreateCall) Header() http.Header {
func (c *ManagedZonesCreateCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3302,7 +3305,7 @@ func (c *ManagedZonesDeleteCall) Header() http.Header {
func (c *ManagedZonesDeleteCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3438,7 +3441,7 @@ func (c *ManagedZonesGetCall) Header() http.Header {
func (c *ManagedZonesGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3620,7 +3623,7 @@ func (c *ManagedZonesListCall) Header() http.Header {
func (c *ManagedZonesListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3804,7 +3807,7 @@ func (c *ManagedZonesPatchCall) Header() http.Header {
func (c *ManagedZonesPatchCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -3967,7 +3970,7 @@ func (c *ManagedZonesUpdateCall) Header() http.Header {
func (c *ManagedZonesUpdateCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4128,7 +4131,7 @@ func (c *PoliciesCreateCall) Header() http.Header {
func (c *PoliciesCreateCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4282,7 +4285,7 @@ func (c *PoliciesDeleteCall) Header() http.Header {
func (c *PoliciesDeleteCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4418,7 +4421,7 @@ func (c *PoliciesGetCall) Header() http.Header {
func (c *PoliciesGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4592,7 +4595,7 @@ func (c *PoliciesListCall) Header() http.Header {
func (c *PoliciesListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4771,7 +4774,7 @@ func (c *PoliciesPatchCall) Header() http.Header {
func (c *PoliciesPatchCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -4934,7 +4937,7 @@ func (c *PoliciesUpdateCall) Header() http.Header {
func (c *PoliciesUpdateCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -5104,7 +5107,7 @@ func (c *ProjectsGetCall) Header() http.Header {
func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}
@ -5288,7 +5291,7 @@ func (c *ResourceRecordSetsListCall) Header() http.Header {
func (c *ResourceRecordSetsListCall) doRequest(alt string) (*http.Response, error) {
reqHeaders := make(http.Header)
reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200205")
reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200302")
for k, v := range c.header_ {
reqHeaders[k] = v
}

View File

@ -0,0 +1,53 @@
// Copyright 2020 Google LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gensupport
import (
"runtime"
"strings"
"unicode"
)
// GoVersion returns the Go runtime version. The returned string
// has no whitespace.
func GoVersion() string {
return goVersion
}
var goVersion = goVer(runtime.Version())
const develPrefix = "devel +"
func goVer(s string) string {
if strings.HasPrefix(s, develPrefix) {
s = s[len(develPrefix):]
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
s = s[:p]
}
return s
}
if strings.HasPrefix(s, "go1") {
s = s[2:]
var prerelease string
if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
s, prerelease = s[:p], s[p:]
}
if strings.HasSuffix(s, ".") {
s += "0"
} else if strings.Count(s, ".") < 2 {
s += ".0"
}
if prerelease != "" {
s += "-" + prerelease
}
return s
}
return ""
}
func notSemverRune(r rune) bool {
return !strings.ContainsRune("0123456789.", r)
}

View File

@ -1,53 +0,0 @@
// Copyright 2016 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal
import (
"errors"
"google.golang.org/grpc/naming"
)
// TODO: move to transport/grpc package
// PoolResolver provides a fixed list of addresses to load balance between
// and does not provide further updates.
type PoolResolver struct {
poolSize int
dialOpt *DialSettings
ch chan []*naming.Update
}
// NewPoolResolver returns a PoolResolver
// This is an EXPERIMENTAL API and may be changed or removed in the future.
func NewPoolResolver(size int, o *DialSettings) *PoolResolver {
return &PoolResolver{poolSize: size, dialOpt: o}
}
// Resolve returns a Watcher for the endpoint defined by the DialSettings
// provided to NewPoolResolver.
func (r *PoolResolver) Resolve(target string) (naming.Watcher, error) {
if r.dialOpt.Endpoint == "" {
return nil, errors.New("no endpoint configured")
}
addrs := make([]*naming.Update, 0, r.poolSize)
for i := 0; i < r.poolSize; i++ {
addrs = append(addrs, &naming.Update{Op: naming.Add, Addr: r.dialOpt.Endpoint, Metadata: i})
}
r.ch = make(chan []*naming.Update, 1)
r.ch <- addrs
return r, nil
}
// Next returns a static list of updates on the first call,
// and blocks indefinitely until Close is called on subsequent calls.
func (r *PoolResolver) Next() ([]*naming.Update, error) {
return <-r.ch, nil
}
// Close releases resources associated with the pool and causes Next to unblock.
func (r *PoolResolver) Close() {
close(r.ch)
}

View File

@ -6,6 +6,7 @@
package internal
import (
"crypto/tls"
"errors"
"net/http"
@ -18,6 +19,7 @@ import (
// Google API service.
type DialSettings struct {
Endpoint string
DefaultEndpoint string
Scopes []string
TokenSource oauth2.TokenSource
Credentials *google.Credentials
@ -33,6 +35,7 @@ type DialSettings struct {
GRPCConnPoolSize int
NoAuth bool
TelemetryDisabled bool
ClientCertSource func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
@ -90,6 +93,12 @@ func (ds *DialSettings) Validate() error {
if ds.HTTPClient != nil && ds.RequestReason != "" {
return errors.New("WithHTTPClient is incompatible with RequestReason")
}
if ds.HTTPClient != nil && ds.ClientCertSource != nil {
return errors.New("WithHTTPClient is incompatible with WithClientCertSource")
}
if ds.ClientCertSource != nil && (ds.GRPCConn != nil || ds.GRPCConnPool != nil || ds.GRPCConnPoolSize != 0 || ds.GRPCDialOpts != nil) {
return errors.New("WithClientCertSource is currently only supported for HTTP. gRPC settings are incompatible")
}
return nil
}

View File

@ -0,0 +1,26 @@
// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package internaloption contains options used internally by Google client code.
package internaloption
import (
"google.golang.org/api/internal"
"google.golang.org/api/option"
)
type defaultEndpointOption string
func (o defaultEndpointOption) Apply(settings *internal.DialSettings) {
settings.DefaultEndpoint = string(o)
}
// WithDefaultEndpoint is an option that indicates the default endpoint.
//
// It should only be used internally by generated clients.
//
// This is similar to WithEndpoint, but allows us to determine whether the user has overriden the default endpoint.
func WithDefaultEndpoint(url string) option.ClientOption {
return defaultEndpointOption(url)
}

View File

@ -6,6 +6,7 @@
package option
import (
"crypto/tls"
"net/http"
"golang.org/x/oauth2"
@ -142,6 +143,7 @@ func (w withGRPCDialOption) Apply(o *internal.DialSettings) {
// WithGRPCConnectionPool returns a ClientOption that creates a pool of gRPC
// connections that requests will be balanced between.
//
// This is an EXPERIMENTAL API and may be changed or removed in the future.
func WithGRPCConnectionPool(size int) ClientOption {
return withGRPCConnectionPool(size)
@ -227,11 +229,43 @@ func (w withRequestReason) Apply(o *internal.DialSettings) {
// settings on gRPC and HTTP clients.
// An example reason would be to bind custom telemetry that overrides the defaults.
func WithTelemetryDisabled() ClientOption {
return withTelemetryDisabledOption{}
return withTelemetryDisabled{}
}
type withTelemetryDisabledOption struct{}
type withTelemetryDisabled struct{}
func (w withTelemetryDisabledOption) Apply(o *internal.DialSettings) {
func (w withTelemetryDisabled) Apply(o *internal.DialSettings) {
o.TelemetryDisabled = true
}
// ClientCertSource is a function that returns a TLS client certificate to be used
// when opening TLS connections.
//
// It follows the same semantics as crypto/tls.Config.GetClientCertificate.
//
// This is an EXPERIMENTAL API and may be changed or removed in the future.
type ClientCertSource = func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
// WithClientCertSource returns a ClientOption that specifies a
// callback function for obtaining a TLS client certificate.
//
// This option is used for supporting mTLS authentication, where the
// server validates the client certifcate when establishing a connection.
//
// The callback function will be invoked whenever the server requests a
// certificate from the client. Implementations of the callback function
// should try to ensure that a valid certificate can be repeatedly returned
// on demand for the entire life cycle of the transport client. If a nil
// Certificate is returned (i.e. no Certificate can be obtained), an error
// should be returned.
//
// This is an EXPERIMENTAL API and may be changed or removed in the future.
func WithClientCertSource(s ClientCertSource) ClientOption {
return withClientCertSource{s}
}
type withClientCertSource struct{ s ClientCertSource }
func (w withClientCertSource) Apply(o *internal.DialSettings) {
o.ClientCertSource = w.s
}

View File

@ -0,0 +1,110 @@
// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cert contains certificate tools for Google API clients.
// This package is intended to be used with crypto/tls.Config.GetClientCertificate.
//
// The certificates can be used to satisfy Google's Endpoint Validation.
// See https://cloud.google.com/endpoint-verification/docs/overview
//
// This package is not intended for use by end developers. Use the
// google.golang.org/api/option package to configure API clients.
package cert
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"os/user"
"path/filepath"
"sync"
)
const (
metadataPath = ".secureConnect"
metadataFile = "context_aware_metadata.json"
)
var (
defaultSourceOnce sync.Once
defaultSource Source
defaultSourceErr error
)
// Source is a function that can be passed into crypto/tls.Config.GetClientCertificate.
type Source func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
// DefaultSource returns a certificate source that execs the command specified
// in the file at ~/.secureConnect/context_aware_metadata.json
//
// If that file does not exist, a nil source is returned.
func DefaultSource() (Source, error) {
defaultSourceOnce.Do(func() {
defaultSource, defaultSourceErr = newSecureConnectSource()
})
return defaultSource, defaultSourceErr
}
type secureConnectSource struct {
metadata secureConnectMetadata
}
type secureConnectMetadata struct {
Cmd []string `json:"cert_provider_command"`
}
// newSecureConnectSource creates a secureConnectSource by reading the well-known file.
func newSecureConnectSource() (Source, error) {
user, err := user.Current()
if err != nil {
// Ignore.
return nil, nil
}
filename := filepath.Join(user.HomeDir, metadataPath, metadataFile)
file, err := ioutil.ReadFile(filename)
if os.IsNotExist(err) {
// Ignore.
return nil, nil
}
if err != nil {
return nil, err
}
var metadata secureConnectMetadata
if err := json.Unmarshal(file, &metadata); err != nil {
return nil, fmt.Errorf("cert: could not parse JSON in %q: %v", filename, err)
}
if err := validateMetadata(metadata); err != nil {
return nil, fmt.Errorf("cert: invalid config in %q: %v", filename, err)
}
return (&secureConnectSource{
metadata: metadata,
}).getClientCertificate, nil
}
func validateMetadata(metadata secureConnectMetadata) error {
if len(metadata.Cmd) == 0 {
return errors.New("empty cert_provider_command")
}
return nil
}
func (s *secureConnectSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
// TODO(cbro): consider caching valid certificates rather than exec'ing every time.
command := s.metadata.Cmd
data, err := exec.Command(command[0], command[1:]...).Output()
if err != nil {
// TODO(cbro): read stderr for error message? Might contain sensitive info.
return nil, err
}
cert, err := tls.X509KeyPair(data, data)
if err != nil {
return nil, err
}
return &cert, nil
}

View File

@ -9,14 +9,18 @@ package http
import (
"context"
"crypto/tls"
"errors"
"net/http"
"net/url"
"strings"
"go.opencensus.io/plugin/ochttp"
"golang.org/x/oauth2"
"google.golang.org/api/googleapi/transport"
"google.golang.org/api/internal"
"google.golang.org/api/option"
"google.golang.org/api/transport/cert"
"google.golang.org/api/transport/http/internal/propagation"
)
@ -28,15 +32,23 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*http.Client,
if err != nil {
return nil, "", err
}
// TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided?
if settings.HTTPClient != nil {
return settings.HTTPClient, settings.Endpoint, nil
}
trans, err := newTransport(ctx, defaultBaseTransport(ctx), settings)
clientCertSource, err := getClientCertificateSource(settings)
if err != nil {
return nil, "", err
}
return &http.Client{Transport: trans}, settings.Endpoint, nil
endpoint, err := getEndpoint(settings, clientCertSource)
if err != nil {
return nil, "", err
}
// TODO(cbro): consider injecting the User-Agent even if an explicit HTTP client is provided?
if settings.HTTPClient != nil {
return settings.HTTPClient, endpoint, nil
}
trans, err := newTransport(ctx, defaultBaseTransport(ctx, clientCertSource), settings)
if err != nil {
return nil, "", err
}
return &http.Client{Transport: trans}, endpoint, nil
}
// NewTransport creates an http.RoundTripper for use communicating with a Google
@ -137,11 +149,23 @@ func (t *parameterTransport) RoundTrip(req *http.Request) (*http.Response, error
var appengineUrlfetchHook func(context.Context) http.RoundTripper
// defaultBaseTransport returns the base HTTP transport.
// On App Engine, this is urlfetch.Transport, otherwise it's http.DefaultTransport.
func defaultBaseTransport(ctx context.Context) http.RoundTripper {
// On App Engine, this is urlfetch.Transport.
// If TLSCertificate is available, return a custom Transport with TLSClientConfig.
// Otherwise, return http.DefaultTransport.
func defaultBaseTransport(ctx context.Context, clientCertSource cert.Source) http.RoundTripper {
if appengineUrlfetchHook != nil {
return appengineUrlfetchHook(ctx)
}
if clientCertSource != nil {
// TODO (cbro): copy default transport settings from http.DefaultTransport
return &http.Transport{
TLSClientConfig: &tls.Config{
GetClientCertificate: clientCertSource,
},
}
}
return http.DefaultTransport
}
@ -154,3 +178,93 @@ func addOCTransport(trans http.RoundTripper, settings *internal.DialSettings) ht
Propagation: &propagation.HTTPFormat{},
}
}
// getClientCertificateSource returns a default client certificate source, if
// not provided by the user.
//
// A nil default source can be returned if the source does not exist. Any exceptions
// encountered while initializing the default source will be reported as client
// error (ex. corrupt metadata file).
//
// The overall logic is as follows:
// 1. If both endpoint override and client certificate are specified, use them as is.
// 2. If user does not specify client certificate, we will attempt to use default
// client certificate.
// 3. If user does not specify endpoint override, we will use defaultMtlsEndpoint if
// client certificate is available and defaultEndpoint otherwise.
//
// Implications of the above logic:
// 1. If the user specifies a non-mTLS endpoint override but client certificate is
// available, we will pass along the cert anyway and let the server decide what to do.
// 2. If the user specifies an mTLS endpoint override but client certificate is not
// available, we will not fail-fast, but let backend throw error when connecting.
//
// We would like to avoid introducing client-side logic that parses whether the
// endpoint override is an mTLS url, since the url pattern may change at anytime.
func getClientCertificateSource(settings *internal.DialSettings) (cert.Source, error) {
if settings.ClientCertSource != nil {
return settings.ClientCertSource, nil
}
return cert.DefaultSource()
}
// 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 return the default endpoint (or
// the default mTLS endpoint if a client certificate is available).
//
// 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
// WithDefaultEndpoint("https://foo.com/bar/baz") will return "https://myhost:8080/bar/baz"
func getEndpoint(settings *internal.DialSettings, clientCertSource cert.Source) (string, error) {
if settings.Endpoint == "" {
if clientCertSource != nil {
return generateDefaultMtlsEndpoint(settings.DefaultEndpoint), nil
}
return settings.DefaultEndpoint, nil
}
if strings.Contains(settings.Endpoint, "://") {
// User passed in a full URL path, use it verbatim.
return settings.Endpoint, nil
}
if settings.DefaultEndpoint == "" {
return "", errors.New("WithEndpoint requires a full URL path")
}
// Assume user-provided endpoint is host[:port], merge it with the default endpoint.
return mergeEndpoints(settings.DefaultEndpoint, settings.Endpoint)
}
func mergeEndpoints(base, newHost string) (string, error) {
u, err := url.Parse(base)
if err != nil {
return "", err
}
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
}