Skip to content

Commit

Permalink
Implement Service Account Impersonation (#4015) (#551)
Browse files Browse the repository at this point in the history
* add service account impersonation

* fix conflicts

* add the scopes block removed by error

* add service account impersonation

* undo spacing

* update docs for quota project

* fix typos in docs

* fix typo in test and the docs

* use the new gce client

* add impersonate to accesstoken + test

* fix tokensource typo

* replace the envs used for testing impersonation

* add additional scopes

* typo fix

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Oct 15, 2020
1 parent c39d1d7 commit 5ff67cb
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 additions & 12 deletions google/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
sqladmin "google.golang.org/api/sqladmin/v1beta4"
"google.golang.org/api/storage/v1"
"google.golang.org/api/storagetransfer/v1"
"google.golang.org/api/transport"
)

type providerMeta struct {
Expand All @@ -57,16 +58,18 @@ type providerMeta struct {
// Config is the configuration structure used to instantiate the Google
// provider.
type Config struct {
Credentials string
AccessToken string
Project string
BillingProject string
Region string
Zone string
Scopes []string
BatchingConfig *batchingConfig
UserProjectOverride bool
RequestTimeout time.Duration
AccessToken string
Credentials string
ImpersonateServiceAccount string
ImpersonateServiceAccountDelegates []string
Project string
Region string
BillingProject string
Zone string
Scopes []string
BatchingConfig *batchingConfig
UserProjectOverride bool
RequestTimeout time.Duration
// PollInterval is passed to resource.StateChangeConf in common_operation.go
// It controls the interval at which we poll for successful operations
PollInterval time.Duration
Expand Down Expand Up @@ -838,15 +841,25 @@ type staticTokenSource struct {
}

func (c *Config) GetCredentials(clientScopes []string) (googleoauth.Credentials, error) {

if c.AccessToken != "" {
contents, _, err := pathOrContents(c.AccessToken)
if err != nil {
return googleoauth.Credentials{}, fmt.Errorf("Error loading access token: %s", err)
}
token := &oauth2.Token{AccessToken: contents}

if c.ImpersonateServiceAccount != "" {
opts := []option.ClientOption{option.WithTokenSource(oauth2.StaticTokenSource(token)), option.ImpersonateCredentials(c.ImpersonateServiceAccount, c.ImpersonateServiceAccountDelegates...), option.WithScopes(clientScopes...)}
creds, err := transport.Creds(context.TODO(), opts...)
if err != nil {
return googleoauth.Credentials{}, err
}
return *creds, nil
}

log.Printf("[INFO] Authenticating using configured Google JSON 'access_token'...")
log.Printf("[INFO] -- Scopes: %s", clientScopes)
token := &oauth2.Token{AccessToken: contents}

return googleoauth.Credentials{
TokenSource: staticTokenSource{oauth2.StaticTokenSource(token)},
Expand All @@ -858,7 +871,14 @@ func (c *Config) GetCredentials(clientScopes []string) (googleoauth.Credentials,
if err != nil {
return googleoauth.Credentials{}, fmt.Errorf("error loading credentials: %s", err)
}

if c.ImpersonateServiceAccount != "" {
opts := []option.ClientOption{option.WithCredentialsJSON([]byte(contents)), option.ImpersonateCredentials(c.ImpersonateServiceAccount, c.ImpersonateServiceAccountDelegates...), option.WithScopes(clientScopes...)}
creds, err := transport.Creds(context.TODO(), opts...)
if err != nil {
return googleoauth.Credentials{}, err
}
return *creds, nil
}
creds, err := googleoauth.CredentialsFromJSON(c.context, []byte(contents), clientScopes...)
if err != nil {
return googleoauth.Credentials{}, fmt.Errorf("unable to parse credentials from '%s': %s", contents, err)
Expand All @@ -869,6 +889,16 @@ func (c *Config) GetCredentials(clientScopes []string) (googleoauth.Credentials,
return *creds, nil
}

if c.ImpersonateServiceAccount != "" {
opts := option.ImpersonateCredentials(c.ImpersonateServiceAccount, c.ImpersonateServiceAccountDelegates...)
creds, err := transport.Creds(context.TODO(), opts, option.WithScopes(clientScopes...))
if err != nil {
return googleoauth.Credentials{}, err
}
return *creds, nil

}

log.Printf("[INFO] Authenticating using DefaultClient...")
log.Printf("[INFO] -- Scopes: %s", clientScopes)

Expand Down

0 comments on commit 5ff67cb

Please sign in to comment.