Skip to content

Commit

Permalink
Add chain provider
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre-Emmanuel Jacquier <15922119+pierre-emmanuelJ@users.noreply.github.com>
  • Loading branch information
pierre-emmanuelJ committed Jan 11, 2024
1 parent e993051 commit 4955009
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions v3/credentials/chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package credentials

import (
"errors"
"fmt"
)

var (
ErrNoValidCredentialProviders = errors.New("no valid credential providers")
)

// A ChainProvider will search for a provider which returns credentials
// and cache that provider until Retrieve is called again.
type ChainProvider struct {
Providers []Provider
current Provider
}

// NewChainCredentials returns a pointer to a new Credentials object
// wrapping a chain of providers.
func NewChainCredentials(providers []Provider) *Credentials {
return NewCredentials(&ChainProvider{
Providers: append([]Provider{}, providers...),
})
}

// Retrieve returns the credentials value or error if no provider returned
// without error.
//
// If a provider is found it will be cached and any calls to IsExpired()
// will return the expired state of the cached provider.
func (c *ChainProvider) Retrieve() (Value, error) {
var errs = ErrNoValidCredentialProviders

for _, p := range c.Providers {
creds, err := p.Retrieve()
if err == nil {
c.current = p
return creds, nil
}

errs = fmt.Errorf("%v: %w", errs, err)
}
c.current = nil

return Value{}, fmt.Errorf("chain provider: %w", errs)
}

// IsExpired will returned the expired state of the currently cached provider
// if there is one. If there is no current provider, true will be returned.
func (c *ChainProvider) IsExpired() bool {
if c.current != nil {
return c.current.IsExpired()
}

return true
}

0 comments on commit 4955009

Please sign in to comment.