Jenkins Pipeline passing password parameter to downstream job - jenkins

I want to pass a value, from the Password Parameter plugin, in a Jenkins Pipeline job, to another freestyle job, to be used for login. I don't want to see it in the output or anywhere else. I can do it between two freestyle jobs but it seems that the pipeline is a bit different.
Even if I'm able to send as a string, it would be visible in the Parameters tab or the Environment Variables tab.
Does anyone have any idea how this could be achieved?

I've spent hours trying different solutions for the same problem as you've had and here is the final solution, which worked for me:
In your pipeline script:
stages {
stage("Do something with credentials and pass them to the downstream job") {
steps {
build job: 'your/jobname/path', parameters: [
[$class: 'hudson.model.PasswordParameterValue', name: 'PASSWORD', value: env.PASSWORD],
[$class: 'TextParameterValue', name: 'USERNAME', value: env.USERNAME]
]
}
}
The trick is to use hudson.model.PasswordParameterValue class when passing password parameter to downstream (Freestyle) job, but you must use then the same class for parameter definition in your main pipeline (parent job) in order to make it work.
For example in your pipeline job you would configure password parameter:
configure {
it / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions' << 'hudson.model.PasswordParameterDefinition' {
name('PASSWORD')
description('My password')
}
}

You should make sure that parent and child job both are using password parameters. Then, this parameters tab will mask you password. Making build parameters as password parameter will not mask passwords in environment variables tab, for that you need to enable mask password in child and parent job configuration or use Inject passwords to the build as environment variables and enable mask password.

You should use credentials plugin, which in pipeline you write with withCredentials block. For example:
withCredentials([usernamePassword(credentialsId: 'abcd1234-56ef-494f-a4d9-d5b5e8ac357d',
usernameVariable: 'USERNAME',
passwordVariable: 'PASSWORD')])
{
echo 'username='+USERNAME
echo 'password='+PASSWORD
}
where abcd1234-56ef-494f-a4d9-d5b5e8ac357d is the id of credentials you have in jenkins, and of course, as long as you don't echo the variables (as I did in the example obviously for demonstration purposes), username and password are not visible.

You can trigger you downstream job with the help of below plugin
Parameterized+Trigger+Plugin

Related

Jenkins Pipeline dynamically set parameter based on Artifactory trigger URL

I have a pipeline job that triggers when finding changes in Artifactory at a specific path. I want to pass the Artifactory url value to a parameter (my goal for this job is to allow users to manually build this job and enter a path as well as have this job automatically trigger when changes are found in a specific path in Artifactory and pass that value to the parameter).
node {
def server
def rtTriggerUrl = currentBuild.getBuildCauses('org.jfrog.hudson.trigger.ArtifactoryCause')[0]?.url
stage ('Artifactory configuration') {
server = Artifactory.server 'artifactory-1'
}
stage('Trigger build') {
server.setBuildTrigger spec: "H/2 * * * *", paths: "maven-examplerepo-local/path/to/jar"
}
}
pipeline {
parameters {
string(
name: 'JAR_LOCATION',
defaultValue: rtTriggerUrl,
trim: true,
description: 'Artifactory URL of jar'
I have tried setting it a couple different ways:
defaultValue: rtTriggerUrl
defaultValue: "${currentBuild.getBuildCauses('org.jfrog.hudson.trigger.ArtifactoryCause')[0]?.url}"
However these gave blank or null values (I also tried setting the rtTriggerUrl function before node to see if that'd make it available to the parameter but that didn't work either).
Has anyone figured out how to do this? As a workaround I created an upstream job that triggers when changes are in Artifactory, then it triggers the downstream job and passes the url value to the downstream job's parameter. I wanted to see if I could combine that logic into one job.

Jenkins role strategy plugin and restrict user to build if not in proper group -- Jenkins file

We have two environments, qa and dev, and that is configured as parameters in Jenkinsfile. Plugin Role-based Authorization Strategy is enabled, and there are two groups of users, qa and dev (same as environment). The problem here is that qa users can start to build jobs with dev environment. Is there any way that we restrict this behavior?
Here is a simple example:
pipeline {
agent any
choice(name: 'environment', choices: ['dev', 'qa']
stages {
stage('test') {
script {
if (params.environment == 'dev' && env.BUILD_USER_ID not in env.BUILD_USER_GROUPS) {echo "User ${env.BUILD_USER_ID} can not start build on DEV enviroment"}
else if (params.environment == 'qa' && env.BUILD_USER_ID not in env.BUILD_USER_GROUPS) {echo "User ${env.BUILD_USER_ID} can not start build on QA enviroment"}
else {echo "You can run job, You are in proper group for this enviroment"}
}
}
}
}
An example is not real, and maybe not working, but I hope that can be understood what I want to accomplish.
P.S. Documentation for this is not so good, and also can't find much more examples on web.
Instead of blocking (or failing) the execution after it started, you can use a different approach and prevent an unauthorized user to even start the build with irrelevant parameters (dev environment in this case).
To do so you can use the Extended Choice Parameter plugin, it enables you to create a select list value (multi or single select) based on the return value of a groovy script.
Then you can use the following script:
def buildUserGroup = ["group1","group 2","group3"]
def environments = ['qa'] // This default value will be available to everyone
// All the groups that the current logged in user is a member of
def currentUserGroups = hudson.model.User.current().getAuthorities()
if (currentUserGroups.any{ buildUserGroup.contains(it) }) {
environments.add("dev") // Add relevant environments according to groups
}
return environments
This way you can define the logic that will add environments according to group membership and adjusted it according to your needs. The user that builds the job wont even see the environments that he is not allowed to build and you will get the restriction you need.
In a Pipeline Job using your requirements the configuration can be simplified and will look like:
pipeline {
agent any
parameters {
extendedChoice(name: 'environment', type: 'PT_SINGLE_SELECT', description: 'Environment type', visibleItemCount: 10,
groovyScript:"return hudson.model.User.current().getAuthorities().contains('dev') ? ['dev','qa'] : ['qa']")
}
stages {
stage('test') {
....
}
}
}
Update:
If you are using the Role-based Authorization Strategy and want to use the above solution with roles instead of groups you can use the following code (based on this script in your parameter:
def environments = ['qa'] // This default value will be available to everyone
def userID = hudson.model.User.current().id // The current user it
def authStrategy = jenkins.model.Jenkins.instance.getAuthorizationStrategy()
def permissions = authStrategy.roleMaps.inject([:]){map, it -> map + it.value.grantedRoles}
// Validate current user is in the 'dev' role
if (permissions.any{it.key.name == 'dev' && it.value.contains(userID)}) {
environments.add("dev") // Add relevant environments according to groups
}
return environments

emailext EmailDL usage outside of email stage

How do I use the email-id in prior stages from the variable EmailDL which I have used in the email text plugin in the declarative pipeline template in the last stage?
Is there any Global variable for the EmailDL/recipient/To like $BUILDID which can be used?
we have EmailDL to receive Job Status Emails to collect the email id & use it in the template
post {
always {
emailext (
body:
subject: "XXXXXX",
mimeType: 'text/html',
to: "${EmailDL}"
)
}
}
All works good but how do I reuse the parameter EmailDL outside of the Post stages?
I would suggest define it in environment like this
environment {
EmailDL = "abc#.com"
}
and use it anywhere using ${EmailDL}

Jenkins job DSL plugin - hidden parameter

I am using the Jenkins hidden parameter plugin but I cant find the syntax to write it in DSL like I am doing with other parameters.
For example:
https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.helpers.BuildParametersContext.activeChoiceParam
Is there any way to reflect hidden parameter in DSL?
Job DSL has no built-in support for the Hidden Parameter plugin, so it's not mentioned in the API viewer. But it's supported by the Automatically Generated DSL:
job('example') {
parameters {
wHideParameterDefinition {
name('FOO')
defaultValue('bar')
description('lorem ipsum')
}
}
}
BEfore using the declarative pipeline syntax (described in jenkinsci/pipeline-model-definition-plugin), you would have used:
the groovy-based DSL plugin
in combination with the JENKINS Mask Passwords Plugin (PR 755)
But with the pure DSL pipeline syntax, this is not yet supported (April 2017).
The PR 34 (a secret step) has been rejected
The following issues are still open:
"JENKINS-27386: Access credentials value from workflow Groovy script" (when to be implemented in a DSL pipeline)
"JENKINS-27398: Pipeline-as-Code CredentialsProvider for a job" (which would at least allow you tu use credentials as a workaround to access secret values)
The last issue though points out to JENKINS-29922 (Promote delegates of metasteps to top-level functions, deprecate $class) and adds the comment:
JENKINS-29922 is implemented, so assuming a #Symbol is defined for each credentials kind, and a credentials step is marked metaStep, you could write more simply:
usernamePassword id: 'hipchat-login', username: 'bob', password: 'abc/def+GHI0123='
hipchat server: …, message: …, credentialsId: 'hipchat-login'
or even allow the id to be generated, and return it from the step:
hipchat server: …, message: …, credentialsId: usernamePassword(username: 'bob', password: 'abc/def+GHI0123=')
While that is encrypted, that is not exactly "hidden" though.

How to get culprits or committers inside a Jenkins workflow with one or more SCMs

Is it possible to access information about committers and/or culprits of a Jenkins workflow job when checking out from one or more SCMs (either via checkout() or other SCM steps like git/svn)?
The intention is to use that information to notify committers and/or culprits about the job status, for example in a mail step.
A small example of a workflow definition:
node {
// checkout from one or more SCMs, e.g.
git url: '<URL>'
checkout([$class:...])
...
// how can we know about committers or culprits at this point?
$committers = ??
// send a mail to committers or culprits
mail to: '$committers', subject: 'JENKINS', body: '<information about the job status>'
}
How could this be adapted to get a collection of the committers after running the SCM steps?
Edit:
I am currently working with Jenkins version 1.596.2 and Workflow: Aggregator version 1.6 and it seems this is an open issue in JENKINS-24141
This is now possible using the email-ext plugin.
def to = emailextrecipients([[$class: 'CulpritsRecipientProvider'],
[$class: 'DevelopersRecipientProvider'],
[$class: 'RequesterRecipientProvider']])
if (to != null && !to.isEmpty()) {
mail to: to, subject: "JENKINS", body: "See ${env.BUILD_URL}"
}
However, if you just want to send an email on failures, you may want to use Mailer (based on the email-ext pipeline examples):
step([$class: 'Mailer',
notifyEveryUnstableBuild: true,
recipients: emailextrecipients([[$class: 'CulpritsRecipientProvider'],
[$class: 'RequesterRecipientProvider']])])
Using groovy within a pipeline script:
#NonCPS // Necessary to allow .each to work.
def changelist() {
def changes = ""
currentBuild.changeSets.each { set ->
set.each { entry ->
changes += "${entry.commitId} by ${entry.author.fullName}\n"
}
}
changes
}
similar to the answer from #szym, but without the #NonCPS required:
def authors = currentBuild.changeSets.collectMany { it.toList().collect { it.author } }.unique()
As you found, pending JENKINS-24141 this is not supported. Changes to Jenkins core are required.
You can get the xml info for a job in which you will find the name of the person who committed the change along with the commit messages.
http://<Jenkins URL>:<Port Number>/job/<Jobname>/<BuildNumber>/api/xml?
Give this a go in your browser. Search for "user".
You can dump this information in a text file to process.
It seems that this feature was implemented inside the email-ext plugin but the author forgot to document the way we are supposed to use this.
Please check https://issues.jenkins-ci.org/browse/JENKINS-34763 -- and add a comment there, asking for an example. I already did.
You can fetch committers email :
committerEmail = sh (
script: 'git --no-pager show -s --format=\'%ae\'',
returnStdout: true
).trim()
and send:
emailext body: 'text you choose', subject: 'subject you choose', recipientProviders: [[$class: 'DevelopersRecipientProvider']], to: committerEmail
taken from : https://medium.com/#dilunika/find-the-git-commit-user-jenkins-pipeline-b6790613f8b5
In the emailext plugin you can provide culprits, developers, requestor etc in the recipientProviders directly.
emailext body: '',
recipientProviders: [culprits(),
developers(),
brokenBuildSuspects(),
brokenTestsSuspects(),
requestor()],
subject: ''
Description
Culprits: Sends email to the list of users who committed a change since the last non-broken build till now. This list at least always include people who made changes in this build, but if the previous build was a failure it also includes the culprit list from there.
Developers: Sends email to all the people who caused a change in the change set.
Broken Build suspects: Sends email to the list of users suspected of causing the build to begin failing.
Broken Test suspects: Sends email to the list of users suspected of causing a unit test to begin failing. This list includes committers and requestors of the build where the test began to fail, and those for any consecutive failed builds prior to the build in which the test began to fail.
Source: Jenkins Pipeline Syntax - Snippet Generator
If you want to notify the culprits who broke the build, You do not need to any checks, Use email plugin in jenkins. This plugin gives you option to send mails to commiter between past good build and current broken build.
If you are using "Editable email notifier plugin" You get option of send mail to culprit.
If you are using email plugin then you get the option "Send separate e-mails to individuals who broke the build".

Resources