From 184b90d79b6b77e00b3634494e9789f05f9950d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Mass=C3=A9?= Date: Wed, 22 May 2019 09:36:39 +0200 Subject: [PATCH] move to its own repo --- 3scale_toolbox.groovy | 296 ------------------------------------------ 1 file changed, 296 deletions(-) delete mode 100644 3scale_toolbox.groovy diff --git a/3scale_toolbox.groovy b/3scale_toolbox.groovy deleted file mode 100644 index 79bf236..0000000 --- a/3scale_toolbox.groovy +++ /dev/null @@ -1,296 +0,0 @@ -#!groovy - -def importOpenAPI(Map conf) { - assert conf.destination != null - assert conf.baseSystemName != null - assert conf.oasFile != null - - // Read the OpenAPI Specification file - def openAPI = readOpenAPISpecificationFile(conf.oasFile) - assert openAPI.swagger == "2.0" - def version = openAPI.info.version - assert version != null - def major = version.tokenize(".")[0] - def baseName = basename(conf.oasFile) - - // Compute the target system_name - def targetSystemName = (conf.environmentName != null ? "${conf.environmentName}_" : "") + conf.baseSystemName + "_${major}" - - def commandLine = "3scale import openapi -t ${targetSystemName} -d ${conf.destination} /artifacts/${baseName}" - def result = runToolbox(commandLine: commandLine, - jobName: "import", - openAPI: [ - "filename": baseName, - "content": readFile(conf.oasFile) - ], - toolboxConfig: conf.toolboxConfig) - echo result.stdout -} - -def basename(path) { - return path.drop(path.lastIndexOf("/") != -1 ? path.lastIndexOf("/") : 0) -} - -def readOpenAPISpecificationFile(fileName) { - if (fileName.toLowerCase().endsWith(".json")) { - return readJSON(file: fileName) - } else if (fileName.toLowerCase().endsWith(".yaml") || fileName.toLowerCase().endsWith(".yml")) { - return readYaml(file: fileName) - } else { - throw new Exception("Can't decide between JSON and YAML on ${fileName}") - } -} - -def getToolboxVersion() { - def result = runToolbox(commandLine: "3scale -v", - jobName: "version") - return result.stdout -} - -def generateRandomBaseSystemName() { - String alphabet = (('A'..'N')+('P'..'Z')+('a'..'k')+('m'..'z')+('2'..'9')).join() - def length = 6 - id = new Random().with { - (1..length).collect{ alphabet[nextInt(alphabet.length())] }.join() - } - return "testcase_${id}" -} - -def runToolbox(Map conf) { - def result = null - - assert conf.jobName != null - assert conf.commandLine != null - - def defaultToolboxConf = [ - "toolboxConfig": null, - "openAPI": null, - "image": "quay.io/redhat/3scale-toolbox:v0.10.0", - "backoffLimit": 2, // three attempts (one first try + two retries) - "imagePullPolicy": "IfNotPresent", - "activeDeadlineSeconds": 90 - ] - - // Apply default values - conf = defaultToolboxConf + conf - - if (conf.toolboxConfig != null && conf.toolboxConfig.configFileId != null) { - // Generate a default secret name if none has been provided - if (conf.toolboxConfig.secretName == null) { - conf.toolboxConfig = [ - "configFileId": conf.toolboxConfig.configFileId, - "secretName": "3scale-toolbox-${JOB_BASE_NAME}" - ] - } - - echo "Creating a secret named ${conf.toolboxConfig.secretName} containing file ${conf.toolboxConfig.configFileId}..." - configFileProvider([configFile(fileId: conf.toolboxConfig.configFileId, variable: 'TOOLBOX_CONFIG')]) { - def toolboxConfig = readFile(TOOLBOX_CONFIG) - createSecret(conf.toolboxConfig.secretName, [ ".3scalerc.yaml": toolboxConfig ]) - } - } - - def oasConfigMapName = null - if (conf.openAPI != null) { - oasConfigMapName = "3scale-toolbox-${JOB_BASE_NAME}-${BUILD_NUMBER}-openapi" - echo "Creating a configMap named ${oasConfigMapName} containing the OpenAPI file..." - createConfigMap(oasConfigMapName, [ (conf.openAPI.filename): conf.openAPI.content ]) - } - - def jobName = "${JOB_BASE_NAME}-${BUILD_NUMBER}-${conf.jobName}" - def jobSpecs = [ - "apiVersion": "batch/v1", - "kind": "Job", - "metadata": [ - "name": jobName, - "labels": [ - "build": "${JOB_BASE_NAME}-${BUILD_NUMBER}", - "job": "${JOB_BASE_NAME}" - ] - ], - "spec": [ - "backoffLimit": conf.backoffLimit, - "activeDeadlineSeconds": conf.activeDeadlineSeconds, - "template": [ - "spec": [ - "restartPolicy": "Never", - "containers": [ - [ - "name": "job", - "image": conf.image, - "imagePullPolicy": conf.imagePullPolicy, - "command": [ "scl", "enable", "rh-ruby25", "/opt/rh/rh-ruby25/root/usr/local/bin/${conf.commandLine}" ], - "volumeMounts": [ - [ - "mountPath": "/opt/app-root/src/", - "name": "toolbox-config" - ], - [ - "mountPath": "/artifacts", - "name": "artifacts" - ] - - ] - ] - ], - "volumes": [ - [ - "name": "toolbox-config" - ], - [ - "name": "artifacts" - ] - ] - ] - ] - ] - ] - - // Inject the toolbox configuration as a volume - if (conf.toolboxConfig != null && conf.toolboxConfig.secretName != null) { - jobSpecs.spec.template.spec.volumes[0].secret = [ - "secretName": conf.toolboxConfig.secretName - ] - } else { - jobSpecs.spec.template.spec.volumes[0].emptyDir = [:] - } - - // Inject the OpenAPI file as a volume - if (oasConfigMapName != null) { - jobSpecs.spec.template.spec.volumes[1].configMap = [ - "name": oasConfigMapName - ] - } else { - jobSpecs.spec.template.spec.volumes[1].emptyDir = [:] - } - - def job = null - try { - job = openshift.create(jobSpecs) - - int jobTimeout = 2 + (int)(conf.activeDeadlineSeconds / 60.0f) - echo "Waiting ${jobTimeout} minutes for the job to complete..." - timeout(jobTimeout) { - // Wait for the job to complete, either Succeeded or Failed - job.watch { - def jobStatus = getJobStatus(it.object()) - echo "Job ${it.name()}: succeeded = ${jobStatus.succeeded}, failed = ${jobStatus.failed}, status = ${jobStatus.status}, reason = ${jobStatus.reason}" - - // Exit the watch loop when the Job has one successful pod or failed - return jobStatus.succeeded > 0 || jobStatus.status == "Failed" - } - } - } finally { - if (job != null) { - def jobStatus = getJobStatus(job.object()) - echo "job ${job.name()} has status '${jobStatus.status}' and reason '${jobStatus.reason}'" - - // Iterate over pods to find: - // - the pod that succeeded - // - as last resort, a pod that failed - def pods = job.related("pod") - pods.withEach { - if (it.object().status.phase == "Succeeded") { - result = getPodDetails(it) - } - if (it.object().status.phase == "Failed" && result == null) { - result = getPodDetails(it) - } - } - - if (result != null && result.podPhase == "Failed") { - echo "RC: ${result.status}" - echo "STDOUT:" - echo "-------" - echo result.stdout - echo "STDERR:" - echo "-------" - echo result.stderr - - error("job ${job.name()} exited with '${jobStatus.status}' and reason '${jobStatus.reason}'") - } - - // Delete the job - try { - openshift.selector('job', jobName).delete() - } catch (e2) { // Best effort - echo "cannot delete the job ${jobName}: ${e2}" - } - } - - // Delete the temporary configMap containing the OAS file - if (oasConfigMapName != null) { - try { - openshift.selector('configMap', oasConfigMapName).delete() - } catch (e2) { // Best effort - echo "cannot delete the configMap ${oasConfigMapName}: ${e2}" - } - } - - // Delete the temporary secret - if (conf.toolboxConfig != null && conf.toolboxConfig.configFileId != null) { - try { - openshift.selector('secret', conf.toolboxConfig.secretName).delete() - } catch (e2) { // Best effort - echo "cannot delete the secret ${conf.toolboxConfig.secretName}: ${e2}" - } - } - } - - return result -} - -def getJobStatus(obj) { - return [ - "succeeded": obj.status.succeeded != null ? obj.status.succeeded : 0, - "failed": obj.status.failed != null ? obj.status.failed : 0, - "status": obj.status.conditions != null && obj.status.conditions.size() > 0 ? obj.status.conditions[0].type : "Unknown", - "reason": obj.status.conditions != null && obj.status.conditions.size() > 0 ? obj.status.conditions[0].reason : "" - ] -} -def getPodDetails(pod) { - def logs = pod.logs() - return [ - "status": logs.actions[0].status, - "stdout": logs.actions[0].out, - "stderr": logs.actions[0].err, - "podPhase": pod.object().status.phase, - "podName": pod.name() - ] -} - -def createConfigMap(configMapName, content) { - def configMapSpecs = [ - "apiVersion": "v1", - "kind": "ConfigMap", - "metadata": [ - "name": "${configMapName}", - "labels": [ - "job": "${JOB_BASE_NAME}", - "build": "${JOB_BASE_NAME}-${BUILD_NUMBER}" - ] - ], - "data": [:] - ] - content.each{ k, v -> configMapSpecs.data[k] = v } - openshift.apply(configMapSpecs) -} - -def createSecret(secretName, content) { - def secretSpecs = [ - "apiVersion": "v1", - "kind": "Secret", - "metadata": [ - "name": "${secretName}", - "labels": [ - "job": "${JOB_BASE_NAME}" - ] - ], - "stringData": [:] - ] - content.each{ k, v -> secretSpecs.stringData[k] = v } - openshift.apply(secretSpecs) -} - -// required to be loaded from a jenkins pipeline -return this;