|  | package com.mirantis.mk | 
|  | /** | 
|  | * | 
|  | * HTTP functions | 
|  | * | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * Make generic HTTP call and return parsed JSON | 
|  | * | 
|  | * @param url       URL to make the request against | 
|  | * @param method    HTTP method to use (default GET) | 
|  | * @param data      JSON data to POST or PUT | 
|  | * @param headers   Map of additional request headers | 
|  | * @param read_timeout http session read timeout | 
|  | */ | 
|  | @NonCPS | 
|  | def sendHttpRequest(url, method = 'GET', data = null, headers = [:], read_timeout=-1) { | 
|  | def connection = new URL(url).openConnection() | 
|  |  | 
|  | if (read_timeout != -1){ | 
|  | connection.setReadTimeout(read_timeout*1000) | 
|  | } | 
|  | if (method != 'GET') { | 
|  | connection.setRequestMethod(method) | 
|  | } | 
|  |  | 
|  | if (data) { | 
|  | headers['Content-Type'] = 'application/json' | 
|  | } | 
|  |  | 
|  | headers['User-Agent'] = 'jenkins-groovy' | 
|  | headers['Accept'] = 'application/json' | 
|  |  | 
|  | for (header in headers) { | 
|  | connection.setRequestProperty(header.key, header.value) | 
|  | } | 
|  |  | 
|  | if (data) { | 
|  | connection.setDoOutput(true) | 
|  | if (data instanceof String) { | 
|  | dataStr = data | 
|  | } else { | 
|  | dataStr = new groovy.json.JsonBuilder(data).toString() | 
|  | } | 
|  | if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){ | 
|  | println("[HTTP] Request URL: ${url}, method: ${method}, headers: ${headers}, content: ${dataStr}") | 
|  | } | 
|  | def output = new OutputStreamWriter(connection.outputStream) | 
|  | output.write(dataStr) | 
|  | output.close() | 
|  | } | 
|  |  | 
|  | if ( connection.responseCode == 200 ) { | 
|  | response = connection.inputStream.text | 
|  | try { | 
|  | response_content = new groovy.json.JsonSlurperClassic().parseText(response) | 
|  | } catch (groovy.json.JsonException|java.lang.NullPointerException e) { | 
|  | if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){ | 
|  | println("[HTTP] Cought exception while trying parsing response as JSON: ${e}") | 
|  | } | 
|  | response_content = response | 
|  | } | 
|  | if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){ | 
|  | println("[HTTP] Response: code ${connection.responseCode}") | 
|  | } | 
|  | return response_content | 
|  | } else { | 
|  | if(env.getEnvironment().containsKey('DEBUG') && env['DEBUG'] == "true"){ | 
|  | println("[HTTP] Response: code ${connection.responseCode}") | 
|  | } | 
|  | throw new Exception(connection.responseCode + ": " + connection.inputStream.text) | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP GET request | 
|  | * | 
|  | * @param url     URL which will requested | 
|  | * @param data    JSON data to PUT | 
|  | */ | 
|  | def sendHttpGetRequest(url, data = null, headers = [:]) { | 
|  | return sendHttpRequest(url, 'GET', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP POST request | 
|  | * | 
|  | * @param url     URL which will requested | 
|  | * @param data    JSON data to PUT | 
|  | * @param read_timeout http session read timeout | 
|  | */ | 
|  | def sendHttpPostRequest(url, data = null, headers = [:], read_timeout=-1) { | 
|  | return sendHttpRequest(url, 'POST', data, headers, read_timeout) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP PUT request | 
|  | * | 
|  | * @param url     URL which will requested | 
|  | * @param data    JSON data to PUT | 
|  | */ | 
|  | def sendHttpPutRequest(url, data = null, headers = [:]) { | 
|  | return sendHttpRequest(url, 'PUT', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP DELETE request | 
|  | * | 
|  | * @param url     URL which will requested | 
|  | * @param data    JSON data to PUT | 
|  | */ | 
|  | def sendHttpDeleteRequest(url, data = null, headers = [:]) { | 
|  | return sendHttpRequest(url, 'DELETE', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make generic call using REST API and return parsed JSON | 
|  | * | 
|  | * @param base    connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri     URI which will be appended to connection base URL | 
|  | * @param method  HTTP method to use (default GET) | 
|  | * @param data    JSON data to POST, PUT or PATCH | 
|  | * @param headers Map of additional request headers | 
|  | */ | 
|  | def restCall(base, uri, method = 'GET', data = null, headers = [:]) { | 
|  | def connection = new URL("${base.url}${uri}").openConnection() | 
|  | if (method != 'GET') { | 
|  | connection.setRequestMethod(method) | 
|  | } | 
|  |  | 
|  | connection.setRequestProperty('User-Agent', 'jenkins-groovy') | 
|  | connection.setRequestProperty('Accept', 'application/json') | 
|  | if (base.authToken) { | 
|  | // XXX: removeme, explicitly use headers instead | 
|  | connection.setRequestProperty('X-Auth-Token', base.authToken) | 
|  | } | 
|  |  | 
|  | for (header in headers) { | 
|  | connection.setRequestProperty(header.key, header.value) | 
|  | } | 
|  |  | 
|  | if (data) { | 
|  | connection.setDoOutput(true) | 
|  | if (data instanceof String) { | 
|  | dataStr = data | 
|  | } else { | 
|  | connection.setRequestProperty('Content-Type', 'application/json') | 
|  | dataStr = new groovy.json.JsonBuilder(data).toString() | 
|  | } | 
|  | def out = new OutputStreamWriter(connection.outputStream) | 
|  | out.write(dataStr) | 
|  | out.close() | 
|  | } | 
|  |  | 
|  | if ( connection.responseCode >= 200 && connection.responseCode < 300 ) { | 
|  | def res = connection.inputStream.text | 
|  | try { | 
|  | return new groovy.json.JsonSlurperClassic().parseText(res) | 
|  | } catch (Exception e) { | 
|  | return res | 
|  | } | 
|  | } else { | 
|  | throw new Exception(connection.responseCode + ": " + connection.inputStream.text) | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make GET request using REST API and return parsed JSON | 
|  | * | 
|  | * @param base  connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri   URI which will be appended to server base URL | 
|  | */ | 
|  | def restGet(base, uri, data = null, headers = [:]) { | 
|  | return restCall(base, uri, 'GET', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make POST request using REST API and return parsed JSON | 
|  | * | 
|  | * @param base  connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri   URI which will be appended to server base URL | 
|  | * @param data  JSON Data to POST | 
|  | */ | 
|  | def restPost(base, uri, data = null, headers = ['Accept': '*/*']) { | 
|  | return restCall(base, uri, 'POST', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make PUT request using REST API and return parsed JSON | 
|  | * | 
|  | * @param base  connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri   URI which will be appended to server base URL | 
|  | * @param data  JSON Data to PUT | 
|  | */ | 
|  | def restPut(base, uri, data = null, headers = ['Accept': '*/*']) { | 
|  | return restCall(base, uri, 'PUT', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make PATCH request using REST API and return parsed JSON | 
|  | * | 
|  | * @param base  connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri   URI which will be appended to server base URL | 
|  | * @param data  JSON Data to PUT | 
|  | */ | 
|  | def restPatch(base, uri, data = null, headers = ['Accept': '*/*']) { | 
|  | return restCall(base, uri, 'PATCH', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make DELETE request using REST API and return parsed JSON | 
|  | * | 
|  | * @param base  connection object, map with 'url' and optional 'authToken' keys | 
|  | * @param uri   URI which will be appended to server base URL | 
|  | */ | 
|  | def restDelete(base, uri, data = null, headers = [:]) { | 
|  | return restCall(base, uri, 'DELETE', data, headers) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Set HTTP and HTTPS proxy for running JVM | 
|  | * @param host HTTP proxy host | 
|  | * @param port HTTP proxy port | 
|  | * @param nonProxyHosts proxy excluded hosts, optional, default *.local | 
|  | */ | 
|  | def enableHttpProxy(host, port, nonProxyHosts="*.local"){ | 
|  | System.getProperties().put("proxySet", "true") | 
|  | System.getProperties().put("http.proxyHost", host) | 
|  | System.getProperties().put("http.proxyPort", port) | 
|  | System.getProperties().put("https.proxyHost", host) | 
|  | System.getProperties().put("https.proxyPort", port) | 
|  | System.getProperties().put("http.nonProxyHosts", nonProxyHosts) | 
|  | System.getProperties().put("https.nonProxyHosts", nonProxyHosts) | 
|  | } | 
|  | /** | 
|  | * Disable HTTP and HTTPS proxy for running JVM | 
|  | */ | 
|  | def disableHttpProxy(){ | 
|  | System.getProperties().put("proxySet", "false") | 
|  | System.getProperties().remove("http.proxyHost") | 
|  | System.getProperties().remove("http.proxyPort") | 
|  | System.getProperties().remove("https.proxyHost") | 
|  | System.getProperties().remove("https.proxyPort") | 
|  | System.getProperties().remove("http.nonProxyHosts") | 
|  | System.getProperties().remove("https.nonProxyHosts") | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP request to the specified URL | 
|  | * | 
|  | * @param url       URL to do HTTP request to | 
|  | * @param method    HTTP method to execute (`GET` by default) | 
|  | * @param credsId   Jenkins credentials ID to use for authorization | 
|  | * @param pushData  Data to send | 
|  | * @param pushType  MIME-type of pushData | 
|  | * @param params    Custom HTTP-headers | 
|  | * | 
|  | * @return          Array containing return code and text | 
|  | * | 
|  | * @exception       org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException | 
|  | */ | 
|  | def methodCall(String url, String method = 'GET', String credsId = '', | 
|  | String pushData = '', String pushType = '', Map params = [:]) { | 
|  |  | 
|  | // Connection object | 
|  | def httpReq = new URI(url).normalize().toURL().openConnection() | 
|  | httpReq.setRequestMethod(method) | 
|  |  | 
|  | // Timeouts | 
|  | httpReq.setConnectTimeout(10*1000) // milliseconds | 
|  | httpReq.setReadTimeout(600*1000)   // milliseconds | 
|  |  | 
|  | // Add authentication data | 
|  | if (credsId) { | 
|  | String authHeader = '' | 
|  | def cred = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials( | 
|  | com.cloudbees.plugins.credentials.impl.BaseStandardCredentials.class, | 
|  | jenkins.model.Jenkins.instance).findAll {it.id == credsId}[0] | 
|  | if (cred.class == com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl.class) { | 
|  | authHeader = 'Basic ' + "${cred.getUsername()}:${cred.getPassword()}".getBytes('UTF-8').encodeBase64().toString() | 
|  | } else if (cred.class == org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl.class) { | 
|  | authHeader = 'Bearer ' + cred.getSecret() | 
|  | //params << ['X-JFrog-Art-Api': cred.getSecret()] | 
|  | } | 
|  | params << ['Authorization': authHeader] | 
|  | } | 
|  |  | 
|  | // Add custom headers if any | 
|  | for (param in params) { | 
|  | httpReq.setRequestProperty(param.key, param.value.toString()) | 
|  | } | 
|  |  | 
|  | // Do request | 
|  | try { | 
|  | if (pushData) { | 
|  | httpReq.setRequestProperty('Content-Type', pushType ?: 'application/x-www-form-urlencoded') | 
|  | if (method == 'GET') { // override incorrect method if pushData is passed | 
|  | httpReq.setRequestMethod('POST') | 
|  | } | 
|  | httpReq.setDoOutput(true) | 
|  | httpReq.getOutputStream().write(pushData.getBytes('UTF-8')) | 
|  | } else { | 
|  | httpReq.connect() | 
|  | } | 
|  | } catch (org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException e) { | 
|  | throw e // show sandbox errors | 
|  | } catch (Exception e) { | 
|  | echo "Cauhgt '${e.class.name}' error: ${e.getMessage()}" | 
|  | return [ -1, e.getMessage() ] | 
|  | } | 
|  |  | 
|  | // Handle return data | 
|  | int respCode = httpReq.getResponseCode() | 
|  | String respText = '' | 
|  | if (respCode >= 400) { | 
|  | respText = httpReq.getErrorStream().getText() ?: httpReq.getResponseMessage() | 
|  | } else { | 
|  | respText = httpReq.getInputStream().getText() | 
|  | } | 
|  |  | 
|  | // Return result as a tuple of response code and text | 
|  | return [respCode, respText] | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP GET request to the specified URL | 
|  | * | 
|  | * @param url       URL to do HTTP request to | 
|  | * @param credsId   Jenkins credentials ID to use for authorization | 
|  | * @param params    Custom HTTP-headers | 
|  | * | 
|  | * @return          Array containing return code and text | 
|  | */ | 
|  | def doGet(String url, String credsId = '', Map params = [:]) { | 
|  | return methodCall(url, 'GET', credsId, null, null, params) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP POST request to the specified URL | 
|  | * | 
|  | * @param url       URL to do HTTP request to | 
|  | * @param credsId   Jenkins credentials ID to use for authorization | 
|  | * @param pushData  Data to send | 
|  | * @param pushType  MIME-type of pushData | 
|  | * @param params    Custom HTTP-headers | 
|  | * | 
|  | * @return          Array containing return code and text | 
|  | */ | 
|  | def doPost(String url, String credsId = '', | 
|  | String pushData = '', String pushType = '', Map params = [:]) { | 
|  | return methodCall(url, 'POST', credsId, pushData, pushType, params) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP PUT request to the specified URL | 
|  | * | 
|  | * @param url       URL to do HTTP request to | 
|  | * @param credsId   Jenkins credentials ID to use for authorization | 
|  | * @param pushData  Data to send | 
|  | * @param pushType  MIME-type of pushData | 
|  | * @param params    Custom HTTP-headers | 
|  | * | 
|  | * @return          Array containing return code and text | 
|  | */ | 
|  | def doPut(String url, String credsId = '', | 
|  | String pushData = '', String pushType = '', Map params = [:]) { | 
|  | return methodCall(url, 'PUT', credsId, pushData, pushType, params) | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make HTTP DELETE request to the specified URL | 
|  | * | 
|  | * @param url       URL to do HTTP request to | 
|  | * @param credsId   Jenkins credentials ID to use for authorization | 
|  | * @param params    Custom HTTP-headers | 
|  | * | 
|  | * @return          Array containing return code and text | 
|  | */ | 
|  | def doDelete(String url, String credsId = '', Map params = [:]) { | 
|  | return methodCall(url, 'DELETE', credsId, null, null, params) | 
|  | } |