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 }