Contents

How to execute Jenkins jobs programatically

The most common usage of Jenkins is to trigger job builds automatically in response to changes in a source code repository. In some other cases you may need to trigger jobs because of any other reason. For example, imagine that you want to execute a Jenkins job after your alert management system detects something is wrong, so it can execute a pipeline that fixes everything and the alert is resolved. This is just an example, but the idea of this post is to be able to execute a Jenkins job programatically, and not using the GUI or anything related to Jenkins itself.

For this, you can have a look at the official documentation, but here I’m providing some straight to the point example.

Create a API token

First of all, you need to create a token to access Jenkins API. You can pick any user of your choice and go to Configure:

/posts/2020-06-03-how-to-execute-jenkins-jobs-programatically/jenkinsConfig1.png

Then create an API token. You’ll need to store it safely, as you cannot recover it again:

/posts/2020-06-03-how-to-execute-jenkins-jobs-programatically/jenkinsConfig2.png

Obtain a breadcrumb

The Jenkins breadcrumb is a mechanism that Jenkins has to avoid attacks. You can think that it’s simply an anti-CSRF token, like the ones we put in forms. Let’s obtain it:

1
curl --user 'fooUser:<token>' 'https://www.mysuperduperjenkins.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

This should return a response in the form Jenkins-Crumb: <BREADCRUMB>. You can insert it directly as a header:

1
curl -u 'fooUser:<token>' -X POST --data '<parameters>' -H '$breadcrumb' www.mysuperduperjenkins.com

Let’s do an snippet with this

Here’s a Groovy script. In this case, we needed to run a script using a Marid instance. This server receives alerts pushed from a well known alert automation software and executes the script as response to these alerts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
jenkinsUser = System.getenv('JENKINS_USER')
jenkinsPassword = System.getenv('JENKINS_PASSWORD')
jenkinsToken = System.getenv('JENKINS_TOKEN')

def runJenkins(jobName, jobData) {
    def breadcrumbCommand = ["/bin/sh", "-c", "curl -s --user fooUser:${jenkinsToken} 'https://www.mysuperduperjenkins.com/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)'"]
    def jenkinsCrumb = breadcrumbCommand.execute().text
    if (jenkinsCrumb.contains("Jenkins-Crumb")) {
        def command = ["/bin/sh", "-c", "curl --insecure -u '${jenkinsUser}:${jenkinsToken}' -X POST --data-urlencode json='$jobData' -H '${jenkinsCrumb}' https://www.mysuperduperjenkins.com/job/$jobName/build"]
        def result = command.execute().text
        logger.warn("Response: $result")
    } else {
        logger.error("Couldn't obtain a valid Jenkins breadcrumb. Review the JENKINS_TOKEN env variable.")
    }
}