Rollout and test the config change
Change-Id: I456cf4855981b846b19decb2c7dbab9dd82d11f5
diff --git a/git-merge-branch.groovy b/git-merge-branch.groovy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/git-merge-branch.groovy
diff --git a/rollout-config-change.groovy b/rollout-config-change.groovy
new file mode 100644
index 0000000..06219a3
--- /dev/null
+++ b/rollout-config-change.groovy
@@ -0,0 +1,95 @@
+
+/**
+ * Rollout changes to the node(s) configuration
+ *
+ * Expected parameters:
+ * TST_SALT_MASTER_CREDENTIALS Credentials to the Salt API (QA environment).
+ * TST_SALT_MASTER_URL Full Salt API address [https://10.10.10.1:8000].
+ * PRD_SALT_MASTER_CREDENTIALS Credentials to the Salt API (PRD environment).
+ * PRD_SALT_MASTER_URL Full Salt API address [https://10.10.10.1:8000].
+ * Model parameters:
+ * MODEL_REPO_CREDENTIALS Credentials to the Model.
+ * MODEL_REPO_URL Full model repo address.
+ * MODEL_REPO_SOURCE_BRANCH Source branch to merge from.
+ * MODEL_REPO_TARGET_BRANCH Target branch to merge fo.
+ * Change settings:
+ * TARGET_SERVERS Salt compound target to match nodes to be updated [*, G@osfamily:debian].
+ * TARGET_STATES States to be applied, empty string means running highstate [linux, linux,openssh, salt.minion.grains].
+ * TARGET_SUBSET_TEST Number of nodes to test config changes, empty string means all targetted nodes.
+ * TARGET_SUBSET_LIVE Number of selected noded to live apply selected config changes.
+ * TARGET_BATCH_LIVE Batch size for the complete live config changes on all nodes, empty string means apply to all targetted nodes.
+ * Test settings:
+ * TEST_SERVICE Comma separated list of services to test
+ * TEST_K8S_API_SERVER Kubernetes API address
+ * TEST_K8S_CONFORMANCE_IMAGE Path to docker image with conformance e2e tests
+ * TEST_DOCKER_INSTALL Install docker on the target if true
+ * TEST_TEMPEST_IMAGE Tempest image link
+ * TEST_TEMPEST_PATTERN If not false, run tests matched to pattern only
+ * TEST_TEMPEST_TARGET Salt target for tempest node
+ *
+**/
+
+def common = new com.mirantis.mk.Common()
+def salt = new com.mirantis.mk.Salt()
+
+node() {
+ try {
+
+ stage('Run config change on test env') {
+ build job: "deploy-update-service-config", parameters: [
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: TST_SALT_MASTER_URL],
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: TST_SALT_MASTER_CREDENTIALS],
+ [$class: 'StringParameterValue', name: 'TARGET_BATCH_LIVE', value: TARGET_BATCH_LIVE],
+ [$class: 'StringParameterValue', name: 'TARGET_SERVERS', value: TARGET_SERVERS],
+ [$class: 'StringParameterValue', name: 'TARGET_STATES', value: TARGET_STATES],
+ [$class: 'StringParameterValue', name: 'TARGET_SUBSET_LIVE', value: TARGET_SUBSET_LIVE],
+ [$class: 'StringParameterValue', name: 'TARGET_SUBSET_TEST', value: TARGET_SUBSET_TEST],
+ ]
+ }
+
+ stage('Test config change on test env') {
+ build job: "deploy-test-service", parameters: [
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: TST_SALT_MASTER_URL],
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: TST_SALT_MASTER_CREDENTIALS],
+ [$class: 'StringParameterValue', name: 'TEST_SERVICE', value: TEST_SERVICE],
+ [$class: 'StringParameterValue', name: 'TEST_K8S_API_SERVER', value: TEST_K8S_API_SERVER],
+ [$class: 'StringParameterValue', name: 'TEST_K8S_CONFORMANCE_IMAGE', value: TEST_K8S_CONFORMANCE_IMAGE],
+ ]
+ }
+
+ stage('Promote config change in repo') {
+ build job: "gerrit-merge-branch", parameters: [
+ [$class: 'StringParameterValue', name: 'MODEL_REPO_URL', value: MODEL_REPO_URL],
+ [$class: 'StringParameterValue', name: 'MODEL_REPO_CREDENTIALS', value: MODEL_REPO_CREDENTIALS],
+ [$class: 'StringParameterValue', name: 'MODEL_REPO_SOURCE_BRANCH', value: MODEL_REPO_SOURCE_BRANCH],
+ [$class: 'StringParameterValue', name: 'MODEL_REPO_TARGET_BRANCH', value: MODEL_REPO_TARGET_BRANCH],
+ ]
+ }
+
+ stage('Run config change on production env') {
+ build job: "deploy-update-service-config", parameters: [
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: PRD_SALT_MASTER_URL],
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: PRD_SALT_MASTER_CREDENTIALS],
+ [$class: 'StringParameterValue', name: 'TARGET_BATCH_LIVE', value: TARGET_BATCH_LIVE],
+ [$class: 'StringParameterValue', name: 'TARGET_SERVERS', value: TARGET_SERVERS],
+ [$class: 'StringParameterValue', name: 'TARGET_STATES', value: TARGET_STATES],
+ [$class: 'StringParameterValue', name: 'TARGET_SUBSET_LIVE', value: TARGET_SUBSET_LIVE],
+ [$class: 'StringParameterValue', name: 'TARGET_SUBSET_TEST', value: TARGET_SUBSET_TEST],
+ ]
+ }
+
+ stage('Test config change on prod env') {
+ build job: "deploy-test-service", parameters: [
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: PRD_SALT_MASTER_URL],
+ [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: PRD_SALT_MASTER_CREDENTIALS],
+ [$class: 'StringParameterValue', name: 'TEST_SERVICE', value: TEST_SERVICE],
+ [$class: 'StringParameterValue', name: 'TEST_K8S_API_SERVER', value: TEST_K8S_API_SERVER],
+ [$class: 'StringParameterValue', name: 'TEST_K8S_CONFORMANCE_IMAGE', value: TEST_K8S_CONFORMANCE_IMAGE],
+ ]
+ }
+
+ } catch (Throwable e) {
+ currentBuild.result = 'FAILURE'
+ throw e
+ }
+}
diff --git a/test-service.groovy b/test-service.groovy
new file mode 100644
index 0000000..cb9265c
--- /dev/null
+++ b/test-service.groovy
@@ -0,0 +1,96 @@
+/**
+ *
+ * Service test pipeline
+ *
+ * Expected parameters:
+ * SALT_MASTER_URL URL of Salt master
+ * SALT_MASTER_CREDENTIALS Credentials to the Salt API
+ * Test settings:
+ * TEST_SERVICE Comma separated list of services to test
+ * TEST_K8S_API_SERVER Kubernetes API address
+ * TEST_K8S_CONFORMANCE_IMAGE Path to docker image with conformance e2e tests
+ * TEST_DOCKER_INSTALL Install docker on the target if true
+ * TEST_TEMPEST_IMAGE Tempest image link
+ * TEST_TEMPEST_PATTERN If not false, run tests matched to pattern only
+ * TEST_TEMPEST_TARGET Salt target for tempest node
+ *
+ */
+
+common = new com.mirantis.mk.Common()
+git = new com.mirantis.mk.Git()
+salt = new com.mirantis.mk.Salt()
+test = new com.mirantis.mk.Test()
+
+// Define global variables
+def saltMaster
+
+node("python") {
+ try {
+
+ //
+ // Prepare connection
+ //
+ stage ('Connect to salt master') {
+ // Connect to Salt master
+ saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
+ }
+
+ //
+ // Test
+ //
+ def artifacts_dir = '_artifacts/'
+
+ if (common.checkContains('TEST_SERVICE', 'k8s')) {
+ stage('Run k8s bootstrap tests') {
+ def image = 'tomkukral/k8s-scripts'
+ def output_file = image.replaceAll('/', '-') + '.output'
+
+ // run image
+ test.runConformanceTests(saltMaster, TEST_K8S_API_SERVER, image)
+
+ // collect output
+ sh "mkdir -p ${artifacts_dir}"
+ file_content = salt.getFileContent(saltMaster, 'ctl01*', '/tmp/' + output_file)
+ writeFile file: "${artifacts_dir}${output_file}", text: file_content
+ sh "cat ${artifacts_dir}${output_file}"
+
+ // collect artifacts
+ archiveArtifacts artifacts: "${artifacts_dir}${output_file}"
+ }
+
+ stage('Run k8s conformance e2e tests') {
+ def image = K8S_CONFORMANCE_IMAGE
+ def output_file = image.replaceAll('/', '-') + '.output'
+
+ // run image
+ test.runConformanceTests(saltMaster, TEST_K8S_API_SERVER, image)
+
+ // collect output
+ sh "mkdir -p ${artifacts_dir}"
+ file_content = salt.getFileContent(saltMaster, 'ctl01*', '/tmp/' + output_file)
+ writeFile file: "${artifacts_dir}${output_file}", text: file_content
+ sh "cat ${artifacts_dir}${output_file}"
+
+ // collect artifacts
+ archiveArtifacts artifacts: "${artifacts_dir}${output_file}"
+ }
+ }
+
+ if (common.checkContains('TEST_SERVICE', 'openstack')) {
+ if (common.checkContains('TEST_DOCKER_INSTALL', 'true')) {
+ test.install_docker(saltMaster, TEST_TEMPEST_TARGET)
+ }
+ stage('Run OpenStack tests') {
+ test.runTempestTests(saltMaster, TEST_TEMPEST_IMAGE, TEST_TEMPEST_TARGET, TEST_TEMPEST_PATTERN)
+ }
+
+ stage('Copy Tempest results to config node') {
+ test.copyTempestResults(saltMaster, TEST_TEMPEST_TARGET)
+ }
+ }
+
+ } catch (Throwable e) {
+ currentBuild.result = 'FAILURE'
+ throw e
+ }
+}