diff --git a/Jenkinsfile b/Jenkinsfile index b80266876dc2f1f182b1f0c2033b82fe1ca58ae2..a2821930c10fc2a340deb528109a7d82eed0136e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ pipeline { agent { node { - label 'jenkins-worker' + label 'jenkins-build-agent' } } @@ -54,36 +54,34 @@ pipeline { } stage('Client') { steps { - container("nodejs"){ - script { - FAILED_STAGE=env.STAGE_NAME + script { + FAILED_STAGE=env.STAGE_NAME - sh 'npm --version' - dir('goofy-client') { - sh 'echo "registry=https://nexus.ozg-sh.de/repository/npm-proxy" >> ~/.npmrc' - sh 'echo "_auth=amVua2luczpQaihzX0ZNNFU5ZC8=" >> ~/.npmrc' + sh 'npm --version' + dir('goofy-client') { + sh 'echo "registry=https://nexus.ozg-sh.de/repository/npm-proxy" >> ~/.npmrc' + sh 'echo "_auth=amVua2luczpQaihzX0ZNNFU5ZC8=" >> ~/.npmrc' - sh 'npm cache verify' - sh 'npm install --no-optional --legacy-peer-deps' + sh 'npm cache verify' + sh 'npm install --legacy-peer-deps' - if (env.BRANCH_NAME == 'release') { - sh 'npm run ci-prodBuild' - } - else { - sh 'npm run ci-build' - } + if (env.BRANCH_NAME == 'release') { + sh 'npm run ci-prodBuild' + } + else { + sh 'npm run ci-build' + } - sh 'npm run ci-test' + sh 'npm run ci-test' - try { - if (env.BRANCH_NAME == 'master') { - withSonarQubeEnv('sonarqube-ozg-sh'){ - sh 'npm run ci-sonar' - } + try { + if (env.BRANCH_NAME == 'master') { + withSonarQubeEnv('sonarqube-ozg-sh'){ + sh 'npm run ci-sonar' } - } catch (Exception e) { - unstable("SonarQube failed") - } + } + } catch (Exception e) { + unstable("SonarQube failed") } } } @@ -100,40 +98,37 @@ pipeline { FAILED_STAGE=env.STAGE_NAME IMAGE_TAG = generateImageTag() - container("maven-17"){ - configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) { - sh 'mvn --version' - sh "mvn -s $MAVEN_SETTINGS -pl -goofy-client clean install spring-boot:build-image -Dspring-boot.build-image.imageName=docker.ozg-sh.de/goofy:${IMAGE_TAG} -Dspring-boot.build-image.publish -Dmaven.wagon.http.retryHandler.count=3" - - try { - if (env.BRANCH_NAME == 'master') { - dir('goofy-server'){ - withSonarQubeEnv('sonarqube-ozg-sh'){ - sh 'mvn -s $MAVEN_SETTINGS sonar:sonar' - } + configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) { + sh 'mvn --version' + sh "mvn -s $MAVEN_SETTINGS -pl -goofy-client clean install spring-boot:build-image -Dspring-boot.build-image.imageName=docker.ozg-sh.de/goofy:${IMAGE_TAG} -Dspring-boot.build-image.publish -Dmaven.wagon.http.retryHandler.count=3" + + try { + if (env.BRANCH_NAME == 'master') { + dir('goofy-server'){ + withSonarQubeEnv('sonarqube-ozg-sh'){ + sh 'mvn -s $MAVEN_SETTINGS sonar:sonar' } - } - } catch (Exception e) { - unstable("SonarQube failed") - } + } + } + } catch (Exception e) { + unstable("SonarQube failed") } } } } - post { - always{ - junit testResults: '**/target/surefire-reports/*.xml', skipPublishingChecks: true - } - } + post { + always{ + junit testResults: '**/target/surefire-reports/*.xml', skipPublishingChecks: true + } + } } stage('Init k8s') { steps { script { FAILED_STAGE = env.STAGE_NAME E2E_FAILED = "" - } - container("k8s") { - configFileProvider([configFile(fileId: 'jenkins-kuby-kubeconfig', variable: 'KUBE_CONFIG')]) { + + configFileProvider([configFile(fileId: 'kubeconfig-old-dev-cluster', variable: 'KUBE_CONFIG')]) { sh 'mkdir ~/.kube' sh 'cp ${KUBE_CONFIG} ~/.kube/config' } @@ -142,7 +137,6 @@ pipeline { sh 'helm version' } - setAnsibleKubeConfig() } } stage('Deploy Maven Artifacts to Nexus') { @@ -156,10 +150,9 @@ pipeline { script { FAILED_STAGE = env.STAGE_NAME } - container('maven-17') { - configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) { - sh 'mvn -s $MAVEN_SETTINGS -pl -goofy-client -DskipTests deploy' - } + + configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) { + sh 'mvn -s $MAVEN_SETTINGS -pl -goofy-client -DskipTests deploy' } } } @@ -187,20 +180,18 @@ pipeline { stage('Test, build and deploy Helm Chart') { steps { - container('k8s') { - script { - FAILED_GOOFY_STAGE=env.STAGE_NAME - HELM_CHART_VERSION = generateHelmChartVersion() + script { + FAILED_GOOFY_STAGE=env.STAGE_NAME + HELM_CHART_VERSION = generateHelmChartVersion() - dir('src/main/helm') { - sh "helm lint -f test-values.yaml" + dir('src/main/helm') { + sh "helm lint -f test-values.yaml" - sh "helm unittest -f '../../test/helm/*.yaml' ." + sh "helm unittest -f '../../test/helm/*.yaml' ." - sh "helm package --version=${HELM_CHART_VERSION} ." + sh "helm package --version=${HELM_CHART_VERSION} ." - deployHelmChart(HELM_CHART_VERSION) - } + deployHelmChart(HELM_CHART_VERSION) } } } @@ -236,10 +227,11 @@ pipeline { script { def stageName = env.STAGE_NAME def bezeichner = generateBezeichner(stageName) + def dbPort = 27018 - startEnvironment(bezeichner, stageName, IMAGE_TAG, true, HELM_CHART_VERSION) + startEnvironment(bezeichner, stageName, IMAGE_TAG, true, HELM_CHART_VERSION, 'sh', dbPort) - def testResult = runTests(stageName, bezeichner, 'einheitlicher-ansprechpartner') + def testResult = runTests(stageName, bezeichner, 'einheitlicher-ansprechpartner', 'sh', dbPort) if (env.BRANCH_NAME != 'master') { deleteKopStack(bezeichner, stageName) @@ -264,10 +256,11 @@ pipeline { script { def stageName = env.STAGE_NAME def bezeichner = generateBezeichner(stageName) + def dbPort = 27019 - startEnvironment(bezeichner, stageName, IMAGE_TAG, false, HELM_CHART_VERSION) + startEnvironment(bezeichner, stageName, IMAGE_TAG, false, HELM_CHART_VERSION, 'sh', dbPort) - def testResult = runTests(stageName, bezeichner, 'main-tests') + def testResult = runTests(stageName, bezeichner, 'main-tests', 'sh', dbPort) if (env.BRANCH_NAME != 'master') { deleteKopStack(bezeichner, stageName) @@ -332,10 +325,10 @@ pipeline { Void deployHelmChart(String helmChartVersion) { withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]){ if (env.BRANCH_NAME == 'release') { - result = sh script: '''curl -u $USERNAME:$PASSWORD http://nexus.dev-tools:8081/service/rest/v1/components?repository=ozg-base-apps -F file=@goofy-'''+helmChartVersion+'''.tgz''', returnStdout: true + result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps -F file=@goofy-'''+helmChartVersion+'''.tgz''', returnStdout: true } else { - result = sh script: '''curl -u $USERNAME:$PASSWORD http://nexus.dev-tools:8081/service/rest/v1/components?repository=ozg-base-apps-snapshot -F file=@goofy-'''+helmChartVersion+'''.tgz''', returnStdout: true + result = sh script: '''curl -u $USERNAME:$PASSWORD https://nexus.ozg-sh.de/service/rest/v1/components?repository=ozg-base-apps-snapshot -F file=@goofy-'''+helmChartVersion+'''.tgz''', returnStdout: true } if (result != '') { @@ -358,13 +351,11 @@ String generateHelmChartVersion() { } Void tagAndPushDockerImage(String newTag){ - container("docker") { - withCredentials([usernamePassword(credentialsId: 'jenkins-docker-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) { - sh 'docker login docker.ozg-sh.de -u ${USER} -p ${PASSWORD}' + withCredentials([usernamePassword(credentialsId: 'jenkins-docker-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) { + sh 'docker login docker.ozg-sh.de -u ${USER} -p ${PASSWORD}' - sh "docker tag docker.ozg-sh.de/goofy:${IMAGE_TAG} docker.ozg-sh.de/goofy:${newTag}" - sh "docker push docker.ozg-sh.de/goofy:${newTag}" - } + sh "docker tag docker.ozg-sh.de/goofy:${IMAGE_TAG} docker.ozg-sh.de/goofy:${newTag}" + sh "docker push docker.ozg-sh.de/goofy:${newTag}" } } @@ -378,7 +369,7 @@ String generateImageTag() { return imageTag } -Void startEnvironment(String bezeichner, String stage, String imageTag, Boolean isEa, String chartVersion) { +Void startEnvironment(String bezeichner, String stage, String imageTag, Boolean isEa, String chartVersion, String bundesland, dbPort) { setupAnsible(imageTag, stage, isEa, chartVersion) try { @@ -388,8 +379,10 @@ Void startEnvironment(String bezeichner, String stage, String imageTag, Boolean } rolloutKopStack(bezeichner, stage) - addKeycloakGroups(bezeichner, stage) - addKeycloakUser(bezeichner, stage) + addKeycloakGroups(bezeichner, stage, bundesland) + addKeycloakUser(bezeichner, stage, bundesland) + exposeDatenbank("${bundesland}-${bezeichner}-dev", dbPort) + exposeElasticSearch() } Void setupAnsible(String imageTag, String stage, Boolean isEa, String chartVersion) { @@ -409,11 +402,9 @@ Void setupAnsible(String imageTag, String stage, Boolean isEa, String chartVersi } Void setAnsibleKubeConfig() { - container("ansible") { - configFileProvider([configFile(fileId: 'jenkins-kuby-kubeconfig', variable: 'KUBE_CONFIG')]) { - sh 'mkdir ~/.kube' - sh 'cp ${KUBE_CONFIG} ~/.kube/config' - } + configFileProvider([configFile(fileId: 'kubeconfig-old-dev-cluster', variable: 'KUBE_CONFIG')]) { + sh 'mkdir ~/.kube' + sh 'cp ${KUBE_CONFIG} ~/.kube/config' } } @@ -514,91 +505,83 @@ Void setPlutoDatabasePassword(String stage) { } Void rolloutKopStack(String bezeichner, String stage) { - container("ansible") { - dir("${stage}/provisioning") { - def ansibleVars = """{"k8s_context":"ozg-dev", \ - "kop_env":"dev", \ - "kop_bezeichner":${bezeichner}, \ - "kop_displayname":${bezeichner}, \ - "kop_postfach_api_key":"", \ - "install_afm_adapter":false, \ - "install_fs_adapter":false, \ - "external_db_enabled":false, \ - "disable_update":true}""" + dir("${stage}/provisioning") { + def ansibleVars = """{"k8s_context":"ozg-dev", \ + "kop_env":"dev", \ + "kop_bezeichner":${bezeichner}, \ + "kop_displayname":${bezeichner}, \ + "kop_postfach_api_key":"", \ + "install_afm_adapter":false, \ + "install_fs_adapter":false, \ + "external_db_enabled":false, \ + "disable_update":true}""" - if (env.BRANCH_NAME == 'release') { - sh "ansible-playbook playbook/rollout.yml --extra-vars '${ansibleVars}'" - } - else { - sh "ansible-playbook playbooks/rollout.yml --extra-vars '${ansibleVars}'" - } + if (env.BRANCH_NAME == 'release') { + sh "ansible-playbook playbook/rollout.yml --extra-vars '${ansibleVars}'" + } + else { + sh "ansible-playbook playbooks/rollout.yml --extra-vars '${ansibleVars}'" } } } -Void addKeycloakGroups(String bezeichner, String stage) { - container("ansible") { - def groupFiles = sh (script: 'ls goofy-client/apps/goofy-e2e/src/fixtures/group', returnStdout: true) +Void addKeycloakGroups(String bezeichner, String stage, String bundesland) { + def groupFiles = sh (script: 'ls goofy-client/apps/goofy-e2e/src/fixtures/group', returnStdout: true) - groupFiles.split("\\n").each { group -> - def groupJson = sh (script: "cat goofy-client/apps/goofy-e2e/src/fixtures/group/${group}", returnStdout: true) + groupFiles.split("\\n").each { group -> + def groupJson = sh (script: "cat goofy-client/apps/goofy-e2e/src/fixtures/group/${group}", returnStdout: true) - def ansibleVars = """{"k8s_context":"ozg-dev", \ - "kop_env":"dev", \ - "keycloak_realm":"sh-${bezeichner}-dev", \ - "group":${groupJson} + def ansibleVars = """{"k8s_context":"ozg-dev", \ + "kop_env":"dev", \ + "keycloak_realm":"${bundesland}-${bezeichner}-dev", \ + "group":${groupJson} }""" - dir("${stage}/provisioning") { - if (env.BRANCH_NAME == 'release') { - sh "ansible-playbook playbook/add-keycloak-group.yml --extra-vars '${ansibleVars}'" - } - else { - sh "ansible-playbook playbooks/add-keycloak-group.yml --extra-vars '${ansibleVars}'" - } + dir("${stage}/provisioning") { + if (env.BRANCH_NAME == 'release') { + sh "ansible-playbook playbook/add-keycloak-group.yml --extra-vars '${ansibleVars}'" } - } - } + else { + sh "ansible-playbook playbooks/add-keycloak-group.yml --extra-vars '${ansibleVars}'" + } + } + } } -Void addKeycloakUser(String bezeichner, String stage) { - container("ansible") { - def userFiles = sh (script: 'ls goofy-client/apps/goofy-e2e/src/fixtures/user', returnStdout: true) +Void addKeycloakUser(String bezeichner, String stage, String bundesland) { + def userFiles = sh (script: 'ls goofy-client/apps/goofy-e2e/src/fixtures/user', returnStdout: true) - userFiles.split("\\n").each { user -> - def userJson = sh (script: "cat goofy-client/apps/goofy-e2e/src/fixtures/user/${user}", returnStdout: true) + userFiles.split("\\n").each { user -> + def userJson = sh (script: "cat goofy-client/apps/goofy-e2e/src/fixtures/user/${user}", returnStdout: true) - def ansibleVars = """{"k8s_context":"ozg-dev", \ - "kop_env":"dev", \ - "keycloak_realm":"sh-${bezeichner}-dev", \ - "user":${userJson} - }""" + def ansibleVars = """{"k8s_context":"ozg-dev", \ + "kop_env":"dev", \ + "keycloak_realm":"${bundesland}-${bezeichner}-dev", \ + "user":${userJson} + }""" - dir("${stage}/provisioning") { - if (env.BRANCH_NAME == 'release') { - sh "ansible-playbook playbook/add-keycloak-user.yml --extra-vars '${ansibleVars}'" - } - else { - sh "ansible-playbook playbooks/add-keycloak-user.yml --extra-vars '${ansibleVars}'" - } + dir("${stage}/provisioning") { + if (env.BRANCH_NAME == 'release') { + sh "ansible-playbook playbook/add-keycloak-user.yml --extra-vars '${ansibleVars}'" + } + else { + sh "ansible-playbook playbooks/add-keycloak-user.yml --extra-vars '${ansibleVars}'" } } } } Void deleteKopStack(String bezeichner, String stage) { - container("ansible") { - dir("${stage}/provisioning") { - def ansibleVars = """{"k8s_context":"ozg-dev", \ - "kop_env":"dev", \ - "kop_bezeichner":${bezeichner}}""" + dir("${stage}/provisioning") { + def ansibleVars = """{"k8s_context":"ozg-dev", \ + "kop_env":"dev", \ + "kop_bezeichner":${bezeichner}}""" - if (env.BRANCH_NAME == 'release') { - sh "ansible-playbook playbook/delete-commune.yml --extra-vars '${ansibleVars}'" - } - else { - sh "ansible-playbook playbooks/delete-commune.yml --extra-vars '${ansibleVars}'" - } + if (env.BRANCH_NAME == 'release') { + sh "ansible-playbook playbook/delete-commune.yml --extra-vars '${ansibleVars}'" + } + else { + sh "ansible-playbook playbooks/delete-commune.yml --extra-vars '${ansibleVars}'" } } } @@ -616,22 +599,20 @@ Void publishE2ETestResult(String reportFolder, String reportName) { ) } -String runTests(String stageName, String bezeichner, String reportFolder) { - def configFile = generateCypressConfig(stageName, bezeichner, reportFolder) +String runTests(String stageName, String bezeichner, String reportFolder, String bundesland, dbPort) { + def configFile = generateCypressConfig(stageName, bezeichner, reportFolder, bundesland, dbPort) - container("cypress") { - try { - dir("goofy-client") { - sh "npm run cypress:version" - sh "npm run cypress:ci-run --CONFIG_FILE=${configFile} --REPORT_FOLDER=${reportFolder}" + try { + dir("goofy-client") { + sh "npm run cypress:version" + sh "npm run cypress:ci-run --CONFIG_FILE=${configFile} --REPORT_FOLDER=${reportFolder}" - return true - } - } catch (Exception e) { - sh "ls -l /root/.npm/_logs/*-debug.log" - sh "cat /root/.npm/_logs/*-debug.log" - return false + return true } + } catch (Exception e) { + sh "ls -l /root/.npm/_logs/*-debug.log" + sh "cat /root/.npm/_logs/*-debug.log" + return false } } @@ -658,16 +639,18 @@ String cutBranchNameForKeycloakRealm(String branchName, String stageName) { return branchName } -String generateCypressConfig(String stage, String bezeichner, String testFolder) { - def namespace = "sh-${bezeichner}-dev" +String generateCypressConfig(String stage, String bezeichner, String testFolder, String bundesland, dbPort) { + def namespace = "${bundesland}-${bezeichner}-dev" def configName = "cypress-ci-"+testFolder+".json" + + def url = ".dev.ozg-sh.de" dir('goofy-client/apps/goofy-e2e/'){ def config = readJSON file: 'cypress-ci.json' def elasticsearchEnv = getElasticsearchEnv(namespace) - config.baseUrl = "https://${bezeichner}.dev.ozg-sh.de" as String - config.env.dbUrl = "mongodb+srv://pluto-database-user:XnHhfznNWg65NNd@pluto-database-svc.${namespace}.svc.cluster.local/admin?ssl=false" as String + config.baseUrl = "https://${bezeichner}.${url}" as String + config.env.dbUrl = "mongodb://pluto-database-user:XnHhfznNWg65NNd@localhost:${dbPort}/admin?ssl=false&directConnection=true" as String config.env.keycloakRealm = namespace as String config.env.keycloakClient = namespace + "-goofy" as String config.env.sabineUuid = getKeycloakUuid(namespace, "sabine") as String @@ -679,7 +662,7 @@ String generateCypressConfig(String stage, String bezeichner, String testFolder) environment = config.env environment.put("search", elasticsearchEnv) - environment.put("userManager", getUserManagerEnv(namespace)); + environment.put("userManager", getUserManagerEnv(namespace, dbPort)); writeJSON file: configName, json: config @@ -689,19 +672,17 @@ String generateCypressConfig(String stage, String bezeichner, String testFolder) return configName } -String getUserManagerEnv(namespace){ +String getUserManagerEnv(namespace, dbPort){ def secret = getSecrect(namespace, 'pluto-database-admin-user-manager-database-user'); def secretPassword = decodeString(secret.password); return readJSON(text: """{ - "dbUrl":"mongodb+srv://user-manager-database-user:${secretPassword}@pluto-database-svc.${namespace}.svc.cluster.local/admin?ssl=false", \ + "dbUrl":"mongodb://user-manager-database-user:${secretPassword}@localhost:${dbPort}/admin?ssl=false&directConnection=true", \ "database":"user-manager-database"}"""); } def getSecrect(namespace, secretName){ - container("k8s"){ - script { - return readJSON ( text: sh (script: "kubectl get secret ${secretName} -n ${namespace} -o jsonpath={.data}", returnStdout: true)) - } + script { + return readJSON ( text: sh (script: "kubectl get secret ${secretName} -n ${namespace} -o jsonpath={.data}", returnStdout: true)) } } @@ -722,7 +703,7 @@ String getKeycloakUuid(realm, userName) { } String getKeycloakAccessToken() { - withCredentials([usernamePassword(credentialsId: 'keycloak-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) { + withCredentials([usernamePassword(credentialsId: 'keycloak-old-dev-cluster', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) { def token = readJSON text: sh (script: 'curl -d "client_id=admin-cli" -d "username=$USER" -d "password=$PASSWORD" -d "grant_type=password" "https://sso.dev.ozg-sh.de/realms/master/protocol/openid-connect/token"', returnStdout: true) return token.access_token @@ -760,12 +741,10 @@ Void initHelmRepo() { } def getElasticsearchSecret(namespace) { - container("k8s"){ - script { - def elasticsearch = readJSON ( text: sh (script: "kubectl get secret elasticsearch-credentials -n ${namespace} -o jsonpath={.data}", returnStdout: true)) + script { + def elasticsearch = readJSON ( text: sh (script: "kubectl get secret elasticsearch-credentials -n ${namespace} -o jsonpath={.data}", returnStdout: true)) - return elasticsearch - } + return elasticsearch } } @@ -776,7 +755,7 @@ String getElasticsearchEnv(namespace) { "user":"${decodeString(elasticsearchSecret.username)}", \ "password":"${decodeString(elasticsearchSecret.password)}", \ "index":"${decodeString(elasticsearchSecret.index)}", \ - "url":"${decodeString(elasticsearchSecret.uris)}"}""" + "url":"http://localhost:9200"}""" return readJSON ( text: env) } @@ -817,3 +796,14 @@ Void pushNewProvisioningVersion(String environment) { } } } + +Void exposeElasticSearch() { + portStatus = sh (script: "lsof -i -P -n | grep LISTEN | grep :9200", returnStatus: true) as Integer + if(portStatus == 1) { + sh "kubectl port-forward ozg-search-cluster-es-ozg-search-0 9200:9200 -n elastic-system &" + } +} + +Void exposeDatenbank(String namespace, port) { + sh "kubectl port-forward pluto-database-0 ${port}:27017 -n ${namespace} &" +} \ No newline at end of file