How to mask a password field in Jenkins Pipeline project? - jenkins

When a password property is defined in a Jenkinsfile:
properties([
parameters([
password(name: 'KEY', description: 'Encryption key')
])
])
Jenkins prompts users to provide its value every time the pipeline is executed:
I want this parameter to be masked so that echo ${KEY} does not print the actual value passed by the user. However, at the moment echoing it prints the provided value verbatim:
properties([
parameters([
password(name: 'KEY', description: 'Encryption key')
])
])
node {
stage('Stage 1') {
# Will print the actual value of the KEY, verbatim
sh "echo ${KEY}"
}
}
Also it seems that the Mask Passwords plugin does not work with Jenkins pipelines, so using that is not an option.
Is there a way to mask these password-typed parameters in the build logs?

You'll want to use the mask passwords plugin. Here's a Jenkinsfile example taken from my shared pipeline library.
properties([
parameters([
password(name: 'KEY', description: 'Encryption key')
])
])
node {
stage('Stage 1') {
// Will print the masked value of the KEY, replaced with ****
wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[var: 'KEY', password: KEY]], varMaskRegexes: []]) {
sh "echo ${KEY}"
}
}
}
Other than existing suggestions on withCredentials, there's not much to add. However, of you're automatically generating your jobs via templates and you're setting a default password, then you might want to make use of hudson.util.Secret to secure your templates.

You can use Jenkins Credentials plugin.With this plugin you can create a credential with an ID for use in your pipeline:
The code will be:
withCredentials([string(credentialsId: 'pass', variable: 'password1')]) {
echo "My password is '${password1}'!"
}
In your user case:
node {
stage('Echo') {
withCredentials([string(credentialsId: 'pass', variable: 'password1')]) {
echo "'${password1}'!"
}
}
}
Note: The password will be masked only in the withCredentials block.

Related

what can I do on Jenkinsfile to get credentials?

I'm new to jenkins and I'm creating a jenkinsfile with a declarative pipeline that supports different parameters. I also need to access to a credential stored in Jenkins, that I created already. How can I access to this credentials though jenkinsfile? do I need to call them inside of the stage or like this is ok? I got very confused in this part :S
I saw something like this on internet:
steps {
withCredentials([usernamePassword(credentialsId: 'x'....
}
Until now I have this:
pipeline {
agent any
environment{
my_credentials = credentials('x-credentials-id')
}
stages{
stage('Setup parameters') {
steps {
parameters([
string(name: 'a', defaultValue: 'x', description: 'test'),
text(name: 'b', defaultValue: ''),
text(name: 'b2', defaultValue: ''),
text(name: 'c', defaultValue: ''),
text(name: 'c2', defaultValue: '')
])
//])
}
}
}
}
From Jenkins documentation.
Jenkins' declarative Pipeline syntax has the credentials() helper
method (used within the environment directive) which supports secret
text, username and password, as well as secret file credentials.
So basically credentials('x-credentials-id') will support the aforementioned credential types and you should be using this helper method within an Environment block. You can use this approach if you want to declare your credentials globally so they can be used anywhere in the pipeline.
example
environment {
AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id')
AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
}
For other types, you can use withCredentials directive.(This is coming from Credentials Binding plugin) Both will get the Job done.
withCredentials(bindings: [certificate(credentialsId: 'jenkins-certificate-for-xyz', \
keystoreVariable: 'CERTIFICATE_FOR_XYZ', \
passwordVariable: 'XYZ-CERTIFICATE-PASSWORD')]) {
//
}
Although it says secrettext, username and password etc are not supported with Bind Credentials plugin, you can use WithCredentials for those types as well.
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
echo "username is $USERNAME"
}
Read more from here and here

set pipelineTriggers in Jenkinsfile to set 'Trigger builds remotely (e.g., from scripts)'

I have a Jenkinsfile and I want to set a pipelineTrigger property for my stage 'setup parameters'
#! /usr/bin/env groovy
pipeline {
agent any
stages {
stage('setup parameters'){
steps{
script{
properties([
parameters([
string(name: 'payload', defaultValue: '')
]),
pipelineTriggers(])
])
}
}
}
What i'm trying to do is after the first attempted run of the Job, the following checkbox should be checked with token filled out.
When I have looked for the pipeline syntax, it does not list this as one of the trigger options.
Thanks!
It's authenticationToken in the pipelineJob:
pipelineJob('project-name') {
definition {
...
}
parameters {
...
}
authenticationToken('TOKENHERE')
}
https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.jobs.WorkflowJob.authenticationToken

In Jenkins how can I mask the contents of a dynamic variable from output?

I have a dynamic credential that I am fetching in a script. When I later use that secret it is un-masked in the Jenkins output. How can I tell Jenkins to just mask a particular string dynamically?
stage ("Release") {
steps {
script {
withCredentials([
usernamePassword(
credentialsId: 'github-app',
usernameVariable: 'GITHUB_API_ID',
passwordVariable: 'GITHUB_API_KEY'
)
]) {
def TOKEN = sh(
returnStdout: true,
script: '''#!/bin/bash
ENCODED_KEY=$(echo -n "$GITHUB_API_KEY" | base64)
github_app_auth "$GITHUB_API_ID" "$ENCODED_KEY" "$GITHUB_INSTALLATION_ID"
'''
).trim()
// This function is logging TOKEN unmasked...
glGithubRelease([
token: TOKEN,
tagName: VERSION,
commitish: COMMIT,
])
}
}
}
}
In the above script I would like to know how to tell Jenkins to mask the local TOKEN. I am using withCredentials to mask my GITHUB_API_KEY and I am using #!/bin/bash to mask the contents of ENCODED_KEY (by showing no output at all) but the glGithubRelease function is 3rd party and it is logging all input parameters and I want to tell Jenkins to mask the TOKEN string as if its a credential.

Jenkins Publish Over SSh pipeline parameterized

I am using Publish over SSH plugin in Jenkins to deploy the jar file which is created from the build process. I have created a pipeline like this
node {
{
stage('Checkout') {
git([url: '.............', branch: 'myBranch', credentialsId: 'mycredentials'])
}
stage('Build') {
script{
sh 'chmod a+x mvnw'
sh './mvnw clean package'
}
}
stage('Deploy to Server'){
def pom = readMavenPom file: 'pom.xml'
script {
sshPublisher(publishers: [sshPublisherDesc(configName: 'server-instance1',
transfers: [sshTransfer(cleanRemote:true,
sourceFiles: "target/${env.PROJECT_NAME}-${pom.version}.jar",
removePrefix: "target",
remoteDirectory: "${env.PROJECT_NAME}",
execCommand: "mv ${env.PROJECT_NAME}/${env.PROJECT_NAME}-${pom.version}.jar ${env.PROJECT_NAME}/${env.PROJECT_NAME}.jar"),
sshTransfer(
execCommand: "/etc/init.d/${env.PROJECT_NAME} restart -Dspring.profiles.active=${PROFILE}"
)
])
])
}
}
}
}
This works. I have a SSH Server configured under Manage Jenkins >> Configure System >> Publish Over SSH.
Now I want to deploy on multiple servers. Lets say I create multiple ssh configurations by name server-instance1, server-instance2. How do I make this Jenkins job parameterized ? I tried with checking the checkbox and selecting a Choice Parameter. But I am not able to figure out how to make the values for this dropdown come from the SSH server list(instead of hardcoding)
I tried few things as mentioned here(How to Control Parametrized publishing in Jenkins using Publish over SSH plugin's Label field). Unfortunately none of the articles talks about doing this from a pipeline.
Any help is much appreciated.
If you want to select the SSH server name dynamically, you can use the Extended Choice Parameter plugin which allows you to execute groovy code that will create the options for the parameter.
In the plugin you can use the following code to get the values:
import jenkins.model.*
def publish_ssh = Jenkins.instance.getDescriptor("jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin")
configurations = publish_ssh.getHostConfigurations() // get all server configurations
return configurations.collect { it.name } // return the list of all servers
To configure this parameter in you pipeline you can use the following code for scripted pipeline:
properties([
parameters([
extendedChoice(name: 'SERVER', type: 'PT_SINGLE_SELECT', description: 'Server for publishing', visibleItemCount: 10,
groovyScript: '''
import jenkins.model.*
def publish_ssh = Jenkins.instance.getDescriptor("jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin")
return publish_ssh.getHostConfigurations() .collect { it.name }
''')
])
])
Or the following code for declarative pipeline:
pipeline {
agent any
parameters {
extendedChoice(name: 'SERVER', type: 'PT_SINGLE_SELECT', description: 'Server for publishing', visibleItemCount: 10,
groovyScript: '''
import jenkins.model.*
def publish_ssh = Jenkins.instance.getDescriptor("jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin")
return publish_ssh.getHostConfigurations() .collect { it.name }
''')
}
...
}
Once the parameter is defined just use it in your sshPublisher step:
sshPublisher(publishers: [sshPublisherDesc(configName: SERVER, transfers: ...
Another option you can have when using the Extended Choice Parameter is to configure it as Multi-Select instead of Single-Select so a user can then select multiple severs, and you can use the parallel option to publish over all selected servers in parallel.

Define credential parameter in parameters in Jenkins declarative pipeline?

I Currently using Jenkins Delarative pipeline with a parameterised build
pipeline {
agent any
parameters {
booleanParam(name: 'cleanDB',defaultValue: false,description: 'should clean db ?' )
string(name: 'host',defaultValue: 'xyx',description: 'DB Host')
}
stages {
stage('Build') {
steps {
sh 'mvn verify'
}
}
stage('Execute') {
steps {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'CREDENTIALS', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']])
{
sh "ant " +"-Ddb.clean=${params.cleanDB} -Ddb.host=${params.host} -Ddb.userid=$USERNAME \"-Ddb.password=$PASSWORD\" "
}
}
}
}
}
when i try to build with parameters it prompts only two param cleanDB,host params.i would like it to also ask which credential parameter to take.it takes only when explicitly added though UI in parameterised build.
so how can i add credential parameter in parameters can any one share an example of defining it in below syntax.
parameters {
booleanParam(name: 'cleanDB',defaultValue: false,description: 'should clean db ?' )
string(name: 'host',defaultValue: 'xyx',description: 'DB Host')
credentialParam(name: 'host',description: 'Credentials')
}
While as of today (2017-08-29) jenkins docs mention only string and boolean types of possible parameters, there is some ticket that answer this question. It says to do:
parameters {
credentials(name: 'CredsToUse', description: 'A user to build with', defaultValue: '', credentialType: "Username with password", required: true )
}
I just tried it and it works fine. When executed for the first time it doesn't ask anything, it just creates parameter for the job. After then it asks for credentials as it should.
Naturally, it works for Declarative Pipeline syntax, so must be enveloped with 'pipeline'.
Try the following:
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'CREDENTIALS', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']])
{
sh 'ant -Ddb.clean=${params.cleanDB} -Ddb.host=${params.host} -Ddb.userid=$USERNAME -Ddb.password=$PASSWORD'
}
according to the documentation on cloudbees https://support.cloudbees.com/hc/en-us/articles/204897020-Fetch-a-userid-and-password-from-a-Credential-object-in-a-Pipeline-job-

Resources