Merge "Add possibility to use comments in 'tag-git-repos'"
diff --git a/cvp-func.groovy b/cvp-func.groovy
index d1fff1a..94f3eeb 100644
--- a/cvp-func.groovy
+++ b/cvp-func.groovy
@@ -35,7 +35,7 @@
             sh "rm -rf ${artifacts_dir}"
             salt.cmdRun(saltMaster, TARGET_NODE, "rm -rf ${remote_artifacts_dir}")
             salt.cmdRun(saltMaster, TARGET_NODE, "mkdir -p ${remote_artifacts_dir}")
-            validate.configureContainer(saltMaster, TARGET_NODE, PROXY, TOOLS_REPO, TEMPEST_REPO, TEMPEST_ENDPOINT_TYPE)
+            validate.configureContainer(saltMaster, TARGET_NODE, PROXY, TOOLS_REPO, TEMPEST_REPO, TEMPEST_ENDPOINT_TYPE, TEMPEST_VERSION)
         }
 
         stage('Run Tempest tests') {
diff --git a/generate-cookiecutter-products.groovy b/generate-cookiecutter-products.groovy
index 703620d..12dc88d 100644
--- a/generate-cookiecutter-products.groovy
+++ b/generate-cookiecutter-products.groovy
@@ -13,6 +13,11 @@
 saltModelTesting = new com.mirantis.mk.SaltModelTesting()
 ssh = new com.mirantis.mk.Ssh()
 
+def reclassVersion = 'v1.5.4'
+if (common.validInputParam('RECLASS_VERSION')) {
+  reclassVersion = RECLASS_VERSION
+}
+
 timeout(time: 12, unit: 'HOURS') {
   node("python&&docker") {
     def templateEnv = "${env.WORKSPACE}/template"
@@ -178,7 +183,7 @@
               testEnv,
               'pkg',
               'stable',
-              'master',
+              reclassVersion,
               0,
               false,
               false,
diff --git a/test-cookiecutter-reclass.groovy b/test-cookiecutter-reclass.groovy
index 5fe02db..66961f8 100644
--- a/test-cookiecutter-reclass.groovy
+++ b/test-cookiecutter-reclass.groovy
@@ -4,6 +4,11 @@
 python = new com.mirantis.mk.Python()
 saltModelTesting = new com.mirantis.mk.SaltModelTesting()
 
+def reclassVersion = 'v1.5.4'
+if (common.validInputParam('RECLASS_VERSION')) {
+  reclassVersion = RECLASS_VERSION
+}
+
 def generateSaltMaster(modEnv, clusterDomain, clusterName) {
     def nodeFile = "${modEnv}/nodes/cfg01.${clusterDomain}.yml"
     def nodeString = """classes:
@@ -76,7 +81,7 @@
     generateSaltMaster(generatedModel, clusterDomain, clusterName)
 }
 
-def testModel(modelFile, testEnv) {
+def testModel(modelFile, testEnv, reclassVersion='v1.5.4') {
   def templateEnv = "${env.WORKSPACE}"
   def content = readFile(file: "${templateEnv}/contexts/${modelFile}.yml")
   def templateContext = readYaml text: content
@@ -101,7 +106,7 @@
       testEnv,
       'pkg',
       DISTRIB_REVISION,
-      'master',
+      reclassVersion,
       0,
       false,
       false,
@@ -187,7 +192,7 @@
                     for(part in partition){
                         def basename = sh(script: "basename ${part} .yml", returnStdout: true).trim()
                         def testEnv = "${env.WORKSPACE}/model/${basename}"
-                        buildSteps.get("partition-${i}").put(basename, { testModel(basename, testEnv) })
+                        buildSteps.get("partition-${i}").put(basename, { testModel(basename, testEnv, reclassVersion) })
                     }
                 }
                 common.serial(buildSteps)
diff --git a/test-drivetrain.groovy b/test-drivetrain.groovy
new file mode 100644
index 0000000..21d1a8a
--- /dev/null
+++ b/test-drivetrain.groovy
@@ -0,0 +1,102 @@
+/**
+ *
+ * Test Drivetrain pipeline
+ *
+ * Expected parameters:
+ *   COOKIECUTTER_TEMPLATE_CONTEXT                 Template context for CookieCutter
+ *   SOURCE_MCP_VERSION                            MCP version to start with
+ *   TARGET_MCP_VERSION                            MCP version to upgrade to
+ *   FUNC_TEST_SETTINGS                            Settings for functional tests
+ *   ENVIRONMENT_IP                                IP of already deployed environment
+ */
+
+
+common = new com.mirantis.mk.Common()
+salt = new com.mirantis.mk.Salt()
+test = new com.mirantis.mk.Test()
+python = new com.mirantis.mk.Python()
+
+pepperEnv = "pepperEnv"
+
+def setupPepperVirtualenv(path, url, creds) {
+    requirements = ['salt-pepper>=0.5.2,<0.5.4']
+    python.setupVirtualenv(path, 'python2', requirements, null, true, true)
+    rcFile = "${path}/pepperrc"
+    rc = """\
+[main]
+SALTAPI_EAUTH=pam
+SALTAPI_URL=${url}
+SALTAPI_USER=${creds.username}
+SALTAPI_PASS=${creds.password}
+"""
+    writeFile file: rcFile, text: rc
+    return rcFile
+}
+
+def runJobOnJenkins(jenkinsUrl, userName, password, jobName, parameters){
+    def jenkinsDownCmd = "curl -OL ${jenkinsUrl}/jnlpJars/jenkins-cli.jar --output ./jenkins-cli.jar"
+    def runJobFromSaltMasterCmd = "java -jar jenkins-cli.jar -s ${jenkinsUrl} -noKeyAuth -auth admin:${password} build ${jobName} ${parameters} -s | grep -E 'SUCCESS|UNSTABLE'"
+    salt.cmdRun(pepperEnv, "I@salt:master", jenkinsDownCmd)
+    salt.cmdRun(pepperEnv, "I@salt:master", runJobFromSaltMasterCmd)
+}
+
+timeout(time: 12, unit: 'HOURS') {
+    node("python") {
+        try {
+            def mcpEnvJob
+            def saltReturn
+            def saltCreds = [:]
+            def mcpEnvJobIP
+
+            if(ENVIRONMENT_IP == ""){
+                stage('Trigger deploy job') {
+                    mcpEnvJob = build(job: "create-mcp-env", parameters: [
+                        [$class: 'StringParameterValue', name: 'OS_AZ', value: 'mcp-mk'],
+                        [$class: 'StringParameterValue', name: 'OS_PROJECT_NAME', value: 'mcp-mk'],
+                        [$class: 'StringParameterValue', name: 'STACK_NAME', value: 'jenkins-drivetrain-test-' + currentBuild.number],
+                        [$class: 'StringParameterValue', name: 'STACK_INSTALL', value: 'core,cicd'],
+                        [$class: 'BooleanParameterValue', name: 'STACK_FULL', value: false],
+                        [$class: 'BooleanParameterValue', name: 'RUN_TESTS', value: false],
+                        [$class: 'TextParameterValue', name: 'COOKIECUTTER_TEMPLATE_CONTEXT', value: COOKIECUTTER_TEMPLATE_CONTEXT]
+                    ])
+                }
+
+                def mcpEnvJobDesc = mcpEnvJob.getDescription().tokenize(" ")
+                mcpEnvJobIP = mcpEnvJobDesc[2]
+            }else{
+                mcpEnvJobIP = ENVIRONMENT_IP
+            }
+
+            def saltMasterUrl = "http://${mcpEnvJobIP}:6969"
+            def script = "println(com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,jenkins.model.Jenkins.instance).findAll {cred -> cred.id == 'salt'}[0].password)"
+            def saltPasswd = sh(returnStdout: true, script: "curl -d \"script=${script}\" --user admin:r00tme http://${mcpEnvJobIP}:8081/scriptText")
+            saltPasswd = saltPasswd.trim()
+            saltCreds.put("username", "salt")
+            saltCreds.put("password", saltPasswd)
+            setupPepperVirtualenv(pepperEnv, saltMasterUrl, saltCreds)
+            saltReturn = salt.getPillar(pepperEnv, 'I@jenkins:client and not I@salt:master', '_param:openldap_admin_password')
+            def stackCicdPassword = saltReturn.get("return")[0].values()[0]
+            saltReturn = salt.getPillar(pepperEnv, 'I@jenkins:client and not I@salt:master', 'jenkins:client:master:host')
+            def stackCicdAddr = saltReturn.get("return")[0].values()[0]
+            def jenkinsUrl = "http://${stackCicdAddr}:8081"
+
+            stage('Run CVP before upgrade') {
+                runJobOnJenkins(jenkinsUrl, "admin", stackCicdPassword, "cvp-sanity", "-p TESTS_SET=cvp-sanity-checks/cvp_checks/tests/test_drivetrain.py -p TESTS_SETTINGS='drivetrain_version=\"${SOURCE_MCP_VERSION}\"'")
+                //runJobOnJenkins(jenkinsUrl, "admin", stackCicdPassword, "cvp-dt-func", "-p SETTINGS=${FUNC_TEST_SETTINGS}")
+            }
+
+            stage('Run Upgrade on DriveTrain') {
+                runJobOnJenkins(jenkinsUrl, "admin", stackCicdPassword, "upgrade-mcp-release", "-p MCP_VERSION=${TARGET_MCP_VERSION}")
+            }
+
+            stage('Run CVP after upgrade') {
+                runJobOnJenkins(jenkinsUrl, "admin", stackCicdPassword, "cvp-sanity", "-p TESTS_SET=cvp-sanity-checks/cvp_checks/tests/test_drivetrain.py -p TESTS_SETTINGS='drivetrain_version=\"${TARGET_MCP_VERSION}\"'")
+                //runJobOnJenkins(jenkinsUrl, "admin", stackCicdPassword, "cvp-dt-func", "-p SETTINGS=${FUNC_TEST_SETTINGS}")
+            }
+
+        } catch (Throwable e) {
+            currentBuild.result = 'FAILURE'
+            throw e
+        }
+    }
+}
\ No newline at end of file
diff --git a/test-salt-model-node.groovy b/test-salt-model-node.groovy
index 9b31168..ed525bd 100644
--- a/test-salt-model-node.groovy
+++ b/test-salt-model-node.groovy
@@ -29,6 +29,11 @@
 
 def checkouted = false
 
+def reclassVersion = 'v1.5.4'
+if (common.validInputParam('RECLASS_VERSION')) {
+  reclassVersion = RECLASS_VERSION
+}
+
 throttle(['test-model']) {
   timeout(time: 1, unit: 'HOURS') {
     node("python&&docker") {
@@ -73,7 +78,7 @@
                   workspace,
                   FORMULAS_SOURCE,
                   FORMULAS_REVISION,
-                  RECLASS_VERSION,
+                  reclassVersion,
                   MAX_CPU_PER_JOB.toInteger(),
                   RECLASS_IGNORE_CLASS_NOTFOUND,
                   LEGACY_TEST_MODE,
diff --git a/validate-cloud.groovy b/validate-cloud.groovy
index 7d3b2e2..503b375 100644
--- a/validate-cloud.groovy
+++ b/validate-cloud.groovy
@@ -49,7 +49,7 @@
 
 def pepperEnv = "pepperEnv"
 def artifacts_dir = 'validation_artifacts/'
-if (env.JOB_TIMEOUT == ''){
+if (!env.JOB_TIMEOUT){
     job_timeout = 12
 } else {
     job_timeout = env.JOB_TIMEOUT.toInteger()