Upload secret file credentials to Jenkins with REST / CLI - rest

How can I create a Jenkins Credential via REST API or Jenkins CLI? The credential should be of type "secret file", instead of a username / password combination.
The question is similar to this question, but not the same or a duplicate.

You can do it as follows:
curl -X POST \
https://jenkins.local/job/TEAM-FOLDER/credentials/store/folder/domain/_/createCredentials \
-F secret=#/Users/maksym/secret \
-F 'json={"": "4", "credentials": {"file": "secret", "id": "test",
"description": "HELLO-curl", "stapler-class":
"org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl",
"$class":
"org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl"}}'
just finished with it today https://www.linkedin.com/pulse/upload-jenkins-secret-file-credential-via-api-maksym-lushpenko/?trackingId=RDcgSk0KyvW5RxrBD2t1RA%3D%3D

To create Jenkins credentials via the CLI you can use the create-credentials-by-xml command:
java -jar jenkins-cli.jar -s <JENKINS_URL> create-credentials-by-xml system::system::jenkins _ < credential-name.xml
The best way to know the syntax of this is to create a credential manually, and then dump it:
java -jar jenkins-cli.jar -s <JENKINS_URL> get-credentials-as-xml system::system::jenkins _ credential-name > credential-name.xml
Then you can use this XML example as a template, it should be self-explanatory.

If you want to update an existing secret file, the simplest way I found was to delete and re-create.
A delete request, to extend #lumaks answer (i.e. with the same hostname, folder name and credentials id), looks like:
curl -v -X POST \
-u "user:password" \
https://jenkins.local/job/TEAM-FOLDER/credentials/store/folder/domain/_/credential/test/doDelete
This will return either HTTP status code 302 Found or 404 Not Found for existing and non-existing creds file respectively.

Related

How can I get Azure pipeline log file from command line

I have an Azure pipeline. I can start and see the logs in Chrome. But I would like to do these steps from command line (actually Cygwin, but IMHO this is not relevant).
az pipelines run --name $pipeline --branch $branch
This command gives back a json file format text on the stdout. This json has a entry, called logs:
{
...
"logs": {
"id": 0,
"type": "Container",
"url": "https://dev.azure.com/myazure/a56234f9-0101-5183-b422-db6f8cb55857/_apis/mybuild/mybuilds/1822266/logs"
},
...
}
If I copy the "url" into Chrome I get another json format homepage, like:
{"count":27,"value":[{"lineCount":371,"createdOn":"2022-10-17T13:38:14.013Z","lastChangedOn":"2022-10-17T13:38:14.183Z","id":1,"type":"Container","url":"https://dev.azure.com/myazure/...
But I cannot get back this json data from command line. I tried to get by curl or wget. I got back a HTML page (full with with JavaScript), not the json answer.
I also tried az:
az rest --method get --url "$logs_url"
But the response is:
Can't derive appropriate Azure AD resource from --url to acquire an access token. If access token is required, use --resource to specify the resource
Not a json response, outputting to stdout. For binary data suggest use "--output-file" to write to a file
Then I tried to do:
az account get-access-token --query accessToken --output tsv > access_token.tsv
az rest --method get --resource access_token.tsv --url "$logs_url"
So, I assume I should get an access token to the URL. But how can I acquire it?
You can use curl to call rest api: https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/logs/list?view=azure-devops-rest-6.0
E.g.
curl https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineId}/runs/{runId}/logs?api-version=6.0-preview.1 ' -H 'Authorization: Basic YourPAT'

Upload username and password to rundeck key storage using CLI / REST?

I want to use username and password in Rundeck to run jobs on node instead of public / private keys. How do I do it?
Rundeck CLI always asks for the user and password by default, also, you can define environments vars RD_USER and RD_PASSWORD in your .bashrc file. Take a look at this (Credentials section).
Example:
export RD_USER=username
export RD_PASSWORD=password
Using API you can use use the "cookie way" to access an endpoint, take a look at this.
And check the following example:
#!/bin/sh
curl -v -c cookie -b cookie -d j_username=admin -d j_password=admin http://localhost:4440/j_security_check \
-H "Accept: application/json" \
http://hyperion:4440/api/31/system/info/

Downloading an artifact from actions on someone else's repository

This problem seems really simple. I'm trying to download a pre-built binary for a program from somebody's github repo.
They suggest that I can do this:
"You can also download pre-built binaries from GitHub Actions artifacts."
But it turns out that I have no idea what that means!
The file is not in the actions page (I'm not sure if it should be) and when I try:
curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/nbdd0121/wsld/actions/artifacts/42682371/zip
I receive { "message": "You must have the actions scope to download artifacts.", "documentation_url": "https://docs.github.com/rest/reference/actions#download-an-artifact" }
But this documentation implies that I need to Build an app in order to download a file???
Can this possibly be correct?
What am I missing here?
This works for me:
curl.exe `
--netrc-file C:\Users\Steven\_netrc `
-L `
-o wsldhost.exe.zip `
https://api.github.com/repos/nbdd0121/wsld/actions/artifacts/42682371/zip
Where _netrc looks like this:
default login <USERNAME> password <PERSONAL ACCESS TOKEN>
https://github.com/actions/upload-artifact/issues/89
You can also directly use Basic auth. In curl:
curl -L -u <USERNAME>:<PERSONAL_ACCESS_TOKEN> -o artifact.zip https://api.github.com/repos/nbdd0121/wsld/actions/artifacts/42682371/zip
And the personal access token is generated at: https://github.com/settings/tokens

Getting "500 Internal Server Error" when trying to create oidc-full-name-mapper via kcadm.sh

I am using Keycloak kcadm.sh tool to define a client. I am now trying to define protocol mappers similar to the ones that can be defined by the Keycloak's Web interface. The following command executes successfully:
./kcadm.sh create clients/myclientid/protocol-mappers/models -r myrealm -s name="full name" -s protocolMapper=oidc-full-name-mapper -s protocol=openid-connect
However when I examine the created full name mapper, I see that it's created with "Add to ID token" - OFF, and "Add to access token" - OFF. I want them to be ON. So, after deleting the created mapper I tried adding -s config.access.token.claim=true -s config.id.token.claim=true to the above command. So the command becomes:
./kcadm.sh create clients/myclientid/protocol-mappers/models -r myrealm -s name="full name" -s protocolMapper=oidc-full-name-mapper -s protocol=openid-connect -s config.access.token.claim=true -s config.id.token.claim=true
but this results in "HTTP error - 500 Internal Server Error"
I tried creating a mapper with the options turned off as before, then setting them on using the Web interface, then exporting the client and examine the result. The resulting json includes the following protocol mapper for my client:
"protocolMappers": [
{
"id": "...",
"name": "full name",
"protocol": "openid-connect",
"protocolMapper": "oidc-full-name-mapper",
"consentRequired": false,
"config": {
"id.token.claim": "true",
"access.token.claim": "true"
}
}
],
so it seems that the path I gave was correct. Any idea what I am doing wrong?
Found it! On Linux, I had to use \" after the config. So the command became:
./kcadm.sh create clients/myclientid/protocol-mappers/models -r myrealm -s name="full name" -s protocolMapper=oidc-full-name-mapper -s protocol=openid-connect -s config.\"access.token.claim\"=true -s config.\"id.token.claim\"=true
JustinT's (https://stackoverflow.com/users/1717360/justint) comment to
Add protocol-mapper to keycloak using kcadm.sh gave me the direction.
Specify the config values in Linux like this:
-s 'config."id.token.claim"=true'
-s 'config."access.token.claim"=true'

Create jobs and execute them in jenkins using REST

I am trying to create a WCF REST client that will communicate to Jenkins and create a job from an XML file and then build the job. My understanding is that you can do that with Jenkins.
Can some one please provide some commands that you can type on a browser's address bar to create and build jobs? ie: http:localhost/jenkins/createItem?name=TESTJOB something along those lines.
Usually, when parsing through the documentation, it can take one or two days. It is helpful to be able to access code or curl commands to get you up and running in one hour. That is my objective with a lot of third party software.
See the post at http://scottizu.wordpress.com/2014/04/30/getting-started-with-the-jenkins-api/ which lists several of the curl commands. You will have to replace my.jenkins.com (ie JENKINS_HOST) with the your own url.
To create a job, for instance, try:
curl -X POST -H "Content-Type:application/xml" -d "<project><builders/><publishers/><buildWrappers/></project>" "http://JENKINS_HOST/createItem?name=AA_TEST_JOB2"
This uses a generic config. You can also download a config from a manually created job and then use that as a template.
curl "http://JENKINS_HOST/job/MY_JOB_NAME/config.xml" > config.xml
curl -X POST -H "Content-Type:application/xml" -d #config.xml "http://JENKINS_HOST/createItem?name=AA_TEST_JOB3"
To execute the job (and set string parameters), use:
curl "http://JENKINS_HOST/job/MY_JOB_NAME/build"
curl "http://JENKINS_HOST/job/MY_JOB_NAME/buildWithParameters?PARAMETER0=VALUE0&PARAMETER1=VALUE1"
See the Jenkins API Wiki page (including the comments at the end). You can fill in the gaps using the documentation provided by Jenkins itself; for example, http://JENKINS_HOST/api will give you the URL for creating a job and http://JENKINS_HOST/job/JOBNAME/api will give you the URL to trigger a build.
I highly recommend avoiding the custom creation of job configuration XML files and looking at something like the Job DSL plugin instead. This gives you a nice Groovy-based DSL to create jobs programmatically - much more concise and less error-prone.
Thanks to a GIST - https://gist.github.com/stuart-warren/7786892
Check if job exists
curl -XGET 'http://jenkins/checkJobName?value=yourJobFolderName' --user user.name:YourAPIToken
With folder plugin
curl -s -XPOST 'http://jenkins/job/FolderName/createItem?name=yourJobName' --data-binary #config.xml -H "Content-Type:text/xml" --user user.name:YourAPIToken
Without folder plugin
curl -s -XPOST 'http://jenkins/createItem?name=yourJobName' --data-binary #config.xml -H "Content-Type:text/xml" --user user.name:YourAPIToken
Create folder
curl -XPOST 'http://jenkins/createItem?name=FolderName&mode=com.cloudbees.hudson.plugins.folder.Folder&from=&json=%7B%22name%22%3A%22FolderName%22%2C%22mode%22%3A%22com.cloudbees.hudson.plugins.folder.Folder%22%2C%22from%22%3A%22%22%2C%22Submit%22%3A%22OK%22%7D&Submit=OK' --user user.name:YourAPIToken -H "Content-Type:application/x-www-form-urlencoded"
If you want to create a job into a view given the view exists.
curl -X POST -H "Content-Type:application/xml" -d #build.xml "http://jenkins_host/view/viewName/createItem?name=itemName"
the build.xml filetemplate could be found in the root directory of a job's workspace
if you want to create a view:
curl -X POST -H "Content-Type:application/xml" -d #view.xml "http://jenkins_host/createView?name=viewName"
the content of the file view.xml could be:
<?xml version="1.0" encoding="UTF-8"?>
<hudson.model.ListView>
<name>viewName</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
<jobNames>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</jobNames>
<jobFilters/>
<columns>
<hudson.views.StatusColumn/>
<hudson.views.WeatherColumn/>
<hudson.views.JobColumn/>
<hudson.views.LastSuccessColumn/>
<hudson.views.LastFailureColumn/>
<hudson.views.LastDurationColumn/>
<hudson.views.BuildButtonColumn/>
</columns>
</hudson.model.ListView>
and to check if a view exists:
curl -X POST -H "Content-Type:application/xml" "http://jenkins_host/checkViewName?value=viewName"
to check if a job exists:
curl -X POST -H "Content-Type:application/xml" "http://jenkins_host/checkJobName?value=jobName"
To create a job:
curl -X POST -H "Content-Type:application/xml" -d "<project><builders/><publishers/><buildWrappers/></project>" -u username: API_Token http://JENKINS_HOST/createItem?name=AA_TEST_JOB2
To build a job:
curl -X POST -u username:API_TOKEN http://JENKINS_HOST/job/MY_JOB_NAME/build
In case you need to make the same HTTP calls using the Python requests library, instead of CURL...
Download a job config:
import requests
auth = ("username", "api_token")
url = "http://" + JENKINS_HOST + "/job/" + JOB_NAME + "/config.xml"
response = requests.get(url, auth=auth)
open('config.xml', 'wt').write(response.text)
Create a new job using same config:
url = "http://" + JENKINS_HOST + "/createItem?name=" + NEW_JOB_NAME
headers = {'content-type': 'text/xml'}
data = response.text
response = requests.post(url, auth=auth, headers=headers, data=data)
Omit auth parameter when not needed.