#!groovy

node {
  def rootPath = "/src/rancher-validation/"

  def job_name = "${JOB_NAME}"
  if (job_name.contains('/')) { 
    job_names = job_name.split('/')
    job_name = job_names[job_names.size() - 1] 
  }

  def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup"
  def testContainer = "${job_name}${env.BUILD_NUMBER}_test"
  def deleteContainer = "${job_name}${env.BUILD_NUMBER}_delete"

  def deployPytestOptions = "-k test_deploy_rancher_server"
  def deletePytestOptions = "-k test_delete_rancher_server"

  def setupResultsOut = "setup-results.xml"
  def testResultsOut = "results.xml"
  def deleteResultsOut = "delete-results.xml"
  def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}"
  def testsDir = "tests/v3_api/"

  def envFile = ".env"
  def rancherConfig = "rancher_env.config"

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

  wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) {
    withFolderProperties {
      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: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'),
                        string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'),
                        string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'),
                        string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'),
                        string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'),
                        string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'),
                        string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'),
                        string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'),
                        string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'),
                        string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'),
                        string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'),
                        string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'),
                        string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'),
                        string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'),
                        string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'),
                        string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'),
                        string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'),
                        string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'),
                        string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'),
                        string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'),
                        string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'),
                        string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'),
                        string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'),
                        string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'),
                        string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'),
                        string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'),
                        string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'),
                        string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'),
                        string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'),
                        string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'),
                        string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'),
                        string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'),
                        string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'),
                        string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'),
                        string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'),
                        string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'),
                        string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_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: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) {
        stage('Checkout') {
          deleteDir()
          checkout([
                    $class: 'GitSCM',
                    branches: [[name: "*/${branch}"]],
                    extensions: scm.extensions + [[$class: 'CleanCheckout']],
                    userRemoteConfigs: scm.userRemoteConfigs
                  ])
        }

        dir ("tests/validation") {
          try {
            stage('Configure and Build') {
              if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) {
                dir(".ssh") {
                  def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64())
                  writeFile file: AWS_SSH_KEY_NAME, text: decoded
                }
              }
          
              sh "./tests/v3_api/scripts/configure.sh"
              sh "./tests/v3_api/scripts/build.sh"
            }
          
            stage('Deploy Rancher Server') {
              try {
              if (!env.CATTLE_TEST_URL || !env.ADMIN_TOKEN || !env.USER_TOKEN ||
                (env.CATTLE_TEST_URL == "" && env.ADMIN_TOKEN == "" && env.USER_TOKEN == "")) {
                // deploy rancher server
                sh "docker run --name ${setupContainer} -t --env-file ${envFile} " +
                  "${imageName} /bin/bash -c \'pytest -v -s --junit-xml=${setupResultsOut} " +
                  "${deployPytestOptions} ${testsDir}\'"
                RANCHER_DEPLOYED = true

                // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables
                sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ."
                load rancherConfig
                
              }
              else {
                  echo "User Provided Rancher Server"
                  RANCHER_DEPLOYED = false
               }
               }
                catch(err) {
                echo "Error: " + err
                RANCHER_DEPLOYED = false
              }
            }

            stage('Run Validation Tests') {
              try { 
                // run tests
                def clusterName="${env.RANCHER_CLUSTER_NAME}"
                if (RANCHER_DEPLOYED) {
                    clusterName="${env.CLUSTER_NAME}"
                }
                sh "docker run --name ${testContainer} -t --env-file ${envFile} " +
                  "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} " +
                  "&& export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} "+
                  "&& export RANCHER_CLUSTER_NAME=${clusterName} " + "&& pytest -v -s --junit-xml=${testResultsOut} " +
                  "${PYTEST_OPTIONS} ${testsDir}\'"
               } catch(err) {
                echo "Error: " + err
                echo 'Test run had failures. Collecting results...'
              }
            }
          } catch(err) {
            echo "Error: " + err
          } finally {
            stage('Delete Rancher Server') {
              try {
                if (env.RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) {
                  sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " +
                  "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} && " +
                  "export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} && "+
                  "pytest -v -s --junit-xml=${deleteResultsOut} " +
                  "${deletePytestOptions} ${testsDir}\'"
                  sh "docker cp ${deleteContainer}:${rootPath}${deleteResultsOut} ."
                  step([$class: 'JUnitResultArchiver', testResults: "**/${deleteResultsOut}"])
                }
                else {
                  echo "Rancher server not deployed, skipping delete."
                }
              } catch(err) {
                echo "Error: " + err
                currentBuild.result = 'FAILURE'
              }
            }
            
            stage('Test Report') {
              // copy and archive test results
              if (RANCHER_DEPLOYED) {
                  sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ."
                  step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"])

              }
              sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ."
              step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"])

            }
            if (RANCHER_DEPLOYED) {
                sh "docker stop ${setupContainer}"
                sh "docker rm -v ${setupContainer}"
            }
                sh "docker stop ${testContainer}"
                sh "docker rm -v ${testContainer}"

            if (env.RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) {
              sh "docker stop ${deleteContainer}"
              sh "docker rm -v ${deleteContainer}"
            }

            sh "docker rmi ${imageName}"
          } // finally
        } // dir 
      } // creds
    } // folder properties
  } // wrap 
} // node