github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/gce/google/auth.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package google
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/juju/errors"
    10  	jujuhttp "github.com/juju/http/v2"
    11  	"golang.org/x/oauth2/google"
    12  	"golang.org/x/oauth2/jwt"
    13  	"google.golang.org/api/compute/v1"
    14  	"google.golang.org/api/option"
    15  	transporthttp "google.golang.org/api/transport/http"
    16  )
    17  
    18  var scopes = []string{
    19  	"https://www.googleapis.com/auth/compute",
    20  	"https://www.googleapis.com/auth/devstorage.full_control",
    21  }
    22  
    23  // newComputeService opens a new low-level connection to the GCE API using
    24  // the input credentials and returns it.
    25  // This includes building the OAuth-wrapping network transport.
    26  // TODO (manadart 2019-11-15) This the bottom layer in a cake of needless
    27  // abstractions:
    28  // This is embedded in rawConn, which is embedded in Connection,
    29  // which is then used by the Environ.
    30  // This should also be relocated alongside its wrapper,
    31  // rather than this "auth.go" file.
    32  func newComputeService(ctx context.Context, creds *Credentials, httpClient *jujuhttp.Client) (*compute.Service, error) {
    33  	cfg, err := newJWTConfig(creds)
    34  	if err != nil {
    35  		return nil, errors.Trace(err)
    36  	}
    37  
    38  	// We're substituting the transport, with a wrapped GCE specific version of
    39  	// the original http.Client.
    40  	newClient := *httpClient.Client()
    41  
    42  	tsOpt := option.WithTokenSource(cfg.TokenSource(ctx))
    43  	if newClient.Transport, err = transporthttp.NewTransport(ctx, newClient.Transport, tsOpt); err != nil {
    44  		return nil, errors.Trace(err)
    45  	}
    46  
    47  	service, err := compute.NewService(ctx,
    48  		tsOpt,
    49  		option.WithHTTPClient(&newClient),
    50  	)
    51  	return service, errors.Trace(err)
    52  }
    53  
    54  func newJWTConfig(creds *Credentials) (*jwt.Config, error) {
    55  	jsonKey := creds.JSONKey
    56  	if jsonKey == nil {
    57  		var err error
    58  		jsonKey, err = creds.buildJSONKey()
    59  		if err != nil {
    60  			return nil, errors.Trace(err)
    61  		}
    62  	}
    63  
    64  	return google.JWTConfigFromJSON(
    65  		jsonKey,
    66  		scopes...,
    67  	)
    68  }