google.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. // Package google defines credentials for google cloud services.
  19. package google
  20. import (
  21. "context"
  22. "fmt"
  23. "time"
  24. "google.golang.org/grpc/credentials"
  25. "google.golang.org/grpc/credentials/alts"
  26. "google.golang.org/grpc/credentials/oauth"
  27. "google.golang.org/grpc/grpclog"
  28. "google.golang.org/grpc/internal"
  29. )
  30. const tokenRequestTimeout = 30 * time.Second
  31. var logger = grpclog.Component("credentials")
  32. // DefaultCredentialsOptions constructs options to build DefaultCredentials.
  33. type DefaultCredentialsOptions struct {
  34. // PerRPCCreds is a per RPC credentials that is passed to a bundle.
  35. PerRPCCreds credentials.PerRPCCredentials
  36. }
  37. // NewDefaultCredentialsWithOptions returns a credentials bundle that is
  38. // configured to work with google services.
  39. //
  40. // This API is experimental.
  41. func NewDefaultCredentialsWithOptions(opts DefaultCredentialsOptions) credentials.Bundle {
  42. if opts.PerRPCCreds == nil {
  43. ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout)
  44. defer cancel()
  45. var err error
  46. opts.PerRPCCreds, err = newADC(ctx)
  47. if err != nil {
  48. logger.Warningf("NewDefaultCredentialsWithOptions: failed to create application oauth: %v", err)
  49. }
  50. }
  51. c := &creds{opts: opts}
  52. bundle, err := c.NewWithMode(internal.CredsBundleModeFallback)
  53. if err != nil {
  54. logger.Warningf("NewDefaultCredentialsWithOptions: failed to create new creds: %v", err)
  55. }
  56. return bundle
  57. }
  58. // NewDefaultCredentials returns a credentials bundle that is configured to work
  59. // with google services.
  60. //
  61. // This API is experimental.
  62. func NewDefaultCredentials() credentials.Bundle {
  63. return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{})
  64. }
  65. // NewComputeEngineCredentials returns a credentials bundle that is configured to work
  66. // with google services. This API must only be used when running on GCE. Authentication configured
  67. // by this API represents the GCE VM's default service account.
  68. //
  69. // This API is experimental.
  70. func NewComputeEngineCredentials() credentials.Bundle {
  71. return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{
  72. PerRPCCreds: oauth.NewComputeEngine(),
  73. })
  74. }
  75. // creds implements credentials.Bundle.
  76. type creds struct {
  77. opts DefaultCredentialsOptions
  78. // Supported modes are defined in internal/internal.go.
  79. mode string
  80. // The active transport credentials associated with this bundle.
  81. transportCreds credentials.TransportCredentials
  82. // The active per RPC credentials associated with this bundle.
  83. perRPCCreds credentials.PerRPCCredentials
  84. }
  85. func (c *creds) TransportCredentials() credentials.TransportCredentials {
  86. return c.transportCreds
  87. }
  88. func (c *creds) PerRPCCredentials() credentials.PerRPCCredentials {
  89. if c == nil {
  90. return nil
  91. }
  92. return c.perRPCCreds
  93. }
  94. var (
  95. newTLS = func() credentials.TransportCredentials {
  96. return credentials.NewTLS(nil)
  97. }
  98. newALTS = func() credentials.TransportCredentials {
  99. return alts.NewClientCreds(alts.DefaultClientOptions())
  100. }
  101. newADC = func(ctx context.Context) (credentials.PerRPCCredentials, error) {
  102. return oauth.NewApplicationDefault(ctx)
  103. }
  104. )
  105. // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
  106. // existing Bundle may cause races.
  107. func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) {
  108. newCreds := &creds{
  109. opts: c.opts,
  110. mode: mode,
  111. }
  112. // Create transport credentials.
  113. switch mode {
  114. case internal.CredsBundleModeFallback:
  115. newCreds.transportCreds = newClusterTransportCreds(newTLS(), newALTS())
  116. case internal.CredsBundleModeBackendFromBalancer, internal.CredsBundleModeBalancer:
  117. // Only the clients can use google default credentials, so we only need
  118. // to create new ALTS client creds here.
  119. newCreds.transportCreds = newALTS()
  120. default:
  121. return nil, fmt.Errorf("unsupported mode: %v", mode)
  122. }
  123. if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer {
  124. newCreds.perRPCCreds = newCreds.opts.PerRPCCreds
  125. }
  126. return newCreds, nil
  127. }