Problem
I recently needed to download an artifact from a Jenkins build to my remote dev machine.
The remote machine has access to the Jenkins controller, so I just ran wget
with the link.
$ wget https://jenkins.local/job/.../artifact/my_artifact.tar.gz
I got this back:
HTTP request sent, awaiting response... 403 Forbidden
2023-04-02 17:43:27 ERROR 403: Forbidden.
Jenkins required authentication…
Solution
API token
To authenticate ourselves we need to supply username and an API token. The token can be generated in the Web-UI:
- Click on your username in the top right corner
- Click “Configure” in the side menu
- Under the API Token section, click “Add new Token”, give it a name and click “Generate”
It should look something like this: 11a6b656cac594240285968eaa9347f491
Wget
Now we can provide this information to wget
and download our file.
$ wget --auth-no-challenge --user=david --password=11a6b656cac594240285968eaa9347f491 https://...
It works! But, it’s not really recommended to pass API tokens on the command line since the secret can be easily exposed that way, so let’s put it in a file.
Security and usability improvements
By having the username and API token as environment variables we can refer to them in the CLI instead of writing them out in plain text.
# ~/.jenkins_token
JENKINS_USERNAME=david
JENKINS_TOKEN=11a6b656cac594240285968eaa9347f491
Change the file permissions so only your user can view the file contents:
$ chmod 600 ~/jenkins_token
To access these environment variables, we need to source the file.
Put this in your ~/.zshenv
or ~/.bashrc
depending on what shell you use.
# ~/.zshenv or ~/.bashrc
source $HOME/.jenkins_token
If we now open up a fresh terminal we can access the variables this:
$ wget --auth-no-challenge --user=$JENKINS_USERNAME --password=$JENKINS_TOKEN
Utility functions
To make it easier to use, we can create a utility function.
Here we also add support for authenticated curl
.
# ~/.zshrc or ~/.bashrc
wget_jenkins() {
wget --auth-no-challenge --user=$JENKINS_USERNAME --password=$JENKINS_TOKEN $@
}
curl_jenkins() {
curl --user ${JENKINS_USERNAME}:${JENKINS_TOKEN} $@
}
Now it’s much easier to download files!
$ wget_jenkins https://...
# or
$ curl_jenkins -o artifact.tar.gz https://...
Bonus: trigger jobs
In addition to downloading artifacts, you can also use the curl_jenkins
function to trigger Jenkins jobs remotely:
$ curl_jenkins -X POST -L https://jenkins.local/job/your_job/build
Conclusion
In conclusion, this article provides a practical solution for downloading
artifacts and triggering Jenkins jobs remotely using the wget
and curl
tools.
Official documentation
Jenkins - Authenticating scripted clients
Discuss on Hacker News