credentials: add compute engine channel creds (#2708)
This commit is contained in:
@ -38,7 +38,17 @@ const tokenRequestTimeout = 30 * time.Second
|
||||
//
|
||||
// This API is experimental.
|
||||
func NewDefaultCredentials() credentials.Bundle {
|
||||
c := &creds{}
|
||||
c := &creds{
|
||||
newPerRPCCreds: func() credentials.PerRPCCredentials {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout)
|
||||
defer cancel()
|
||||
perRPCCreds, err := oauth.NewApplicationDefault(ctx)
|
||||
if err != nil {
|
||||
grpclog.Warningf("google default creds: failed to create application oauth: %v", err)
|
||||
}
|
||||
return perRPCCreds
|
||||
},
|
||||
}
|
||||
bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
|
||||
if err != nil {
|
||||
grpclog.Warningf("google default creds: failed to create new creds: %v", err)
|
||||
@ -46,6 +56,24 @@ func NewDefaultCredentials() credentials.Bundle {
|
||||
return bundle
|
||||
}
|
||||
|
||||
// NewComputeEngineCredentials returns a credentials bundle that is configured to work
|
||||
// with google services. This API must only be used when running on GCE. Authentication configured
|
||||
// by this API represents the GCE VM's default service account.
|
||||
//
|
||||
// This API is experimental.
|
||||
func NewComputeEngineCredentials() credentials.Bundle {
|
||||
c := &creds{
|
||||
newPerRPCCreds: func() credentials.PerRPCCredentials {
|
||||
return oauth.NewComputeEngine()
|
||||
},
|
||||
}
|
||||
bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
|
||||
if err != nil {
|
||||
grpclog.Warningf("compute engine creds: failed to create new creds: %v", err)
|
||||
}
|
||||
return bundle
|
||||
}
|
||||
|
||||
// creds implements credentials.Bundle.
|
||||
type creds struct {
|
||||
// Supported modes are defined in internal/internal.go.
|
||||
@ -54,6 +82,8 @@ type creds struct {
|
||||
transportCreds credentials.TransportCredentials
|
||||
// The per RPC credentials associated with this bundle.
|
||||
perRPCCreds credentials.PerRPCCredentials
|
||||
// Creates new per RPC credentials
|
||||
newPerRPCCreds func() credentials.PerRPCCredentials
|
||||
}
|
||||
|
||||
func (c *creds) TransportCredentials() credentials.TransportCredentials {
|
||||
@ -70,7 +100,10 @@ func (c *creds) PerRPCCredentials() credentials.PerRPCCredentials {
|
||||
// NewWithMode should make a copy of Bundle, and switch mode. Modifying the
|
||||
// existing Bundle may cause races.
|
||||
func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
|
||||
newCreds := &creds{mode: mode}
|
||||
newCreds := &creds{
|
||||
mode: mode,
|
||||
newPerRPCCreds: c.newPerRPCCreds,
|
||||
}
|
||||
|
||||
// Create transport credentials.
|
||||
switch mode {
|
||||
@ -81,20 +114,11 @@ func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
|
||||
// to create new ALTS client creds here.
|
||||
newCreds.transportCreds = alts.NewClientCreds(alts.DefaultClientOptions())
|
||||
default:
|
||||
return nil, fmt.Errorf("google default creds: unsupported mode: %v", mode)
|
||||
return nil, fmt.Errorf("unsupported mode: %v", mode)
|
||||
}
|
||||
|
||||
if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
|
||||
// Create per RPC credentials.
|
||||
// For the time being, we required per RPC credentials for both TLS and
|
||||
// ALTS. In the future, this will only be required for TLS.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout)
|
||||
defer cancel()
|
||||
var err error
|
||||
newCreds.perRPCCreds, err = oauth.NewApplicationDefault(ctx)
|
||||
if err != nil {
|
||||
grpclog.Warningf("google default creds: failed to create application oauth: %v", err)
|
||||
}
|
||||
newCreds.perRPCCreds = newCreds.newPerRPCCreds()
|
||||
}
|
||||
|
||||
return newCreds, nil
|
||||
|
@ -38,6 +38,7 @@ import (
|
||||
|
||||
const (
|
||||
googleDefaultCredsName = "google_default_credentials"
|
||||
computeEngineCredsName = "compute_engine_channel_creds"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -68,6 +69,7 @@ var (
|
||||
per_rpc_creds: large_unary with per rpc token;
|
||||
oauth2_auth_token: large_unary with oauth2 token auth;
|
||||
google_default_credentials: large_unary with google default credentials
|
||||
compute_engine_channel_credentials: large_unary with compute engine creds
|
||||
cancel_after_begin: cancellation after metadata has been sent but before payloads are sent;
|
||||
cancel_after_first_response: cancellation after receiving 1st message from the server;
|
||||
status_code_and_message: status code propagated back to client;
|
||||
@ -84,19 +86,26 @@ const (
|
||||
credsTLS
|
||||
credsALTS
|
||||
credsGoogleDefaultCreds
|
||||
credsComputeEngineCreds
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
var useGDC bool // use google default creds
|
||||
var useCEC bool // use compute engine creds
|
||||
if *customCredentialsType != "" {
|
||||
if *customCredentialsType != googleDefaultCredsName {
|
||||
grpclog.Fatalf("custom_credentials_type can only be set to %v or not set", googleDefaultCredsName)
|
||||
switch *customCredentialsType {
|
||||
case googleDefaultCredsName:
|
||||
useGDC = true
|
||||
case computeEngineCredsName:
|
||||
useCEC = true
|
||||
default:
|
||||
grpclog.Fatalf("If set, custom_credentials_type can only be set to one of %v or %v",
|
||||
googleDefaultCredsName, computeEngineCredsName)
|
||||
}
|
||||
useGDC = true
|
||||
}
|
||||
if (*useTLS && *useALTS) || (*useTLS && useGDC) || (*useALTS && useGDC) {
|
||||
grpclog.Fatalf("only one of TLS, ALTS and google default creds can be used")
|
||||
if (*useTLS && *useALTS) || (*useTLS && useGDC) || (*useALTS && useGDC) || (*useTLS && useCEC) || (*useALTS && useCEC) {
|
||||
grpclog.Fatalf("only one of TLS, ALTS, google default creds, or compute engine creds can be used")
|
||||
}
|
||||
|
||||
var credsChosen credsMode
|
||||
@ -107,6 +116,8 @@ func main() {
|
||||
credsChosen = credsALTS
|
||||
case useGDC:
|
||||
credsChosen = credsGoogleDefaultCreds
|
||||
case useCEC:
|
||||
credsChosen = credsComputeEngineCreds
|
||||
}
|
||||
|
||||
resolver.SetDefaultScheme("dns")
|
||||
@ -141,6 +152,8 @@ func main() {
|
||||
opts = append(opts, grpc.WithTransportCredentials(altsTC))
|
||||
case credsGoogleDefaultCreds:
|
||||
opts = append(opts, grpc.WithCredentialsBundle(google.NewDefaultCredentials()))
|
||||
case credsComputeEngineCreds:
|
||||
opts = append(opts, grpc.WithCredentialsBundle(google.NewComputeEngineCredentials()))
|
||||
case credsNone:
|
||||
opts = append(opts, grpc.WithInsecure())
|
||||
default:
|
||||
@ -230,6 +243,12 @@ func main() {
|
||||
}
|
||||
interop.DoGoogleDefaultCredentials(tc, *defaultServiceAccount)
|
||||
grpclog.Infoln("GoogleDefaultCredentials done")
|
||||
case "compute_engine_channel_credentials":
|
||||
if credsChosen != credsComputeEngineCreds {
|
||||
grpclog.Fatalf("ComputeEngineCreds need to be set for compute_engine_channel_credentials test case.")
|
||||
}
|
||||
interop.DoComputeEngineChannelCredentials(tc, *defaultServiceAccount)
|
||||
grpclog.Infoln("ComputeEngineChannelCredentials done")
|
||||
case "cancel_after_begin":
|
||||
interop.DoCancelAfterBegin(tc)
|
||||
grpclog.Infoln("CancelAfterBegin done")
|
||||
|
@ -393,7 +393,7 @@ func DoPerRPCCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScop
|
||||
}
|
||||
}
|
||||
|
||||
// DoGoogleDefaultCredentials performs a unary RPC with google default credentials
|
||||
// DoGoogleDefaultCredentials performs an unary RPC with google default credentials
|
||||
func DoGoogleDefaultCredentials(tc testpb.TestServiceClient, defaultServiceAccount string) {
|
||||
pl := ClientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
|
||||
req := &testpb.SimpleRequest{
|
||||
@ -412,6 +412,25 @@ func DoGoogleDefaultCredentials(tc testpb.TestServiceClient, defaultServiceAccou
|
||||
}
|
||||
}
|
||||
|
||||
// DoComputeEngineChannelCredentials performs an unary RPC with compute engine channel credentials
|
||||
func DoComputeEngineChannelCredentials(tc testpb.TestServiceClient, defaultServiceAccount string) {
|
||||
pl := ClientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
|
||||
req := &testpb.SimpleRequest{
|
||||
ResponseType: testpb.PayloadType_COMPRESSABLE,
|
||||
ResponseSize: int32(largeRespSize),
|
||||
Payload: pl,
|
||||
FillUsername: true,
|
||||
FillOauthScope: true,
|
||||
}
|
||||
reply, err := tc.UnaryCall(context.Background(), req)
|
||||
if err != nil {
|
||||
grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
|
||||
}
|
||||
if reply.GetUsername() != defaultServiceAccount {
|
||||
grpclog.Fatalf("Got user name %q; wanted %q. ", reply.GetUsername(), defaultServiceAccount)
|
||||
}
|
||||
}
|
||||
|
||||
var testMetadata = metadata.MD{
|
||||
"key1": []string{"value1"},
|
||||
"key2": []string{"value2"},
|
||||
|
Reference in New Issue
Block a user