Merge "Add Mos-Tf deploy trigger"
diff --git a/src/com/mirantis/mk/KaasUtils.groovy b/src/com/mirantis/mk/KaasUtils.groovy
index 4b53487..4ade7d8 100644
--- a/src/com/mirantis/mk/KaasUtils.groovy
+++ b/src/com/mirantis/mk/KaasUtils.groovy
@@ -65,6 +65,7 @@
     def runMgmtConformance = env.RUN_MGMT_CFM ? env.RUN_MGMT_CFM.toBoolean() : false
     def runLMATest = env.RUN_LMA_TEST ? env.RUN_LMA_TEST.toBoolean() : false
     def runMgmtUserControllerTest = env.RUN_MGMT_USER_CONTROLLER_TEST ? env.RUN_MGMT_USER_CONTROLLER_TEST.toBoolean() : false
+    def runProxyChildTest = env.RUN_PROXY_CHILD_TEST ? env.RUN_PROXY_CHILD_TEST : false
     def runChildConformance = env.RUN_CHILD_CFM ? env.RUN_CHILD_CFM.toBoolean() : false
     def fetchServiceBinaries = env.FETCH_BINARIES_FROM_UPSTREAM ? env.FETCH_BINARIES_FROM_UPSTREAM.toBoolean() : false
     def equinixMetalV2ChildDiffMetro = env.EQUINIXMETALV2_CHILD_DIFF_METRO ? env.EQUINIXMETALV2_CHILD_DIFF_METRO.toBoolean() : false
@@ -93,6 +94,7 @@
     def enableVsphereDemo = true
     def enableOSDemo = true
     def enableBMDemo = true
+    def enableArtifactsBuild = true
     def openstackIMC = env.OPENSTACK_CLOUD_LOCATION ? env.OPENSTACK_CLOUD_LOCATION : 'us'
 
     def commitMsg = env.GERRIT_CHANGE_COMMIT_MESSAGE ? new String(env.GERRIT_CHANGE_COMMIT_MESSAGE.decodeBase64()) : ''
@@ -103,7 +105,7 @@
     if (commitMsg ==~ /(?s).*\[seed-macos\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*seed-macos.*/) {
         seedMacOs = true
     }
-    if (commitMsg ==~ /(?s).*\[child-deploy\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*child-deploy.*/ || upgradeChild || runChildConformance) {
+    if (commitMsg ==~ /(?s).*\[child-deploy\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*child-deploy.*/ || upgradeChild || runChildConformance || runProxyChildTest) {
         deployChild = true
     }
     if (commitMsg ==~ /(?s).*\[child-upgrade\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*child-upgrade.*/) {
@@ -160,6 +162,11 @@
     if (commitMsg ==~ /(?s).*\[test-user-controller\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*test-user-controller.*/) {
         runMgmtUserControllerTest = true
     }
+    if (commitMsg ==~ /(?s).*\[test-proxy-child\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*test-proxy-child.*/) {
+        runProxyChildTest = true
+        deployChild = true
+        common.infoMsg('Child cluster deployment will be enabled since proxy child test suite will be executed')
+    }
     if (commitMsg ==~ /(?s).*\[child-cfm\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*child-cfm.*/) {
         runChildConformance = true
         deployChild = true
@@ -232,6 +239,11 @@
         common.errorMsg('vSphere demo deployment will be aborted, VF -1 will be set')
     }
 
+    if (commitMsg ==~ /(?s).*\[disable-artifacts-build\].*/ || env.GERRIT_EVENT_COMMENT_TEXT ==~ /(?s).*disable-artifacts-build\.*/) {
+        enableArtifactsBuild = false
+        common.errorMsg('artifacts build will be aborted, VF -1 will be set')
+    }
+
     // TODO (vnaumov) remove below condition after moving all releases to UCP
     def ucpChildMatches = (commitMsg =~ /(\[child-ucp\s*ucp-.*?\])/)
     if (ucpChildMatches.size() > 0) {
@@ -334,6 +346,7 @@
         Mgmt user controller testing scheduled: ${runMgmtUserControllerTest}
         Mgmt UI e2e testing scheduled: ${runUie2e}
         Maintenance test: ${runMaintenanceTest}
+        Child proxy test: ${runProxyChildTest}
         AWS provider deployment scheduled: ${awsOnDemandDemo}
         Equinix provider deployment scheduled: ${equinixOnDemandDemo}
         EquinixmetalV2 provider deployment scheduled: ${equinixMetalV2OnDemandDemo}
@@ -344,6 +357,7 @@
         VSPHERE provider deployment scheduled: ${enableVsphereDemo}
         OS provider deployment scheduled: ${enableOSDemo}
         BM provider deployment scheduled: ${enableBMDemo}
+        Artifacts build scheduled: ${enableArtifactsBuild}
         Multiregional configuration: ${multiregionalMappings}
         Service binaries fetching scheduled: ${fetchServiceBinaries}
         Current weight of the demo run: ${demoWeight} (Used to manage lockable resources)
@@ -371,6 +385,7 @@
         runMaintenanceTestEnable             : runMaintenanceTest,
         runLMATestEnabled                    : runLMATest,
         runMgmtUserControllerTestEnabled     : runMgmtUserControllerTest,
+        runProxyChildTestEnabled             : runProxyChildTest,
         fetchServiceBinariesEnabled          : fetchServiceBinaries,
         awsOnDemandDemoEnabled               : awsOnDemandDemo,
         equinixOnDemandDemoEnabled           : equinixOnDemandDemo,
@@ -383,6 +398,7 @@
         vsphereOnDemandDemoEnabled           : enableVsphereDemo, // TODO: remove after MCC 2.7 is out
         bmDemoEnabled                        : enableBMDemo,
         osDemoEnabled                        : enableOSDemo,
+        artifactsBuildEnabled                : enableArtifactsBuild,
         multiregionalConfiguration           : multiregionalMappings,
         demoWeight                           : demoWeight]
 }
@@ -649,6 +665,7 @@
         booleanParam(name: 'RUN_MGMT_USER_CONTROLLER_TEST', value: triggers.runMgmtUserControllerTestEnabled),
         booleanParam(name: 'DEPLOY_CHILD_CLUSTER', value: triggers.deployChildEnabled),
         booleanParam(name: 'UPGRADE_CHILD_CLUSTER', value: triggers.upgradeChildEnabled),
+        booleanParam(name: 'RUN_PROXY_CHILD_TEST', value: triggers.runProxyChildTestEnabled),
         booleanParam(name: 'ATTACH_BYO', value: triggers.attachBYOEnabled),
         booleanParam(name: 'UPGRADE_BYO', value: triggers.upgradeBYOEnabled),
         booleanParam(name: 'RUN_BYO_MATRIX', value: triggers.runBYOMatrixEnabled),
@@ -830,3 +847,95 @@
             error('Net map locks supported for Equinix/Vsphere providers only')
     }
 }
+
+/**
+* getCIKeywordsFromCommitMsg parses commit message and returns all gerrit keywords with their values as a list of maps.
+* Each element (map) contains keys 'key' for keyword name and 'value' for its value.
+* If keyword contains only 'key' part then 'value' is boolean True.
+* This function does not perform keywords validation.
+* First line of a commit message is ignored.
+* To use '[' or ']' characters inside keyword prepend it with backslash '\'.
+* TODO: Remove backslash chars from values if they prepend '[' or ']'.
+**/
+
+List getCIKeywordsFromCommitMsg() {
+    String commitMsg = env.GERRIT_CHANGE_COMMIT_MESSAGE ? new String(env.GERRIT_CHANGE_COMMIT_MESSAGE.decodeBase64()) : ''
+    List commitMsgLines = commitMsg.split('\n')
+    List keywords = []
+    if (commitMsgLines.size() < 2) {
+        return keywords
+    }
+
+    String commitMsgBody = commitMsgLines[1..-1].join('\n')
+
+    // Split commit message body to chunks using '[' or ']' as delimiter,
+    // ignoring them if prepended by backslash (regex negative lookbehind).
+    // Resulting list will have chunks between '[' and ']' at odd indexes.
+    List parts = commitMsgBody.split(/(?<!\\)[\[\]]/)
+
+    // Iterate chunks by odd indexes only, trim values and split to
+    // <key> / <value> pair where <key> is the part of a sting before the first
+    // whitespace delimiter, and <value> is the rest (may include whitespaces).
+    // If there is no whitespace in the string then this is a 'switch'
+    // and <value> will be boolean True.
+    for (i = 1; i < parts.size(); i += 2) {
+        def (key, value) = (parts[i].trim().split(/\s+/, 2) + [true, ])[0..1]
+        keywords.add(['key': key, 'value': value])
+    }
+
+    return keywords
+}
+
+/**
+* getJobsParamsFromCommitMsg parses list of CI keywords and returns values of 'job-params' keyword
+* that were specified for given job name. `job-params` keyword has the following structure
+*
+*   [job-params <job name> <parameter name> <parameter value>]
+*
+* Return value is a Map that contains those parameters using the following structure:
+*
+*    <job name>:
+*       <parameter name>: <parameter value>
+*
+**/
+Map getJobsParamsFromCommitMsg() {
+    List keywords = getCIKeywordsFromCommitMsg()
+
+    List jobsParamsList = []
+    keywords.findAll{ it.key == 'job-params' }.collect(jobsParamsList) {
+        def (name, params) = (it['value'].split(/\s+/, 2) + [null, ])[0..1]
+        def (key, value) = params.split(/\s+/, 2)
+        ['name': name, 'key': key, 'value': value]
+    }
+
+    Map jobsParams = jobsParamsList.inject([:]) { result, it ->
+        if (!result.containsKey(it.name)) {
+            result[it.name] = [:]
+        }
+        result[it.name][it.key] = it.value
+        result
+    }
+
+    return jobsParams
+}
+
+
+/**
+* getJobParamsFromCommitMsg returns key:value Map of parameters set for a job in commit message.
+* It uses getJobsParamsFromCommitMsg to get all parameters from commit message and then
+* uses only those parametes that were set to all jobs (with <job name> == '*') or to
+* a particular job. Parameters set to a particular job have higher precedence.
+*
+* Return value is a Map that contains those parameters:
+*
+*    <parameter name>: <parameter value>
+*
+**/
+Map getJobParamsFromCommitMsg(String jobName) {
+    jobsParams = getJobsParamsFromCommitMsg()
+    jobParams = jobsParams.getOrDefault('*', [:])
+    if (jobName) {
+        jobParams.putAll(jobsParams.getOrDefault(jobName, [:]))
+    }
+    return jobParams
+}