func writeCacheWhileLocked(filename string, cache cacheFile) error {
	data, err := yaml.Marshal(cache)
	if err == nil {
		err = f.WriteFile(filename, data, 0600)
	}
	return err
}
writeCacheWhileLocked writes the contents of the credential cache using the
yaml marshaled form of the passed cacheFile object.  This method must be
called while an exclusive lock is held on the filename.
package token
import (
	"context"
	"errors"
	"fmt"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/gofrs/flock"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"time"
)
const cacheFileNameEnv = "AWS_IAM_AUTHENTICATOR_CACHE_FILE"
var f filesystem = osFS{}
type filesystem interface {
	Stat(filename string) (os.FileInfo, error)
	ReadFile(filename string) ([]byte, error)
	WriteFile(filename string, data []byte, perm os.FileMode) error
	MkdirAll(path string, perm os.FileMode) error
}
type osFS struct{}
func (osFS) Stat(filename string) (os.FileInfo, error) {
	return os.Stat(filename)
}
func (osFS) ReadFile(filename string) ([]byte, error) {
	return ioutil.ReadFile(filename)
}
func (osFS) WriteFile(filename string, data []byte, perm os.FileMode) error {
	return ioutil.WriteFile(filename, data, perm)
}
func (osFS) MkdirAll(path string, perm os.FileMode) error {
	return os.MkdirAll(path, perm)
}
var e environment = osEnv{}
type environment interface {
	Getenv(key string) string
	LookupEnv(key string) (string, bool)
}
type osEnv struct{}
func (osEnv) Getenv(key string) string {
	return os.Getenv(key)
}
func (osEnv) LookupEnv(key string) (string, bool) {
	return os.LookupEnv(key)
}
type filelock interface {
	Unlock() error
	TryLockContext(ctx context.Context, retryDelay time.Duration) (bool, error)
	TryRLockContext(ctx context.Context, retryDelay time.Duration) (bool, error)
}
var newFlock = func(filename string) filelock {
	return flock.New(filename)
}
type cacheFile struct {
	ClusterMap map[string]map[string]map[string]cachedCredential `yaml:"clusters"`
}
type cacheKey struct {
	clusterID string
	profile   string
	roleARN   string
}
func (c *cacheFile) Put(key cacheKey, credential cachedCredential) {
	if _, ok := c.ClusterMap[key.clusterID]; !ok {
		c.ClusterMap[key.clusterID] = map[string]map[string]cachedCredential{}
	}
	if _, ok := c.ClusterMap[key.clusterID][key.profile]; !ok {
		c.ClusterMap[key.clusterID][key.profile] = map[string]cachedCredential{}
	}
	c.ClusterMap[key.clusterID][key.profile][key.roleARN] = credential
}
func (c *cacheFile) Get(key cacheKey) (credential cachedCredential) {
	if _, ok := c.ClusterMap[key.clusterID]; ok {
		if _, ok := c.ClusterMap[key.clusterID][key.profile]; ok {
			credential = c.ClusterMap[key.clusterID][key.profile][key.roleARN]
		}
	}
	return
}
type cachedCredential struct {
	Credential credentials.Value
	Expiration time.Time
	currentTime func() time.Time
}
func (c *cachedCredential) IsExpired() bool {
	curTime := c.currentTime
	if curTime == nil {
		curTime = time.Now
	}
	return c.Expiration.Before(curTime())
}
func readCacheWhileLocked(filename string) (cache cacheFile, err error) {
	cache = cacheFile{
		map[string]map[string]map[string]cachedCredential{},
	}
	data, err := f.ReadFile(filename)
	if err != nil {
		err = fmt.Errorf("unable to open file %s: %v", filename, err)
		return
	}
	err = yaml.Unmarshal(data, &cache)
	if err != nil {
		err = fmt.Errorf("unable to parse file %s: %v", filename, err)
	}
	return
}