mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
feat(configs): vaultCredentialEnvPrefix to support several prefixes (#4745)
* feat(configs): vaultCredentialEnvPrefix to support several prefixes * minor refactoring * docs --------- Co-authored-by: Muhammadali Nazarov <muhammadalinazarov@gmail.com>
This commit is contained in:
parent
32657c44d7
commit
a5ea24dfb0
@ -129,12 +129,16 @@ The `vaultCredentialPath` parameter is the endpoint of your credential path in V
|
||||
|
||||
The `vaultCredentialKeys`parameter is a list of credential IDs. The secret value of the credential will be exposed as an environment variable prefixed by "PIPER_VAULTCREDENTIAL_" and transformed to a valid variable name. For a credential ID named `myAppId` the forwarded environment variable to the step will be `PIPER_VAULTCREDENTIAL_MYAPPID` containing the secret. The Base64 encoded secret value will be exposed as environment variable to the step as `PIPER_VAULTCREDENTIAL_MYAPPID_BASE64`. Hyphens will be replaced by underscores and other non-alphanumeric characters will be removed.
|
||||
|
||||
!!! hint "Using a custom prefix for test credentials"
|
||||
By default the prefix for test credentials is `PIPER_VAULTCREDENTIAL_`.
|
||||
!!! hint "Using a custom prefix for credentials"
|
||||
By default the prefix for credentials is `PIPER_VAULTCREDENTIAL_`.
|
||||
|
||||
It is possible to use a custom prefix by setting for example `vaultCredentialEnvPrefix: MY_CUSTOM_PREFIX` in your configuration.
|
||||
With this above credential ID named `myAppId` will be populated into an environment variable with the name `MY_CUSTOM_PREFIX_MYAPPID`.
|
||||
|
||||
In case you want to use specific prefix for secrets retrieved from different vault folders, pass multiple prefixes as
|
||||
`vaultCredentialEnvPrefix: ['MY_CUSTOM_PREFIX_1', 'MY_CUSTOM_PREFIX_2']`.
|
||||
With this above credential ID named `myAppId1` will be populated into an environment variable with the name `MY_CUSTOM_PREFIX_1_MYAPPID1` and `myAppId2` will be populated into an environment variable with name `MY_CUSTOM_PREFIX_2_MYAPPID2`
|
||||
|
||||
Extended logging for Vault secret fetching (e.g. found credentials and environment variable names) can be activated via `verbose: true` configuration.
|
||||
|
||||
## Using Vault for test credentials (Deprecated : use general purpose and test credentials as above)
|
||||
|
@ -175,44 +175,54 @@ func resolveVaultReference(ref *ResourceReference, config *StepConfig, client va
|
||||
|
||||
func resolveVaultTestCredentialsWrapper(config *StepConfig, client vaultClient) {
|
||||
log.Entry().Infof("Resolving test credentials wrapper")
|
||||
resolveVaultTestCredentialsWrapperBase(config, client, vaultTestCredentialPath, vaultTestCredentialKeys, resolveVaultTestCredentials)
|
||||
resolveVaultCredentialsWrapperBase(config, client, vaultTestCredentialPath, vaultTestCredentialKeys, vaultTestCredentialEnvPrefix, resolveVaultTestCredentials)
|
||||
}
|
||||
|
||||
func resolveVaultCredentialsWrapper(config *StepConfig, client vaultClient) {
|
||||
log.Entry().Infof("Resolving credentials wrapper")
|
||||
resolveVaultTestCredentialsWrapperBase(config, client, vaultCredentialPath, vaultCredentialKeys, resolveVaultCredentials)
|
||||
resolveVaultCredentialsWrapperBase(config, client, vaultCredentialPath, vaultCredentialKeys, vaultCredentialEnvPrefix, resolveVaultCredentials)
|
||||
}
|
||||
|
||||
func resolveVaultTestCredentialsWrapperBase(
|
||||
func resolveVaultCredentialsWrapperBase(
|
||||
config *StepConfig, client vaultClient,
|
||||
vaultCredPath, vaultCredKeys string,
|
||||
vaultCredPath, vaultCredKeys, vaultCredEnvPrefix string,
|
||||
resolveVaultCredentials func(config *StepConfig, client vaultClient),
|
||||
) {
|
||||
switch config.Config[vaultCredPath].(type) {
|
||||
case string:
|
||||
resolveVaultCredentials(config, client)
|
||||
case []interface{}:
|
||||
vaultCredentialPathCopy := config.Config[vaultCredPath]
|
||||
vaultCredentialKeysCopy := config.Config[vaultCredKeys]
|
||||
vaultCredentialPathCopy := config.Config[vaultCredPath].([]interface{})
|
||||
vaultCredentialKeysCopy, keysOk := config.Config[vaultCredKeys].([]interface{})
|
||||
vaultCredentialEnvPrefixCopy, prefixOk := config.Config[vaultCredEnvPrefix].([]interface{})
|
||||
|
||||
if _, ok := vaultCredentialKeysCopy.([]interface{}); !ok {
|
||||
if !keysOk {
|
||||
log.Entry().Debugf(" failed, unknown type of keys")
|
||||
return
|
||||
}
|
||||
|
||||
if len(vaultCredentialKeysCopy.([]interface{})) != len(vaultCredentialPathCopy.([]interface{})) {
|
||||
if len(vaultCredentialKeysCopy) != len(vaultCredentialPathCopy) {
|
||||
log.Entry().Debugf(" failed, not same count of values and keys")
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < len(vaultCredentialPathCopy.([]interface{})); i++ {
|
||||
config.Config[vaultCredPath] = vaultCredentialPathCopy.([]interface{})[i]
|
||||
config.Config[vaultCredKeys] = vaultCredentialKeysCopy.([]interface{})[i]
|
||||
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]
|
||||
resolveVaultCredentials(config, client)
|
||||
}
|
||||
|
||||
config.Config[vaultCredPath] = vaultCredentialPathCopy
|
||||
config.Config[vaultCredKeys] = vaultCredentialKeysCopy
|
||||
config.Config[vaultCredEnvPrefix] = vaultCredentialEnvPrefixCopy
|
||||
default:
|
||||
log.Entry().Debugf(" failed, unknown type of path")
|
||||
return
|
||||
|
@ -269,6 +269,88 @@ func TestResolveVaultTestCredentialsWrapper(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Multiple test credential prefixes", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// init
|
||||
vaultMock := &mocks.VaultMock{}
|
||||
envPrefixes := []interface{}{"TEST1_", "TEST2_"}
|
||||
stepConfig := StepConfig{Config: map[string]interface{}{
|
||||
"vaultPath": "team1",
|
||||
"vaultTestCredentialPath": []interface{}{"appCredentials1", "appCredentials2"},
|
||||
"vaultTestCredentialKeys": []interface{}{[]interface{}{"appUser", "appUserPw"}, []interface{}{"appUser", "appUserPw"}},
|
||||
"vaultTestCredentialEnvPrefix": envPrefixes,
|
||||
}}
|
||||
|
||||
defer os.Unsetenv("TEST1_APPUSER")
|
||||
defer os.Unsetenv("TEST1_APPUSERPW")
|
||||
defer os.Unsetenv("TEST2_APPUSER")
|
||||
defer os.Unsetenv("TEST2_APPUSERPW")
|
||||
|
||||
// mock
|
||||
vaultData1 := map[string]string{"appUser": "test-user1", "appUserPw": "password1"}
|
||||
vaultMock.On("GetKvSecret", "team1/appCredentials1").Return(vaultData1, nil)
|
||||
vaultData2 := map[string]string{"appUser": "test-user2", "appUserPw": "password2"}
|
||||
vaultMock.On("GetKvSecret", "team1/appCredentials2").Return(vaultData2, nil)
|
||||
|
||||
// test
|
||||
resolveVaultTestCredentialsWrapper(&stepConfig, vaultMock)
|
||||
|
||||
// assert
|
||||
for k, expectedValue := range vaultData1 {
|
||||
env := envPrefixes[0].(string) + strings.ToUpper(k)
|
||||
assert.NotEmpty(t, os.Getenv(env))
|
||||
assert.Equal(t, expectedValue, os.Getenv(env))
|
||||
}
|
||||
|
||||
// assert
|
||||
for k, expectedValue := range vaultData2 {
|
||||
env := envPrefixes[1].(string) + strings.ToUpper(k)
|
||||
assert.NotEmpty(t, os.Getenv(env))
|
||||
assert.Equal(t, expectedValue, os.Getenv(env))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Multiple custom general purpuse credential environment prefixes", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// init
|
||||
vaultMock := &mocks.VaultMock{}
|
||||
envPrefixes := []interface{}{"CUSTOM1_", "CUSTOM2_"}
|
||||
stepConfig := StepConfig{Config: map[string]interface{}{
|
||||
"vaultPath": "team1",
|
||||
"vaultCredentialPath": []interface{}{"appCredentials1", "appCredentials2"},
|
||||
"vaultCredentialKeys": []interface{}{[]interface{}{"appUser", "appUserPw"}, []interface{}{"appUser", "appUserPw"}},
|
||||
"vaultCredentialEnvPrefix": envPrefixes,
|
||||
}}
|
||||
|
||||
defer os.Unsetenv("CUSTOM1_APPUSER")
|
||||
defer os.Unsetenv("CUSTOM1_APPUSERPW")
|
||||
defer os.Unsetenv("CUSTOM2_APPUSER")
|
||||
defer os.Unsetenv("CUSTOM2_APPUSERPW")
|
||||
|
||||
// mock
|
||||
vaultData1 := map[string]string{"appUser": "test-user1", "appUserPw": "password1"}
|
||||
vaultMock.On("GetKvSecret", "team1/appCredentials1").Return(vaultData1, nil)
|
||||
vaultData2 := map[string]string{"appUser": "test-user2", "appUserPw": "password2"}
|
||||
vaultMock.On("GetKvSecret", "team1/appCredentials2").Return(vaultData2, nil)
|
||||
|
||||
// test
|
||||
resolveVaultCredentialsWrapper(&stepConfig, vaultMock)
|
||||
|
||||
// assert
|
||||
for k, expectedValue := range vaultData1 {
|
||||
env := envPrefixes[0].(string) + strings.ToUpper(k)
|
||||
assert.NotEmpty(t, os.Getenv(env))
|
||||
assert.Equal(t, expectedValue, os.Getenv(env))
|
||||
}
|
||||
|
||||
// assert
|
||||
for k, expectedValue := range vaultData2 {
|
||||
env := envPrefixes[1].(string) + strings.ToUpper(k)
|
||||
assert.NotEmpty(t, os.Getenv(env))
|
||||
assert.Equal(t, expectedValue, os.Getenv(env))
|
||||
}
|
||||
})
|
||||
|
||||
// Test empty and non-empty custom general purpose credential prefix
|
||||
envPrefixes := []string{"CUSTOM_MYCRED1_", ""}
|
||||
for idx, envPrefix := range envPrefixes {
|
||||
|
Loading…
Reference in New Issue
Block a user