Merge "Fixed test cookiecutter pipeline"
diff --git a/build-debian-packages-telegraf.groovy b/build-debian-packages-telegraf.groovy
index b946688..a2b71a8 100644
--- a/build-debian-packages-telegraf.groovy
+++ b/build-debian-packages-telegraf.groovy
@@ -81,6 +81,10 @@
                         aptly.snapshotRepo(APTLY_URL, APTLY_REPO, timestamp)
                         aptly.publish(APTLY_URL)
                     }
+
+                    stage("rebuild docker images") {
+                        build job: "docker-build-images-prometheus", parameters: []
+                    }
                 }
             }
 
diff --git a/ceph-enforce-weights.groovy b/ceph-enforce-weights.groovy
new file mode 100644
index 0000000..4e06322
--- /dev/null
+++ b/ceph-enforce-weights.groovy
@@ -0,0 +1,60 @@
+/**
+ *
+ * Enforce OSD weights from model
+ *
+ * Requred parameters:
+ *  SALT_MASTER_URL             URL of Salt master
+ *  SALT_MASTER_CREDENTIALS     Credentials to the Salt API
+ *
+ *  ADMIN_HOST                  Host (minion id) with admin keyring
+ *
+ */
+
+common = new com.mirantis.mk.Common()
+salt = new com.mirantis.mk.Salt()
+
+// configure global variables
+def saltMaster
+
+def runCephCommand(master, cmd) {
+    return salt.cmdRun(master, ADMIN_HOST, cmd)
+}
+
+def grains
+
+node("python") {
+
+    stage('Load cluster information') {
+        // create connection to salt master
+        saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
+
+        // get list of disk from grains
+        grains = salt.getGrain(saltMaster, 'I@ceph:osd')['return'][0]
+        common.prettyPrint(grains)
+
+    }
+
+    stage('Enforce weights on OSDs') {
+
+        for (host in grains) {
+            // parse grains
+            def hostGrains = host.value
+            common.prettyPrint(hostGrains)
+
+            def hostname = hostGrains.host
+            def salt_id = hostGrains.id
+            def ceph_host_id = hostGrains.ceph_osd_host_id
+
+            common.infoMsg("Setting weights on host ${hostname} (${salt_id}), ceph_id ${ceph_host_id}")
+            for (disk in hostGrains.ceph_osd_disk) {
+                def osd_id = ceph_host_id + disk.key
+                print(osd_id)
+                print(disk.value)
+                print(disk.key)
+                def cmd = "ceph osd crush set ${osd_id} ${disk.value.weight} host=${hostname}"
+                print(runCephCommand(saltMaster, cmd))
+            }
+        }
+
+    }
+}
diff --git a/ceph-remove-osd.groovy b/ceph-remove-osd.groovy
index 9f6934e..ac102eb 100644
--- a/ceph-remove-osd.groovy
+++ b/ceph-remove-osd.groovy
@@ -40,14 +40,21 @@
 
     // get list of disk at the osd
     def pillar_disks = salt.getPillar(saltMaster, HOST, 'ceph:osd:disk')['return'][0].values()[0]
-    def hostname = salt.getPillar(saltMaster, HOST, 'linux:system:name')['return'][0].values()[0]
-    def hostname_id = hostname.replaceAll('osd', '')
+    def hostname_id = salt.getPillar(saltMaster, HOST, 'ceph:osd:host_id')['return'][0].values()[0]
     def osd_ids = []
 
-    for (i in pillar_disks.keySet()) {
-        def osd_id = (hostname_id + i).toInteger()
+    print("host_id is ${hostname_id}")
+    print("osds:")
+    print(osds)
+
+    for (i in pillar_disks) {
+        def osd_id = (hostname_id + i.key).toInteger().toString()
+        print("Evaluating ${osd_id}")
         if (osd_id in osds || OSD == '*') {
             osd_ids.add('osd.' + osd_id)
+            print("Will delete " + osd_id)
+        } else {
+            print("Skipping " + osd_id)
         }
     }
 
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index b8ac3b0..22867ce 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -242,8 +242,13 @@
 
         // install ceph
         if (common.checkContains('STACK_INSTALL', 'ceph')) {
-            orchestrate.installCephMon(saltMaster)
-            orchestrate.installCephOsd(saltMaster)
+            stage('Install Ceph MONs') {
+                orchestrate.installCephMon(saltMaster)
+            }
+
+            stage('Install Ceph OSDs') {
+                orchestrate.installCephOsd(saltMaster)
+            }
         }
 
         // install k8s
@@ -376,7 +381,7 @@
             }
 
             stage('Run k8s conformance e2e tests') {
-                def image = K8S_CONFORMANCE_IMAGE
+                def image = TEST_K8S_CONFORMANCE_IMAGE
                 def output_file = image.replaceAll('/', '-') + '.output'
 
                 // run image
@@ -410,6 +415,17 @@
             }
         }
 
+
+        if (common.checkContains('STACK_TEST', 'ceph')) {
+            stage('Run infra tests') {
+                def cmd = "apt-get install -y python-pip && pip install -r /usr/share/salt-formulas/env/ceph/files/testinfra/requirements.txt && python -m pytest --junitxml=/root/report.xml /usr/share/salt-formulas/env/ceph/files/testinfra/"
+                salt.cmdRun(saltMaster, 'I@salt:master', cmd)
+                writeFile(file: 'report.xml', text: salt.getFileContent(saltMaster, 'I@salt:master', '/root/report.xml'))
+                junit(keepLongStdio: true, testResults: 'report.xml')
+            }
+        }
+
+
         if (common.checkContains('STACK_INSTALL', 'finalize')) {
             stage('Finalize') {
                 salt.runSaltProcessStep(saltMaster, '*', 'state.apply', [], null, true)
diff --git a/validate-cloud.groovy b/validate-cloud.groovy
index 6c25071..8381d6e 100644
--- a/validate-cloud.groovy
+++ b/validate-cloud.groovy
@@ -11,11 +11,15 @@
  *   TEMPEST_TEST_SET            If not false, run tests matched to pattern only
  *   RUN_TEMPEST_TESTS           If not false, run Tempest tests
  *   RUN_RALLY_TESTS             If not false, run Rally tests
+ *   RUN_K8S_TESTS               If not false, run Kubernetes tests
+ *   TEST_K8S_API_SERVER         Kubernetes API address
+ *   TEST_K8S_CONFORMANCE_IMAGE  Path to docker image with conformance e2e tests
  *
  */
 
 common = new com.mirantis.mk.Common()
 salt = new com.mirantis.mk.Salt()
+test = new com.mirantis.mk.Test()
 validate = new com.mirantis.mcp.Validate()
 
 def saltMaster
@@ -48,6 +52,39 @@
                 common.infoMsg("Skipping Rally tests")
             }
         }
+
+        stage('Run k8s bootstrap tests') {
+            if (RUN_K8S_TESTS.toBoolean() == true) {
+                def image = 'tomkukral/k8s-scripts'
+                def output_file = image.replaceAll('/', '-') + '.output'
+
+                // run image
+                test.runConformanceTests(saltMaster, TEST_K8S_API_SERVER, image)
+
+                // collect output
+                def file_content = salt.getFileContent(saltMaster, 'ctl01*', '/tmp/' + output_file)
+                writeFile file: "${artifacts_dir}${output_file}", text: file_content
+            } else {
+                common.infoMsg("Skipping k8s bootstrap tests")
+            }
+        }
+
+        stage('Run k8s conformance e2e tests') {
+            if (RUN_K8S_TESTS.toBoolean() == true) {
+                def image = TEST_K8S_CONFORMANCE_IMAGE
+                def output_file = image.replaceAll('/', '-') + '.output'
+
+                // run image
+                test.runConformanceTests(saltMaster, TEST_K8S_API_SERVER, image)
+
+                // collect output
+                def file_content = salt.getFileContent(saltMaster, 'ctl01*', '/tmp/' + output_file)
+                writeFile file: "${artifacts_dir}${output_file}", text: file_content
+            } else {
+                common.infoMsg("Skipping k8s conformance e2e tests")
+            }
+        }
+
         stage('Collect results') {
             archiveArtifacts artifacts: "${artifacts_dir}/*"
         }