From dcf92ec08bac66fdeedc7b8aa7e85a180638bfc2 Mon Sep 17 00:00:00 2001 From: Pavlina Bortlova 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= --from-literal=PASSWORD=``` + 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: