1package auth 2 3import ( 4 "github.com/hashicorp/terraform/svchost" 5) 6 7// CachingCredentialsSource creates a new credentials source that wraps another 8// and caches its results in memory, on a per-hostname basis. 9// 10// No means is provided for expiration of cached credentials, so a caching 11// credentials source should have a limited lifetime (one Terraform operation, 12// for example) to ensure that time-limited credentials don't expire before 13// their cache entries do. 14func CachingCredentialsSource(source CredentialsSource) CredentialsSource { 15 return &cachingCredentialsSource{ 16 source: source, 17 cache: map[svchost.Hostname]HostCredentials{}, 18 } 19} 20 21type cachingCredentialsSource struct { 22 source CredentialsSource 23 cache map[svchost.Hostname]HostCredentials 24} 25 26// ForHost passes the given hostname on to the wrapped credentials source and 27// caches the result to return for future requests with the same hostname. 28// 29// Both credentials and non-credentials (nil) responses are cached. 30// 31// No cache entry is created if the wrapped source returns an error, to allow 32// the caller to retry the failing operation. 33func (s *cachingCredentialsSource) ForHost(host svchost.Hostname) (HostCredentials, error) { 34 if cache, cached := s.cache[host]; cached { 35 return cache, nil 36 } 37 38 result, err := s.source.ForHost(host) 39 if err != nil { 40 return result, err 41 } 42 43 s.cache[host] = result 44 return result, nil 45} 46