Skip to content

Instantly share code, notes, and snippets.

@perzizzle
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

  • Save perzizzle/5a1d4ba5efb444476445 to your computer and use it in GitHub Desktop.

Select an option

Save perzizzle/5a1d4ba5efb444476445 to your computer and use it in GitHub Desktop.
Jenkins API Calls
package com.surescripts.devops.util
import hudson.model.*
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.ContentType
import static groovyx.net.http.Method.*
// get current thread / Executor
def thr = Thread.currentThread()
// get current build
def buildInfo = thr?.executable
def parameterMap= [:]
// get parameters
def parameters = buildInfo?.actions.find{ it instanceof ParametersAction }?.parameters
parameters.each { it ->
parameterMap += [(it.name):(it.value)]
}
println parameterMap
def user = "ansible"
def password='password'
public launchJob(String url, String name, String job_template_id, String limit, String extra_vars, String user, String password ) {
def remote = new HTTPBuilder(url)
def messageBody = ['name': name, 'limit': limit, 'extra_vars': extra_vars ]
def job = null
remote.request(POST) { req ->
uri.path = "/api/v1/job_templates/"+job_template_id+"/launch/"
requestContentType = ContentType.JSON
body = messageBody
headers.'Authorization' = "Basic ${"$user:$password".bytes.encodeBase64().toString()}"
response.success = { resp, json ->
job = json.job
println "Job ${json.job} created: status ${resp.status}"
}
response.failure = { resp -> println "Request failed with status ${resp.status}" }
}
return job
}
public createJob(String url, String name, String job_template, String limit, String extra_vars, String user, String password ) {
def remote = new HTTPBuilder(url)
def messageBody = ['name': name, 'job_template': job_template, 'limit': limit, 'extra_vars': extra_vars ]
def id = null
remote.request(POST) { req ->
uri.path = "/api/v1/jobs/"
requestContentType = ContentType.JSON
body = messageBody
headers.'Authorization' = "Basic ${"$user:$password".bytes.encodeBase64().toString()}"
response.success = { resp, json ->
id = json.id
println "Job ${json.id} created: status ${resp.status}"
}
response.failure = { resp -> println "Request failed with status ${resp.status}" }
}
return id
}
void startJob(String url, String id, String user, String password ) {
def remote = new HTTPBuilder(url)
remote.request(POST) { req ->
uri.path = "/api/v1/jobs/"+id+"/start/"
requestContentType = ContentType.JSON
headers.'Authorization' = "Basic ${"$user:$password".bytes.encodeBase64().toString()}"
response.success = { resp, json ->
println "Job ${id} started: status ${resp.status}"
}
response.failure = { resp -> println "Request failed with status ${resp.status}" }
}
}
public getJob(String url, String id, String user, String password ) {
def remote = new HTTPBuilder(url)
def jobOutput = null
remote.request(GET) { req ->
uri.path = "/api/v1/jobs/"+id+"/"
uri.query = [page_size:'1000']
requestContentType = ContentType.JSON
headers.'Authorization' = "Basic ${"$user:$password".bytes.encodeBase64().toString()}"
response.success = { resp, json ->
jobOutput = json
}
response.failure = { resp -> println "Request failed with status ${resp.status}" }
}
return jobOutput
}
public getJobTemplate(String url, String query, String user, String password ) {
def remote = new HTTPBuilder(url)
def jobTemplate = null
remote.request(GET) { req ->
uri.path = "/api/v1/job_templates/${query}/"
uri.query = [page_size:'1000']
requestContentType = ContentType.JSON
headers.'Authorization' = "Basic ${"$user:$password".bytes.encodeBase64().toString()}"
response.success = { resp, json ->
jobTemplate = json
}
response.failure = { resp -> println "Request failed with status ${resp.status}"
}
}
return jobTemplate
}
public Map JenkinsControl (String user, String password, String applicationCSV, String customLimit, String repository, String build, String serviceStartup = null) {
def url = "http://ansible/"
def name = "Automated deploy"
//This is what will be provided to the jenkins job as output
//Should use logger class http://stackoverflow.com/questions/7742472/groovy-script-in-jenkins-println-output-disappears-when-called-inside-class-envi
//Split list of job_templates to execute
String[] applicationsList = applicationCSV.split(",")
def jobStatus = [:]
applicationsList.each() { application ->
//Use the app name to find the ansible job_template id
//For some reason the built in api queries aren't working
//def String query = "?name__contains=HelloWorldLinux"
def query = ""
def String job_template_id = null
def job_template = getJobTemplate(url, query, user, password)
//Iterate through results to find id
def int count = 0
job_template.results.each() { job ->
if (job.name.equals(application.toString())) {
job_template_id = job.id
count ++
}
}
if (!(count.equals(1))) {
println "${count} ansible job templates match ${application}"
return
}
//Get job_template so that we can make modifications
def jobTemplateConfig = getJobTemplate(url, job_template_id, user, password)
def extra_vars = jobTemplateConfig.extra_vars
//Convert json to map
// This will throw an error if extra_vars == null
// host_limit must always be defined in extra_vars
def slurper = new JsonSlurper()
def map = slurper.parseText(extra_vars)
def host_limit = map.host_limit + customLimit
//Update extra_vars
//Test to see if repo, build already assigned
map << ['repository':repository]
map << ['build':build]
map << ['host_limit':host_limit]
if (serviceStartup != null ) {
map << ['serviceStartup':serviceStartup]
}
//Not sure why the \n is needed at the end of extra_vars but the jobs fail without it
extra_vars = new JsonBuilder( map ).toString()+"\n"
def limit = jobTemplateConfig.limit
name = "${application} ${limit}"
//println "url ${url} name ${name} job_template_id ${job_template_id} limit ${limit} extra_vars ${extra_vars}"
def String id = launchJob( url, name, job_template_id, limit, extra_vars, user, password)
//Check to see if id null empty meaning there was a bad response from the post
if (id == null) {
println "Unable to launch job with job template id ${job_template_id}"
return
}
//Retrieve job output
def jobOutput = getJob(url, id, user, password)
if (jobOutput == null) {
//test to see if jobOutput is null
println "jobOutput is null. Launch job probably failed, check permissions"
return
}
//Wait for job to complete
def int counter = 0
while (jobOutput.finished == null ) {
jobOutput = getJob(url, id, user, password)
println jobOutput.status
Thread.sleep(10000);
counter ++
// 25 minutes * 60 seconds / 10 seconds per check = 150 counters
if ( counter > 150 ) {
break
}
}
println jobOutput.result_stdout
jobStatus.put(jobOutput.name, jobOutput.status)
}
return jobStatus;
}
def jobStatus
if (parameterMap.containsKey('serviceStartup') ) {
jobStatus = JenkinsControl(user, password, parameterMap['applications'], parameterMap['environment'], parameterMap['repository'], parameterMap['build'], parameterMap['serviceStartup'] )
}
else {
jobStatus = JenkinsControl(user, password, parameterMap['applications'], parameterMap['environment'], parameterMap['repository'], parameterMap['build'] )
}
println("\n\n\n******* Ansible Status *********")
jobStatus.each{ job,status ->
println("${job}: ${status}")
if( status == "failed" ){
build.result = Result.FAILURE
}
}
println("\n\n\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment