From fcff4cbc9571d0e9ab8dc16fcfab84c9f9d7c4e8 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 17 Oct 2017 18:56:14 -0700 Subject: [PATCH] svchost/auth: caching credentials source This credentials source wraps another and caches its results in memory in a map that is keyed on the request hostname. This should ease the common case of many services operating on the same hostname by allowing an initial set of credentials to be re-used for subsequent requests. --- svchost/auth/cache.go | 45 +++++++++++++++++++++++++++++++++++++ svchost/auth/credentials.go | 2 ++ 2 files changed, 47 insertions(+) create mode 100644 svchost/auth/cache.go diff --git a/svchost/auth/cache.go b/svchost/auth/cache.go new file mode 100644 index 0000000000..4f0d1689f6 --- /dev/null +++ b/svchost/auth/cache.go @@ -0,0 +1,45 @@ +package auth + +import ( + "github.com/hashicorp/terraform/svchost" +) + +// CachingCredentialsSource creates a new credentials source that wraps another +// and caches its results in memory, on a per-hostname basis. +// +// No means is provided for expiration of cached credentials, so a caching +// credentials source should have a limited lifetime (one Terraform operation, +// for example) to ensure that time-limited credentials don't expire before +// their cache entries do. +func CachingCredentialsSource(source CredentialsSource) CredentialsSource { + return &cachingCredentialsSource{ + source: source, + cache: map[svchost.Hostname]HostCredentials{}, + } +} + +type cachingCredentialsSource struct { + source CredentialsSource + cache map[svchost.Hostname]HostCredentials +} + +// ForHost passes the given hostname on to the wrapped credentials source and +// caches the result to return for future requests with the same hostname. +// +// Both credentials and non-credentials (nil) responses are cached. +// +// No cache entry is created if the wrapped source returns an error, to allow +// the caller to retry the failing operation. +func (s *cachingCredentialsSource) ForHost(host svchost.Hostname) (HostCredentials, error) { + if cache, cached := s.cache[host]; cached { + return cache, nil + } + + result, err := s.source.ForHost(host) + if err != nil { + return result, err + } + + s.cache[host] = result + return result, nil +} diff --git a/svchost/auth/credentials.go b/svchost/auth/credentials.go index 8378236e0e..9eafdd93e6 100644 --- a/svchost/auth/credentials.go +++ b/svchost/auth/credentials.go @@ -1,3 +1,5 @@ +// Package auth contains types and functions to manage authentication +// credentials for service hosts. package auth import (