Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions validation/pipeline/qainfra/Jenkinsfile.capi.e2e
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!groovy
library('qa-jenkins-library')
node {
def workPath = "/root/go/src/github.com/rancher/tests/validation/"
def rancherRepo = "https://github.com/rancher/tests"
def jobName = "${JOB_NAME}"
if (jobName.contains('/')) {
jobNames = jobName.split('/')
jobName = jobNames[jobNames.size() - 1]
}
def buildTestContainer = "${jobName}${env.BUILD_NUMBER}-buildtest"
def cleanupTestContainer = "${jobName}${env.BUILD_NUMBER}-cleanuptest"
def imageName = "rancher-recurring-runs-validation-${jobName}${env.BUILD_NUMBER}"
def validationVolume = "RecurringRunsSharedVolume-${jobName}${env.BUILD_NUMBER}"
def envFile = ".env"
def branch = "main"
def qaInfraBranch = "main"
def qaInfraRepo = "https://github.com/rancher/qa-infra-automation"
def config = env.CONFIG
def ansibleConfig = env.ANSIBLE_CONFIG
def terraformConfig = env.TERRAFORM_CONFIG
def filename = "config.yaml"
def ansibleVarsFilename = "vars.yaml"
def terraformVarsfilename = "cluster.tfvars"
def capiConfig = env.CAPI_CONFIG
def capiClusterConfig = env.CAPI_CLUSTER_CONFIG
def capiAnsibleConfig = env.CAPI_ANSIBLE_CONFIG
def capiConfigFile = "capiconfig.yaml"
def capiClusterConfigFile = "capiclusterconfig.yaml"
def yqVersion = "v4.47.2"

if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") {
branch = "${env.BRANCH}"
}

if ("${env.REPO}" != "null" && "${env.REPO}" != "") {
rancherRepo = "${env.REPO}"
}

if ("${env.QA_INFRA_REPO_BRANCH}" != "null" && "${env.QA_INFRA_REPO_BRANCH}" != "") {
qaInfraBranch = "${env.QA_INFRA_REPO_BRANCH}"
}

if ("${env.QA_INFRA_REPO_URL}" != "null" && "${env.QA_INFRA_REPO_URL}" != "") {
qaInfraRepo = "${env.QA_INFRA_REPO_URL}"
}

wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) {
withFolderProperties {
paramsMap = []
params.each {
if (it.value && it.value.trim() != "") {
paramsMap << "$it.key=$it.value"
}
}
withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'),
string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'),
string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'),
string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'),
string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'),
string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'),
string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'),
string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'),
string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'),
string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'),
string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'),
string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'),
string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'),
string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'),
string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN'),
string(credentialsId: 'AWS_B64ENCODED_CREDENTIALS', variable: 'AWS_B64ENCODED_CREDENTIALS'),
string(credentialsId: 'JENKINS_CAPI_SSH_KEY_NAME', variable: 'JENKINS_CAPI_SSH_KEY_NAME')]) {

withEnv(paramsMap) {
stage('Checkout') {
deleteDir()
dir("./tests") {
echo "cloning rancher tests"
checkout([
$class: 'GitSCM',
branches: [[name: "*/${branch}"]],
extensions: scm.extensions + [[$class: 'CleanCheckout']],
userRemoteConfigs: [[url: rancherRepo]]
])
}
dir('./qa-infra-automation') {
echo "cloning qa-infra-automation repo"
checkout([
$class: 'GitSCM',
branches: [[name: "*/${qaInfraBranch}"]],
extensions: scm.extensions + [[$class: 'CleanCheckout']],
userRemoteConfigs: [[url: qaInfraRepo]]
])
}
}
dir ("./") {
stage('Configure and Build') {
terraformConfig = terraformConfig.replace('${AWS_SECRET_ACCESS_KEY}', env.AWS_SECRET_ACCESS_KEY)
terraformConfig = terraformConfig.replace('${AWS_ACCESS_KEY_ID}', env.AWS_ACCESS_KEY_ID)
terraformConfig = terraformConfig.replace('${AWS_REGION}', env.AWS_REGION)
terraformConfig = terraformConfig.replace('${AWS_VPC}', env.AWS_VPC)
terraformConfig = terraformConfig.replace('${AWS_SECURITY_GROUPS}', env.AWS_SECURITY_GROUPS)
ansibleConfig = ansibleConfig.replace('${ADMIN_PASSWORD}', env.ADMIN_PASSWORD)
capiConfig = capiConfig.replace('${AWS_B64ENCODED_CREDENTIALS}', env.AWS_B64ENCODED_CREDENTIALS)
capiConfig = capiConfig.replace('${AWS_ACCESS_KEY_ID}', env.AWS_ACCESS_KEY_ID)
capiConfig = capiConfig.replace('${AWS_SECRET_ACCESS_KEY}', env.AWS_SECRET_ACCESS_KEY)
capiClusterConfig = capiClusterConfig.replace('${JENKINS_CAPI_SSH_KEY_NAME}', env.JENKINS_CAPI_SSH_KEY_NAME)


if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) {
dir("./tests/.ssh") {
def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64())
writeFile file: AWS_SSH_KEY_NAME, text: decoded
sh "chmod 600 ${env.AWS_SSH_KEY_NAME}"
}
}

dir("./tests/validation") {
writeFile file: filename, text: ""
}

dir("./qa-infra-automation") {
dir ("./ansible") {
writeFile file: ansibleVarsFilename, text: ansibleConfig
}
dir ("./tofu/aws/modules/cluster_nodes") {
writeFile file: terraformVarsfilename, text: terraformConfig
}
dir ("./ansible/rancher/downstream/capi") {
writeFile file: ansibleVarsFilename, text: capiAnsibleConfig
writeFile file: capiConfigFile, text: capiConfig
writeFile file: capiClusterConfigFile, text: capiClusterConfig
}
}

dir ("./") {
sh "./tests/validation/configure.sh"
sh "docker build . -f ./tests/validation/Dockerfile.e2e -t ${imageName}"
sh "docker volume create --name ${validationVolume}"
}
}
stage('Setup') {
def envText = readFile("${envFile}")
writeFile file: "${envFile}", text: envText+"BUILD_DOWNSTREAM_CLUSTER=false"
sh returnStdout: true, script: "wget -qO ./yq https://github.com/mikefarah/yq/releases/download/${yqVersion}/yq_linux_amd64 && wget -qO ./yq_checksums https://github.com/mikefarah/yq/releases/download/${yqVersion}/checksums && grep -q '^yq_linux_amd64 ' ./yq_checksums && awk '/^yq_linux_amd64 / {print \$19 \" ./yq\"}' ./yq_checksums | sha256sum -c - && rm -f ./yq_checksums"
sh returnStdout:true, script: 'chmod a+x ./yq'
}
stage("Build Environment") {
try {
sh "docker run -v ${validationVolume}:/root --name ${buildTestContainer} -t --env-file ${envFile} " +
"${imageName} sh -c \"${workPath}pipeline/scripts/setup_environment.sh && chmod +x ${workPath}pipeline/scripts/build_capi_qa_infra.sh && ${workPath}pipeline/scripts/build_capi_qa_infra.sh\""
} catch(err) {
container.remove([[name: buildTestContainer, image: imageName]])
sh "docker volume rm -f ${validationVolume}"
error "Build Environment had failures."
}
}

stage('Cleanup Rancher Environment') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this stage cleanup any clusters that may have been made with CAPI?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just following up on this question.

@lscalabrini01 lscalabrini01 Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this stage cleanup the CAPI resources, the turtles clean the resources

if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") {
try {
sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " +
"${imageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\""
} catch(err) {
container.remove([[name: buildTestContainer, image: imageName], [name: cleanupTestContainer, image: imageName]])
sh "docker volume rm -f ${validationVolume}"
error "Cleanup had failures."
}
}
}
stage('Clean Up Images and Volume') {
echo 'Cleaning test images and volume.'
container.remove([[name: buildTestContainer, image: imageName]])
if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") {
container.remove([[name: cleanupTestContainer, image: imageName]])
}
sh "docker volume rm -f ${validationVolume}"
}
} // dir
} // withEnv
} // creds
} // folder properties
} // wrap
} // node
13 changes: 13 additions & 0 deletions validation/pipeline/scripts/build_capi_qa_infra.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to have a script to run a single command that basically only works in Jenkins. Why not just run the command with sh?

@lscalabrini01 lscalabrini01 Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep the code organized and follow the standard

@hamistao hamistao Jul 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which standard are you referring to? Perhaps I am unaware of this

set -ex

echo "Create capi cluster"

: "${QAINFRA_SCRIPT_PATH:=/root/go/src/github.com/rancher/qa-infra-automation}"
: "${CAPI_PLAYBOOK_PATH:=ansible/rancher/downstream/capi}"
: "${CAPI_PLAYBOOK_FILE:=capi-playbook.yml}"
: "${CAPI_VARS_FILE:=vars.yaml}"

cd "$QAINFRA_SCRIPT_PATH/$CAPI_PLAYBOOK_PATH"

ansible-playbook "$CAPI_PLAYBOOK_FILE" -e "@$CAPI_VARS_FILE"
Loading