github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/creds/vault/vault.go (about)

     1  package vault
     2  
     3  import (
     4  	"path"
     5  	"time"
     6  
     7  	"github.com/pf-qiu/concourse/v6/atc/creds"
     8  
     9  	vaultapi "github.com/hashicorp/vault/api"
    10  )
    11  
    12  // A SecretReader reads a vault secret from the given path. It should
    13  // be thread safe!
    14  type SecretReader interface {
    15  	Read(path string) (*vaultapi.Secret, error)
    16  }
    17  
    18  // Vault converts a vault secret to our completely untyped secret
    19  // data.
    20  type Vault struct {
    21  	SecretReader    SecretReader
    22  	Prefix          string
    23  	LookupTemplates []*creds.SecretTemplate
    24  	SharedPath      string
    25  }
    26  
    27  // NewSecretLookupPaths defines how variables will be searched in the underlying secret manager
    28  func (v Vault) NewSecretLookupPaths(teamName string, pipelineName string, allowRootPath bool) []creds.SecretLookupPath {
    29  	lookupPaths := []creds.SecretLookupPath{}
    30  	for _, tmpl := range v.LookupTemplates {
    31  		if lPath := creds.NewSecretLookupWithTemplate(tmpl, teamName, pipelineName); lPath != nil {
    32  			lookupPaths = append(lookupPaths, lPath)
    33  		}
    34  	}
    35  	if v.SharedPath != "" {
    36  		lookupPaths = append(lookupPaths, creds.NewSecretLookupWithPrefix(path.Join(v.Prefix, v.SharedPath)+"/"))
    37  	}
    38  	if allowRootPath {
    39  		lookupPaths = append(lookupPaths, creds.NewSecretLookupWithPrefix(v.Prefix+"/"))
    40  	}
    41  	return lookupPaths
    42  }
    43  
    44  // Get retrieves the value and expiration of an individual secret
    45  func (v Vault) Get(secretPath string) (interface{}, *time.Time, bool, error) {
    46  	secret, expiration, found, err := v.findSecret(secretPath)
    47  	if err != nil {
    48  		return nil, nil, false, err
    49  	}
    50  	if !found {
    51  		return nil, nil, false, nil
    52  	}
    53  
    54  	val, found := secret.Data["value"]
    55  	if found {
    56  		return val, expiration, true, nil
    57  	}
    58  
    59  	return secret.Data, expiration, true, nil
    60  }
    61  
    62  func (v Vault) findSecret(path string) (*vaultapi.Secret, *time.Time, bool, error) {
    63  	secret, err := v.SecretReader.Read(path)
    64  	if err != nil {
    65  		return nil, nil, false, err
    66  	}
    67  
    68  	if secret != nil {
    69  		// The lease duration is TTL: the time in seconds for which the lease is valid
    70  		// A consumer of this secret must renew the lease within that time.
    71  		duration := time.Duration(secret.LeaseDuration) * time.Second / 2
    72  		expiration := time.Now().Add(duration)
    73  		return secret, &expiration, true, nil
    74  	}
    75  
    76  	return nil, nil, false, nil
    77  }