dsymquen
dsymquen

Reputation: 594

How can i update a jenkins job using the api

I have to create/update a jenkins job using its api because all of my jobs are using parameters which are also used by other scripts and I am trying to centralize the scripts so when i change it in one place, the change reflects in all.

currently, if someone changes the script, they they also have to manually edit the parameters of the jenkins job as well.

I saw the example of the Remote API for creating jobs and was able to successfully create test jobs but how can i edit an existing job besides deleting it and creating it again(which isnt an option as i have to maintain the build history).

Upvotes: 24

Views: 42240

Answers (6)

amine.ouahman
amine.ouahman

Reputation: 11

curl -v -X POST https://jenkinsurl.fr:8443/job/jobname/config.xml  --data-binary "@config.xml" -u "jenkinsusername:yourjenkinstoken" -H "Content-Type: application/xml"

Upvotes: 0

Dave Michener
Dave Michener

Reputation: 1098

For those using RestSharp, I found that I needed to make sure that:

  1. The user ID performing the update had permission to do so under Manage > Global Security > Authorization Matrix
  2. I had a current Jenkins Crumb token, required once CSRF (also under Manage > Security) is enabled.
  3. Send the updated XML using a parameter of the Request object with the value of [ParameterType.RequestBody] (link)1 for the type argument.

    private XmlDocument JobConfigGet()
    {
        Uri JobConfigURI = GetJenkinsURI("job/" + _args.JobName + "/config.xml", null);
        RestClient restClient = new RestClient(JobConfigURI);
        RestRequest restRequest = new RestRequest(Method.GET);
    
        byte[] ua = Encoding.ASCII.GetBytes(Properties.Settings.Default.UserID + ":" + Properties.Settings.Default.UserPassword);
        restRequest.AddHeader("authorization", "Basic " + Convert.ToBase64String(ua));
        IRestResponse restResponse = restClient.Execute(restRequest);
    
        if (restResponse.ResponseStatus != ResponseStatus.Completed || restResponse.StatusCode != HttpStatusCode.OK)
            throw new Exception(string.Format("Unable to retrieve job config: {0}. Wrong ResponseStatus ({1}) or StatusCode ({2}) returned.\nURL: {3}", _args.JobName, restResponse.ResponseStatus.ToString(), restResponse.StatusCode.ToString(), restClient.BaseUrl.AbsoluteUri));
        if (restResponse.ContentType != "application/xml")
            throw new Exception("Unexpected data type returned for job config: " + _args.JobName + ".  Expected 'application/xml'. Got: " + restResponse.ContentType + ".\nURL: " + restClient.BaseUrl.AbsoluteUri);
    
        XmlDocument jobConfig = new XmlDocument();
        jobConfig.LoadXml(restResponse.Content);
        return jobConfig;
    }
    
    private void JobConfigUpdate(XmlDocument JobConfig, string JenkinCrumb)
    {
        // Update JobConfig XML as needed here.
        Uri JobConfigURI = GetJenkinsURI("job/" + _args.JobName + "/config.xml", null);
        RestClient restClient = new RestClient(JobConfigURI);
    
        RestRequest restRequest = new RestRequest(Method.POST);
        byte[] ua = Encoding.ASCII.GetBytes(Properties.Settings.Default.UserID + ":" + Properties.Settings.Default.UserPassword);
        restRequest.AddHeader("authorization", "Basic " + Convert.ToBase64String(ua));
    
        string[] crumbSplit = JenkinCrumb.Split(':');
        restRequest.AddHeader(crumbSplit[0], crumbSplit[1]);
        restRequest.AddParameter("text/xml", JobConfig.InnerXml, ParameterType.RequestBody);
    
        IRestResponse restResponse = restClient.Execute(restRequest);
        string resp = restResponse.Content;
    }
    

Upvotes: 0

user2800006
user2800006

Reputation: 51

http://asheepapart.blogspot.ca/2014/03/use-jenkins-rest-api-to-update-job.html

That little bit of scripting looks to be what you are looking for. Uses the REST API to get and set the config with some regex S&R in the middle.

Edit: Code below based on comment. It is copied directly from the blog so I take no credit for it.

# First, get the http://jenkins.example.com/job/folder-name/job/sample-job--template/configure looking like you want

read -s token
# type token from http://jenkins.example.com/user/$userName/configure

# Download the configuration XML for the template job (which will be our model template)
curl -v -u "bvanevery:$token" http://jenkins.example.com/job/folder-name/job/sample-job--template/config.xml > generic-config.xml

# My modules
declare modules=('module1' 'module2' 'module3')

# POST the updated configuration XML to Jenkins
for m in ${modules[@]}; do
   echo "module $m";
   sed "s/MODULE/$m/g" generic-config.xml > $m-config.xml; 
   curl -v -X POST --data-binary @$m-config.xml -u "bvanevery:$token" \
        -H 'Content-Type: application/xml' \
        "http://jenkins.example.com/job/folder-name/job/$m/config.xml" ;
done

Upvotes: 4

Frank Chen
Frank Chen

Reputation: 181

You can also POST an updated config.xml to the URL which can fetch config.xml, to programmatically update the configuration of a job.

The fetch url pattern: $JENKINS_SERVER/job/$JOB_NAME/config.xml

detailed doc pattern: $JENKINS_SERVER/job/$JOB_NAME/api

example: https://ci.jenkins-ci.org/job/infra_atlassian-base/api/

Upvotes: 11

Dave
Dave

Reputation: 201

You could use python like this:

from jenkinsapi.jenkins import Jenkins
jenkinsSource = 'http://10.52.123.124:8080/'
server = Jenkins(jenkinsSource, username = 'XXXXX', password = 'YYYYY')
myJob=server.get_job("__test")
myConfig=myJob.get_config()
print myConfig
new = myConfig.replace('<string>clean</string>', '<string>string bean</string>')
myJob.update_config(new)

Upvotes: 20

dsymquen
dsymquen

Reputation: 594

in case anyone else is also looking for the same answer,

It appears the solution is far easier, all you have to do is update the config.xml and post the updated config.xml back to jenkins and your job will be updated.

Upvotes: 16

Related Questions