1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-09-16 09:26:22 +02:00

feat(Vault): custom prefix for test credentials (#3043)

Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
Oliver Nocon
2021-08-11 16:20:08 +02:00
committed by GitHub
parent c66c868d7c
commit 97b84429f1
3 changed files with 73 additions and 27 deletions

View File

@@ -117,4 +117,10 @@ The `vaultTestCredentialPath` parameter is the endpoint of your credential path
The `vaultTestCredentialKeys`parameter is a list of credential IDs. The secret value of the credential will be exposed as an environment variable prefixed by "PIPER_TESTCREDENTIAL_" and transformed to a valid variable name. For a credential ID named `myAppId` the forwarded environment variable to the step will be `PIPER_TESTCREDENTIAL_MYAPPID` containing the secret. Hyphens will be replaced by underscores and other non-alphanumeric characters will be removed. The `vaultTestCredentialKeys`parameter is a list of credential IDs. The secret value of the credential will be exposed as an environment variable prefixed by "PIPER_TESTCREDENTIAL_" and transformed to a valid variable name. For a credential ID named `myAppId` the forwarded environment variable to the step will be `PIPER_TESTCREDENTIAL_MYAPPID` containing the secret. 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_TESTCREDENTIAL_`.
It is possible to use a custom prefix by setting for example `vaultTestCredentialEnvPrefix: 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`.
Extended logging for vault secret fetching (e.g. found credentials and environment variable names) can be activated via `verbose: true` configuration. Extended logging for vault secret fetching (e.g. found credentials and environment variable names) can be activated via `verbose: true` configuration.

View File

@@ -13,9 +13,9 @@ import (
) )
const ( const (
vaultTestCredentialPath = "vaultTestCredentialPath" vaultTestCredentialPath = "vaultTestCredentialPath"
vaultTestCredentialKeys = "vaultTestCredentialKeys" vaultTestCredentialKeys = "vaultTestCredentialKeys"
vaultTestCredentialEnvPrefix = "PIPER_TESTCREDENTIAL_" vaultTestCredentialEnvPrefix_Default = "PIPER_TESTCREDENTIAL_"
) )
var ( var (
@@ -27,6 +27,7 @@ var (
"vaultBasePath", "vaultBasePath",
"vaultPipelineName", "vaultPipelineName",
"vaultPath", "vaultPath",
"vaultTestCredentialEnvPrefix",
"skipVault", "skipVault",
"vaultDisableOverwrite", "vaultDisableOverwrite",
vaultTestCredentialPath, vaultTestCredentialPath,
@@ -165,7 +166,7 @@ func resolveVaultTestCredentials(config *StepConfig, client vaultClient) {
continue continue
} }
secretsResolved := false secretsResolved := false
secretsResolved = populateTestCredentialsAsEnvs(secret, keys) secretsResolved = populateTestCredentialsAsEnvs(config, secret, keys)
if secretsResolved { if secretsResolved {
// prevent overwriting resolved secrets // prevent overwriting resolved secrets
// only allows vault test credentials on one / the same vault path // only allows vault test credentials on one / the same vault path
@@ -174,7 +175,12 @@ func resolveVaultTestCredentials(config *StepConfig, client vaultClient) {
} }
} }
func populateTestCredentialsAsEnvs(secret map[string]string, keys []string) (matched bool) { func populateTestCredentialsAsEnvs(config *StepConfig, secret map[string]string, keys []string) (matched bool) {
vaultTestCredentialEnvPrefix, ok := config.Config["vaultTestCredentialEnvPrefix"].(string)
if !ok || len(vaultTestCredentialEnvPrefix) == 0 {
vaultTestCredentialEnvPrefix = vaultTestCredentialEnvPrefix_Default
}
for secretKey, secretValue := range secret { for secretKey, secretValue := range secret {
for _, key := range keys { for _, key := range keys {
if secretKey == key { if secretKey == key {

View File

@@ -219,32 +219,66 @@ func addAlias(param *StepParameters, aliasName string) {
param.Aliases = append(param.Aliases, alias) param.Aliases = append(param.Aliases, alias)
} }
func Test_resolveVaultTestCredentials(t *testing.T) { func TestResolveVaultTestCredentials(t *testing.T) {
// init t.Parallel()
vaultMock := &mocks.VaultMock{} t.Run("Default credential prefix", func(t *testing.T) {
envPrefix := "PIPER_TESTCREDENTIAL_" t.Parallel()
stepConfig := StepConfig{Config: map[string]interface{}{ // init
"vaultPath": "team1", vaultMock := &mocks.VaultMock{}
"vaultTestCredentialPath": "appCredentials", envPrefix := "PIPER_TESTCREDENTIAL_"
"vaultTestCredentialKeys": []interface{}{"appUser", "appUserPw"}, stepConfig := StepConfig{Config: map[string]interface{}{
}} "vaultPath": "team1",
"vaultTestCredentialPath": "appCredentials",
"vaultTestCredentialKeys": []interface{}{"appUser", "appUserPw"},
}}
defer os.Unsetenv("PIPER_TESTCREDENTIAL_APPUSER") defer os.Unsetenv("PIPER_TESTCREDENTIAL_APPUSER")
defer os.Unsetenv("PIPER_TESTCREDENTIAL_APPUSERPW") defer os.Unsetenv("PIPER_TESTCREDENTIAL_APPUSERPW")
// mock // mock
vaultData := map[string]string{"appUser": "test-user", "appUserPw": "password1234"} vaultData := map[string]string{"appUser": "test-user", "appUserPw": "password1234"}
vaultMock.On("GetKvSecret", "team1/appCredentials").Return(vaultData, nil) vaultMock.On("GetKvSecret", "team1/appCredentials").Return(vaultData, nil)
// test // test
resolveVaultTestCredentials(&stepConfig, vaultMock) resolveVaultTestCredentials(&stepConfig, vaultMock)
// assert // assert
for k, v := range vaultData { for k, v := range vaultData {
env := envPrefix + strings.ToUpper(k) env := envPrefix + strings.ToUpper(k)
assert.NotEmpty(t, os.Getenv(env)) assert.NotEmpty(t, os.Getenv(env))
assert.Equal(t, os.Getenv(env), v) assert.Equal(t, os.Getenv(env), v)
} }
})
t.Run("Custom credential prefix", func(t *testing.T) {
t.Parallel()
// init
vaultMock := &mocks.VaultMock{}
envPrefix := "CUSTOM_CREDENTIAL_"
stepConfig := StepConfig{Config: map[string]interface{}{
"vaultPath": "team1",
"vaultTestCredentialPath": "appCredentials",
"vaultTestCredentialKeys": []interface{}{"appUser", "appUserPw"},
"vaultTestCredentialEnvPrefix": envPrefix,
}}
defer os.Unsetenv("CUSTOM_CREDENTIAL_APPUSER")
defer os.Unsetenv("CUSTOM_CREDENTIAL_APPUSERPW")
// mock
vaultData := map[string]string{"appUser": "test-user", "appUserPw": "password1234"}
vaultMock.On("GetKvSecret", "team1/appCredentials").Return(vaultData, nil)
// test
resolveVaultTestCredentials(&stepConfig, vaultMock)
// assert
for k, v := range vaultData {
env := envPrefix + strings.ToUpper(k)
assert.NotEmpty(t, os.Getenv(env))
assert.Equal(t, os.Getenv(env), v)
}
})
} }
func Test_convertEnvVar(t *testing.T) { func Test_convertEnvVar(t *testing.T) {