Skip to content
Snippets Groups Projects
Jenkinsfile.e2e 32.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
     * Ministerpräsidenten des Landes Schleswig-Holstein
     * Staatskanzlei
     * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
     *
     * Lizenziert unter der EUPL, Version 1.2 oder - sobald
     * diese von der Europäischen Kommission genehmigt wurden -
     * Folgeversionen der EUPL ("Lizenz");
     * Sie dürfen dieses Werk ausschließlich gemäß
     * dieser Lizenz nutzen.
     * Eine Kopie der Lizenz finden Sie hier:
     *
     * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
     *
     * Sofern nicht durch anwendbare Rechtsvorschriften
     * gefordert oder in schriftlicher Form vereinbart, wird
     * die unter der Lizenz verbreitete Software "so wie sie
     * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
     * ausdrücklich oder stillschweigend - verbreitet.
     * Die sprachspezifischen Genehmigungen und Beschränkungen
     * unter der Lizenz sind dem Lizenztext zu entnehmen.
     */
    
    OZGCloud's avatar
    OZGCloud committed
    import groovy.json.JsonOutput
    
    
    OZGCloud's avatar
    OZGCloud committed
    def SKIP_RUN = false
    
    
    pipeline {
        agent {
            node {
    
                label 'ozgcloud-jenkins-build-agent-jdk21-node20'
    
        triggers {
    
    OZGCloud's avatar
    OZGCloud committed
            // upstream(upstreamProjects: getUpstreamProjects(), threshold: hudson.model.Result.SUCCESS)
            cron('0 18-23,0-5 * * *')
    
    OZGCloud's avatar
    OZGCloud committed
        environment {
    
    OZGCloud's avatar
    OZGCloud committed
            BLUE_OCEAN_URL = "https://jenkins.infra.ozg-cloud.systems/job/E2E%20Tests/job/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/"
    
    OZGCloud's avatar
    OZGCloud committed
            BUNDESLAND = "by"
    
    OZGCloud's avatar
    OZGCloud committed
            SSO_URL = "sso.dev.by.ozg-cloud.de"
            CLUSTER_BASE_URL = "dev.by.ozg-cloud.de"
    
    OZGCloud's avatar
    OZGCloud committed
            FAILED_STAGE = ""
            FAILED_PARALLEL_STAGE = " "
            EA_BEZEICHNER = generateBezeichner("e2e-ea")
            MAIN_BEZEICHNER = generateBezeichner("e2e-main")
    
            ADMIN_BEZEICHNER = generateBezeichner("e2e-admin")
    
    OZGCloud's avatar
    OZGCloud committed
            SH_SUCCESS_STATUS_CODE = 0
    
            FORCE_COLOR = 0
            NO_COLOR = 1
            NX_DISABLE_DB = true
    
    OZGCloud's avatar
    OZGCloud committed
            KEYCLOAK_CLIENT_ADMIN_APP = "admin"
            KEYCLOAK_CLIENT_ALFA_APP = "alfa"
    
    OZGCloud's avatar
    OZGCloud committed
        }
    
        options {
    
    OZGCloud's avatar
    OZGCloud committed
            timeout(time: 2, unit: 'HOURS')
    
    OZGCloud's avatar
    OZGCloud committed
            disableConcurrentBuilds()
    
    OZGCloud's avatar
    OZGCloud committed
            buildDiscarder(logRotator(numToKeepStr: '15'))
    
            skipDefaultCheckout(true)
    
    OZGCloud's avatar
    OZGCloud committed
        }
    
    
        stages {
    
    OZGCloud's avatar
    OZGCloud committed
           stage('Checkout build trigger') {
               when {
                   not {
    
    OZGCloud's avatar
    OZGCloud committed
                       anyOf {
                           triggeredBy 'UpstreamCause'
                           triggeredBy 'BuildUpstreamCause'
                           triggeredBy cause: 'UserIdCause'
                           triggeredBy 'TimerTrigger'
                       }
                   }
    
    OZGCloud's avatar
    OZGCloud committed
               }
               steps {
                   script {
                      SKIP_RUN = true
                       currentBuild.result= "UNSTABLE"
                   }
               }
           }
            stage('Check branch') {
    
                when {
                    triggeredBy 'TimerTrigger'
    
    OZGCloud's avatar
    OZGCloud committed
                }
                steps {
    
    OZGCloud's avatar
    OZGCloud committed
                    script {
                         if (!isMasterBranch()) {
                            echo "Branchname "+env.BRANCH_NAME+" does not match, skipping e2e tests"
                            SKIP_RUN = true
                        }
                    }
    
    OZGCloud's avatar
    OZGCloud committed
            stage('Checkout SCM') {
                when {
                    expression { !SKIP_RUN }
                }
    
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
                        checkout scm
                    }
                }
            }
    
            stage("Clone Gitops Repo") {
    
                when {
    
    OZGCloud's avatar
    OZGCloud committed
                    expression { !SKIP_RUN }
    
                steps {
    
    OZGCloud's avatar
    OZGCloud committed
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
                        cloneGitopsRepo()
                    }
    
    
            stage("Init Default Versions") {
    
                when {
    
    OZGCloud's avatar
    OZGCloud committed
                    expression { !SKIP_RUN }
    
                steps {
                    script {
    
    OZGCloud's avatar
    OZGCloud committed
                        FAILED_STAGE = env.STAGE_NAME
    
    
                        initEnvAlfaDefaultVersions()
                        initEnvVorgangManagerDefaultVersions()
    
                        initEnvUserManagerDefaultVersions()
                    }
                }
            }
    
            stage("Set User Versions") {
                when {
    
    OZGCloud's avatar
    OZGCloud committed
                    expression { !SKIP_RUN }
    
                    beforeInput true
                    triggeredBy cause: "UserIdCause"
                }
                steps {
    
    OZGCloud's avatar
    OZGCloud committed
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
    
                        catchError {
                            timeout(time: 5, unit: 'MINUTES') {
                                userVersions = input message: "Edit Default Values",
                                    parameters: [
                                        string(name: "AlfaImageTag", defaultValue: env.ALFA_IMAGE_TAG, trim: true),
                                        string(name: "AlfaHelmChartVersion", defaultValue: env.ALFA_HELM_CHART_VERSION, trim: true),
                                        string(name: "AlfaHelmRepoUrl", defaultValue: env.ALFA_HELM_REPO_URL, trim: true),
    
                                        string(name: "AdministrationImageTag", defaultValue: env.ADMINISTRATION_IMAGE_TAG, trim: true),
                                        string(name: "AdministrationHelmChartVersion", defaultValue: env.ADMINISTRATION_HELM_CHART_VERSION, trim: true),
                                        string(name: "AdministrationHelmRepoUrl", defaultValue: env.ADMINISTRATION_HELM_REPO_URL, trim: true),
                                        string(name: "AdminClientImageTag", defaultValue: env.ADMIN_CLIENT_IMAGE_TAG, trim: true),
                                        string(name: "AdminClientHelmChartVersion", defaultValue: env.ADMIN_CLIENT_HELM_CHART_VERSION, trim: true),
                                        string(name: "AdminClientHelmRepoUrl", defaultValue: env.ADMIN_CLIENT_HELM_REPO_URL, trim: true),
    
                                        string(name: "VorgangManagerImageTag", defaultValue: env.VORGANG_MANAGER_IMAGE_TAG, trim: true),
                                        string(name: "VorgangManagerHelmChartVersion", defaultValue: env.VORGANG_MANAGER_HELM_CHART_VERSION, trim: true),
                                        string(name: "VorgangManagerHelmRepoUrl", defaultValue: env.VORGANG_MANAGER_HELM_REPO_URL, trim: true),
                                        string(name: "UserManagerImageTag", defaultValue: env.USER_MANAGER_IMAGE_TAG, trim: true),
                                        string(name: "UserManagerHelmChartVersion", defaultValue: env.USER_MANAGER_HELM_CHART_VERSION, trim: true),
                                        string(name: "UserManagerHelmRepoUrl", defaultValue: env.USER_MANAGER_HELM_REPO_URL, trim: true)
                                    ]
    
                                initEnvUserVersions(userVersions)
                            }
                        }
    
    OZGCloud's avatar
    OZGCloud committed
            stage('Init k8s') {
    
                when {
    
    OZGCloud's avatar
    OZGCloud committed
                    expression { !SKIP_RUN }
    
    OZGCloud's avatar
    OZGCloud committed
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
    
    OZGCloud's avatar
    OZGCloud committed
                        configFileProvider([configFile(fileId: 'kubeconfig-dev-okd-cluster', variable: 'KUBE_CONFIG')]) {
    
    OZGCloud's avatar
    OZGCloud committed
                            sh 'mkdir ~/.kube'
                            sh 'cp ${KUBE_CONFIG} ~/.kube/config'
                        }
    
                        sh 'helm version'
                    }
                }
            }
    
    
            stage('Rollout E2E Namespaces') {
    
                when {
    
    OZGCloud's avatar
    OZGCloud committed
                    expression { !SKIP_RUN }
    
    OZGCloud's avatar
    OZGCloud committed
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
    
                        checkoutGitopsE2eBranch()
    
    OZGCloud's avatar
    OZGCloud committed
    
    
                        deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    OZGCloud's avatar
    OZGCloud committed
    
    
                        pushGitopsRepo()
    
                            deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
    
                        }
                    }
                }
            }
    
            stage("Install Cypress") {
                when {
                    expression { !SKIP_RUN }
                }
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
    
    OZGCloud's avatar
    OZGCloud committed
                        withNPM(npmrcConfig: 'npm-nexus-auth') {
                            sh 'npm --version'
                            dir('alfa-client') {
                                sh 'npm cache verify'
                                sh 'npm install'
                                sh "npm run cypress:install"
                            }
    
                        }
                    }
                }
            }
    
            stage('Wait for Rollout E2E Namespaces') {
                when {
                    expression { !SKIP_RUN }
                }
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
    OZGCloud's avatar
    OZGCloud committed
    
    
                      waitForAdminRollout(env.ADMIN_BEZEICHNER)
    
    OZGCloud's avatar
    OZGCloud committed
                      waitForAlfaRollout([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER])
    
    OZGCloud's avatar
    OZGCloud committed
                    }
                }
                post {
                    failure {
                        script {
    
                            deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
    
            stage('Init PortForwards') {
                when {
                    expression { !SKIP_RUN }
                }
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
                        forwardElasticSearch()
                    }
                }
            }
    
            //stage('Run E2E-Tests') {
            //    when {
            //        expression { !SKIP_RUN }
            //    }
            //    failFast false
    
                    stage('E2E-Alfa-EA') {
    
                        when {
                            expression { !SKIP_RUN }
                        }
                        steps {
                            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                                script {
                                    def bezeichner = env.EA_BEZEICHNER
    
                                    Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
    
    
                                    runTests(bezeichner, 'alfa-e2e', 'einheitlicher-ansprechpartner', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME)
    
    
                                    stopForwardMongoDbPort(generateNamespace(bezeichner))
                                }
                            }
                        }
                        post {
                            failure {
                                script {
                                    FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
                                }
                            }
                            always {
                                script {
    
                                    publishAlfaE2ETestResult("einheitlicher-ansprechpartner", "Alfa E2E-Tests EA")
    
                    stage('E2E-Alfa-Main') {
    
    OZGCloud's avatar
    OZGCloud committed
                        when {
    
                            expression { !SKIP_RUN }
    
    OZGCloud's avatar
    OZGCloud committed
                        }
                        steps {
                            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                                script {
                                    def bezeichner = env.MAIN_BEZEICHNER
    
    
                                    Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
    
                                    runTests(bezeichner, 'alfa-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ALFA_APP, mongoDbPort, env.STAGE_NAME)
    
    
                                    stopForwardMongoDbPort(generateNamespace(bezeichner))
    
    OZGCloud's avatar
    OZGCloud committed
                                }
                            }
                        }
                        post {
                            failure {
                                script {
                                    FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
                                }
                            }
                            always {
                                script {
    
                                    publishAlfaE2ETestResult("main-tests", "Alfa E2E-Tests main")
    
                    stage('E2E-Admin-Main') {
                      when {
                        expression { !SKIP_RUN }
                      }
                      steps {
                        catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                          script {
    
                            String bezeichner = env.ADMIN_BEZEICHNER
    
    
                            Integer mongoDbPort = forwardMongoDbPort(generateNamespace(bezeichner))
    
    
    OZGCloud's avatar
    OZGCloud committed
                            runTests(bezeichner, 'admin-e2e', 'main-tests', env.KEYCLOAK_CLIENT_ADMIN_APP, mongoDbPort, env.STAGE_NAME)
    
    
                            stopForwardMongoDbPort(generateNamespace(bezeichner))
                          }
                        }
                      }
                      post {
                        failure {
                          script {
                            FAILED_PARALLEL_STAGE += "${env.STAGE_NAME} "
                          }
                        }
                        always {
                          script {
    
                            publishAdminE2ETestResult()
    
    OZGCloud's avatar
    OZGCloud committed
    
    
            stage('Delete E2E Namespaces') {
                when {
                    expression { !SKIP_RUN }
                }
                steps {
                    script {
                        FAILED_STAGE = env.STAGE_NAME
    
                        deleteNamespaces([env.EA_BEZEICHNER, env.MAIN_BEZEICHNER, env.ADMIN_BEZEICHNER])
    
    OZGCloud's avatar
    OZGCloud committed
        }
        post {
            failure {
                script {
                    if (isMasterBranch() || isReleaseBranch()) {
    
    OZGCloud's avatar
    OZGCloud committed
                        sendFailureMessage()
    
                    }
                }
            }
        }
    }
    
    String getUpstreamProjects() {
        if (isMasterBranch() || isReleaseBranch()){
    
            return "alfa/${env.BRANCH_NAME},vorgang-manager/${env.BRANCH_NAME},user-manager/${env.BRANCH_NAME}"
    
    OZGCloud's avatar
    OZGCloud committed
        return ""
    
    }
    
    def cloneGitopsRepo() {
    
    OZGCloud's avatar
    OZGCloud committed
        final email = "jenkins@ozg-sh.de"
        final name = "jenkins"
    
    
        withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
    
            sh 'git clone https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
    
    OZGCloud's avatar
    OZGCloud committed
    
            dir("gitops") {
                sh "git config user.email '${email}'"
                sh "git config user.name '${name}'"
            }
    
        }
    }
    
    Map getApplicationValues(String application) {
        def applicationValues = readYaml file: "gitops/${getEnvironment()}/application/values/${application}-values.yaml"
    
        return applicationValues.get(application.replaceAll("-", "_"))
    }
    
    String getEnvironment() {
        if (isReleaseBranch()) {
            return "test"
        }
    
        return "dev"
    }
    
    String getImageTag(Map applicationValues) {
        return applicationValues.image.tag
    }
    
    String getHelmChartVersion(Map applicationValues) {
        return applicationValues.helm.version
    }
    
    
    Boolean isMasterBranch() {
        return env.BRANCH_NAME == 'master'
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    String getHelmRepoUrl() {
        if (isReleaseBranch()) {
            return "https://nexus.ozg-sh.de/repository/ozg-base-apps"
        }
    
        return "https://nexus.ozg-sh.de/repository/ozg-base-apps-snapshot"
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    String getFeatureBranchImageTag() {
        return "${env.BRANCH_NAME}-${getRootPomVersion()}"
    }
    
    String getFeatureBranchHelmChartVersion() {
        return "${getRootPomVersion()}-${env.BRANCH_NAME}".replaceAll("_", "-")
    }
    
    String getRootPomVersion() {
        def rootPom = readMavenPom file: 'pom.xml'
    
    OZGCloud's avatar
    OZGCloud committed
        return rootPom.version
    
    Void initEnvAdminDefaultVersions() {
      def values = getApplicationValues('administration')
      env.ADMINISTRATION_IMAGE_TAG = getImageTag(values)
      env.ADMINISTRATION_HELM_CHART_VERSION = getHelmChartVersion(values)
      env.ADMINISTRATION_HELM_REPO_URL = getHelmRepoUrl()
    
      values = getApplicationValues('admin-client')
      env.ADMIN_CLIENT_IMAGE_TAG = getImageTag(values)
      env.ADMIN_CLIENT_HELM_CHART_VERSION = getHelmChartVersion(values)
      env.ADMIN_CLIENT_HELM_REPO_URL = getHelmRepoUrl()
    }
    
    Void initEnvAlfaDefaultVersions() {
      if (isMasterBranch() || isReleaseBranch()) {
        values = getApplicationValues('alfa')
    
        env.ALFA_IMAGE_TAG = getImageTag(values)
        env.ALFA_HELM_CHART_VERSION = getHelmChartVersion(values)
      }
      else {
        env.ALFA_IMAGE_TAG = getFeatureBranchImageTag()
        env.ALFA_HELM_CHART_VERSION = getFeatureBranchHelmChartVersion()
      }
    
      env.ALFA_HELM_REPO_URL = getHelmRepoUrl()
    }
    
    
    Void initEnvVorgangManagerDefaultVersions() {
    
    OZGCloud's avatar
    OZGCloud committed
        def values = getApplicationValues('vorgang-manager')
    
        env.VORGANG_MANAGER_IMAGE_TAG = getImageTag(values)
        env.VORGANG_MANAGER_HELM_CHART_VERSION = getHelmChartVersion(values)
        env.VORGANG_MANAGER_HELM_REPO_URL = getHelmRepoUrl()
    
    }
    
    Void initEnvUserManagerDefaultVersions() {
    
    OZGCloud's avatar
    OZGCloud committed
        def values = getApplicationValues('user-manager')
    
        env.USER_MANAGER_HELM_CHART_VERSION = getHelmChartVersion(values)
    
    OZGCloud's avatar
    OZGCloud committed
        env.USER_MANAGER_HELM_REPO_URL = getHelmRepoUrl()
    
    }
    
    Void initEnvUserVersions(userVersions) {
    
        env.ALFA_IMAGE_TAG = userVersions.AlfaImageTag
        env.ALFA_HELM_CHART_VERSION = userVersions.AlfaHelmChartVersion
        env.ALFA_HELM_REPO_URL = userVersions.AlfaHelmRepoUrl
    
        env.ADMINISTRATION_IMAGE_TAG = userVersions.AdministrationImageTag
        env.ADMINISTRATION_HELM_CHART_VERSION = userVersions.AdministrationHelmChartVersion
        env.ADMINISTRATION_HELM_REPO_URL = userVersions.AdministrationHelmRepoUrl
        env.ADMIN_CLIENT_IMAGE_TAG = userVersions.AdminClientImageTag
        env.ADMIN_CLIENT_HELM_CHART_VERSION = userVersions.AdminClientHelmChartVersion
        env.ADMIN_CLIENT_HELM_REPO_URL = userVersions.AdminClientHelmRepoUrl
    
        env.VORGANG_MANAGER_IMAGE_TAG = userVersions.VorgangManagerImageTag
        env.VORGANG_MANAGER_HELM_CHART_VERSION = userVersions.VorgangManagerHelmChartVersion
        env.VORGANG_MANAGER_HELM_REPO_URL = userVersions.VorgangManagerHelmRepoUrl
    
        env.USER_MANAGER_IMAGE_TAG = userVersions.UserManagerImageTag
        env.USER_MANAGER_HELM_CHART_VERSION = userVersions.UserManagerHelmChartVersion
    
    OZGCloud's avatar
    OZGCloud committed
        env.USER_MANAGER_HELM_REPO_URL = userVersions.UserManagerHelmRepoUrl
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    
    Void pushGitopsRepo() {
        withCredentials([usernamePassword(credentialsId: 'jenkins-gitea-access-token', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {
    
            dir('gitops') {
    
    OZGCloud's avatar
    OZGCloud committed
                if (hasUnpushedCommits()) {
    
                    sh 'git config pull.rebase false'
    
    OZGCloud's avatar
    OZGCloud committed
                    sh 'git pull'
    
                    sh 'git push https://${USER}:${TOKEN}@git.ozg-sh.de/ozgcloud-devops/gitops.git'
    
    OZGCloud's avatar
    OZGCloud committed
                }
            }
        }
    }
    
    Boolean hasUnpushedCommits() {
        return sh (script: "git cherry -v | grep .", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    }
    
    Void checkoutGitopsE2eBranch() {
    
        dir('gitops') {
    
    OZGCloud's avatar
    OZGCloud committed
            sh 'git checkout e2e'
    
      def y1 = generateAdminNamespaceYaml()
    
      def y2 = generateEaNamespaceYaml()
      def y3 = generateMainNamespaceYaml()
    
        sh "git add ${y1} ${y2} ${y3}"
    
        sh "git commit -m 'add e2e namespaces for testrun'"
      }
    
    }
    
    
    Void generateAdminNamespaceYaml() {
      def bezeichner = env.ADMIN_BEZEICHNER
      def envValues
    
      dir("alfa-client/apps/admin-e2e/") {
    
        envValues = readYaml file: "src/fixtures/argocd/by-admin-dev.yaml";
    
        envValues.ozgcloud.bezeichner = bezeichner
        envValues.administration.put("image", ['tag': env.ADMINISTRATION_IMAGE_TAG])
        envValues.administration.put("helm", ['version': env.ADMINISTRATION_HELM_CHART_VERSION, 'repoUrl': env.ADMINISTRATION_HELM_REPO_URL])
    
        envValues.admin_client.put("image", ['tag': env.ADMIN_CLIENT_IMAGE_TAG])
        envValues.admin_client.put("helm", ['version': env.ADMIN_CLIENT_HELM_CHART_VERSION, 'repoUrl': env.ADMIN_CLIENT_HELM_REPO_URL])
      }
    
      return writeYamlToGitOps(bezeichner, envValues);
    
    String generateEaNamespaceYaml() {
        return generateNamespaceYaml(env.EA_BEZEICHNER, "by-ea-dev.yaml");
    
    String generateMainNamespaceYaml() {
        return generateNamespaceYaml(env.MAIN_BEZEICHNER, "by-main-dev.yaml");
    
    String generateNamespaceYaml(String bezeichner, String valuesPathSuffix) {
    
    	def envValues
    	dir('alfa-client/apps/alfa-e2e/') {
    		envValues = readYaml file: "src/fixtures/argocd/" + valuesPathSuffix;
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    		envValues.ozgcloud.bezeichner = bezeichner
    		envValues.alfa.put("image", ['tag': env.ALFA_IMAGE_TAG])
    		envValues.alfa.put("helm", ['version': env.ALFA_HELM_CHART_VERSION, 'repoUrl': env.ALFA_HELM_REPO_URL])
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    		envValues.vorgang_manager.put("image", ['tag': env.VORGANG_MANAGER_IMAGE_TAG])
    		envValues.vorgang_manager.put("helm", ['version': env.VORGANG_MANAGER_HELM_CHART_VERSION, 'repoUrl': env.VORGANG_MANAGER_HELM_REPO_URL])
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    		envValues.user_manager.put("image", ['tag': env.USER_MANAGER_IMAGE_TAG])
    		envValues.user_manager.put("helm", ['version': env.USER_MANAGER_HELM_CHART_VERSION, 'repoUrl': env.USER_MANAGER_HELM_REPO_URL])
    	}
    
      return writeYamlToGitOps(bezeichner, envValues);
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    String writeYamlToGitOps(String bezeichner, Object envValues){
    
      def bezeichnerYaml = "dev/namespace/namespaces/by-${bezeichner}-dev.yaml"
    
    OZGCloud's avatar
    OZGCloud committed
    
    
      writeYaml file: "gitops/${bezeichnerYaml}", data: envValues, overwrite: true
    
    OZGCloud's avatar
    OZGCloud committed
    
    
      return bezeichnerYaml;
    
    Void deleteNamespaces(ozgCloudBezeichner) {
    
        for(bezeichner in ozgCloudBezeichner) {
            if (hasNamespaceFile(bezeichner)) {
                removeNamespaceFile(bezeichner)
            }
        }
    
    OZGCloud's avatar
    OZGCloud committed
    
    
        pushGitopsRepo()
    
    OZGCloud's avatar
    OZGCloud committed
    
    
        for(bezeichner in ozgCloudBezeichner) {
            waitForDeletion(bezeichner)
        }
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    Void removeNamespaceFile(String bezeichner) {
        dir("gitops/dev/namespace/namespaces") {
            sh "rm by-${bezeichner}-dev.yaml"
            sh "git add by-${bezeichner}-dev.yaml"
            sh "git commit -m 'delete e2e by-${bezeichner}-dev.yaml'"
        }
    }
    
    Boolean hasNamespaceFile(String bezeichner) {
        return sh (script: "ls gitops/dev/namespace/namespaces | grep 'by-${bezeichner}-dev.yaml'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    }
    
    Void waitForDeletion(String bezeichner) {
        try {
    
    OZGCloud's avatar
    OZGCloud committed
            sh "kubectl wait --for=delete applications/by-${bezeichner}-dev-application -n argocd --timeout=900s"
    
    OZGCloud's avatar
    OZGCloud committed
        } catch (Exception e) {
            error("Application by-${bezeichner}-dev-application konnte nicht gelöscht werden")
        }
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    Void waitForAlfaRollout(ozgCloudBezeichner) {
    
        for(bezeichner in ozgCloudBezeichner) {
    
    Void waitForAdminRollout(String bezeichner) {
    
    OZGCloud's avatar
    OZGCloud committed
      waitForAlfaRollout([bezeichner])
    
      waitForHealthyApplication(bezeichner, 'administration')
      waitForHealthyApplication(bezeichner, 'admin-client')
    }
    
    Void waitForAlfaRollout(String bezeichner) {
    
    OZGCloud's avatar
    OZGCloud committed
        waitForHealthyApplication(bezeichner, 'application')
    
        waitForHealthyApplication(bezeichner, 'vorgang-manager')
    
    OZGCloud's avatar
    OZGCloud committed
        waitForHealthyApplication(bezeichner, 'user-manager')
    
        waitForHealthyApplication(bezeichner, 'alfa')
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    Void waitForHealthyApplication(String bezeichner, String application) {
        try {
            def countRetry = 0
    
    OZGCloud's avatar
    OZGCloud committed
            def maxRetry = 24
    
    OZGCloud's avatar
    OZGCloud committed
    
            while (!isApplicationPresent(bezeichner, application) && countRetry < maxRetry ) {
                countRetry++
    
                sh "sleep 20"
    
    OZGCloud's avatar
    OZGCloud committed
            }
    
            if (!isApplicationHealthy(bezeichner, application)) {
                waitForHealthyStatus(bezeichner, application)
            }
        } catch (Exception e) {
    
            echo "waitForHealthyApplication Exception: ${e}"
    
    OZGCloud's avatar
    OZGCloud committed
            error("Application ${application} unhealthy")
        }
    }
    
    Boolean isApplicationPresent(String bezeichner, String application) {
        return sh (script: "kubectl get applications -n argocd | grep 'by-${bezeichner}-dev-${application}'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    }
    
    Boolean isApplicationHealthy(String bezeichner, String application) {
        return sh (script: "kubectl get application/by-${bezeichner}-dev-${application} -n argocd -o=jsonpath='{.status.health.status}' | grep Healthy", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    }
    
    Void waitForHealthyStatus(String bezeichner, String application) {
    
    OZGCloud's avatar
    OZGCloud committed
        sh "kubectl wait --for=jsonpath='{.status.health.status}'=Healthy applications/by-${bezeichner}-dev-${application} -n argocd --timeout=900s"
    
    Void publishAlfaE2ETestResult(String appVariant, String reportName) {
      publishE2ETestResult("alfa-e2e", appVariant, reportName);
    
    Void publishAdminE2ETestResult() {
      publishE2ETestResult("admin-e2e", "main-tests", "Admin E2E-Tests main");
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    Void publishE2ETestResult(String appName, String appVariant, String reportName) {
    
      def reportDir = "alfa-client/apps/"+appName+"/reports/"+appVariant;
    
      publishHTML (
        target: [
          allowMissing: false,
          alwaysLinkToLastBuild: false,
          keepAll: true,
    
          reportDir: reportDir,
    
          reportFiles: 'report.html',
          reportName: reportName
        ]
      )
    
    OZGCloud's avatar
    OZGCloud committed
    String runTests(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort, String stageName) {
      def config = generateCypressConfig(bezeichner, appName, appVariant, keycloakClientName, dbPort)
    
      try {
        dir('alfa-client'){
          sh "npm run cypress:version"
          sh "apps/run-tests.sh ${appName} ${appVariant} ${config}"
    
    OZGCloud's avatar
    OZGCloud committed
        }
    
      } catch (Exception e) {
        printNpmDebugLog()
    
        error("Fehler in Stage ${stageName}")
      }
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    Void printNpmDebugLog() {
        if (hasNpmDebugLog()) {
            sh "cat /root/.npm/_logs/*-debug.log"
        }
        else {
            echo "Npm debug log not found"
        }
    }
    
    String makeUrlConform(String input) {
        return input.replaceAll(/[^a-zA-Z0-9]+/, "").toLowerCase()
    }
    
    String generateBezeichner(String stage) {
        def branchName = makeUrlConform(env.BRANCH_NAME)
        def stageName = makeUrlConform(stage)
    
        return "${cutBranchNameForKeycloakRealm(branchName, stageName)}-${stageName}"
    }
    
    String cutBranchNameForKeycloakRealm(String branchName, String stageName) {
        final maxKeycloakRealmLength = 30
    
        def cutBranchNamePosition = maxKeycloakRealmLength - (stageName.length() + "${env.BUNDESLAND}---dev".length())
    
        return branchName.take(cutBranchNamePosition)
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    String generateCypressConfig(String bezeichner, String appName, String appVariant, String keycloakClientName, Integer dbPort) {
    
      def namespace = generateNamespace(bezeichner)
      def configName = "cypress-ci-"+appVariant+".json"
    
    OZGCloud's avatar
    OZGCloud committed
    
    
    OZGCloud's avatar
    OZGCloud committed
      dir("alfa-client/apps/${appName}/"){
    
        def config = readJSON file: 'cypress-ci.json'
    
        def vorgangManagerDatabaseSecret = getVorgangManagerDatabaseSecret(namespace);
        def decodedPassword = decodeString(vorgangManagerDatabaseSecret.password);
        def parsablePassword = makePasswordUrlConform(decodedPassword);
    
        config.baseUrl = "https://${generateUrlBezeichner(bezeichner, appName)}.${env.CLUSTER_BASE_URL}" as String
    
        config.env.dbUrl = "mongodb://${decodeString(vorgangManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String
        config.env.keycloakUrl = "https://${env.SSO_URL}/" as String
        config.env.keycloakRealm = namespace as String
    
    OZGCloud's avatar
    OZGCloud committed
        config.env.keycloakClient = keycloakClientName as String
    
        config.videosFolder = "./reports/${appVariant}/videos" as String
        config.screenshotsFolder = "./reports/${appVariant}/screenshots" as String
        config.reporterOptions.reportDir = "./reports/${appVariant}/mochawesome-report" as String
    
    OZGCloud's avatar
    OZGCloud committed
    
    
        config.specPattern = "src/e2e/${appVariant}/**/*.cy.{js,jsx,ts,tsx}" as String
    
    OZGCloud's avatar
    OZGCloud committed
    
    
        config.env.put("search", getElasticsearchEnv(namespace))
        config.env.put("userManager", getUserManagerEnv(namespace, dbPort))
        config.env.put("smocker", getSmockerEnv(namespace))
    
        writeJSON file: configName, json: config
    
      return "cypress-ci-"+appVariant+".config.ts"
    
    String generateUrlBezeichner(String bezeichner, String appName){
        if(appName == 'admin-e2e'){
            return "${bezeichner}-admin";
        }
        return bezeichner;
    }
    
    
    String makePasswordUrlConform(String password) {
        return sh (script: "printf %s ${password} | jq -sRr @uri", returnStdout: true);
    }
    
    
    Map getVorgangManagerDatabaseSecret(String namespace) {
        return readJSON ( text: sh (script: "kubectl get secret ozg-mongodb-admin-vorgang-manager-user -n ${namespace} -o jsonpath={.data}", returnStdout: true))
    
    OZGCloud's avatar
    OZGCloud committed
    Map getUserManagerEnv(String namespace, dbPort){
    
        def userManagerDatabaseSecret = getUserManagerDatabaseSecret(namespace);
    
    OZGCloud's avatar
    OZGCloud committed
        def decodedPassword = decodeString(userManagerDatabaseSecret.password);
    
        def parsablePassword = makePasswordUrlConform(decodedPassword);
    
    OZGCloud's avatar
    OZGCloud committed
        return [
    
            "dbUrl": "mongodb://${decodeString(userManagerDatabaseSecret.username)}:${parsablePassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true&socketTimeoutMS=30000&heartbeatFrequencyMS=10000" as String,
    
    OZGCloud's avatar
    OZGCloud committed
            "database": "user-manager-database"
            ]
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    Map getUserManagerDatabaseSecret(String namespace) {
        return readJSON ( text: sh (script: "kubectl get secret ozg-mongodb-admin-user-manager-user -n ${namespace} -o jsonpath={.data}", returnStdout: true))
    
    OZGCloud's avatar
    OZGCloud committed
    Void sendFailureMessage() {
        def data = [
            "msgtype": "m.text",
            "body": "E2E-Tests: Failed stage: ${getFailedStage()} Build-ID: ${env.BUILD_NUMBER} Link: ${BLUE_OCEAN_URL}" as String,
            "format": "org.matrix.custom.html",
            "formatted_body": "E2E-Tests: Failed stage: ${getFailedStage()} Build-ID: <a href='${BLUE_OCEAN_URL}'>${env.BUILD_NUMBER}</a>" as String
            ]
    
        sh "curl -XPOST -H 'authorization: Bearer ${getElementAccessToken()}' -d '${JsonOutput.toJson(data)}' https://matrix.ozg-sh.de/_matrix/client/v3/rooms/${getElementRoomId()}/send/m.room.message"
    }
    
    String getFailedStage() {
        if (FAILED_PARALLEL_STAGE.trim()) {
    
    OZGCloud's avatar
    OZGCloud committed
            return FAILED_PARALLEL_STAGE.trim()
    
    OZGCloud's avatar
    OZGCloud committed
        }
    
        return FAILED_STAGE
    }
    
    String getElementRoomId() {
        final releaseRoomId = "!oWZpUGTFsxkJIYNfYg:matrix.ozg-sh.de"
        final masterRoomId = "!iQPAvQIiRwRpNOszjw:matrix.ozg-sh.de"
    
        if (isReleaseBranch()) {
            return releaseRoomId
        }
    
        return masterRoomId
    }
    
    
    Boolean isReleaseBranch() {
        return env.BRANCH_NAME == 'release'
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    String getElementAccessToken() {
        withCredentials([string(credentialsId: 'element-login-json', variable: 'LOGIN_JSON')]) {
            return readJSON ( text: sh (script: '''curl -XPOST -d \"$LOGIN_JSON\" https://matrix.ozg-sh.de/_matrix/client/v3/login''', returnStdout: true)).access_token
        }
    }
    
    Map getElasticsearchEnv(String namespace) {
        def elasticsearchSecret = getElasticsearchSecret(namespace)
    
        return [
            "user": decodeString(elasticsearchSecret.username),
            "password": decodeString(elasticsearchSecret.password),
            "index": decodeString(elasticsearchSecret.index),
            "url": "https://localhost:9200"
            ]
    }
    
    
    Void forwardMongoDbPort(String namespace) {
    
    OZGCloud's avatar
    OZGCloud committed
        try {
    
            def minPort = 20000
            def portRange = 20000
            //def dbPort = "${Math.abs(new Random().nextInt(portRange+1))+minPort}" as Integer
            def dbPort = Math.abs(new Random().nextInt(portRange+1))+minPort
    
            echo "Forwarding MongoDB Port to local port ${dbPort}"
    
            def pidFile = generateMongoDbPortForwardPidFile(namespace)
    
    OZGCloud's avatar
    OZGCloud committed
            sh "kubectl port-forward ozg-mongodb-0 ${dbPort}:27017 -n ${namespace} & echo \$! > ${pidFile}"
    
    OZGCloud's avatar
    OZGCloud committed
        }
        catch (Exception e) {
    
            echo "forwardMongoDbPort Exception: ${e}"
    
    OZGCloud's avatar
    OZGCloud committed
            error("Error forwarding service")
        }
    }
    
    
    Void stopForwardMongoDbPort(String namespace) {
        echo "Removing forwarding MongoDB Port to local port for ${namespace}"
        def pidFile = generateMongoDbPortForwardPidFile(namespace)
        dir('alfa-client/apps/alfa-e2e/src/jenkins-build-files') {
            sh "./kill-pid-by-filename.sh ${pidFile}"
        }
    }
    
    Void generateMongoDbPortForwardPidFile(String namespace) {
        return "/tmp/pid_file_mongodb_port_forward_${namespace}.pid"
    }
    
    
    OZGCloud's avatar
    OZGCloud committed
    Void forwardElasticSearch() {
        if(!isElasticSearchForwarded()) {
            sh "kubectl port-forward ozg-search-cluster-es-ozg-search-0 9200:9200 -n elastic-system &"
        }
    }
    
    Boolean isElasticSearchForwarded() {
        return sh (script: "lsof -i -P -n | grep LISTEN | grep :9200", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    }
    
    String generateNamespace(String bezeichner) {
        return "${env.BUNDESLAND}-${bezeichner}-dev"
    }
    
    String decodeString(String encoded) {
    
      return sh (script: "echo -n ${encoded} | base64 --decode", returnStdout: true)
    
    OZGCloud's avatar
    OZGCloud committed
    }
    
    Map getElasticsearchSecret(String namespace) {
        return readJSON ( text: sh (script: "kubectl get secret elasticsearch-credentials -n ${namespace} -o jsonpath={.data}", returnStdout: true))
    }
    
    Boolean hasNpmDebugLog() {
        return sh (script: "ls -l /root/.npm/_logs/*-debug.log", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
    
    }
    
    Map getSmockerEnv(String namespace) {
        return [
    
    OZGCloud's avatar
    OZGCloud committed
            "url": "https://${namespace}-smocker.dev.by.ozg-cloud.de".toString()