2020-07-22 11:15:48 +02:00
package config
import (
2020-10-26 14:20:04 +01:00
"os"
2021-09-21 14:06:32 +03:00
"path"
2021-04-09 10:04:35 +02:00
"regexp"
"strings"
2020-10-26 14:20:04 +01:00
2020-09-16 14:50:09 +02:00
"github.com/SAP/jenkins-library/pkg/config/interpolation"
"github.com/SAP/jenkins-library/pkg/log"
2022-08-04 09:20:59 +02:00
"github.com/SAP/jenkins-library/pkg/piperutils"
2020-07-22 11:15:48 +02:00
"github.com/SAP/jenkins-library/pkg/vault"
"github.com/hashicorp/vault/api"
)
2021-04-09 10:04:35 +02:00
const (
2021-09-21 14:06:32 +03:00
vaultRootPaths = "vaultRootPaths"
vaultTestCredentialPath = "vaultTestCredentialPath"
2021-12-21 11:00:13 +01:00
vaultCredentialPath = "vaultCredentialPath"
2021-09-21 14:06:32 +03:00
vaultTestCredentialKeys = "vaultTestCredentialKeys"
2021-12-21 11:00:13 +01:00
vaultCredentialKeys = "vaultCredentialKeys"
2021-09-21 14:06:32 +03:00
vaultAppRoleID = "vaultAppRoleID"
vaultAppRoleSecretID = "vaultAppRoleSecreId"
vaultServerUrl = "vaultServerUrl"
vaultNamespace = "vaultNamespace"
vaultBasePath = "vaultBasePath"
vaultPipelineName = "vaultPipelineName"
vaultPath = "vaultPath"
skipVault = "skipVault"
vaultDisableOverwrite = "vaultDisableOverwrite"
2021-11-19 12:05:39 +03:00
vaultTestCredentialEnvPrefix = "vaultTestCredentialEnvPrefix"
2021-12-21 11:00:13 +01:00
vaultCredentialEnvPrefix = "vaultCredentialEnvPrefix"
2021-09-21 14:06:32 +03:00
vaultTestCredentialEnvPrefixDefault = "PIPER_TESTCREDENTIAL_"
2023-03-31 09:36:59 +02:00
VaultCredentialEnvPrefixDefault = "PIPER_VAULTCREDENTIAL_"
2022-03-17 09:41:51 +01:00
vaultSecretName = ".+VaultSecretName$"
2021-04-09 10:04:35 +02:00
)
2020-10-26 14:20:04 +01:00
var (
vaultFilter = [ ] string {
2021-09-21 14:06:32 +03:00
vaultRootPaths ,
vaultAppRoleID ,
vaultAppRoleSecretID ,
vaultServerUrl ,
vaultNamespace ,
vaultBasePath ,
vaultPipelineName ,
vaultPath ,
skipVault ,
vaultDisableOverwrite ,
2021-04-09 10:04:35 +02:00
vaultTestCredentialPath ,
vaultTestCredentialKeys ,
2021-11-19 12:05:39 +03:00
vaultTestCredentialEnvPrefix ,
2021-12-21 11:00:13 +01:00
vaultCredentialPath ,
vaultCredentialKeys ,
vaultCredentialEnvPrefix ,
2022-03-17 09:41:51 +01:00
vaultSecretName ,
2020-10-26 14:20:04 +01:00
}
2021-09-21 14:06:32 +03:00
// VaultRootPaths are the lookup paths piper tries to use during the vault lookup.
// A path is only used if it's variables can be interpolated from the config
VaultRootPaths = [ ] string {
"$(vaultPath)" ,
"$(vaultBasePath)/$(vaultPipelineName)" ,
"$(vaultBasePath)/GROUP-SECRETS" ,
}
2020-10-26 14:20:04 +01:00
// VaultSecretFileDirectory holds the directory for the current step run to temporarily store secret files fetched from vault
VaultSecretFileDirectory = ""
)
2020-09-16 14:50:09 +02:00
// VaultCredentials hold all the auth information needed to fetch configuration from vault
type VaultCredentials struct {
AppRoleID string
AppRoleSecretID string
2021-02-15 09:48:51 +01:00
VaultToken string
2020-09-16 14:50:09 +02:00
}
2024-05-07 14:19:39 +02:00
// VaultClient interface for mocking
type VaultClient interface {
2020-07-22 11:15:48 +02:00
GetKvSecret ( string ) ( map [ string ] string , error )
2021-03-10 08:36:50 +01:00
MustRevokeToken ( )
2024-05-07 14:19:39 +02:00
GetOIDCTokenByValidation ( string ) ( string , error )
2020-07-22 11:15:48 +02:00
}
2024-10-11 14:55:39 +05:00
// globalVaultClient is supposed to be used in the steps code.
var globalVaultClient * vault . Client
func GlobalVaultClient ( ) VaultClient {
// an interface containing a nil pointer is considered non-nil in Go
2024-10-22 13:29:34 +05:00
// It is nil if Vault is not configured
2024-10-11 14:55:39 +05:00
if globalVaultClient == nil {
return nil
}
return globalVaultClient
}
2021-09-21 14:06:32 +03:00
func ( s * StepConfig ) mixinVaultConfig ( parameters [ ] StepParameters , configs ... map [ string ] interface { } ) {
2021-01-20 14:59:47 +01:00
for _ , config := range configs {
2024-01-10 15:02:11 +05:00
s . mixIn ( config , vaultFilter , StepData { } )
2021-09-21 14:06:32 +03:00
// when an empty filter is returned we skip the mixin call since an empty filter will allow everything
if referencesFilter := getFilterForResourceReferences ( parameters ) ; len ( referencesFilter ) > 0 {
2024-01-10 15:02:11 +05:00
s . mixIn ( config , referencesFilter , StepData { } )
2021-09-21 14:06:32 +03:00
}
2021-01-20 14:59:47 +01:00
}
}
2024-10-11 14:55:39 +05:00
// GetVaultClientFromConfig logs in to Vault and returns authorized Vault client.
// It's important to revoke token provided to this client after usage.
// Currently, revocation will happen at the end of each step execution (see _generated.go part of the steps)
2024-05-07 14:19:39 +02:00
func GetVaultClientFromConfig ( config map [ string ] interface { } , creds VaultCredentials ) ( VaultClient , error ) {
address , addressOk := config [ "vaultServerUrl" ] . ( string )
2020-07-22 11:15:48 +02:00
// if vault isn't used it's not an error
2021-02-15 09:48:51 +01:00
if ! addressOk || creds . VaultToken == "" && ( creds . AppRoleID == "" || creds . AppRoleSecretID == "" ) {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debug ( "Vault not configured" )
2020-07-22 11:15:48 +02:00
return nil , nil
}
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Info ( "Logging into Vault" )
log . Entry ( ) . Debugf ( " with URL %s" , address )
2020-10-13 14:14:47 +02:00
namespace := ""
2020-07-22 11:15:48 +02:00
// namespaces are only available in vault enterprise so using them should be optional
2024-05-07 14:19:39 +02:00
if config [ "vaultNamespace" ] != nil {
namespace = config [ "vaultNamespace" ] . ( string )
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " with namespace %s" , namespace )
2020-10-13 14:14:47 +02:00
}
2024-10-22 13:29:34 +05:00
var client * vault . Client
2021-02-15 09:48:51 +01:00
var err error
2024-10-22 13:29:34 +05:00
clientConfig := & vault . ClientConfig { Config : & api . Config { Address : address } , Namespace : namespace }
2021-02-15 09:48:51 +01:00
if creds . VaultToken != "" {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " with Token authentication" )
2024-10-22 13:29:34 +05:00
client , err = vault . NewClientWithToken ( clientConfig , creds . VaultToken )
2021-02-15 09:48:51 +01:00
} else {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " with AppRole authentication" )
2024-10-22 13:29:34 +05:00
clientConfig . RoleID = creds . AppRoleID
clientConfig . SecretID = creds . AppRoleSecretID
client , err = vault . NewClient ( clientConfig )
2021-02-15 09:48:51 +01:00
}
2020-07-22 11:15:48 +02:00
if err != nil {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Info ( " failed" )
2020-07-22 11:15:48 +02:00
return nil , err
}
2024-10-11 14:55:39 +05:00
// Set global vault client for usage in steps
2024-10-22 13:29:34 +05:00
globalVaultClient = client
2024-10-11 14:55:39 +05:00
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Info ( " succeeded" )
2021-02-15 09:48:51 +01:00
return client , nil
2020-07-22 11:15:48 +02:00
}
2024-05-07 14:19:39 +02:00
func resolveAllVaultReferences ( config * StepConfig , client VaultClient , params [ ] StepParameters ) {
2020-07-22 11:15:48 +02:00
for _ , param := range params {
2020-10-26 14:20:04 +01:00
if ref := param . GetReference ( "vaultSecret" ) ; ref != nil {
resolveVaultReference ( ref , config , client , param )
}
if ref := param . GetReference ( "vaultSecretFile" ) ; ref != nil {
resolveVaultReference ( ref , config , client , param )
}
}
}
2024-05-07 14:19:39 +02:00
func resolveVaultReference ( ref * ResourceReference , config * StepConfig , client VaultClient , param StepParameters ) {
2021-02-15 09:48:51 +01:00
vaultDisableOverwrite , _ := config . Config [ "vaultDisableOverwrite" ] . ( bool )
2024-07-23 15:43:24 +05:00
if paramValue , _ := config . Config [ param . Name ] . ( string ) ; vaultDisableOverwrite && paramValue != "" {
2021-12-21 11:52:10 +01:00
log . Entry ( ) . Debugf ( "Not fetching '%s' from Vault since it has already been set" , param . Name )
2021-02-15 09:48:51 +01:00
return
}
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Infof ( "Resolving '%s'" , param . Name )
2020-10-26 14:20:04 +01:00
var secretValue * string
2021-09-21 14:06:32 +03:00
for _ , vaultPath := range getSecretReferencePaths ( ref , config . Config ) {
2020-10-26 14:20:04 +01:00
// it should be possible to configure the root path were the secret is stored
vaultPath , ok := interpolation . ResolveString ( vaultPath , config . Config )
if ! ok {
2020-07-22 11:15:48 +02:00
continue
}
2020-10-26 14:20:04 +01:00
secretValue = lookupPath ( client , vaultPath , & param )
if secretValue != nil {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Infof ( " succeeded with Vault path '%s'" , vaultPath )
2020-10-26 14:20:04 +01:00
if ref . Type == "vaultSecret" {
2020-10-13 14:14:47 +02:00
config . Config [ param . Name ] = * secretValue
2020-10-26 14:20:04 +01:00
} else if ref . Type == "vaultSecretFile" {
filePath , err := createTemporarySecretFile ( param . Name , * secretValue )
if err != nil {
log . Entry ( ) . WithError ( err ) . Warnf ( "Couldn't create temporary secret file for '%s'" , param . Name )
return
}
config . Config [ param . Name ] = filePath
2020-07-22 11:15:48 +02:00
}
2020-10-26 14:20:04 +01:00
break
2020-07-22 11:15:48 +02:00
}
2020-10-26 14:20:04 +01:00
}
if secretValue == nil {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Warn ( " failed" )
2020-10-26 14:20:04 +01:00
}
}
2024-05-07 14:19:39 +02:00
func resolveVaultTestCredentialsWrapper ( config * StepConfig , client VaultClient ) {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Infof ( "Resolving test credentials wrapper" )
2024-01-09 00:07:53 -08:00
resolveVaultCredentialsWrapperBase ( config , client , vaultTestCredentialPath , vaultTestCredentialKeys , vaultTestCredentialEnvPrefix , resolveVaultTestCredentials )
2023-05-22 13:49:28 +05:00
}
2024-05-07 14:19:39 +02:00
func resolveVaultCredentialsWrapper ( config * StepConfig , client VaultClient ) {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Infof ( "Resolving credentials wrapper" )
2024-01-09 00:07:53 -08:00
resolveVaultCredentialsWrapperBase ( config , client , vaultCredentialPath , vaultCredentialKeys , vaultCredentialEnvPrefix , resolveVaultCredentials )
2023-05-22 13:49:28 +05:00
}
2024-01-09 00:07:53 -08:00
func resolveVaultCredentialsWrapperBase (
2024-05-07 14:19:39 +02:00
config * StepConfig , client VaultClient ,
2024-01-09 00:07:53 -08:00
vaultCredPath , vaultCredKeys , vaultCredEnvPrefix string ,
2024-05-07 14:19:39 +02:00
resolveVaultCredentials func ( config * StepConfig , client VaultClient ) ,
2023-05-22 13:49:28 +05:00
) {
switch config . Config [ vaultCredPath ] . ( type ) {
case string :
resolveVaultCredentials ( config , client )
case [ ] interface { } :
2024-01-09 00:07:53 -08:00
vaultCredentialPathCopy := config . Config [ vaultCredPath ] . ( [ ] interface { } )
vaultCredentialKeysCopy , keysOk := config . Config [ vaultCredKeys ] . ( [ ] interface { } )
vaultCredentialEnvPrefixCopy , prefixOk := config . Config [ vaultCredEnvPrefix ] . ( [ ] interface { } )
2023-05-22 13:49:28 +05:00
2024-01-09 00:07:53 -08:00
if ! keysOk {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " failed, unknown type of keys" )
2023-05-22 13:49:28 +05:00
return
}
2024-01-09 00:07:53 -08:00
if len ( vaultCredentialKeysCopy ) != len ( vaultCredentialPathCopy ) {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " failed, not same count of values and keys" )
2023-05-22 13:49:28 +05:00
return
}
2024-01-09 00:07:53 -08:00
if prefixOk && len ( vaultCredentialEnvPrefixCopy ) != len ( vaultCredentialPathCopy ) {
log . Entry ( ) . Debugf ( " failed, not same count of values and environment prefixes" )
return
}
for i := 0 ; i < len ( vaultCredentialPathCopy ) ; i ++ {
if prefixOk {
config . Config [ vaultCredEnvPrefix ] = vaultCredentialEnvPrefixCopy [ i ]
}
config . Config [ vaultCredPath ] = vaultCredentialPathCopy [ i ]
config . Config [ vaultCredKeys ] = vaultCredentialKeysCopy [ i ]
2023-05-22 13:49:28 +05:00
resolveVaultCredentials ( config , client )
}
config . Config [ vaultCredPath ] = vaultCredentialPathCopy
config . Config [ vaultCredKeys ] = vaultCredentialKeysCopy
2024-01-09 00:07:53 -08:00
config . Config [ vaultCredEnvPrefix ] = vaultCredentialEnvPrefixCopy
2023-05-22 13:49:28 +05:00
default :
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " failed, unknown type of path" )
2023-05-22 13:49:28 +05:00
return
}
}
2021-04-09 10:04:35 +02:00
// resolve test credential keys and expose as environment variables
2024-05-07 14:19:39 +02:00
func resolveVaultTestCredentials ( config * StepConfig , client VaultClient ) {
2021-04-09 10:04:35 +02:00
credPath , pathOk := config . Config [ vaultTestCredentialPath ] . ( string )
keys := getTestCredentialKeys ( config )
if ! ( pathOk && keys != nil ) || credPath == "" || len ( keys ) == 0 {
2021-12-21 11:52:10 +01:00
log . Entry ( ) . Debugf ( "Not fetching test credentials from Vault since they are not (properly) configured" )
2021-04-09 10:04:35 +02:00
return
}
lookupPath := make ( [ ] string , 3 )
lookupPath [ 0 ] = "$(vaultPath)/" + credPath
lookupPath [ 1 ] = "$(vaultBasePath)/$(vaultPipelineName)/" + credPath
lookupPath [ 2 ] = "$(vaultBasePath)/GROUP-SECRETS/" + credPath
for _ , path := range lookupPath {
vaultPath , ok := interpolation . ResolveString ( path , config . Config )
if ! ok {
continue
}
secret , err := client . GetKvSecret ( vaultPath )
if err != nil {
log . Entry ( ) . WithError ( err ) . Debugf ( "Couldn't fetch secret at '%s'" , vaultPath )
continue
}
if secret == nil {
continue
}
secretsResolved := false
2021-08-11 16:20:08 +02:00
secretsResolved = populateTestCredentialsAsEnvs ( config , secret , keys )
2021-04-09 10:04:35 +02:00
if secretsResolved {
// prevent overwriting resolved secrets
// only allows vault test credentials on one / the same vault path
break
}
}
}
2024-05-07 14:19:39 +02:00
func resolveVaultCredentials ( config * StepConfig , client VaultClient ) {
2021-12-21 11:00:13 +01:00
credPath , pathOk := config . Config [ vaultCredentialPath ] . ( string )
keys := getCredentialKeys ( config )
if ! ( pathOk && keys != nil ) || credPath == "" || len ( keys ) == 0 {
2022-01-19 08:41:11 +01:00
log . Entry ( ) . Debugf ( "Not fetching credentials from vault since they are not (properly) configured" )
2021-12-21 11:00:13 +01:00
return
}
lookupPath := make ( [ ] string , 3 )
lookupPath [ 0 ] = "$(vaultPath)/" + credPath
lookupPath [ 1 ] = "$(vaultBasePath)/$(vaultPipelineName)/" + credPath
lookupPath [ 2 ] = "$(vaultBasePath)/GROUP-SECRETS/" + credPath
for _ , path := range lookupPath {
vaultPath , ok := interpolation . ResolveString ( path , config . Config )
if ! ok {
continue
}
secret , err := client . GetKvSecret ( vaultPath )
if err != nil {
log . Entry ( ) . WithError ( err ) . Debugf ( "Couldn't fetch secret at '%s'" , vaultPath )
continue
}
if secret == nil {
continue
}
secretsResolved := false
secretsResolved = populateCredentialsAsEnvs ( config , secret , keys )
if secretsResolved {
// prevent overwriting resolved secrets
// only allows vault test credentials on one / the same vault path
break
}
}
}
2021-08-11 16:20:08 +02:00
func populateTestCredentialsAsEnvs ( config * StepConfig , secret map [ string ] string , keys [ ] string ) ( matched bool ) {
vaultTestCredentialEnvPrefix , ok := config . Config [ "vaultTestCredentialEnvPrefix" ] . ( string )
if ! ok || len ( vaultTestCredentialEnvPrefix ) == 0 {
2021-09-21 14:06:32 +03:00
vaultTestCredentialEnvPrefix = vaultTestCredentialEnvPrefixDefault
2021-08-11 16:20:08 +02:00
}
2021-04-09 10:04:35 +02:00
for secretKey , secretValue := range secret {
for _ , key := range keys {
if secretKey == key {
log . RegisterSecret ( secretValue )
2023-03-31 09:36:59 +02:00
envVariable := vaultTestCredentialEnvPrefix + ConvertEnvVar ( secretKey )
2021-04-09 10:04:35 +02:00
log . Entry ( ) . Debugf ( "Exposing test credential '%v' as '%v'" , key , envVariable )
os . Setenv ( envVariable , secretValue )
matched = true
}
}
}
return
}
2021-12-21 11:00:13 +01:00
func populateCredentialsAsEnvs ( config * StepConfig , secret map [ string ] string , keys [ ] string ) ( matched bool ) {
vaultCredentialEnvPrefix , ok := config . Config [ "vaultCredentialEnvPrefix" ] . ( string )
isCredentialEnvPrefixDefault := false
2022-06-27 09:24:52 +02:00
if ! ok {
2023-03-31 09:36:59 +02:00
vaultCredentialEnvPrefix = VaultCredentialEnvPrefixDefault
2021-12-21 11:00:13 +01:00
isCredentialEnvPrefixDefault = true
}
for secretKey , secretValue := range secret {
for _ , key := range keys {
if secretKey == key {
log . RegisterSecret ( secretValue )
2023-03-31 09:36:59 +02:00
envVariable := vaultCredentialEnvPrefix + ConvertEnvVar ( secretKey )
2021-12-21 11:00:13 +01:00
log . Entry ( ) . Debugf ( "Exposing general purpose credential '%v' as '%v'" , key , envVariable )
os . Setenv ( envVariable , secretValue )
2022-08-16 17:52:20 +02:00
log . RegisterSecret ( piperutils . EncodeString ( secretValue ) )
2023-03-31 09:36:59 +02:00
envVariable = vaultCredentialEnvPrefix + ConvertEnvVar ( secretKey ) + "_BASE64"
2022-01-13 13:08:19 +01:00
log . Entry ( ) . Debugf ( "Exposing general purpose base64 encoded credential '%v' as '%v'" , key , envVariable )
2022-08-04 09:20:59 +02:00
os . Setenv ( envVariable , piperutils . EncodeString ( secretValue ) )
2021-12-21 11:00:13 +01:00
matched = true
}
}
}
// we always create a standard env variable with the default prefx so that
// we can always refer to it in steps if its to be hard-coded
if ! isCredentialEnvPrefixDefault {
for secretKey , secretValue := range secret {
for _ , key := range keys {
if secretKey == key {
log . RegisterSecret ( secretValue )
2023-03-31 09:36:59 +02:00
envVariable := VaultCredentialEnvPrefixDefault + ConvertEnvVar ( secretKey )
2021-12-21 11:00:13 +01:00
log . Entry ( ) . Debugf ( "Exposing general purpose credential '%v' as '%v'" , key , envVariable )
os . Setenv ( envVariable , secretValue )
2022-08-16 17:52:20 +02:00
log . RegisterSecret ( piperutils . EncodeString ( secretValue ) )
2023-03-31 09:36:59 +02:00
envVariable = VaultCredentialEnvPrefixDefault + ConvertEnvVar ( secretKey ) + "_BASE64"
2022-01-13 13:08:19 +01:00
log . Entry ( ) . Debugf ( "Exposing general purpose base64 encoded credential '%v' as '%v'" , key , envVariable )
2022-08-04 09:20:59 +02:00
os . Setenv ( envVariable , piperutils . EncodeString ( secretValue ) )
2021-12-21 11:00:13 +01:00
matched = true
}
}
}
}
return
}
2021-04-09 10:04:35 +02:00
func getTestCredentialKeys ( config * StepConfig ) [ ] string {
keysRaw , ok := config . Config [ vaultTestCredentialKeys ] . ( [ ] interface { } )
if ! ok {
return nil
}
keys := make ( [ ] string , 0 , len ( keysRaw ) )
for _ , keyRaw := range keysRaw {
key , ok := keyRaw . ( string )
if ! ok {
2021-12-21 11:52:10 +01:00
log . Entry ( ) . Warnf ( "%s needs to be an array of strings" , vaultTestCredentialKeys )
2021-04-09 10:04:35 +02:00
return nil
}
keys = append ( keys , key )
}
return keys
}
2021-12-21 11:00:13 +01:00
func getCredentialKeys ( config * StepConfig ) [ ] string {
keysRaw , ok := config . Config [ vaultCredentialKeys ] . ( [ ] interface { } )
if ! ok {
log . Entry ( ) . Debugf ( "Not fetching general purpose credentials from vault since they are not (properly) configured" )
return nil
}
keys := make ( [ ] string , 0 , len ( keysRaw ) )
for _ , keyRaw := range keysRaw {
key , ok := keyRaw . ( string )
if ! ok {
log . Entry ( ) . Warnf ( "%s is needs to be an array of strings" , vaultCredentialKeys )
return nil
}
keys = append ( keys , key )
}
return keys
}
2023-03-31 09:36:59 +02:00
// ConvertEnvVar converts to a valid environment variable string
func ConvertEnvVar ( s string ) string {
2021-04-09 10:04:35 +02:00
r := strings . ToUpper ( s )
r = strings . ReplaceAll ( r , "-" , "_" )
reg , err := regexp . Compile ( "[^a-zA-Z0-9_]*" )
if err != nil {
log . Entry ( ) . Debugf ( "could not compile regex of convertEnvVar: %v" , err )
}
replacedString := reg . ReplaceAllString ( r , "" )
return replacedString
}
2020-10-26 14:20:04 +01:00
// RemoveVaultSecretFiles removes all secret files that have been created during execution
func RemoveVaultSecretFiles ( ) {
if VaultSecretFileDirectory != "" {
os . RemoveAll ( VaultSecretFileDirectory )
}
}
func createTemporarySecretFile ( namePattern string , content string ) ( string , error ) {
if VaultSecretFileDirectory == "" {
var err error
2022-08-04 09:20:59 +02:00
fileUtils := & piperutils . Files { }
VaultSecretFileDirectory , err = fileUtils . TempDir ( "" , "vault" )
2020-10-26 14:20:04 +01:00
if err != nil {
return "" , err
2020-10-13 14:14:47 +02:00
}
}
2020-10-26 14:20:04 +01:00
2023-08-16 12:57:04 +02:00
file , err := os . CreateTemp ( VaultSecretFileDirectory , namePattern )
2020-10-26 14:20:04 +01:00
if err != nil {
return "" , err
}
defer file . Close ( )
_ , err = file . WriteString ( content )
if err != nil {
return "" , err
}
return file . Name ( ) , nil
2020-10-13 14:14:47 +02:00
}
2024-05-07 14:19:39 +02:00
func lookupPath ( client VaultClient , path string , param * StepParameters ) * string {
2023-10-11 10:14:31 +02:00
log . Entry ( ) . Debugf ( " with Vault path '%s'" , path )
2020-10-13 14:14:47 +02:00
secret , err := client . GetKvSecret ( path )
if err != nil {
log . Entry ( ) . WithError ( err ) . Warnf ( "Couldn't fetch secret at '%s'" , path )
return nil
}
if secret == nil {
return nil
}
field := secret [ param . Name ]
if field != "" {
log . RegisterSecret ( field )
return & field
}
2020-11-17 13:49:31 +01:00
log . Entry ( ) . Debugf ( "Secret did not contain a field name '%s'" , param . Name )
2020-10-13 14:14:47 +02:00
// try parameter aliases
for _ , alias := range param . Aliases {
2020-11-17 13:49:31 +01:00
log . Entry ( ) . Debugf ( "Trying alias field name '%s'" , alias . Name )
2020-11-06 17:54:01 +01:00
field := secret [ alias . Name ]
2020-10-13 14:14:47 +02:00
if field != "" {
log . RegisterSecret ( field )
if alias . Deprecated {
2021-12-21 11:52:10 +01:00
log . Entry ( ) . WithField ( "package" , "SAP/jenkins-library/pkg/config" ) . Warningf ( "DEPRECATION NOTICE: old step config key '%s' used in Vault. Please switch to '%s'!" , alias . Name , param . Name )
2020-10-13 14:14:47 +02:00
}
return & field
}
2020-07-22 11:15:48 +02:00
}
return nil
}
2021-09-21 14:06:32 +03:00
func getSecretReferencePaths ( reference * ResourceReference , config map [ string ] interface { } ) [ ] string {
retPaths := make ( [ ] string , 0 , len ( VaultRootPaths ) )
secretName := reference . Default
if providedName , ok := config [ reference . Name ] . ( string ) ; ok && providedName != "" {
secretName = providedName
}
for _ , rootPath := range VaultRootPaths {
fullPath := path . Join ( rootPath , secretName )
retPaths = append ( retPaths , fullPath )
}
return retPaths
}
func toStringSlice ( interfaceSlice [ ] interface { } ) [ ] string {
retSlice := make ( [ ] string , 0 , len ( interfaceSlice ) )
for _ , vRaw := range interfaceSlice {
if v , ok := vRaw . ( string ) ; ok {
retSlice = append ( retSlice , v )
continue
}
log . Entry ( ) . Warnf ( "'%s' needs to be of type string or an array of strings but got %T (%[2]v)" , vaultPath , vRaw )
}
return retSlice
}