chain_provider.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package credentials
  2. import (
  3. "github.com/aws/aws-sdk-go/aws/awserr"
  4. )
  5. var (
  6. // ErrNoValidProvidersFoundInChain Is returned when there are no valid
  7. // providers in the ChainProvider.
  8. //
  9. // This has been deprecated. For verbose error messaging set
  10. // aws.Config.CredentialsChainVerboseErrors to true
  11. //
  12. // @readonly
  13. ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders",
  14. `no valid providers in chain. Deprecated.
  15. For verbose messaging see aws.Config.CredentialsChainVerboseErrors`,
  16. nil)
  17. )
  18. // A ChainProvider will search for a provider which returns credentials
  19. // and cache that provider until Retrieve is called again.
  20. //
  21. // The ChainProvider provides a way of chaining multiple providers together
  22. // which will pick the first available using priority order of the Providers
  23. // in the list.
  24. //
  25. // If none of the Providers retrieve valid credentials Value, ChainProvider's
  26. // Retrieve() will return the error ErrNoValidProvidersFoundInChain.
  27. //
  28. // If a Provider is found which returns valid credentials Value ChainProvider
  29. // will cache that Provider for all calls to IsExpired(), until Retrieve is
  30. // called again.
  31. //
  32. // Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
  33. // In this example EnvProvider will first check if any credentials are available
  34. // vai the environment variables. If there are none ChainProvider will check
  35. // the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
  36. // does not return any credentials ChainProvider will return the error
  37. // ErrNoValidProvidersFoundInChain
  38. //
  39. // creds := NewChainCredentials(
  40. // []Provider{
  41. // &EnvProvider{},
  42. // &EC2RoleProvider{
  43. // Client: ec2metadata.New(sess),
  44. // },
  45. // })
  46. //
  47. // // Usage of ChainCredentials with aws.Config
  48. // svc := ec2.New(&aws.Config{Credentials: creds})
  49. //
  50. type ChainProvider struct {
  51. Providers []Provider
  52. curr Provider
  53. VerboseErrors bool
  54. }
  55. // NewChainCredentials returns a pointer to a new Credentials object
  56. // wrapping a chain of providers.
  57. func NewChainCredentials(providers []Provider) *Credentials {
  58. return NewCredentials(&ChainProvider{
  59. Providers: append([]Provider{}, providers...),
  60. })
  61. }
  62. // Retrieve returns the credentials value or error if no provider returned
  63. // without error.
  64. //
  65. // If a provider is found it will be cached and any calls to IsExpired()
  66. // will return the expired state of the cached provider.
  67. func (c *ChainProvider) Retrieve() (Value, error) {
  68. var errs []error
  69. for _, p := range c.Providers {
  70. creds, err := p.Retrieve()
  71. if err == nil {
  72. c.curr = p
  73. return creds, nil
  74. }
  75. errs = append(errs, err)
  76. }
  77. c.curr = nil
  78. var err error
  79. err = ErrNoValidProvidersFoundInChain
  80. if c.VerboseErrors {
  81. err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
  82. }
  83. return Value{}, err
  84. }
  85. // IsExpired will returned the expired state of the currently cached provider
  86. // if there is one. If there is no current provider, true will be returned.
  87. func (c *ChainProvider) IsExpired() bool {
  88. if c.curr != nil {
  89. return c.curr.IsExpired()
  90. }
  91. return true
  92. }