Skip to content

Instantly share code, notes, and snippets.

@raunak-r
Last active September 28, 2022 12:43
Show Gist options
  • Save raunak-r/4e580f5fc336f5734f572c43c3b22014 to your computer and use it in GitHub Desktop.
Save raunak-r/4e580f5fc336f5734f572c43c3b22014 to your computer and use it in GitHub Desktop.
Jenkins REST Api Formats

Jenkins REST API Formats (Java)

Refer - https://stackoverflow.com/a/51517348

I'll leave the original question as is and elaborate here on the various API calls to trigger parameterized builds. These are the calls options that I used.

Additional documentation: https://wiki.jenkins.io/display/JENKINS/Remote+access+API

The job contains 3 parameters named: product, suites, markers

Send the parameters as URL query parameters to /buildWithParameters: http://jenkins:8080/view/Orion_phase_2/job/test_remote_api_triggerring/buildWithParameters?product=ALL&suites=ALL&markers=ALL

Send the parameters as JSON data\payload to /build: http://jenkins:8080/view/Orion_phase_2/job/test_remote_api_triggerring/build

The JSON data\payload is not sent as the call's json_body (which is what confused me), but rater in the data payload as:

json:'{
       "parameter": [
                     {"name":"product", "value":"123"}, 
                     {"name":"suites", "value":"high"}, 
                     {"name":"markers", "value":"Hello"}
                    ]
      }'
And here are the CURL commands for each of the above calls:

curl -X POST -H "Jenkins-Crumb:2e11fc9...0ed4883a14a" http://jenkins:8080/view/Orion_phase_2/job/test_remote_api_triggerring/build --user "raameeil:228366f31...f655eb82058ad12d" --form json='{"parameter": [{"name":"product", "value":"123"}, {"name":"suites", "value":"high"}, {"name":"markers", "value":"Hello"}]}'

curl -X POST \ 'http://jenkins:8080/view/Orion_phase_2/job/test_remote_api_triggerring/buildWithParameters?product=234&suites=333&markers=555' \ -H 'authorization: Basic c2hsb21pb...ODRlNjU1ZWI4MjAyOGFkMTJk' \ -H 'cache-control: no-cache' \ -H 'jenkins-crumb: 0bed4c7...9031c735a' \ -H 'postman-token: 0fb2ef51-...-...-...-6430e9263c3b'

What to send to Python's requests In order to send the above calls in Python you will need to pass:

headers = jenkins-crumb
auth = tuple of your (user_name, user_auth_token)
data = dictionary type { 'json' : json string of {"parameter":[....]} }

Refer - https://stackoverflow.com/a/22289625

've worked around this issue by providing an 'ident' param to jobs that I wish to interact with programatically.

When submitting the job, I generate a uuid and submit this as the ident param to /job/<job_name>/buildWithParameters.

I then get /queue/api/json and iterate through the list of queued items, searching for an item with that uuid in it's params. That gets the queue id.

I then use this queue id to poll /queue/item/<queue_id>/api/json every N seconds, waiting for jenkins to provide a build number in the response (it will once the build has started). You can use this build number to construct the url you want, /job/<job_name>/<build_number>.

You actually need to add the ident as a param in your jenkins job. It's a pain, but it works reliably.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
{
public ResponseEntity<String> makeAPICall() throws JsonProcessingException {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(jenkinsUserName, buildToken);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> payload = createPayload();
org.springframework.http.HttpEntity request = new HttpEntity(payload, headers);
String urlString = jenkinsDomain + jenkinsJobUrl + "/build";
logger.info("Requesting build at - {} with param - {}", urlString, payload.toString());
ResponseEntity<String> response = restTemplate.postForEntity(urlString, request, String.class);
logger.info("Build Response - {}", ReflectionToStringBuilder.toString(response));
return response;
}
MultiValueMap<String, String> createPayload() throws JsonProcessingException {
Map<String, List<Map<String, String>>> body = new HashMap<String, List<Map<String, String>>>();
List<Map<String, String>> bodyList = new ArrayList<Map<String, String>>();
// convert any dto to <string, string> hashmap.
ObjectMapper m = new ObjectMapper();
Map<String, String> dict = m.convertValue(DTOObject, new TypeReference<Map<String, String>>() {});
for (Map.Entry<String, String> entry : dict.entrySet()) {
HashMap<String, String> element = new HashMap<>();
element.put("name", entry.getKey());
element.put("value", entry.getValue());
bodyList.add(element);
}
body.put("parameter", bodyList);
MultiValueMap<String, String> payload = new LinkedMultiValueMap<String, String>();
payload.add("json", new ObjectMapper().writeValueAsString(body));
return payload;
}
}
public ResponseEntity<String> makeAPICall() throws JsonProcessingException {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(jenkinsUserName, buildToken);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String appendPayload = createPayload();
org.springframework.http.HttpEntity request = new HttpEntity(headers);
String urlString = jenkinsDomain + jenkinsJobUrl + "/buildWithParameters?" + appendPayload;
logger.info("Requesting build at - {}", urlString);
ResponseEntity<String> response = restTemplate.postForEntity(urlString, request, String.class);
logger.info("Build Response - {}", ReflectionToStringBuilder.toString(response));
return response;
}
String createSlugPublishPayload() throws JsonProcessingException {
String append = "";
ObjectMapper m = new ObjectMapper();
Map<String, String> dict = m.convertValue(dtoObject, new TypeReference<Map<String, String>>() {
});
Integer i = 0;
for (Map.Entry<String, String> entry : dict.entrySet()) {
HashMap<String, String> element = new HashMap<>();
append = append + entry.getKey() + "=" + entry.getValue();
if (i != dict.size() - 1) {
append = append + "&";
i++;
}
}
return append;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment