github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/credentials/google/google.go (about)

     1  /*
     2   *
     3   * Copyright 2018 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  // Package google defines credentials for google cloud services.
    20  package google
    21  
    22  import (
    23  	"context"
    24  	"fmt"
    25  	"time"
    26  
    27  	"github.com/hxx258456/ccgo/grpc/credentials"
    28  	"github.com/hxx258456/ccgo/grpc/credentials/alts"
    29  	"github.com/hxx258456/ccgo/grpc/credentials/oauth"
    30  	"github.com/hxx258456/ccgo/grpc/grpclog"
    31  	"github.com/hxx258456/ccgo/grpc/internal"
    32  )
    33  
    34  const tokenRequestTimeout = 30 * time.Second
    35  
    36  var logger = grpclog.Component("credentials")
    37  
    38  // DefaultCredentialsOptions constructs options to build DefaultCredentials.
    39  type DefaultCredentialsOptions struct {
    40  	// PerRPCCreds is a per RPC credentials that is passed to a bundle.
    41  	PerRPCCreds credentials.PerRPCCredentials
    42  }
    43  
    44  // NewDefaultCredentialsWithOptions returns a credentials bundle that is
    45  // configured to work with google services.
    46  //
    47  // This API is experimental.
    48  func NewDefaultCredentialsWithOptions(opts DefaultCredentialsOptions) credentials.Bundle {
    49  	if opts.PerRPCCreds == nil {
    50  		ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout)
    51  		defer cancel()
    52  		var err error
    53  		opts.PerRPCCreds, err = oauth.NewApplicationDefault(ctx)
    54  		if err != nil {
    55  			logger.Warningf("NewDefaultCredentialsWithOptions: failed to create application oauth: %v", err)
    56  		}
    57  	}
    58  	c := &creds{opts: opts}
    59  	bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
    60  	if err != nil {
    61  		logger.Warningf("NewDefaultCredentialsWithOptions: failed to create new creds: %v", err)
    62  	}
    63  	return bundle
    64  }
    65  
    66  // NewDefaultCredentials returns a credentials bundle that is configured to work
    67  // with google services.
    68  //
    69  // This API is experimental.
    70  func NewDefaultCredentials() credentials.Bundle {
    71  	return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{})
    72  }
    73  
    74  // NewComputeEngineCredentials returns a credentials bundle that is configured to work
    75  // with google services. This API must only be used when running on GCE. Authentication configured
    76  // by this API represents the GCE VM's default service account.
    77  //
    78  // This API is experimental.
    79  func NewComputeEngineCredentials() credentials.Bundle {
    80  	return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{
    81  		PerRPCCreds: oauth.NewComputeEngine(),
    82  	})
    83  }
    84  
    85  // creds implements credentials.Bundle.
    86  type creds struct {
    87  	opts DefaultCredentialsOptions
    88  
    89  	// Supported modes are defined in internal/internal.go.
    90  	mode string
    91  	// The active transport credentials associated with this bundle.
    92  	transportCreds credentials.TransportCredentials
    93  	// The active per RPC credentials associated with this bundle.
    94  	perRPCCreds credentials.PerRPCCredentials
    95  }
    96  
    97  func (c *creds) TransportCredentials() credentials.TransportCredentials {
    98  	return c.transportCreds
    99  }
   100  
   101  func (c *creds) PerRPCCredentials() credentials.PerRPCCredentials {
   102  	if c == nil {
   103  		return nil
   104  	}
   105  	return c.perRPCCreds
   106  }
   107  
   108  var (
   109  	newTLS = func() credentials.TransportCredentials {
   110  		return credentials.NewTLS(nil)
   111  	}
   112  	newALTS = func() credentials.TransportCredentials {
   113  		return alts.NewClientCreds(alts.DefaultClientOptions())
   114  	}
   115  )
   116  
   117  // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
   118  // existing Bundle may cause races.
   119  func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
   120  	newCreds := &creds{
   121  		opts: c.opts,
   122  		mode: mode,
   123  	}
   124  
   125  	// Create transport credentials.
   126  	switch mode {
   127  	case internal.CredsBundleModeFallback:
   128  		newCreds.transportCreds = newClusterTransportCreds(newTLS(), newALTS())
   129  	case internal.CredsBundleModeBackendFromBalancer, internal.CredsBundleModeBalancer:
   130  		// Only the clients can use google default credentials, so we only need
   131  		// to create new ALTS client creds here.
   132  		newCreds.transportCreds = newALTS()
   133  	default:
   134  		return nil, fmt.Errorf("unsupported mode: %v", mode)
   135  	}
   136  
   137  	if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
   138  		newCreds.perRPCCreds = newCreds.opts.PerRPCCreds
   139  	}
   140  
   141  	return newCreds, nil
   142  }