Implementation of CLIHelper

#!groovy

/*--------------------------------------------------------------------------------------------------
 *
 * Copyright (C) 2018, HERE Global B.V.
 *
 * These coded instructions, statements, and computer programs contain
 * unpublished proprietary information of HERE Global B.V., and are copy
 * protected by law. They may not be disclosed to third parties or copied
 * or duplicated in any form, in whole or in part, without the specific,
 * prior written permission of HERE Global B.V.
 *
 *--------------------------------------------------------------------------------------------------
 */

package com.here.platform.ci

// More information: https://github.com/jenkinsci/workflow-cps-plugin/blob/master/README.md#technical-design
import com.cloudbees.groovy.cps.NonCPS

/**
 * Helpers class which implements an abstraction on top of OLP CLI for Jenkins
 */
class CLIHelper implements Serializable {

    private context
    private cleanup_list
    private envs
    private sdk_version
    private olp_cli_path

    /**
     * Constructor.
     */
    public CLIHelper(context) {
        this.context = context
        this.envs = context.env
        this.cleanup_list = []
    }

    public String quote(String quoted) {
        if (quoted.contains(" ")) {
            return "\"${quoted}\""
        } else {
            return quoted
        }
    }

    public String optional(String param, String str) {
        if (str == null) {
            return ""
        } else {
            if (param.isEmpty()) {
                return str
            } else {
                return "${param} ${str}"
            }
        }
    }

    /**
     * Creates a catalog
     * @param id a suggestion for Data Service to use when generating HRN
     * @param name catalog name
     * @param summary catalog summary
     * @param args additional parameters passed to the CLI
     * @param cleanup controls whether the catalog should be added to cleanup list
     * @return catalog hrn
     */
    public String createCatalog(String id, String name, String summary,
                                String args = "") {
        String hrn = json(
                "olp catalog create ${id} ${name} "
                        + "--summary ${quote(summary)} ${args} "
        ).hrn
        cleanup_list.add("olp catalog delete ${hrn}")
        return hrn
    }

    /**
     * Returns the most recent pipeline job or empty map if none was found
     * @param pipeline_id
     * @param version_id
     * @return
     */
    public Map getLastPipelineVersionJob(String pipeline_id, String version_id) {
        context.echo("Showing pipeline jobs")
        def json_obj = json(
                "olp pipeline version job list ${pipeline_id} ${version_id}")
                .pipelineVersionJobs
        if (json_obj.size() > 0) {
            context.echo("Pipeline job found ${json_obj[0]}")
            return json_obj[0]
        } else {
            context.echo("No pipeline jobs found were found")
            def result = [:]
            return result
        }
    }

    @NonCPS
    public String getCurrentVersionId(pipeline_versions) {
        context.echo("Getting current version Id")
        for (int i = 0; i < pipeline_versions.size(); i++) {
            if (pipeline_versions[i] == "running" || pipeline_versions[i] == "scheduled") {
                context.echo("Found Current Version Id ${pipeline_versions[i].id}")
                return pipeline_versions[i].id
            }
        }
        context.echo("Current Version ID not found")
        return ""
    }

    /**
     * Prepares a catalog for using in pipeline
     * @param deployment
     * @param catalog_configurations_path
     * @param prefix
     * @return
     */
    public String prepareCatalog(
            String catalog_configurations_path,
            Map deployment,
            String catalog_prefix) {
        def catalog = { param -> deployment["${catalog_prefix}.${param}"].replaceAll('\"', "") }

        String hrn = "";
        String method = catalog("method")
        if (method == "create") {
            hrn = json(
                    "olp catalog create ${catalog("id")}${optional("", deployment.suffix)} ${catalog("name")} "
                            + "--summary ${quote(catalog("summary"))}").hrn
            cleanup_list.add("olp catalog delete ${hrn}")
            run(
                    "olp catalog update ${hrn} --config ${catalog_configurations_path}/${catalog("config")} "
                            + "--name ${catalog("name")}")
            run(
                    "olp catalog permission grant ${hrn} "
                            + "--group ${deployment.group_id} "
                            + "--read --write --share --manage")
        } else if (method == "use") {
            hrn = catalog("hrn")
        } else {
            context.error("Unsupported method for catalog ${catalog_prefix}: ${method}")
        }
        return hrn
    }

    private void clearFile(file) {
        context.sh("echo > ${file}")
    }

    private void addProperty(key, value, file) {
        context.sh("echo \'${key} = \"${value}\"\' >> ${file}")
    }
    /**
     * Prepares pipeline-config.conf file for the specified deployment recipe
     *
     * @param pipeline_config_path Path to the created file
     * @param catalog_configurations_path Path to the catalog configuration directory
     * @param deployment Deployment description
     * @return
     */
    public Map preparePipelineConfig(
            String pipeline_config_path,
            String catalog_configurations_path,
            Map deployment) {
        Map hrns = [:]
        // Create empty file
        clearFile(pipeline_config_path)
        // Add input catalogs
        def input_catalogs = deployment.input_catalog_ids.split(" ")
        input_catalogs.each { id ->
            def id_stripped = id.replaceAll('\"', "")
            hrns[id_stripped] = prepareCatalog(
                    catalog_configurations_path,
                    deployment,
                    "input-catalogs.${id_stripped}")
            addProperty("pipeline.config.input-catalogs.${id_stripped}.hrn", hrns[id_stripped], pipeline_config_path)
        }
        // Add output catalog
        hrns["output"] = prepareCatalog(
                catalog_configurations_path,
                deployment,
                "output-catalog")
        addProperty("pipeline.config.output-catalog.hrn", hrns["output"], pipeline_config_path)
        return hrns
    }

    /**
     * Deploys a new version of the pipeline
     * @param deployment deployment description
     * @param artifact_path path to fat JAR uploaded to Pipeline Service
     * @param pipeline_config_path path to pipeline-config.conf file
     * @return a map containing keys pipeline_id and version_id
     */
    public Map deployPipeline(Map deployment, artifact_path, pipeline_config_path) {
        String prefix = ""
        if (deployment.prefix != null) {
            prefix = deployment.prefix
        }
        String suffix = ""
        if (deployment.suffix != null) {
            suffix = deployment.suffix
        }

        def result = [:]

        if (deployment.pipeline_id == null) {
            result["pipeline_id"] = json(
                    "olp pipeline create "
                            + "${quote(prefix + deployment.pipeline_name + suffix)} ${deployment.group_id} "
                            + optional("--description", quote(deployment.pipeline_description))).id
            cleanup_list.add("olp pipeline delete ${result["pipeline_id"]}")
        } else {
            result["pipeline_id"] = deployment.pipeline_id
        }

        result["template_id"] = json(
                "olp pipeline template create "
                        + "${quote(prefix + deployment.pipeline_template_name + suffix)} "
                        + "${deployment.pipeline_type} ${artifact_path} ${deployment.class_name} "
                        + "${deployment.group_id} "
                        + "--input-catalog-ids ${deployment.input_catalog_ids}").id
        cleanup_list.add("olp pipeline template delete ${result["template_id"]}")

        result["version_id"] = json(
                "olp pipeline version create "
                        + "jenkins-created-version${suffix} ${result["pipeline_id"]} ${result["template_id"]} "
                        + pipeline_config_path + " "
                        + optional("", deployment.pipeline_version_options)).id
        cleanup_list.add("olp pipeline version delete ${result["pipeline_id"]} ${result["version_id"]}")
        return result
    }

    /** Clean up the data provisioned using CLI helper
     *
     *  The clean up is exexcuted in the order reverse to the order of commands that created
     *  removed objects.
     */
    @NonCPS
    public void cleanUp() {
        cleanup_list.reverseEach { command ->
            context.echo("Executing cleanup command: ${command}")
            try {
                run(command)
            } catch (Exception e) {
                context.echo("Failed to clean up the resource.")
            }
        }
    }

    public void getOlpCliFromSDK(String sdk_version, String mavenSettings = "-q -s \$MAVEN_SETTINGS") {
        this.sdk_version = sdk_version
        this.olp_cli_path = "${envs.WORKSPACE}/target/dependency/sdk-${this.sdk_version}/tools/OLP_CLI/"

        context.sh(script:
                "mvn -B " + mavenSettings + " dependency:unpack " +
                        "-Dartifact=com.here.platform:sdk:${sdk_version}:zip " +
                        "-Dproject.basedir=${envs.WORKSPACE}")
    }

    public Map json(String command) {
        def cliOutput =
                context.withEnv(["PATH=${this.olp_cli_path}:${envs.PATH}"]) {
                    context.sh(
                            script: "${command} --json",
                            returnStdout: true).trim()
                }
        return context.readJSON(text: cliOutput)
    }

    public String run(String command) {
        def cliOutput =
                context.withEnv(["PATH=${this.olp_cli_path}:${envs.PATH}"]) {
                    context.sh(
                            script: command,
                            returnStdout: true).trim()
                }
        return cliOutput
    }
}

results matching ""

    No results matching ""