How to pass a parameter to Jenkins using curl and Authentication Token - jenkins

I have a Jenkins job MY_REMOTE_JOB on which I enabled Triger Builds Remotely to run it with Authentication Token.
I would like to trigger MY_REMOTE_JOB in another job (CALLING_JOB) with an input parameter $MYPARAMETER that is already set (in CALLING_JOB). I tried this command:
curl -k -u JENKINS_USER_JOHN:123TOKEN123 https://myserver.com:8443/jenkins/job/MY_REMOTE_JOB/buildWithParameters?token=123TOKEN123&INPUT_PARAMETER=$MYPARAMETER
The trigger / call of a job MY_REMOTE_JOB is actually successful, but the parameter ($MYPARAMETER) that should be passed to that job is somehow left behind, so the job gets executed without a parameter.
How should I modify my curl so it will pass the parameter to the MY_REMOTE_JOB ?
I am running on Jenkins 1.609.3

At the first glance I could say you are missing -X flag for Posting data
I had similar issues, I referred man page for curl and found -F flag to be useful as this emulates a filled-in form, please also see to that parameter names and their order are matching exactly with the parameter names and its order on Jenkins Build With Parameters Page/Form
For instance let us assume the order of your Parameter Section looks in the following Format in a Descriptive Pipeline Syntax
pipeline {
parameters {
string(name: "PARAMETER1", defaultValue: "", description: "Enter a Value")
string(name: "PARAMETER2", defaultValue: "", description: "Enter a Value")
string(name: "PARAMETER3", defaultValue: "", description: "Enter a Value")
string(name: "PARAMETER4", defaultValue: "", description: "Enter a Value")
string(name: "PARAMETER5", defaultValue: "", description: "Enter a Value")
}
}
the order of the parameters in the curl command should be similar
Based on the format of your curl command below
curl -k -u JENKINS_USER_JOHN:123TOKEN123 https://myserver.com:8443/jenkins/job/MY_REMOTE_JOB/buildWithParameters?token=123TOKEN123&INPUT_PARAMETER=$MYPARAMETER
I would recommend try the following format
curl -k -X POST -u JENKINS_USER_JOHN:123TOKEN123 "https://myserver.com:8443/jenkins/job/MY_REMOTE_JOB/buildWithParameters" -F PARAMETER1=${PARAMETER1_VALUE} -F PARAMETER2=${PARAMETER2_VALUE} -F PARAMETER3=${PARAMETER3_VALUE} -F PARAMETER34=${PARAMETER4_VALUE} -F PARAMETER5=${PARAMETER5_VALUE}
Here is the link for Jenkins Documentation
If you also intend to use CSRF Protection with proper authentication follow the Jenkins CSRF , with this being enabled you could use the value in the curl command with -H flag
so with CSRF your curl command will be with the following format
curl -k -X POST -u JENKINS_USER_JOHN:123TOKEN123 -H ${YOUR_CRUMB_VALUE} "https://myserver.com:8443/jenkins/job/MY_REMOTE_JOB/buildWithParameters" -F PARAMETER1=${PARAMETER1_VALUE} -F PARAMETER2=${PARAMETER2_VALUE} -F PARAMETER3=${PARAMETER3_VALUE} -F PARAMETER4=${PARAMETER4_VALUE} -F PARAMETER5=${PARAMETER5_VALUE}
Finally also find some other answers related to your question Here
Hope the above recommendation solves your issue, Good Luck

Related

CURL response from Jenkinsfile, http_code problematic due to escape chars

I have written a function to record http code after the application is up to verify if response code is appropriate. This is on windows agent hosted on Azure VM.
def result = bat (returnStdout: true,
script: "curl --output /dev/null --silent --write-out '\\n%{http_code} http://localhost:8080")
echo "HTTP Code: ${result}"
So as I run the pipeline I get the following response in console log
**F:\jenkin_workspace\workspace\curl-test-pipeline>curl --write-out '\n//localhost:8080**
I tried various methods like using double quotes, single quotes and even without quotes but none helps.
Please suggest where am I wrong here?

Resource not found - Triggering BitBucket Pipeline using curl

I created a new project and added a repository to it in my workspace. Further, I added a bitbucket-pipelines.yml to build a pipeline. I am able to trigger the pipeline manually however while trying to execute it using BitBucket API using curl, I get the below error every time:
Can anyone suggest what I am missing here?
NOTE: The same curl command (below) is able to run other pipelines in different repositories in the same workspace, so do I need to enable something in my current repository to access pipeline using BitBucket APIs. TIA
Error:
{"type": "error", "error": {"message": "Resource not found"}}%
cURL command:
curl -X POST -is -u username:password \
-H 'Content-Type: application/json' \
https://api.bitbucket.org/2.0/repositories/workspace-name/repo-name/pipelines/ \
-d '
{
"target": {
"type": "pipeline_ref_target",
"ref_type": "branch",
"ref_name": "master",
"selector": {
"type": "custom",
"pattern": "create-tenant"
}
}}'
So the tokens I was using in the curl weren't added to Repository Settings -> User and group access. Got them added and was able to execute it successfully.

Jenkins string interpolation with credentials

I'm coding this function in Jenkins to query Artifactory:
def curlDockerArtifact(URL, registryName, moduleName, tag, token) {
def controlURI = "${URL}/artifactory/api/storage/${registryName}/${moduleName}/${tag}"
def result = sh(script: """
curl -I -H \'Authorization: Bearer $token\' \
https://$controlURI -o /dev/null -w \'%{http_code}\' -s
""", returnStdout: true)
}
But I get this warning which I'm tying to avoid.
Warning: A secret was passed to "sh" using Groovy string interpolation, which is insecure.
I tried using single quotes but the variables don't get correctly interpreted from Groovy. Any idea how to fix/refactor the code?
You have to keep double quotes like you do, but you need to escape the $ sign for the token. Like this :
curl -I -H \'Authorization: Bearer \$token\'
The groovy will not interpolate the variable and the correct value will be passed on the shell level.
More informations : https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#interpolation-of-sensitive-environment-variables

Unable to get the payload from GitHub web hook trigger in jenkins pipeline

I have configured a Github web hook with the below settings:
Payload URL: https:///github-webhook/
Content Type: application/x-www-form-urlencoded
Events : Pushes, Pull Requests
The Jenkins job that I have, is a pipeline job that has the below enabled:
Build Trigger: GitHub hook trigger for GITScm polling
With the above configuration, I see that in response to an event ie; push/PR in GitHub, the jenkins job gets triggered successfully. In GitHub, under Recent Deliveries for the web hook, I see the details of the payload and a successful Response of 200.
I am trying to get the payload in Jenkins Pipeline for further processing. I need some details eg: PR URL/PR number, refs type, branch name etc for conditional processing in the Jenkins Pipeline.
I tried accessing the "payload" variable (as mentioned in other stack overflow posts and the documentations available around) and printing it as part of the pipeline, but I have had no luck yet.
So my question is, How can I get the payload from GitHub web hook trigger in my Jenkins Pipeline ?
You need to select Content type: application/json in your webhook in GitHub. Then you would be able to access any variable from the payload GitHub sends as follows: $. pull_request.url for pr url, for example.
Unsure if this is possible.
With the GitHub plugin we use (Pipeline Github), PR number is stored in the variable CHANGE_ID.
PR URL is pretty easy to generate given the PR number. Branch name is stored in the variable BRANCH_NAME. In case of pull requests, the global variable pullRequest is populated with lots of data.
Missing information can be obtained from Github by using their API. Here's an example of checking if PR is "behind", you can modify that to your specific requirements:
def checkPrIsNotBehind(String repo) {
withCredentials([usernamePassword(credentialsId: "<...>",
passwordVariable: 'TOKEN',
usernameVariable: 'USER')]) {
def headers = ' -H "Content-Type: application/json" -H "Authorization: token $TOKEN" '
def url = "https://api.github.com/repos/<...>/<...>/pulls/${env.CHANGE_ID}"
def head_sha = sh (label: "Check PR head SHA",
returnStdout: true,
script: "curl -s ${url} ${headers} | jq -r .head.sha").trim().toUpperCase()
println "PR head sha is ${head_sha}"
headers = ' -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $TOKEN" '
url = "https://api.github.com/repos/<...>/${repo}/compare/${pullRequest.base}...${head_sha}"
def behind_by = sh (label: "Check PR commits behind",
returnStdout: true,
script: "curl -s ${url} ${headers} | jq -r .behind_by").trim().toUpperCase()
if (behind_by != '0') {
currentBuild.result = "ABORTED"
currentBuild.displayName = "#${env.BUILD_NUMBER}-Out of date"
error("The head ref is out of date. Please update your branch.")
}
}
}

How To Capture and Format Json Response in Jenkins Pipeline

I'm running a curl command in my Jenkinsfile.
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|curl -s -u ${apiToken}: ${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children | json_pp -json_opt pretty,canonical > report1.txt
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
But I get the error
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/bin/json_pp
I can't use jq as it's not installed and installing it isn't an option.
The curl command works fine on my terminal but is failing in my Jenkins pipeline.
Also, when I do this instead, it works.
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
sh """
curl -s -u ${apiToken}: '${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children' | json_pp -json_opt pretty,canonical > report1.txt
"""
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
But it throws a warning in the console output.
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
What am I doing wrong, please?
In a Jenkins pipeline, how would you properly pass a JSON response using curl into a file?
I recommend to not use shell scripts whenever it is possible. Shell scripts are not cross platform and require installing additional tools (e.g. curl).
In your case the curl call could be replaced by the httpRequest step.
First let's replace the curl call and saves the result in a componentTree.json file:
httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable',
outputFile: 'componentTree.json'
)
You want to format the JSON data in a human-readable format, so let's use the readJSON and writeJSON steps:
def json = readJSON(file: 'componentTree.json')
writeJSON(json: json, file: 'report1.txt', pretty: 4)
Now the report1.txt file contains JSON formatted with indent 4.
The componentTree.json file is written and read only once, so let's decrease the number of the IO operations:
def response = httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable'
)
def json = readJSON(text: response.content)
writeJSON(json: json, file: 'report1.txt', pretty: 4)
About the warning:
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
Secrets never should be interpolated because they may contain special characters which could be interpreted. Example:
my secret: My' https://example.org; cat /etc/passwd; echo \
command: curl -u '${password}' https://private.server/path/file.txt
After the interpolation the following command is called:
curl -u 'My' https://example.org; cat /etc/passwd; echo \' https://private.server/path/file.txt
There are two options to fix it:
if apiToken is an environment variable:
sh "curl -s -u \$apiToken: '${Sonar_URL}/api/measures/component..."
if apiToken is a Groovy variable:
withEnv(["CREDENTIALS=${apiToken}"]) {
sh "curl -s -u \$CREDENTIALS: '${Sonar_URL}/api/measures/component..."
}
In both cases the dollar sign ($) is escaped before the credentials which means that shell script will resolve it (it will be taken from environment variables).

Resources