chain_provider.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. // via 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 := credentials.NewChainCredentials(
  40. // []credentials.Provider{
  41. // &credentials.EnvProvider{},
  42. // &ec2rolecreds.EC2RoleProvider{
  43. // Client: ec2metadata.New(sess),
  44. // },
  45. // })
  46. //
  47. // // Usage of ChainCredentials with aws.Config
  48. // svc := ec2.New(session.Must(session.NewSession(&aws.Config{
  49. // Credentials: creds,
  50. // })))
  51. //
  52. type ChainProvider struct {
  53. Providers []Provider
  54. curr Provider
  55. VerboseErrors bool
  56. }
  57. // NewChainCredentials returns a pointer to a new Credentials object
  58. // wrapping a chain of providers.
  59. func NewChainCredentials(providers []Provider) *Credentials {
  60. return NewCredentials(&ChainProvider{
  61. Providers: append([]Provider{}, providers...),
  62. })
  63. }
  64. // Retrieve returns the credentials value or error if no provider returned
  65. // without error.
  66. //
  67. // If a provider is found it will be cached and any calls to IsExpired()
  68. // will return the expired state of the cached provider.
  69. func (c *ChainProvider) Retrieve() (Value, error) {
  70. var errs []error
  71. for _, p := range c.Providers {
  72. creds, err := p.Retrieve()
  73. if err == nil {
  74. c.curr = p
  75. return creds, nil
  76. }
  77. errs = append(errs, err)
  78. }
  79. c.curr = nil
  80. var err error
  81. err = ErrNoValidProvidersFoundInChain
  82. if c.VerboseErrors {
  83. err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
  84. }
  85. return Value{}, err
  86. }
  87. // IsExpired will returned the expired state of the currently cached provider
  88. // if there is one. If there is no current provider, true will be returned.
  89. func (c *ChainProvider) IsExpired() bool {
  90. if c.curr != nil {
  91. return c.curr.IsExpired()
  92. }
  93. return true
  94. }