From dcf92ec08bac66fdeedc7b8aa7e85a180638bfc2 Mon Sep 17 00:00:00 2001
From: Pavlina Bortlova <pbortlov@redhat.com>
Date: Apr 22 2020 11:58:58 +0000
Subject: Add tower prod deployment


---

diff --git a/roles/c3i/README.md b/roles/c3i/README.md
index 565d67c..ee500d4 100644
--- a/roles/c3i/README.md
+++ b/roles/c3i/README.md
@@ -11,12 +11,13 @@ Role is configurable with role variables starting `c3i_`. Component developers a
 Requirements
 ------------
 
-Integration with pagure.io:
+#### Integration with pagure.io:
 * Projects have to set 'Fedmsg notifications' in 'Project Options'
 * Projects have to activate 'Hooks' -> 'Fedmsg'
 * OpenShift namespace contains secret defined by `c3i_pagure_api_key_secret`
   - Token permissions: Flag a commit, Comment on a pull-request, Flag a pull-request
 
+
 Jenkins master is listening on Fedmsg and UMB.
 
 Secret creation:
@@ -28,6 +29,13 @@ oc label secret pagure-api-key credential.sync.jenkins.openshift.io=true
 
 Due to pagure.io connection issue it's recommended to set 'SCM checkout retry count' in Jenkins global configuration to 10.
 
+#### Integration with Ansible tower:
+* OpenShift namespace contains secret defined by `c3i_tower_secret: tower-promotion-secret`
+
+Secret creation:
+
+```oc create secret generic tower-promotion-secret --from-literal=USERNAME=<toweruser> --from-literal=PASSWORD=<toweruserpass>```
+
 Workflows
 ---------
 ### Pre-merge
diff --git a/roles/c3i/defaults/main.yml b/roles/c3i/defaults/main.yml
index 16b4f07..ef9bb07 100644
--- a/roles/c3i/defaults/main.yml
+++ b/roles/c3i/defaults/main.yml
@@ -106,3 +106,12 @@ c3i_jenkins_master_validation: jenkins-c3i.cloud.paas.psi.redhat.com
 #   3) Build from noop stages is removed.
 #   4) Job is reconfigured with final configuration.
 c3i_trigger_update_only: false
+
+# Ansible tower instance
+c3i_tower_instance: https://tower.engineering.redhat.com
+# Ansible template ID
+c3i_tower_template_id_dev:
+c3i_tower_template_id_stage:
+c3i_tower_template_id_prod:
+# Ansible credentials - USERNAME and PASSWORD
+c3i_tower_secret: tower-promotion-secret
diff --git a/roles/c3i/templates/build.Jenkinsfile b/roles/c3i/templates/build.Jenkinsfile
index cf9a65a..d11a26b 100644
--- a/roles/c3i/templates/build.Jenkinsfile
+++ b/roles/c3i/templates/build.Jenkinsfile
@@ -223,6 +223,12 @@ pipeline {
         }
       }
     }
+    stage('Triggering Tower deployment') {
+      when {
+        expression { env.GIT_REPO_REF == params.GIT_MAIN_BRANCH && params.TOWER_TEMPLATE_ID && params.TOWER_SECRET }
+      }
+      {% include "triggering-tower-steps.groovy" %}
+    }
   }
   post {
     success {
diff --git a/roles/c3i/templates/build.yml b/roles/c3i/templates/build.yml
index 035eaf5..65adb26 100644
--- a/roles/c3i/templates/build.yml
+++ b/roles/c3i/templates/build.yml
@@ -56,5 +56,12 @@ spec:
       # CI_MESSAGE and MESSAGE_HEADERS are used internally by JMS messaging plugin
       - name: CI_MESSAGE
       - name: MESSAGE_HEADERS
+      # Tower variables
+      - name: TOWER_INSTANCE
+        value: {{ c3i_tower_instance }}
+      - name: TOWER_TEMPLATE_ID
+        value: "{{ c3i_tower_template_id_dev }}"
+      - name: TOWER_SECRET
+        value: {{ c3i_tower_secret }}
       jenkinsfile: |
         {% filter indent(width=10) %}{% include "templates/build.Jenkinsfile" %}{% endfilter %}
diff --git a/roles/c3i/templates/greenwave-promote.Jenkinsfile b/roles/c3i/templates/greenwave-promote.Jenkinsfile
index 10691b4..bd6f5cd 100644
--- a/roles/c3i/templates/greenwave-promote.Jenkinsfile
+++ b/roles/c3i/templates/greenwave-promote.Jenkinsfile
@@ -130,6 +130,12 @@ pipeline {
         }
       }
     }
+    stage('Triggering Tower deployment') {
+      when {
+        expression { env.ALLOW_DEPLOYMENT && params.TOWER_TEMPLATE_ID && params.TOWER_SECRET }
+      }
+      {% include "triggering-tower-steps.groovy" %}
+    }
   }
   {% endif %}
 
diff --git a/roles/c3i/templates/greenwave-promote.yml b/roles/c3i/templates/greenwave-promote.yml
index 4f1d0b1..37156c9 100644
--- a/roles/c3i/templates/greenwave-promote.yml
+++ b/roles/c3i/templates/greenwave-promote.yml
@@ -46,5 +46,12 @@ spec:
       # CI_MESSAGE and MESSAGE_HEADERS are used internally by JMS messaging plugin
       - name: CI_MESSAGE
       - name: MESSAGE_HEADERS
+        value:
+      - name: TOWER_INSTANCE
+        value: {{ c3i_tower_instance }}
+      - name: TOWER_TEMPLATE_ID
+        value: "{{ job_vars.tower_template_id }}"
+      - name: TOWER_SECRET
+        value: {{ c3i_tower_secret }}
       jenkinsfile: |
         {% filter indent(width=10) %}{% include "templates/greenwave-promote.Jenkinsfile" %}{% endfilter %}
diff --git a/roles/c3i/templates/jobs/greenwave-promote-to-prod.yml b/roles/c3i/templates/jobs/greenwave-promote-to-prod.yml
index 6fc12d5..e137802 100644
--- a/roles/c3i/templates/jobs/greenwave-promote-to-prod.yml
+++ b/roles/c3i/templates/jobs/greenwave-promote-to-prod.yml
@@ -6,3 +6,4 @@ target_tag: prod
 promoting_destination_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"
 source_container_repo_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"
 semaphore_check: True
+tower_template_id: "{{ c3i_tower_template_id_prod }}"
diff --git a/roles/c3i/templates/jobs/greenwave-promote-to-stage.yml b/roles/c3i/templates/jobs/greenwave-promote-to-stage.yml
index 96c2e2a..a7f9ca8 100644
--- a/roles/c3i/templates/jobs/greenwave-promote-to-stage.yml
+++ b/roles/c3i/templates/jobs/greenwave-promote-to-stage.yml
@@ -6,3 +6,4 @@ target_tag: stage
 promoting_destination_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"
 source_container_repo_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"
 semaphore_check: False
+tower_template_id: "{{ c3i_tower_template_id_stage }}"
diff --git a/roles/c3i/templates/triggering-tower-steps.groovy b/roles/c3i/templates/triggering-tower-steps.groovy
new file mode 100644
index 0000000..fc3c4c7
--- /dev/null
+++ b/roles/c3i/templates/triggering-tower-steps.groovy
@@ -0,0 +1,43 @@
+steps {
+  script {
+    echo "Curl ${params.TOWER_INSTANCE}/api/v2/job_templates/${params.TOWER_TEMPLATE_ID}/launch/"
+    openshift.withCluster() {
+      if ( openshift.selector('secret', params.TOWER_SECRET).exists() ) {
+        def towerSecretData = openshift.selector('secret', params.TOWER_SECRET).object().data
+        if ( !towerSecretData.containsKey("USERNAME") || !towerSecretData.containsKey("PASSWORD") ) {
+          error("There is not USERNAME or PASSWORD in ${params.TOWER_SECRET}")
+        }
+        def towerUser = new String(towerSecretData.USERNAME.decodeBase64())
+        def towerPassword = new String(towerSecretData.PASSWORD.decodeBase64())
+
+        def launchUrl = "${params.TOWER_INSTANCE}/api/v2/job_templates/${params.TOWER_TEMPLATE_ID}/launch/"
+        echo "curl -X POST -u ${towerUser}:***** ${launchUrl}"
+        def launchOut = sh script: "set +x; curl -k -X POST -u ${towerUser}:${towerPassword} ${launchUrl}", returnStdout: true
+        def launchOutJson
+        try {
+          launchOutJson = readJSON text: launchOut
+        } catch (Exception e) {
+          error("Unable parse output: ${launchOut}")
+        }
+        if (!launchOutJson.containsKey("created")){
+          error("Job was not created from template: ${launchOut}")
+        }
+        def finished = launchOutJson.finished
+        def jobUrl = "${params.TOWER_INSTANCE}${launchOutJson.url}"
+        def jobOutJson
+        while(finished == "null"){
+          sh "set +x; sleep 5; echo 'checking state of ${launchOutJson.id} job'"
+          def jobOut = sh script: "set +x; curl -k -u ${towerUser}:${towerPassword} ${jobUrl}", returnStdout: true
+          jobOutJson = readJSON text: jobOut
+          finished = jobOutJson.finished
+        }
+        if (jobOutJson.failed) {
+          error("Tower job ${params.TOWER_INSTANCE}/#/jobs/playbook/${jobOutJson.id} execution failed")
+        }
+        echo "Job ${params.TOWER_INSTANCE}/#/jobs/playbook/${jobOutJson.id} execution passed"
+      } else {
+        error("Secret ${params.TOWER_SECRET} doesn't exist")
+      }
+    }
+  }
+}
diff --git a/verification/c3i-role-verification.Jenkinsfile b/verification/c3i-role-verification.Jenkinsfile
index a47c177..94af931 100644
--- a/verification/c3i-role-verification.Jenkinsfile
+++ b/verification/c3i-role-verification.Jenkinsfile
@@ -141,9 +141,11 @@ pipeline {
       steps {
         script {
           openshift.withCluster() {
-            factorySecret = openshift.selector('secret', 'factory2-c3i-verification-secret').object(exportable:true)
-            openshift.withProject(env.PIPELINE_ID) {
-              openshift.create(factorySecret)
+            ['factory2-c3i-verification-secret', 'tower-promotion-secret'].each {
+              def secret = openshift.selector('secret', it).object(exportable:true)
+              openshift.withProject(env.PIPELINE_ID) {
+                openshift.create(secret)
+              }
             }
           }
         }
diff --git a/verification/test-project/c3i-role-vars.yml b/verification/test-project/c3i-role-vars.yml
index 88db584..e8ffedb 100644
--- a/verification/test-project/c3i-role-vars.yml
+++ b/verification/test-project/c3i-role-vars.yml
@@ -2,6 +2,9 @@ c3i_component: c3i-library-test
 c3i_build_and_test_snippet: snippets/build-and-test.groovy
 c3i_integration_test_snippet: snippets/full-integration-test.groovy
 
+c3i_tower_template_id_stage: 1197
+c3i_tower_template_id_dev: 1197
+
 c3i_mail_address:
 
 c3i_lib_url:

