I'm using the Jenkins parametrised remote trigger plugin to call Jenkins server (A) from our Jenkins server (B). It's been working successfully using the Jenkins credential manager, but I'm now wishing to fetch it at run time and then pass in that fetched credential directly as a string, rather than have it stored in Jenkins.
Essentially I'm trying to get a String into an auth2 object to use in my remote trigger.
Existing code:
triggerRemoteJob job: "${REMOTE_JOB}",
parameters: "REDACTED",
auth: CredentialsAuth(credentials: "cred-id")
What I'm working towards:
def fetchedCred = getFromThirdPartyResource()
triggerRemoteJob job: "${REMOTE_JOB}",
parameters: "REDACTED",
auth: CredFromString(fetchedCred)
The solution really depends on the type of Authentication method you intend to use. Since you are using CredentialsAuth I assume you plan on using Basic Auth. In Basic Auth you will be passing the Authorization header like below
Authorization: Basic username:password (username:password will be base64 encoded)
So in order to get around your issue, you can use TokenAuth instead of CredentialsAuth. If you look at the code here TokenAuth is also generating a Basic Auth header with the provided apiToken and userName. Hence you can use something like the below.
pipeline {
agent any
stages {
stage('Test') {
steps {
script {
def password = new hudson.util.Secret('admin')
def username = 'admin'
triggerRemoteJob job: "http://localhost:8080/job/test", auth: TokenAuth(apiToken: password, userName: username)
}
}
}
}
}
Related
in the Jenkins credentials I have several types of credentials.
One of them, called my_password is of the type "Secret Text", in which in a Jenkinsfile, I can access like so:
environment {
my_env_var = credentials('my_password')
}
Now I created a credential of type "Username with Password" called user_and_pass in which I can set up both fields in the same credential.
How can I access both params at the same time, and load them into env variables?
I was thinking something like:
environment {
my_user = credentials('user_and_pass').someFunctionThatReturnsUser()
my_pass = credentials('user_and_pass').someFunctionThatReturnsPass()
}
but I don't think it works like that.
When you get back the credentials from a "username and password" secret, you get one string with a username and a password separated by a colon in the format username:password.
Check if using usernamePassword works, as in here.
It is from the Jenkins Credentials Binding Plugin.
withCredentials(
[usernamePassword(credentialsId: 'mycreds',
usernameVariable: 'USERNAME',
passwordVariable: 'PASSWORD')]) {
sh 'cf login some.awesome.url -u $USERNAME -p $PASSWORD'
}
In Jenkins dashboard, Click on Manage Jenkins, Click on Manage Credentials under Security tab, click on system to create Global credentials. This Credential ID (SSH-Centos7 in my case) can be used as below:
stage('Example SSH Username with password') {
environment {
SSH_CREDS = credentials('SSH-Centos7')
}
Recent documentation available at Jenkins official documentation
As far as I know, all we have two methods to extract data from credential type Username and Password:
by the means of Groovy function withCredentials();
by the means of helper credentials().
withCredentials()
Syntax for extracting creds via withCredentials:
withCredentials([usernamePassword(credentialsId: 'your-credentials-id', passwordVariable: 'PASSWORD_VAR', usernameVariable: 'USERNAME')]) {
// your script could access $PASSWORD_VAR and $USERNAME_VAR
// as environment variables
//
// note: PASSWORD_VAR, USERNAME_VAR is just aliases, you may change it to whatever you like
}
If syntax looks too complicated and boring to you, use Pipeline Snippet Generator as follows.
credentials()
Syntax for extracting creds via credentials():
environment {
CREDS = credentials('your-credentials-id')
}
steps {
// your code can access
// username as $CREDS_USR
// and password as $CREDS_PSW
}
Which method to use?
It depends on credential type. For Username and Password you could use any of the methods - as you like.
credentials() helper supports the following types (end of 2022):
secret text;
username and password;
secret file.
For the rest of credentials types you have to use withCredentials().
Check out official docs for more details.
I what to make a httpRequest via pipeline with LDAP Credentials of pipeline triggering user.
LDAP Credentials need to be passed as 'authentication' property in httpRequest Step in pipeline.
pipeline {
agent any
stages{
stage('Remote Call'){
httpRequest url : <RemoteUrl> , authentication : 'LDAP_Credentails'
}
}
}
Suppose user with LDAP Credentials, say
LdapUsername : deerajk
LdapPasssword : dummyPassword
Note :Above mentioned Credentails are not not part of Jenkins Credential Store
Logs in to Jenkins with above mentioned Credentials and triggers a pipeline job , Say pipeline name 'MakeHttpRequestPipeline'. Mentioned pipeline makes an httpRequest call to which needs to use above mentioned Credentials in authentication property of httpRequest Step. This httpRequest is used to get token of LDAP user from Remote Jenkins and Trigger a job on Remote Jenkins.
What did i try ?
I could get user name how Triggered Job by following Code
def job = Jenkins.getInstance().getItemByFullName(env.JOB_BASE_NAME, Job.class)
def build = job.getBuildByNumber(env.BUILD_ID as int)
def userId = build.getCause(Cause.UserIdCause).getUserId()
I want to do the following
- Get LDAP Credentials reference id of user how triggers pipeline
- Pass the LDAP Credentials reference id in httpRequest Made by Pipeline
Let me know if their is a way to do so.
Get user Credentials via following parameters :
parameters{
credentials(credentialType: 'com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl',
defaultValue: '', description: 'Select your LDAP from Drop Down if avaliable else Create it',
name: 'deployCredentialsId', required: true)
}
Use Credentials as follows :
stages{
stage('TRIGGER PIPELINE'){
steps{
withCredentials([usernameColonPassword( credentialsId: '${deployCredentialsId}' , variable: 'DEPLOY_KEY')]){
script{
def creds = "$DEPLOY_KEY"
String auth = creds.bytes.encodeBase64().toString()
def response = httpRequest customHeaders: [ [maskValue: false, name: 'Authorization', value: "Basic ${auth}"], [maskValue: false, name: 'Content-Type', value: 'application/json'],] ,
url : 'https://{jenkinsHost}/me/configure' , ignoreSslErrors: true
}
}
}
}
}
Sending Custom Headers works
Is there a way to get a Jenkins credential based on its username instead of credential ID? My credential is of type username/password with a global scope.
I have a use case where I know what the username is (based on a JSON file where username is stored but it could also be hardcoded in jenkinsFile) and I need to dynamically grap the corresponding password from Jenkins credentials store.
stage("Execute command based on schema"){
withCredentials([usernamePassword(credentialsId: I_DONT_HAVE_THIS, passwordVariable: 'PASSWORD', usernameVariable: 'SCHEMA'])){
sh "sqlplus \"$SCHEMA/$PASSWORD#DBNAME\" #/path/to/script.sql"
}
}
To retrieve credentials in Jenkins, you have to give the credentialsId, then you set the variable name for username and password. They will be linked to the appropriate username and password stored in the credentials manager.
With that, if credentials are correctly stored in Jenkins, you can set the username as id for the credential to retrieve the correct username and password.
I think this is possible for your use case because you have to store credentials before running your pipeline and you can set the id as you want.
EDIT with a workaround
If you really want to get credential using username, you can use a workaround to get the list of all credentials and match the appropriate username :
stage("Execute command based on schema") {
steps {
script {
// Set this variable which should match with the user in credentials
def schema = "usertest"
def credential_id = ""
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance,
null,
null
);
for (c in creds) {
if (c.username == schema) {
credential_id = c.id
}
}
withCredentials([usernamePassword(credentialsId: credential_id, passwordVariable: 'PASSWORD', usernameVariable: 'SCHEMA')]) {
sh 'sqlplus \"$SCHEMA/$PASSWORD#DBNAME\" #/path/to/script.sql'
}
}
}
}
Be aware that there is some security issues :
You will need to activate a lot of script in the administrator side (see script-approval)
Anyone who can access to the script can call, in the loop, all credential field like id, description, username and password (thay will not be masked)
You should manage errors in case the username doesn't match with any credentials
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.
I have a parametrized jenkins job with 2 parameters:
1st job parameter is APIKEY of type 'Password parameter'
2nd job parameter is SERVICE of type 'Active Choices Reactive Parameter' - single select, referencing parameter APIKEY and using following groovy script code which returns value of APIKEY parameter in the single select UI control:
[ APIKEY ]
When I start the build of this job, value offered in single select UI control for parameter SERVICE is garbled (encrypted?) value of APIKEY.
What I want is to be able to use actual (decrypted) value of entered APIKEY password parameter in the script code of SERVICE parameter.
I tried decrypting the APIKEY garbled value by using hudson.util.Secret like below but with no luck:
def apikey = hudson.util.Secret.fromString(APIKEY).getPlainText()
Is there any way to get actual password parameter value from active choices reactive parameter groovy script code?
After a little bit more trying this out it turns out this is working properly after all - but only when password parameter is entered manually, not with the default password parameter value (not sure if this is a bug or a feature).
First time the job is run default password parameter value provided is garbled, but entering the value again in the password field then gives the correct value in groovy script.
This worked for me:
run job build
at this point APIKEY value in groovy script code of the SERVICE field is not evaluated correctly - it is garbled value
enter correct value in APIKEY password parameter field - e.g. "abc123"
switch focus to SERVICE field
SERVICE field groovy code gets executed now and shows actual entered value of APIKEY: "abc123"
Since my use case is such that entering APIKEY is mandatory every time job is build this is good enough for me.
This is an old topic, but I found a solution so I'll add it here in case anyone else still needs it. This was working code, but I sanitized it for publication.
This Groovy script runs in an Active Choices Reactive Parameter. The task is to provide a list of the build versions available to deploy from an internal Artifactory archive. The API key needed for the REST call is stored as Secret Text in our Jenkins instance. So this code reads from the Credentials plugin's repo to find the secret text, then adds it to the header of the http request.
This is a clunky solution. There is much more elegant withCredentials method for Groovy, but it may only work in Jenkins pipelines. I didn't find a way to use it in this parameter.
This solution also does not use HTTPBuilder, which would have been simpler, but wasn't available in our Groovy plugin.
import org.apache.http.client.methods.*
import org.apache.http.impl.client.*
import groovy.json.JsonSlurper;
def APP_FULL_NAME = "My.Project.Name"
def request = new HttpGet("https://fakeDns/artifactory/api/search/versions?r=releases&a="+APP_FULL_NAME)
def jenkinsCredentials = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.Credentials.class,
Jenkins.instance,
null,
null
);
def apiKey
for (creds in jenkinsCredentials)
{
//println creds.id
//println creds.class
if(creds.id == "my_target_api_key")
{
apiKey = creds.secret.toString(creds.secret);
break
}
}
request.addHeader("X-API-KEY", apiKey)
def responseString = new DefaultHttpClient().execute(request, new BasicResponseHandler());
def branchList = new JsonSlurper().parseText(responseString)
//return branchList
def myList= []
branchList.results.each { myList << it }
return myList.version