Add job to deploy BM automatically

It deploys one environment from list defined in the job
Pipeline reboots HW nodes before the deployment

Change-Id: I12ab3b7c0247308ffce6e698a21ff5cda34ebb49
Related-Prod:#PROD-34545
diff --git a/jobs/pipelines/rotation_bm_deployments.groovy b/jobs/pipelines/rotation_bm_deployments.groovy
new file mode 100644
index 0000000..49103a9
--- /dev/null
+++ b/jobs/pipelines/rotation_bm_deployments.groovy
@@ -0,0 +1,113 @@
+/**
+ *
+ * Deploy the product cluster using Jenkins master on CICD cluster
+ *
+ * Expected parameters:
+ *   STACKS                        List of deployments from 'all physical' view in the Jenkins
+                                   They should be separated by newline
+ *   PARENT_NODE_NAME
+ *   OS_AUTH_URL                   OpenStack keystone catalog URL
+ *   OS_PROJECT_NAME               OpenStack project (tenant) name
+ *   OS_CREDENTIALS                OpenStack username and password credentials ID in Jenkins
+
+ *   TCP_QA_REFS                   Reference to the tcp-qa change on Gerrit, like refs/changes/46/418546/41
+ */
+@Library('tcp-qa')_
+
+common = new com.mirantis.mk.Common()
+shared = new com.mirantis.system_qa.SharedPipeline()
+import jenkins.model.*
+
+def stacks = env.STACKS.readLines()
+
+def get_last_build_time(job_name) {
+  def job = Hudson.instance.getJob(job_name)
+  def last_build = Jenkins.instance.getItemByFullName(job.fullName).getLastBuild()
+  if (last_build == null) {
+  	return null
+  }
+  def upStreamBuild = Jenkins.getInstance().getItemByFullName(job.fullName).getBuildByNumber(last_build.getNumber())
+  return upStreamBuild.getTime()
+}
+
+@NonCPS
+def oldest_job(map) {
+  println map.sort({a, b -> a.value <=> b.value})*.value
+  return map.sort({a, b -> a.value <=> b.value})*.key[0]
+}
+
+// ============================================================================
+timeout(time: 15, unit: 'HOURS') {
+  node (env.PARENT_NODE_NAME) {
+    stage("Remove extra stacks") {
+        withCredentials([
+           [$class          : 'UsernamePasswordMultiBinding',
+           credentialsId   : env.OS_CREDENTIALS,
+           passwordVariable: 'OS_PASSWORD',
+           usernameVariable: 'OS_USERNAME']
+        ]) {
+            env.OS_IDENTITY_API_VERSION = 3
+            for (stack_name in stacks) {
+              shared.run_cmd("""
+                # export OS_IDENTITY_API_VERSION=3
+                # export OS_AUTH_URL=${OS_AUTH_URL}
+                # export OS_USERNAME=${OS_USERNAME}
+                # export OS_PASSWORD=${OS_PASSWORD}
+                # export OS_PROJECT_NAME=${OS_PROJECT_NAME}
+                openstack --insecure stack delete -y ${stack_name} || true
+                timeout 20m /bin/bash -c "while openstack --insecure stack show ${stack_name} -f value -c stack_status; do sleep 10; done";
+              """)
+            }
+        }
+    }
+
+    stage("Reboot HW nodes ") {
+        bm_ips = [
+        "185.8.59.227",
+        "185.8.59.229",
+        "5.43.225.88",
+        "5.43.225.112",
+        "5.43.225.208",
+        "5.43.227.118",
+        "185.8.58.248",
+        "185.8.59.222",
+        "5.43.225.228",
+        "5.43.229.28",
+        "5.43.225.23",
+        "185.8.58.9",
+        "185.8.58.246",
+        "185.8.58.243",
+        "185.8.58.244"
+        ]
+
+        withCredentials([
+           [$class          : 'UsernamePasswordMultiBinding',
+           credentialsId   : 'lab_engineer',
+           passwordVariable: 'lab_pass',
+           usernameVariable: 'lab_user']
+        ]) {
+            for (ip in bm_ips) { sh ("ipmitool -H ${ip} -U ${lab_user} -P ${lab_pass} chassis power off")}
+            for (ip in bm_ips) { sh ("ipmitool -H ${ip} -U ${lab_user} -P ${lab_pass} chassis bootdev pxe")}
+        }
+    }
+
+    stage("Start deployment") {
+      def jobs_map = [:]
+      for (stack_name in stacks) {
+        println stack_name
+        println get_last_build_time(stack_name)
+        jobs_map.put ("${stack_name}", get_last_build_time(stack_name))
+      }
+      stack_to_deploy = oldest_job(jobs_map)
+
+      println "Build ${stack_to_deploy}"
+      currentBuild.description = "${stack_to_deploy}"
+      // Trigger job
+      def deploy = build job: "${stack_to_deploy}",
+      parameters: [
+            string(name: 'PARENT_NODE_NAME', value: env.PARENT_NODE_NAME),
+            string(name: 'OS_CREDENTIALS', value: env.OS_CREDENTIALS)
+        ]
+    }
+  }
+}