You've already forked sap-jenkins-library
mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-09-16 09:26:22 +02:00
(Vault) Improvements (#2439)
* vault improvements * Update cloudFoundryDeploy.yaml remove double PARAMETERS * go generate * fix type & resturcutre paragraph to a list * remove non-existent secrets * build trigger Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
This commit is contained in:
12
cmd/piper.go
12
cmd/piper.go
@@ -34,6 +34,10 @@ type GeneralConfigOptions struct {
|
||||
LogFormat string
|
||||
VaultRoleID string
|
||||
VaultRoleSecretID string
|
||||
VaultToken string
|
||||
VaultServerURL string
|
||||
VaultNamespace string
|
||||
VaultPath string
|
||||
HookConfig HookConfiguration
|
||||
}
|
||||
|
||||
@@ -149,6 +153,9 @@ func addRootFlags(rootCmd *cobra.Command) {
|
||||
rootCmd.PersistentFlags().BoolVar(&GeneralConfig.NoTelemetry, "noTelemetry", false, "Disables telemetry reporting")
|
||||
rootCmd.PersistentFlags().BoolVarP(&GeneralConfig.Verbose, "verbose", "v", false, "verbose output")
|
||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.LogFormat, "logFormat", "default", "Log format to use. Options: default, timestamp, plain, full.")
|
||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.VaultServerURL, "vaultServerUrl", "", "The vault server which should be used to fetch credentials")
|
||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.VaultNamespace, "vaultNamespace", "", "The vault namespace which should be used to fetch credentials")
|
||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.VaultPath, "vaultPath", "", "The path which should be used to fetch credentials")
|
||||
|
||||
}
|
||||
|
||||
@@ -226,7 +233,10 @@ func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName strin
|
||||
if GeneralConfig.VaultRoleSecretID == "" {
|
||||
GeneralConfig.VaultRoleSecretID = os.Getenv("PIPER_vaultAppRoleSecretID")
|
||||
}
|
||||
myConfig.SetVaultCredentials(GeneralConfig.VaultRoleID, GeneralConfig.VaultRoleSecretID)
|
||||
if GeneralConfig.VaultToken == "" {
|
||||
GeneralConfig.VaultToken = os.Getenv("PIPER_vaultToken")
|
||||
}
|
||||
myConfig.SetVaultCredentials(GeneralConfig.VaultRoleID, GeneralConfig.VaultRoleSecretID, GeneralConfig.VaultToken)
|
||||
|
||||
if len(GeneralConfig.StepConfigJSON) != 0 {
|
||||
// ignore config & defaults in favor of passed stepConfigJSON
|
||||
|
BIN
documentation/docs/images/jenkins-vault-token-credential.png
Normal file
BIN
documentation/docs/images/jenkins-vault-token-credential.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 210 KiB |
BIN
documentation/docs/images/vault-secret-engine-enable.png
Normal file
BIN
documentation/docs/images/vault-secret-engine-enable.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 204 KiB |
@@ -1,25 +1,50 @@
|
||||
# Vault for Pipeline Secrets
|
||||
|
||||
Project "Piper" also supports fetching your pipeline secrets directly from [Vault](https://www.hashicorp.com/products/vault).
|
||||
Currently Vault's key value engine is supported in version 1 and 2, although we recommend version 2 since it supports versioning of secrets
|
||||
Project "Piper" supports fetching your pipeline secrets directly from [Vault](https://www.hashicorp.com/products/vault).
|
||||
Currently, Vault's key value engine is supported in version 1 and 2, although we recommend version 2 since it supports
|
||||
the versioning of secrets
|
||||
|
||||
Parameters that support being fetched from Vault are marked with the Vault Label in the Step Documentation.
|
||||
|
||||

|
||||
|
||||
## Vault Setup
|
||||
## Authenticating Piper to Vault
|
||||
|
||||
The first step to store your pipeline secrets in vault, is to enable a the [Key-Value Engine](https://www.vaultproject.io/docs/secrets/kv/kv-v2). And then create a policy which grants read access to the key value engine.
|
||||
For Piper to authenticate against Vault, [AppRole](https://www.vaultproject.io/docs/auth/approle) authentication must be enabled in your Vault instance.
|
||||
You have to [create an AppRole Role](https://www.vaultproject.io/api-docs/auth/approle#create-update-approle) for Piper and assign it the necessary policies.
|
||||
Piper currently supports Vault's `AppRole` and `Token` authentication. However, `AppRole` authentication is recommended
|
||||
since Piper is able to regularly rotate the SecretID, which is not possible with a Token.
|
||||
|
||||
## Store Your Vault Credentials In Jenkins
|
||||
### AppRole Authentication
|
||||
|
||||
Take the role ID from your Vault AppRole and create a Jenkins `Secret Text` credential. Do the same for the Vault AppRole secret ID.
|
||||
To authenticate against Vault, using [AppRole](https://www.vaultproject.io/docs/auth/approle) authentication you need to
|
||||
do the following things
|
||||
|
||||
- Enable AppRole authentication in your vault instance.
|
||||
- After that you have
|
||||
to [create an AppRole Role](https://www.vaultproject.io/api-docs/auth/approle#create-update-approle) for Piper
|
||||
- Assign the necessary policies to your newly created AppRole.
|
||||
- Take the **AppRole ID** and create a Jenkins `Secret Text` credential.
|
||||
- Take the **AppRole Secret ID** and create a Jenkins `Secret Text` credential.
|
||||
|
||||

|
||||
|
||||
## Pipline Configuration
|
||||
### Token Authentication
|
||||
|
||||
First step to use Token authentication is
|
||||
to [Create a vault Token](https://www.vaultproject.io/api/auth/token#create-token)
|
||||
In order to use a Vault Token for authentication you need to store the vault token inside your Jenkins instance as shown
|
||||
below.
|
||||
|
||||

|
||||
|
||||
## Setup a Secret Store in Vault
|
||||
|
||||
The first step to store your pipeline secrets in Vault, is to enable a the
|
||||
[Key-Value Engine](https://www.vaultproject.io/docs/secrets/kv/kv-v2). Then create a policy which grants read access to
|
||||
the key value engine.
|
||||
|
||||

|
||||
|
||||
## Pipeline Configuration
|
||||
|
||||
For pipelines to actually use the secrets stored in Vault you need to adjust your `config.yml`
|
||||
|
||||
@@ -33,3 +58,48 @@ general:
|
||||
vaultNamespace: '<YOUR_NAMESPACE_NAME>' # if you are not using vault's namespace feature you can remove this line
|
||||
...
|
||||
```
|
||||
|
||||
Or if you chose to use Vault's token authentication then your `config.yml` should look something like this.
|
||||
|
||||
```yaml
|
||||
general:
|
||||
...
|
||||
vaultTokenCredentialsId: '<JENKINS_CREDENTIAL_ID_FOR_YOUR_VAULT_TOKEN>'
|
||||
vaultPath: 'kv/my-pipeline' # the path under which your jenkins secrets are stored
|
||||
vaultServerUrl: '<YOUR_VAULT_SERVER_URL>'
|
||||
vaultNamespace: '<YOUR_NAMESPACE_NAME>' # if you are not using vault's namespace feature you can remove this line
|
||||
...
|
||||
```
|
||||
|
||||
## Configuring the Secret Lookup
|
||||
|
||||
When Piper is configured to lookup secrets in Vault, there are some aspects that need to be considered.
|
||||
|
||||
### Overwriting of Parameters
|
||||
|
||||
Whenever a parameter is provided via `config.yml` or passed to the CLI it gets overwritten when a secret is found in
|
||||
Vault. To disable overriding parameters put a `vaultDisableOverwrite: false` on `Step` `Stage` or `General` Section in
|
||||
your config.
|
||||
|
||||
```yaml
|
||||
general:
|
||||
...
|
||||
vaultDisableOverwrite: true
|
||||
...
|
||||
steps:
|
||||
executeBuild:
|
||||
vaultDisableOverwrite: false
|
||||
...
|
||||
```
|
||||
|
||||
### Skipping Vault Secret Lookup
|
||||
|
||||
It is also possible to skip Vault for `Steps`, `Stages` or in `General` by using the `skipVault` config parameter as
|
||||
shown below.
|
||||
|
||||
```yaml
|
||||
...
|
||||
steps:
|
||||
executeBuild:
|
||||
skipVault: true # Skip Vault Secret Lookup for this step
|
||||
```
|
||||
|
@@ -235,6 +235,8 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri
|
||||
}
|
||||
|
||||
stepConfig.mixinVaultConfig(c.General, c.Steps[stepName], c.Stages[stageName])
|
||||
// check whether vault should be skipped
|
||||
if skip, ok := stepConfig.Config["skipVault"].(bool); !ok || !skip {
|
||||
// fetch secrets from vault
|
||||
vaultClient, err := getVaultClientFromConfig(stepConfig, c.vaultCredentials)
|
||||
if err != nil {
|
||||
@@ -243,6 +245,7 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri
|
||||
if vaultClient != nil {
|
||||
resolveAllVaultReferences(&stepConfig, vaultClient, parameters)
|
||||
}
|
||||
}
|
||||
|
||||
// finally do the condition evaluation post processing
|
||||
for _, p := range parameters {
|
||||
@@ -262,11 +265,14 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri
|
||||
return stepConfig, nil
|
||||
}
|
||||
|
||||
// SetVaultCredentials sets the appRoleID and the appRoleSecretID to load additional configuration from vault
|
||||
func (c *Config) SetVaultCredentials(appRoleID, appRoleSecretID string) {
|
||||
// SetVaultCredentials sets the appRoleID and the appRoleSecretID or the vaultTokento load additional
|
||||
//configuration from vault
|
||||
// Either appRoleID and appRoleSecretID or vaultToken must be specified.
|
||||
func (c *Config) SetVaultCredentials(appRoleID, appRoleSecretID string, vaultToken string) {
|
||||
c.vaultCredentials = VaultCredentials{
|
||||
AppRoleID: appRoleID,
|
||||
AppRoleSecretID: appRoleSecretID,
|
||||
VaultToken: vaultToken,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,7 @@ func resolveString(str string, lookupMap map[string]interface{}, n int) (string,
|
||||
str = strings.ReplaceAll(str, fmt.Sprintf("$(%s)", property), propVal.(string))
|
||||
} else {
|
||||
// value not found
|
||||
log.Entry().Debugf("Can't interploate '%s'. Missing property '%s'", str, property)
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
@@ -233,7 +233,8 @@ func (m *StepData) GetContextParameterFilters() StepFilters {
|
||||
}
|
||||
|
||||
if m.HasReference("vaultSecret") {
|
||||
contextFilters = append(contextFilters, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}...)
|
||||
contextFilters = append(contextFilters, []string{"vaultAppRoleTokenCredentialsId",
|
||||
"vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}...)
|
||||
}
|
||||
|
||||
if len(contextFilters) > 0 {
|
||||
|
@@ -300,12 +300,12 @@ func TestGetContextParameterFilters(t *testing.T) {
|
||||
|
||||
t.Run("Vault", func(t *testing.T) {
|
||||
filters := metadata4.GetContextParameterFilters()
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.All, "incorrect filter All")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.General, "incorrect filter General")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.Steps, "incorrect filter Steps")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.Stages, "incorrect filter Stages")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.Parameters, "incorrect filter Parameters")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId"}, filters.Env, "incorrect filter Env")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.All, "incorrect filter All")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.General, "incorrect filter General")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.Steps, "incorrect filter Steps")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.Stages, "incorrect filter Stages")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.Parameters, "incorrect filter Parameters")
|
||||
assert.Equal(t, []string{"vaultAppRoleTokenCredentialsId", "vaultAppRoleSecretTokenCredentialsId", "vaultTokenCredentialsId"}, filters.Env, "incorrect filter Env")
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,8 @@ var (
|
||||
"vaultBasePath",
|
||||
"vaultPipelineName",
|
||||
"vaultPath",
|
||||
"skipVault",
|
||||
"vaultDisableOverwrite",
|
||||
}
|
||||
|
||||
// VaultSecretFileDirectory holds the directory for the current step run to temporarily store secret files fetched from vault
|
||||
@@ -29,6 +31,7 @@ var (
|
||||
type VaultCredentials struct {
|
||||
AppRoleID string
|
||||
AppRoleSecretID string
|
||||
VaultToken string
|
||||
}
|
||||
|
||||
// vaultClient interface for mocking
|
||||
@@ -45,7 +48,8 @@ func (s *StepConfig) mixinVaultConfig(configs ...map[string]interface{}) {
|
||||
func getVaultClientFromConfig(config StepConfig, creds VaultCredentials) (vaultClient, error) {
|
||||
address, addressOk := config.Config["vaultServerUrl"].(string)
|
||||
// if vault isn't used it's not an error
|
||||
if !addressOk || creds.AppRoleID == "" || creds.AppRoleSecretID == "" {
|
||||
|
||||
if !addressOk || creds.VaultToken == "" && (creds.AppRoleID == "" || creds.AppRoleSecretID == "") {
|
||||
log.Entry().Debug("Skipping fetching secrets from vault since it is not configured")
|
||||
return nil, nil
|
||||
}
|
||||
@@ -56,21 +60,26 @@ func getVaultClientFromConfig(config StepConfig, creds VaultCredentials) (vaultC
|
||||
log.Entry().Debugf("Using vault namespace %s", namespace)
|
||||
}
|
||||
|
||||
client, err := vault.NewClientWithAppRole(&vault.Config{Config: &api.Config{Address: address}, Namespace: namespace}, creds.AppRoleID, creds.AppRoleSecretID)
|
||||
var client vaultClient
|
||||
var err error
|
||||
clientConfig := &vault.Config{Config: &api.Config{Address: address}, Namespace: namespace}
|
||||
if creds.VaultToken != "" {
|
||||
log.Entry().Debugf("Using Vault Token Authentication")
|
||||
client, err = vault.NewClient(clientConfig, creds.VaultToken)
|
||||
} else {
|
||||
log.Entry().Debugf("Using Vaults AppRole Authentication")
|
||||
client, err = vault.NewClientWithAppRole(clientConfig, creds.AppRoleID, creds.AppRoleSecretID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Entry().Infof("Fetching secrets from vault at %s", address)
|
||||
return &client, nil
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func resolveAllVaultReferences(config *StepConfig, client vaultClient, params []StepParameters) {
|
||||
for _, param := range params {
|
||||
// we don't overwrite secrets that have already been set in any way
|
||||
if _, ok := config.Config[param.Name].(string); ok {
|
||||
continue
|
||||
}
|
||||
if ref := param.GetReference("vaultSecret"); ref != nil {
|
||||
resolveVaultReference(ref, config, client, param)
|
||||
}
|
||||
@@ -81,6 +90,12 @@ func resolveAllVaultReferences(config *StepConfig, client vaultClient, params []
|
||||
}
|
||||
|
||||
func resolveVaultReference(ref *ResourceReference, config *StepConfig, client vaultClient, param StepParameters) {
|
||||
vaultDisableOverwrite, _ := config.Config["vaultDisableOverwrite"].(bool)
|
||||
if _, ok := config.Config[param.Name].(string); vaultDisableOverwrite && ok {
|
||||
log.Entry().Debugf("Not fetching '%s' from vault since it has already been set", param.Name)
|
||||
return
|
||||
}
|
||||
|
||||
var secretValue *string
|
||||
for _, vaultPath := range ref.Paths {
|
||||
// it should be possible to configure the root path were the secret is stored
|
||||
|
@@ -32,6 +32,7 @@ func TestVaultConfigLoad(t *testing.T) {
|
||||
stepConfig := StepConfig{Config: map[string]interface{}{
|
||||
"vaultBasePath": "team1",
|
||||
secretName: "preset value",
|
||||
"vaultDisableOverwrite": true,
|
||||
}}
|
||||
stepParams := []StepParameters{stepParam(secretName, "vaultSecret", "$(vaultBasePath)/pipelineA")}
|
||||
vaultData := map[string]string{secretName: "value1"}
|
||||
@@ -41,6 +42,20 @@ func TestVaultConfigLoad(t *testing.T) {
|
||||
assert.Equal(t, "preset value", stepConfig.Config[secretName])
|
||||
})
|
||||
|
||||
t.Run("Secrets can be overwritten", func(t *testing.T) {
|
||||
vaultMock := &mocks.VaultMock{}
|
||||
stepConfig := StepConfig{Config: map[string]interface{}{
|
||||
"vaultBasePath": "team1",
|
||||
secretName: "preset value",
|
||||
}}
|
||||
stepParams := []StepParameters{stepParam(secretName, "vaultSecret", "$(vaultBasePath)/pipelineA")}
|
||||
vaultData := map[string]string{secretName: "value1"}
|
||||
vaultMock.On("GetKvSecret", "team1/pipelineA").Return(vaultData, nil)
|
||||
resolveAllVaultReferences(&stepConfig, vaultMock, stepParams)
|
||||
|
||||
assert.Equal(t, "value1", stepConfig.Config[secretName])
|
||||
})
|
||||
|
||||
t.Run("Error is passed through", func(t *testing.T) {
|
||||
vaultMock := &mocks.VaultMock{}
|
||||
stepConfig := StepConfig{Config: map[string]interface{}{
|
||||
|
@@ -46,6 +46,7 @@ func NewClient(config *Config, token string) (Client, error) {
|
||||
}
|
||||
|
||||
client.SetToken(token)
|
||||
log.Entry().Debugf("Login to vault %s in namespace %s successfull", config.Address, config.Namespace)
|
||||
return Client{client.Logical(), config}, nil
|
||||
}
|
||||
|
||||
@@ -83,7 +84,6 @@ func NewClientWithAppRole(config *Config, roleID, secretID string) (Client, erro
|
||||
return Client{}, fmt.Errorf("Could not obtain token from approle with role_id %s", roleID)
|
||||
}
|
||||
|
||||
log.Entry().Debugf("Login to vault %s in namespace %s successfull", config.Address, config.Namespace)
|
||||
return NewClient(config, authInfo.ClientToken)
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@ void call(Map parameters = [:], String stepName, String metadataFile, List crede
|
||||
prepareExecution(script, utils, parameters)
|
||||
prepareMetadataResource(script, metadataFile)
|
||||
Map stepParameters = prepareStepParameters(parameters)
|
||||
echo "Step params $stepParameters"
|
||||
|
||||
withEnv([
|
||||
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(stepParameters)}",
|
||||
@@ -155,10 +156,8 @@ void dockerWrapper(script, stepName, config, body) {
|
||||
|
||||
// reused in sonarExecuteScan
|
||||
void credentialWrapper(config, List credentialInfo, body) {
|
||||
if (config.containsKey('vaultAppRoleTokenCredentialsId') && config.containsKey('vaultAppRoleSecretTokenCredentialsId')) {
|
||||
credentialInfo = [[type: 'token', id: 'vaultAppRoleTokenCredentialsId', env: ['PIPER_vaultAppRoleID']],
|
||||
[type: 'token', id: 'vaultAppRoleSecretTokenCredentialsId', env: ['PIPER_vaultAppRoleSecretID']]]
|
||||
}
|
||||
credentialInfo = handleVaultCredentials(config, credentialInfo)
|
||||
|
||||
if (credentialInfo.size() > 0) {
|
||||
def creds = []
|
||||
def sshCreds = []
|
||||
@@ -170,7 +169,7 @@ void credentialWrapper(config, List credentialInfo, body) {
|
||||
credentialsId = config[cred.id]
|
||||
}
|
||||
if (credentialsId) {
|
||||
switch(cred.type) {
|
||||
switch (cred.type) {
|
||||
case "file":
|
||||
creds.add(file(credentialsId: credentialsId, variable: cred.env[0]))
|
||||
break
|
||||
@@ -184,11 +183,17 @@ void credentialWrapper(config, List credentialInfo, body) {
|
||||
sshCreds.add(credentialsId)
|
||||
break
|
||||
default:
|
||||
error ("invalid credential type: ${cred.type}")
|
||||
error("invalid credential type: ${cred.type}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove credentialIds that were probably defaulted and which are not present in jenkins
|
||||
if (containsVaultConfig(config)) {
|
||||
creds = removeMissingCredentials(creds, config)
|
||||
sshCreds = removeMissingCredentials(sshCreds, config)
|
||||
}
|
||||
|
||||
if (sshCreds.size() > 0) {
|
||||
sshagent (sshCreds) {
|
||||
withCredentials(creds) {
|
||||
@@ -205,6 +210,41 @@ void credentialWrapper(config, List credentialInfo, body) {
|
||||
}
|
||||
}
|
||||
|
||||
List removeMissingCredentials(List creds, Map config) {
|
||||
return creds.findAll { credentialExists(it, config) }
|
||||
}
|
||||
|
||||
boolean credentialExists(cred, Map config) {
|
||||
try {
|
||||
withCredentials([cred]) {
|
||||
return true
|
||||
}
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
boolean containsVaultConfig(Map config) {
|
||||
def approleIsUsed = config.containsKey('vaultAppRoleTokenCredentialsId') && config.containsKey('vaultAppRoleSecretTokenCredentialsId')
|
||||
def tokenIsUsed = config.containsKey('vaultTokenCredentialsId')
|
||||
|
||||
return approleIsUsed || tokenIsUsed
|
||||
}
|
||||
|
||||
// Injects vaultCredentials if steps supports resolving parameters from vault
|
||||
List handleVaultCredentials(config, List credentialInfo) {
|
||||
if (config.containsKey('vaultAppRoleTokenCredentialsId') && config.containsKey('vaultAppRoleSecretTokenCredentialsId')) {
|
||||
credentialInfo += [[type: 'token', id: 'vaultAppRoleTokenCredentialsId', env: ['PIPER_vaultAppRoleID']],
|
||||
[type: 'token', id: 'vaultAppRoleSecretTokenCredentialsId', env: ['PIPER_vaultAppRoleSecretID']]]
|
||||
}
|
||||
|
||||
if (config.containsKey('vaultTokenCredentialsId')) {
|
||||
credentialInfo += [[type: 'token', id: 'vaultTokenCredentialsId', env: ['PIPER_vaultToken']]]
|
||||
}
|
||||
|
||||
return credentialInfo
|
||||
}
|
||||
|
||||
// reused in sonarExecuteScan
|
||||
void handleErrorDetails(String stepName, Closure body) {
|
||||
try {
|
||||
@@ -218,7 +258,7 @@ void handleErrorDetails(String stepName, Closure body) {
|
||||
errorCategory = " (category: ${errorDetails.category})"
|
||||
DebugReport.instance.failedBuild.category = errorDetails.category
|
||||
}
|
||||
error "[${stepName}] Step execution failed${errorCategory}. Error: ${errorDetails.error?:errorDetails.message}"
|
||||
error "[${stepName}] Step execution failed${errorCategory}. Error: ${errorDetails.error ?: errorDetails.message}"
|
||||
}
|
||||
error "[${stepName}] Step execution failed. Error: ${ex}, please see log file for more details."
|
||||
}
|
||||
|
Reference in New Issue
Block a user