Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(internaloption): add AllowNonDefaultServiceAccount internaloption #1127

Merged
merged 3 commits into from Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 27 additions & 26 deletions internal/settings.go
Expand Up @@ -19,32 +19,33 @@ import (
// DialSettings holds information needed to establish a connection with a
// Google API service.
type DialSettings struct {
Endpoint string
DefaultEndpoint string
DefaultMTLSEndpoint string
Scopes []string
DefaultScopes []string
EnableJwtWithScope bool
TokenSource oauth2.TokenSource
Credentials *google.Credentials
CredentialsFile string // if set, Token Source is ignored.
CredentialsJSON []byte
UserAgent string
APIKey string
Audiences []string
DefaultAudience 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{}
SkipValidation bool
ImpersonationConfig *impersonate.Config
EnableDirectPath bool
Endpoint string
DefaultEndpoint string
DefaultMTLSEndpoint string
Scopes []string
DefaultScopes []string
EnableJwtWithScope bool
TokenSource oauth2.TokenSource
Credentials *google.Credentials
CredentialsFile string // if set, Token Source is ignored.
CredentialsJSON []byte
UserAgent string
APIKey string
Audiences []string
DefaultAudience 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{}
SkipValidation bool
ImpersonationConfig *impersonate.Config
EnableDirectPath bool
AllowNonDefaultServiceAccount bool

// Google API system parameters. For more information please read:
// https://cloud.google.com/apis/docs/system-parameters
Expand Down
15 changes: 15 additions & 0 deletions option/internaloption/internaloption.go
Expand Up @@ -66,6 +66,21 @@ func (e enableDirectPath) Apply(o *internal.DialSettings) {
o.EnableDirectPath = bool(e)
}

// AllowNonDefaultServiceAccount returns a ClientOption that overrides the default
// requirement for using the default service account for DirectPath.
//
// It should only be used internally by generated clients.
// This is an EXPERIMENTAL API and may be changed or removed in the future.
func AllowNonDefaultServiceAccount(nd bool) option.ClientOption {
return allowNonDefaultServiceAccount(nd)
}

type allowNonDefaultServiceAccount bool

func (a allowNonDefaultServiceAccount) Apply(o *internal.DialSettings) {
o.AllowNonDefaultServiceAccount = bool(a)
}

// WithDefaultAudience returns a ClientOption that specifies a default audience
// to be used as the audience field ("aud") for the JWT token authentication.
//
Expand Down
7 changes: 5 additions & 2 deletions transport/grpc/dial.go
Expand Up @@ -138,7 +138,7 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C
// * The endpoint is a host:port (or dns:///host:port).
// * Credentials are obtained via GCE metadata server, using the default
// service account.
if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource) && metadata.OnGCE() {
if o.EnableDirectPath && checkDirectPathEndPoint(endpoint) && isTokenSourceDirectPathCompatible(creds.TokenSource, o) && metadata.OnGCE() {
Copy link
Contributor

@broady broady Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&& (o.AllowNonDefaultServiceAccount || isTokenSourceDirectPathCompatible(creds.TokenSource))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it seems this comment will change the functionality. For example if creds.TokenSource is nil, then isTokenSourceDirectPathCompatible(creds.TokenSource, o) will be false, but (o.AllowNonDefaultServiceAccount || isTokenSourceDirectPathCompatible(creds.TokenSource)) could be true if o.AllowNonDefaultServiceAccount is true.

if !strings.HasPrefix(endpoint, "dns:///") {
endpoint = "dns:///" + endpoint
}
Expand Down Expand Up @@ -228,7 +228,7 @@ func (ts grpcTokenSource) GetRequestMetadata(ctx context.Context, uri ...string)
return metadata, nil
}

func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool {
func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource, o *internal.DialSettings) bool {
if ts == nil {
return false
}
Expand All @@ -239,6 +239,9 @@ func isTokenSourceDirectPathCompatible(ts oauth2.TokenSource) bool {
if tok == nil {
return false
}
if o.AllowNonDefaultServiceAccount {
return true
}
if source, _ := tok.Extra("oauth2.google.tokenSource").(string); source != "compute-metadata" {
return false
}
Expand Down