diff --git a/.github/workflows/api.yml b/.github/workflows/ci-api-build.and.test.yml similarity index 56% rename from .github/workflows/api.yml rename to .github/workflows/ci-api-build.and.test.yml index 9f40dbb4..2d5e8dd7 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/ci-api-build.and.test.yml @@ -1,7 +1,7 @@ name: API CI on: - workflow_dispatch: + workflow_dispatch: push: branches: - master @@ -18,51 +18,51 @@ on: jobs: quality_profile: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 defaults: run: working-directory: api steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v3 with: - java-version: 11 - - uses: actions/cache@v1 + java-version: 17 + distribution: oracle + - uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Run unit tests - run: mvn -f pom.xml clean test + run: mvn -f pom.xml clean package - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar - #- name: Run Sonar Analysis - # run: mvn -f pom.xml sonar:sonar - # -Dsonar.login=${{ secrets.SONAR_TOKEN }} - # -Dsonar.host.url=https://sonarcloud.io - #-Dsonar.organization=bcgov-sonarcloud - #-Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} + - name: Run Sonar Analysis + run: mvn -f pom.xml sonar:sonar + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + -Dsonar.host.url=https://sonarcloud.io + -Dsonar.organization=bcgov-sonarcloud + -Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} env: GITHUB_TOKEN: ${{ github.token }} - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@master + uses: aquasecurity/trivy-action@0.10.0 with: scan-type: 'fs' ignore-unfixed: true - format: 'template' - template: '@/contrib/sarif.tpl' + format: 'sarif' output: 'trivy-results.sarif' - severity: 'LOW' + severity: 'CRITICAL' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 with: - sarif_file: 'trivy-results.sarif' + sarif_file: 'trivy-results.sarif' \ No newline at end of file diff --git a/.github/workflows/deploy-to.openshift-dev.yml b/.github/workflows/deploy-to.openshift-dev.yml new file mode 100644 index 00000000..edf037ba --- /dev/null +++ b/.github/workflows/deploy-to.openshift-dev.yml @@ -0,0 +1,170 @@ +name: Build & Deploy to DEV + +env: + # 🖊️ EDIT your repository secrets to log into your OpenShift cluster and set up the context. + # See https://github.com/redhat-actions/oc-login#readme for how to retrieve these values. + # To get a permanent token, refer to https://github.com/redhat-actions/oc-login/wiki/Using-a-Service-Account-for-GitHub-Actions + OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }} + OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }} + OPENSHIFT_NAMESPACE_DEV: ${{ secrets.PEN_NAMESPACE_NO_ENV }}-dev + + DB_JDBC_CONNECT_STRING: ${{ secrets.DB_JDBC_CONNECT_STRING }} + DB_PWD: ${{ secrets.DB_PWD }} + DB_USER: ${{ secrets.DB_USER }} + SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }} + + # 🖊️ EDIT to change the image registry settings. + # Registries such as GHCR, Quay.io, and Docker Hub are supported. + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_REGISTRY_USER: ${{ github.actor }} + IMAGE_REGISTRY_PASSWORD: ${{ github.token }} + + # 🖊️ EDIT to specify custom tags for the container image, or default tags will be generated below. + IMAGE_TAGS: "" + + SPRING_BOOT_IMAGE_NAME: pen-reg-batch-api-master + DOCKER_ARTIFACTORY_REPO: artifacts.developer.gov.bc.ca/docker-remote + ARTIFACTORY_REPO: artifacts.developer.gov.bc.ca + + APP_NAME: "pen-reg-batch-api" + REPO_NAME: "educ-pen-reg-batch-api" + BRANCH: "master" + APP_NAME_FULL: "pen-reg-batch-api-master" + NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }} + COMMON_NAMESPACE: ${{ secrets.COMMON_NAMESPACE_NO_ENV }} + TAG: "latest" + MIN_REPLICAS_DEV: "1" + MAX_REPLICAS_DEV: "1" + MIN_CPU: "250m" + MAX_CPU: "500m" + MIN_MEM: "1Gi" + MAX_MEM: "2Gi" + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + build-and-deploy-dev: + name: Build and deploy to OpenShift DEV + # ubuntu-20.04 can also be used. + runs-on: ubuntu-20.04 + environment: dev + + outputs: + ROUTE: ${{ steps.deploy-and-expose.outputs.route }} + SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }} + + steps: + - name: Check for required secrets + uses: actions/github-script@v6 + with: + script: | + const secrets = { + OPENSHIFT_SERVER: `${{ secrets.OPENSHIFT_SERVER }}`, + OPENSHIFT_TOKEN: `${{ secrets.OPENSHIFT_TOKEN }}`, + }; + const GHCR = "ghcr.io"; + if (`${{ env.IMAGE_REGISTRY }}`.startsWith(GHCR)) { + core.info(`Image registry is ${GHCR} - no registry password required`); + } + else { + core.info("A registry password is required"); + secrets["IMAGE_REGISTRY_PASSWORD"] = `${{ secrets.IMAGE_REGISTRY_PASSWORD }}`; + } + const missingSecrets = Object.entries(secrets).filter(([ name, value ]) => { + if (value.length === 0) { + core.error(`Secret "${name}" is not set`); + return true; + } + core.info(`✔️ Secret "${name}" is set`); + return false; + }); + if (missingSecrets.length > 0) { + core.setFailed(`❌ At least one required secret is not set in the repository. \n` + + "You can add it using:\n" + + "GitHub UI: https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository \n" + + "GitHub CLI: https://cli.github.com/manual/gh_secret_set \n" + + "Also, refer to https://github.com/redhat-actions/oc-login#getting-started-with-the-action-or-see-example"); + } + else { + core.info(`✅ All the required secrets are set`); + } + - name: Check out repository + uses: actions/checkout@v3 + + - name: Determine image tags + if: env.IMAGE_TAGS == '' + run: | + echo "IMAGE_TAGS=latest ${GITHUB_SHA::12}" | tee -a $GITHUB_ENV + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + registry: ${{ env.DOCKER_ARTIFACTORY_REPO }} + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + # https://github.com/redhat-actions/buildah-build#readme + - name: Build from Dockerfile + id: build-image + uses: redhat-actions/buildah-build@v2 + with: + image: ${{ env.APP_NAME_FULL }} + tags: ${{ env.IMAGE_TAGS }} + + # If you don't have a Dockerfile/Containerfile, refer to https://github.com/redhat-actions/buildah-build#scratch-build-inputs + # Or, perform a source-to-image build using https://github.com/redhat-actions/s2i-build + # Otherwise, point this to your Dockerfile/Containerfile relative to the repository root. + dockerfiles: | + ./Dockerfile + # https://github.com/redhat-actions/push-to-registry#readme + - name: Push to registry + id: push-image + uses: redhat-actions/push-to-registry@v2 + with: + image: ${{ steps.build-image.outputs.image }} + tags: ${{ steps.build-image.outputs.tags }} + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ env.IMAGE_REGISTRY_USER }} + password: ${{ env.IMAGE_REGISTRY_PASSWORD }} + + # The path the image was pushed to is now stored in ${{ steps.push-image.outputs.registry-path }} + + - name: Install oc + uses: redhat-actions/openshift-tools-installer@v1 + with: + oc: 4 + + # https://github.com/redhat-actions/oc-login#readme + - uses: actions/checkout@v3 + + - name: Deploy API + run: | + set -eu + # Login to OpenShift and select project + oc login --token=${{ env.OPENSHIFT_TOKEN }} --server=${{ env.OPENSHIFT_SERVER }} + oc project ${{ env.OPENSHIFT_NAMESPACE_DEV }} + # Cancel any rollouts in progress + oc rollout cancel dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "No rollout in progress" + + oc tag ${{ steps.push-image.outputs.registry-path }} ${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ env.TAG }} + + # Process and apply deployment template + oc process -f tools/openshift/api.dc.yaml -p APP_NAME=${{ env.APP_NAME }} -p REPO_NAME=${{ env.REPO_NAME }} -p BRANCH=${{ env.BRANCH }} -p NAMESPACE=${{ env.OPENSHIFT_NAMESPACE_DEV }} -p TAG=${{ env.TAG }} -p MIN_REPLICAS=${{ env.MIN_REPLICAS_DEV }} -p MAX_REPLICAS=${{ env.MAX_REPLICAS_DEV }} -p MIN_CPU=${{ env.MIN_CPU }} -p MAX_CPU=${{ env.MAX_CPU }} -p MIN_MEM=${{ env.MIN_MEM }} -p MAX_MEM=${{ env.MAX_MEM }} \ + | oc apply -f - + + curl -s https://raw.githubusercontent.com/bcgov/${{ env.REPO_NAME }}/master/tools/config/update-configmap.sh | bash /dev/stdin dev ${{ env.APP_NAME }} ${{ env.NAMESPACE }} ${{ env.COMMON_NAMESPACE }} ${{ env.DB_JDBC_CONNECT_STRING }} ${{ env.DB_PWD }} ${{ env.DB_USER }} ${{ env.SPLUNK_TOKEN }} + + # Start rollout (if necessary) and follow it + oc rollout latest dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "Rollout in progress" + oc logs -f dc/${{ env.SPRING_BOOT_IMAGE_NAME }} + # Get status, returns 0 if rollout is successful + oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} + - name: ZAP Scan + uses: zaproxy/action-api-scan@v0.5.0 + with: + target: 'https://${{ env.APP_NAME }}-${{ env.OPENSHIFT_NAMESPACE_DEV }}.apps.silver.devops.gov.bc.ca/v3/api-docs' \ No newline at end of file diff --git a/.github/workflows/deploy-to.openshift-prod.yml b/.github/workflows/deploy-to.openshift-prod.yml new file mode 100644 index 00000000..361fd68e --- /dev/null +++ b/.github/workflows/deploy-to.openshift-prod.yml @@ -0,0 +1,131 @@ +name: Deploy to PROD + +env: + # 🖊️ EDIT your repository secrets to log into your OpenShift cluster and set up the context. + # See https://github.com/redhat-actions/oc-login#readme for how to retrieve these values. + # To get a permanent token, refer to https://github.com/redhat-actions/oc-login/wiki/Using-a-Service-Account-for-GitHub-Actions + # Added this comment + OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }} + OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }} + OPENSHIFT_NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }}-prod + + DB_JDBC_CONNECT_STRING: ${{ secrets.DB_JDBC_CONNECT_STRING }} + DB_PWD: ${{ secrets.DB_PWD }} + DB_USER: ${{ secrets.DB_USER }} + SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }} + + # 🖊️ EDIT to change the image registry settings. + # Registries such as GHCR, Quay.io, and Docker Hub are supported. + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_REGISTRY_USER: ${{ github.actor }} + IMAGE_REGISTRY_PASSWORD: ${{ github.token }} + + SPRING_BOOT_IMAGE_NAME: pen-reg-batch-api-master + + APP_NAME: "pen-reg-batch-api" + REPO_NAME: "educ-pen-reg-batch-api" + BRANCH: "master" + NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }} + COMMON_NAMESPACE: ${{ secrets.COMMON_NAMESPACE_NO_ENV }} + TAG: "latest" + TARGET_ENV: "prod" + MIN_REPLICAS: "3" + MAX_REPLICAS: "3" + MIN_CPU: "250m" + MAX_CPU: "500m" + MIN_MEM: "1Gi" + MAX_MEM: "2Gi" + +on: + # https://docs.github.com/en/actions/reference/events-that-trigger-workflows + workflow_dispatch: + +jobs: + openshift-ci-cd: + name: Deploy to OpenShift PROD + # ubuntu-20.04 can also be used. + runs-on: ubuntu-20.04 + environment: production + + outputs: + ROUTE: ${{ steps.deploy-and-expose.outputs.route }} + SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }} + + steps: + - name: Check for required secrets + uses: actions/github-script@v6 + with: + script: | + const secrets = { + OPENSHIFT_SERVER: `${{ secrets.OPENSHIFT_SERVER }}`, + OPENSHIFT_TOKEN: `${{ secrets.OPENSHIFT_TOKEN }}`, + }; + + const GHCR = "ghcr.io"; + if (`${{ env.IMAGE_REGISTRY }}`.startsWith(GHCR)) { + core.info(`Image registry is ${GHCR} - no registry password required`); + } + else { + core.info("A registry password is required"); + secrets["IMAGE_REGISTRY_PASSWORD"] = `${{ secrets.IMAGE_REGISTRY_PASSWORD }}`; + } + + const missingSecrets = Object.entries(secrets).filter(([ name, value ]) => { + if (value.length === 0) { + core.error(`Secret "${name}" is not set`); + return true; + } + core.info(`✔️ Secret "${name}" is set`); + return false; + }); + + if (missingSecrets.length > 0) { + core.setFailed(`❌ At least one required secret is not set in the repository. \n` + + "You can add it using:\n" + + "GitHub UI: https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository \n" + + "GitHub CLI: https://cli.github.com/manual/gh_secret_set \n" + + "Also, refer to https://github.com/redhat-actions/oc-login#getting-started-with-the-action-or-see-example"); + } + else { + core.info(`✅ All the required secrets are set`); + } + + - name: Check out repository + uses: actions/checkout@v3 + + - name: Get latest tag + uses: actions-ecosystem/action-get-latest-tag@v1 + id: get-latest-tag + + - name: Install oc + uses: redhat-actions/openshift-tools-installer@v1 + with: + oc: 4 + + # https://github.com/redhat-actions/oc-login#readme + - uses: actions/checkout@v3 + + - name: Deploy API + run: | + set -eux + # Login to OpenShift and select project + oc login --token=${{ env.OPENSHIFT_TOKEN }} --server=${{ env.OPENSHIFT_SERVER }} + oc project ${{ env.OPENSHIFT_NAMESPACE }} + # Cancel any rollouts in progress + oc rollout cancel dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "No rollout in progress" + + oc tag ${{ env.NAMESPACE }}-test/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ steps.get-latest-tag.outputs.tag }} ${{ env.NAMESPACE }}-prod/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ steps.get-latest-tag.outputs.tag }} + + # Process and apply deployment template + oc process -f tools/openshift/api.dc.yaml -p APP_NAME=${{ env.APP_NAME }} -p REPO_NAME=${{ env.REPO_NAME }} -p BRANCH=${{ env.BRANCH }} -p NAMESPACE=${{ env.OPENSHIFT_NAMESPACE }} -p TAG=${{ steps.get-latest-tag.outputs.tag }} -p MIN_REPLICAS=${{ env.MIN_REPLICAS }} -p MAX_REPLICAS=${{ env.MAX_REPLICAS }} -p MIN_CPU=${{ env.MIN_CPU }} -p MAX_CPU=${{ env.MAX_CPU }} -p MIN_MEM=${{ env.MIN_MEM }} -p MAX_MEM=${{ env.MAX_MEM }} \ + | oc apply -f - + + curl -s https://raw.githubusercontent.com/bcgov/${{ env.REPO_NAME }}/${{ steps.get-latest-tag.outputs.tag }}/tools/config/update-configmap.sh | bash /dev/stdin ${{ env.TARGET_ENV }} ${{ env.APP_NAME }} ${{ env.NAMESPACE }} ${{ env.COMMON_NAMESPACE }} ${{ env.DB_JDBC_CONNECT_STRING }} ${{ env.DB_PWD }} ${{ env.DB_USER }} ${{ env.SPLUNK_TOKEN }} + + # Start rollout (if necessary) and follow it + oc rollout latest dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "Rollout in progress" + oc logs -f dc/${{ env.SPRING_BOOT_IMAGE_NAME }} + # Get status, returns 0 if rollout is successful + oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} \ No newline at end of file diff --git a/.github/workflows/deploy-to.openshift-test.yml b/.github/workflows/deploy-to.openshift-test.yml new file mode 100644 index 00000000..3ccc4f57 --- /dev/null +++ b/.github/workflows/deploy-to.openshift-test.yml @@ -0,0 +1,136 @@ +name: Build & Deploy to TEST + +env: + # 🖊️ EDIT your repository secrets to log into your OpenShift cluster and set up the context. + # See https://github.com/redhat-actions/oc-login#readme for how to retrieve these values. + # To get a permanent token, refer to https://github.com/redhat-actions/oc-login/wiki/Using-a-Service-Account-for-GitHub-Actions + OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }} + OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }} + OPENSHIFT_NAMESPACE_TEST: ${{ secrets.PEN_NAMESPACE_NO_ENV }}-test + + DB_JDBC_CONNECT_STRING: ${{ secrets.DB_JDBC_CONNECT_STRING }} + DB_PWD: ${{ secrets.DB_PWD }} + DB_USER: ${{ secrets.DB_USER }} + SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }} + + # 🖊️ EDIT to change the image registry settings. + # Registries such as GHCR, Quay.io, and Docker Hub are supported. + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_REGISTRY_USER: ${{ github.actor }} + IMAGE_REGISTRY_PASSWORD: ${{ github.token }} + + # 🖊️ EDIT to specify custom tags for the container image, or default tags will be generated below. + IMAGE_TAGS: "" + + SPRING_BOOT_IMAGE_NAME: pen-reg-batch-api-master + DOCKER_ARTIFACTORY_REPO: artifacts.developer.gov.bc.ca/docker-remote + ARTIFACTORY_REPO: artifacts.developer.gov.bc.ca + + APP_NAME: "pen-reg-batch-api" + REPO_NAME: "educ-pen-reg-batch-api" + BRANCH: "master" + NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }} + COMMON_NAMESPACE: ${{ secrets.COMMON_NAMESPACE_NO_ENV }} + TAG: ${{ github.event.inputs.tag }} + MIN_REPLICAS_TEST: "2" + MAX_REPLICAS_TEST: "2" + MIN_CPU: "250m" + MAX_CPU: "500m" + MIN_MEM: "1Gi" + MAX_MEM: "2Gi" + +on: + workflow_dispatch: + inputs: + tag: + description: 'Please input the tag, latest or release ex. 1.2.3' + type: string + required: true + default: "latest" + +jobs: + deploy-test: + name: Deploy to OpenShift TEST + runs-on: ubuntu-20.04 + environment: test + + outputs: + ROUTE: ${{ steps.deploy-and-expose.outputs.route }} + SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }} + + steps: + - name: Check for required secrets + uses: actions/github-script@v6 + with: + script: | + const secrets = { + OPENSHIFT_SERVER: `${{ secrets.OPENSHIFT_SERVER }}`, + OPENSHIFT_TOKEN: `${{ secrets.OPENSHIFT_TOKEN }}`, + }; + + const GHCR = "ghcr.io"; + if (`${{ env.IMAGE_REGISTRY }}`.startsWith(GHCR)) { + core.info(`Image registry is ${GHCR} - no registry password required`); + } + else { + core.info("A registry password is required"); + secrets["IMAGE_REGISTRY_PASSWORD"] = `${{ secrets.IMAGE_REGISTRY_PASSWORD }}`; + } + + const missingSecrets = Object.entries(secrets).filter(([ name, value ]) => { + if (value.length === 0) { + core.error(`Secret "${name}" is not set`); + return true; + } + core.info(`✔️ Secret "${name}" is set`); + return false; + }); + + if (missingSecrets.length > 0) { + core.setFailed(`❌ At least one required secret is not set in the repository. \n` + + "You can add it using:\n" + + "GitHub UI: https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository \n" + + "GitHub CLI: https://cli.github.com/manual/gh_secret_set \n" + + "Also, refer to https://github.com/redhat-actions/oc-login#getting-started-with-the-action-or-see-example"); + } + else { + core.info(`✅ All the required secrets are set`); + } + + - name: Check out repository + uses: actions/checkout@v3 + + - name: Install oc + uses: redhat-actions/openshift-tools-installer@v1 + with: + oc: 4 + + - name: Deploy API + run: | + set -eu + # Login to OpenShift and select project + oc login --token=${{ env.OPENSHIFT_TOKEN }} --server=${{ env.OPENSHIFT_SERVER }} + oc project ${{ env.OPENSHIFT_NAMESPACE_TEST }} + # Cancel any rollouts in progress + oc rollout cancel dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "No rollout in progress" + + oc tag ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ env.TAG }} ${{ env.NAMESPACE }}-test/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ env.TAG }} + + # Process and apply deployment template + oc process -f tools/openshift/api.dc.yaml -p APP_NAME=${{ env.APP_NAME }} -p REPO_NAME=${{ env.REPO_NAME }} -p BRANCH=${{ env.BRANCH }} -p NAMESPACE=${{ env.OPENSHIFT_NAMESPACE_TEST }} -p TAG=${{ env.TAG }} -p MIN_REPLICAS=${{ env.MIN_REPLICAS_TEST }} -p MAX_REPLICAS=${{ env.MAX_REPLICAS_TEST }} -p MIN_CPU=${{ env.MIN_CPU }} -p MAX_CPU=${{ env.MAX_CPU }} -p MIN_MEM=${{ env.MIN_MEM }} -p MAX_MEM=${{ env.MAX_MEM }} \ + | oc apply -f - + + curl -s https://raw.githubusercontent.com/bcgov/${{ env.REPO_NAME }}/master/tools/config/update-configmap.sh | bash /dev/stdin test ${{ env.APP_NAME }} ${{ env.NAMESPACE }} ${{ env.COMMON_NAMESPACE }} ${{ env.DB_JDBC_CONNECT_STRING }} ${{ env.DB_PWD }} ${{ env.DB_USER }} ${{ env.SPLUNK_TOKEN }} + + # Start rollout (if necessary) and follow it + oc rollout latest dc/${{ env.SPRING_BOOT_IMAGE_NAME }} 2> /dev/null \ + || true && echo "Rollout in progress" + oc logs -f dc/${{ env.SPRING_BOOT_IMAGE_NAME }} + # Get status, returns 0 if rollout is successful + oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} + + - name: ZAP Scan + uses: zaproxy/action-api-scan@v0.5.0 + with: + target: 'https://${{ env.APP_NAME }}-${{ env.OPENSHIFT_NAMESPACE_TEST }}.apps.silver.devops.gov.bc.ca/v3/api-docs' \ No newline at end of file diff --git a/.github/workflows/tag-create.git.and.imagestream.tag.yml b/.github/workflows/tag-create.git.and.imagestream.tag.yml new file mode 100644 index 00000000..57b1f8a8 --- /dev/null +++ b/.github/workflows/tag-create.git.and.imagestream.tag.yml @@ -0,0 +1,63 @@ +name: Create Tag + +env: + # 🖊️ EDIT your repository secrets to log into your OpenShift cluster and set up the context. + # See https://github.com/redhat-actions/oc-login#readme for how to retrieve these values. + # To get a permanent token, refer to https://github.com/redhat-actions/oc-login/wiki/Using-a-Service-Account-for-GitHub-Actions + OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }} + OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }} + OPENSHIFT_NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }}-dev + + REPO_NAME: "educ-pen-reg-batch-api" + BRANCH: "master" + NAMESPACE: ${{ secrets.PEN_NAMESPACE_NO_ENV }} + +on: + # https://docs.github.com/en/actions/reference/events-that-trigger-workflows + workflow_dispatch: + inputs: + version: + description: 'Version Number' + required: true + +jobs: + openshift-ci-cd: + name: Tag Image + # ubuntu-latest can also be used. + runs-on: ubuntu-22.04 + environment: dev + + outputs: + ROUTE: ${{ steps.deploy-and-expose.outputs.route }} + SELECTOR: ${{ steps.deploy-and-expose.outputs.selector }} + + steps: + - name: Check out repository + uses: actions/checkout@v3 + + - name: Create tag + uses: actions/github-script@v6 + with: + script: | + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ github.event.inputs.version }}', + sha: context.sha + }) + + - name: Install oc + uses: redhat-actions/openshift-tools-installer@v1 + with: + oc: 4 + + # https://github.com/redhat-actions/oc-login#readme + - uses: actions/checkout@v3 + - name: Tag in OpenShift + run: | + set -eux + # Login to OpenShift and select project + oc login --token=${{ env.OPENSHIFT_TOKEN }} --server=${{ env.OPENSHIFT_SERVER }} + oc project ${{ env.OPENSHIFT_NAMESPACE }} + + oc tag ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:latest ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ github.event.inputs.version }} diff --git a/api/pom.xml b/api/pom.xml index 7126854d..7f0e7da2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -23,7 +23,7 @@ ${java.version} 1.4.1.Final 4.20.0 - 1.5.2 + 1.6.9 2.11.0 21.3.0.0 30.1.1-jre @@ -39,7 +39,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.3 + 2.7.17 diff --git a/api/src/main/java/ca/bc/gov/educ/penreg/api/model/v1/PenRequestBatchEvent.java b/api/src/main/java/ca/bc/gov/educ/penreg/api/model/v1/PenRequestBatchEvent.java index 723431a6..63809954 100644 --- a/api/src/main/java/ca/bc/gov/educ/penreg/api/model/v1/PenRequestBatchEvent.java +++ b/api/src/main/java/ca/bc/gov/educ/penreg/api/model/v1/PenRequestBatchEvent.java @@ -51,7 +51,7 @@ public class PenRequestBatchEvent { @Column(name = "UPDATE_DATE") @PastOrPresent LocalDateTime updateDate; - @Column(name = "SAGA_ID", updatable = false) + @Column(name = "SAGA_ID", updatable = false, columnDefinition = "BINARY(16)") private UUID sagaId; @NotNull(message = "eventOutcome cannot be null.") @Column(name = "EVENT_OUTCOME") diff --git a/api/src/test/java/ca/bc/gov/educ/penreg/api/service/PenRequestBatchEventServiceTest.java b/api/src/test/java/ca/bc/gov/educ/penreg/api/service/PenRequestBatchEventServiceTest.java index d46ce988..94027d4e 100644 --- a/api/src/test/java/ca/bc/gov/educ/penreg/api/service/PenRequestBatchEventServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/penreg/api/service/PenRequestBatchEventServiceTest.java @@ -31,8 +31,6 @@ public class PenRequestBatchEventServiceTest extends BasePenRegAPITest { @Autowired private PenRequestBatchEventRepository penRequestBatchEventRepository; @Autowired - private PenRequestBatchStudentService prbStudentService; - @Autowired private PenRequestBatchRepository penRequestBatchRepository; @Autowired private PenRequestBatchEventService penRequestBatchEventService; diff --git a/tools/jenkins/update-configmap.sh b/tools/config/update-configmap.sh similarity index 71% rename from tools/jenkins/update-configmap.sh rename to tools/config/update-configmap.sh index 1467f1fb..5719a003 100644 --- a/tools/jenkins/update-configmap.sh +++ b/tools/config/update-configmap.sh @@ -1,8 +1,12 @@ envValue=$1 APP_NAME=$2 -PEN_NAMESPACE=$3 +OPENSHIFT_NAMESPACE=$3 COMMON_NAMESPACE=$4 -APP_NAME_UPPER=${APP_NAME^^} +DB_JDBC_CONNECT_STRING=$5 +DB_PWD=$6 +DB_USER=$7 +SPLUNK_TOKEN=$8 + TZVALUE="America/Vancouver" SOAM_KC_REALM_ID="master" SOAM_KC=soam-$envValue.apps.silver.devops.gov.bc.ca @@ -10,10 +14,6 @@ SOAM_KC=soam-$envValue.apps.silver.devops.gov.bc.ca SOAM_KC_LOAD_USER_ADMIN=$(oc -n $COMMON_NAMESPACE-$envValue -o json get secret sso-admin-${envValue} | sed -n 's/.*"username": "\(.*\)"/\1/p' | base64 --decode) SOAM_KC_LOAD_USER_PASS=$(oc -n $COMMON_NAMESPACE-$envValue -o json get secret sso-admin-${envValue} | sed -n 's/.*"password": "\(.*\)",/\1/p' | base64 --decode) -DB_JDBC_CONNECT_STRING=$(oc -n $PEN_NAMESPACE-$envValue -o json get configmaps ${APP_NAME}-${envValue}-setup-config | sed -n 's/.*"DB_JDBC_CONNECT_STRING": "\(.*\)",/\1/p') -DB_PWD=$(oc -n $PEN_NAMESPACE-$envValue -o json get configmaps ${APP_NAME}-${envValue}-setup-config | sed -n "s/.*\"DB_PWD_${APP_NAME_UPPER}\": \"\(.*\)\",/\1/p") -DB_USER=$(oc -n $PEN_NAMESPACE-$envValue -o json get configmaps "${APP_NAME}"-"${envValue}"-setup-config | sed -n "s/.*\"DB_USER_${APP_NAME_UPPER}\": \"\(.*\)\",/\1/p") -SPLUNK_TOKEN=$(oc -n $PEN_NAMESPACE-$envValue -o json get configmaps "${APP_NAME}"-"${envValue}"-setup-config | sed -n "s/.*\"SPLUNK_TOKEN_${APP_NAME_UPPER}\": \"\(.*\)\"/\1/p") NATS_CLUSTER=educ_nats_cluster NATS_URL="nats://nats.${COMMON_NAMESPACE}-${envValue}.svc.cluster.local:4222" @@ -212,18 +212,14 @@ SCHEDULED_JOBS_PURGE_SOFT_DELETED_RECORDS_CRON="@midnight" SCHEDULED_JOBS_PURGE_OLD_SAGA_RECORDS_CRON="@midnight" SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON="0 0/1 * * * *" SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON="0 0/2 * * * *" -if [ "$envValue" = "tools" ]; then - PEN_COORDINATOR_EMAIL=omprakashmishra7234@gmail.com - SOFT_DELETED_RETENTION_DAYS=20 -fi if [ "$envValue" = "dev" ]; then - PEN_COORDINATOR_EMAIL=aditya.sharma@gov.bc.ca + PEN_COORDINATOR_EMAIL=derek.so@gov.bc.ca SOFT_DELETED_RETENTION_DAYS=2 fi if [ "$envValue" = "test" ]; then - PEN_COORDINATOR_EMAIL=Gurvinder.J.Bhatia@gov.bc.ca + PEN_COORDINATOR_EMAIL=derek.so@gov.bc.ca SOFT_DELETED_RETENTION_DAYS=2 fi # when it will be time for go live the value of SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON will be set to "0 0/10 18-23,00-05 * * *" so that it runs from 6PM to 6AM @@ -241,14 +237,14 @@ fi echo echo Creating config map "$APP_NAME"-config-map -oc create -n "$PEN_NAMESPACE"-"$envValue" configmap "$APP_NAME"-config-map --from-literal=TZ=$TZVALUE --from-literal=JDBC_URL=$DB_JDBC_CONNECT_STRING --from-literal=ORACLE_USERNAME="$DB_USER" --from-literal=ORACLE_PASSWORD="$DB_PWD" --from-literal=SPRING_SECURITY_LOG_LEVEL=INFO --from-literal=SPRING_WEB_LOG_LEVEL=INFO --from-literal=APP_LOG_LEVEL=INFO --from-literal=SPRING_BOOT_AUTOCONFIG_LOG_LEVEL=INFO --from-literal=SPRING_SHOW_REQUEST_DETAILS=false --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PENWEB_PEN_WEB_BLOBS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PENWEB_PEN_WEB_BLOBS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON_LOCK_AT_LEAST_FOR="540s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON_LOCK_AT_MOST_FOR="580s" --from-literal=NATS_URL="$NATS_URL" --from-literal=NATS_CLUSTER="$NATS_CLUSTER" --from-literal=SPRING_JPA_SHOW_SQL="false" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON="$SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON_LOCK_AT_LEAST_FOR="55s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON_LOCK_AT_MOST_FOR="57s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON_LOCK_AT_LEAST_FOR="8s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON_LOCK_AT_MOST_FOR="8s" --from-literal=CLIENT_ID="pen-reg-batch-api-service" --from-literal=CLIENT_SECRET="$PRB_APIServiceClientSecret" --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/schools" --from-literal=TOKEN_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/protocol/openid-connect/token" --from-literal=URL_REDIS="redis.$PEN_NAMESPACE-$envValue.svc.cluster.local:6379" --from-literal=REPEAT_TIME_WINDOW_K12=0 --from-literal=REPEAT_TIME_WINDOW_PSI=0 --from-literal=SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE=16 --from-literal=SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE=16 --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080" --from-literal=HIBERNATE_SQL_PARAM_LOG_LEVEL=INFO --from-literal=PURGE_RECORDS_SAGA_AFTER_DAYS=365 --from-literal=SCHEDULED_JOBS_PURGE_OLD_SAGA_RECORDS_CRON="$SCHEDULED_JOBS_PURGE_OLD_SAGA_RECORDS_CRON" --from-literal=SOFT_DELETED_RETENTION_DAYS="$SOFT_DELETED_RETENTION_DAYS" --from-literal=SCHEDULED_JOBS_PURGE_SOFT_DELETED_RECORDS_CRON="$SCHEDULED_JOBS_PURGE_SOFT_DELETED_RECORDS_CRON" --from-literal=NATS_MAX_RECONNECT=60 --from-literal=HOLD_BATCHES_EQUAL_OR_LARGER_THAN=2500 --from-literal=PEN_COORDINATOR_EMAIL="$PEN_COORDINATOR_EMAIL" --from-literal=TOKEN_ISSUER_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID" --from-literal=PEN_COORDINATOR_MAILING_ADDRESS="Ministry of Education and Child Care, Data Collection Unit PO Box 9170, Stn. Prov. Govt, Victoria BC, V8W 9H7" --from-literal=PEN_COORDINATOR_TELEPHONE="(250)356-8020" --from-literal=PEN_COORDINATOR_FACSIMILE="(250)953-0450" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON="$SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON_LOCK_AT_LEAST_FOR="50s" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_LOCK_AT_MOST_FOR="55s" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON="$SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON_LOCK_AT_LEAST_FOR="100s" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON_LOCK_AT_MOST_FOR="110s" --from-literal=SKIP_VALIDATION_FOR_DISTRICT_CODES="102,104" --from-literal=STUDENT_THRESHOLD_GENERATE_PDF="500" --from-literal=THREADS_MIN_SUBSCRIBER="$THREADS_MIN_SUBSCRIBER" --from-literal=THREADS_MAX_SUBSCRIBER="$THREADS_MAX_SUBSCRIBER" --from-literal=SAGAS_MAX_PENDING="$SAGAS_MAX_PENDING" --from-literal=SAGAS_MAX_PARALLEL="$SAGAS_MAX_PARALLEL" --dry-run -o yaml | oc apply -f - +oc create -n "$OPENSHIFT_NAMESPACE"-"$envValue" configmap "$APP_NAME"-config-map --from-literal=TZ=$TZVALUE --from-literal=JDBC_URL="$DB_JDBC_CONNECT_STRING" --from-literal=ORACLE_USERNAME="$DB_USER" --from-literal=ORACLE_PASSWORD="$DB_PWD" --from-literal=SPRING_SECURITY_LOG_LEVEL=INFO --from-literal=SPRING_WEB_LOG_LEVEL=INFO --from-literal=APP_LOG_LEVEL=INFO --from-literal=SPRING_BOOT_AUTOCONFIG_LOG_LEVEL=INFO --from-literal=SPRING_SHOW_REQUEST_DETAILS=false --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PENWEB_PEN_WEB_BLOBS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PENWEB_PEN_WEB_BLOBS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON_LOCK_AT_LEAST_FOR="540s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_PEN_WEB_BLOBS_CRON_LOCK_AT_MOST_FOR="580s" --from-literal=NATS_URL="$NATS_URL" --from-literal=NATS_CLUSTER="$NATS_CLUSTER" --from-literal=SPRING_JPA_SHOW_SQL="false" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON="$SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON_LOCK_AT_LEAST_FOR="55s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNCOMPLETED_SAGAS_CRON_LOCK_AT_MOST_FOR="57s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON="$SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON_LOCK_AT_LEAST_FOR="8s" --from-literal=SCHEDULED_JOBS_EXTRACT_UNPROCESSED_STUDENTS_CRON_LOCK_AT_MOST_FOR="8s" --from-literal=CLIENT_ID="pen-reg-batch-api-service" --from-literal=CLIENT_SECRET="$PRB_APIServiceClientSecret" --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/schools" --from-literal=TOKEN_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/protocol/openid-connect/token" --from-literal=URL_REDIS="redis.$OPENSHIFT_NAMESPACE-$envValue.svc.cluster.local:6379" --from-literal=REPEAT_TIME_WINDOW_K12=0 --from-literal=REPEAT_TIME_WINDOW_PSI=0 --from-literal=SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE=16 --from-literal=SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE=16 --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$OPENSHIFT_NAMESPACE-$envValue.svc.cluster.local:8080" --from-literal=HIBERNATE_SQL_PARAM_LOG_LEVEL=INFO --from-literal=PURGE_RECORDS_SAGA_AFTER_DAYS=365 --from-literal=SCHEDULED_JOBS_PURGE_OLD_SAGA_RECORDS_CRON="$SCHEDULED_JOBS_PURGE_OLD_SAGA_RECORDS_CRON" --from-literal=SOFT_DELETED_RETENTION_DAYS="$SOFT_DELETED_RETENTION_DAYS" --from-literal=SCHEDULED_JOBS_PURGE_SOFT_DELETED_RECORDS_CRON="$SCHEDULED_JOBS_PURGE_SOFT_DELETED_RECORDS_CRON" --from-literal=NATS_MAX_RECONNECT=60 --from-literal=HOLD_BATCHES_EQUAL_OR_LARGER_THAN=2500 --from-literal=PEN_COORDINATOR_EMAIL="$PEN_COORDINATOR_EMAIL" --from-literal=TOKEN_ISSUER_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID" --from-literal=PEN_COORDINATOR_MAILING_ADDRESS="Ministry of Education and Child Care, Data Collection Unit PO Box 9886, Stn. Prov. Govt, Victoria BC, V8W 9T6" --from-literal=PEN_COORDINATOR_TELEPHONE="(250)356-8020" --from-literal=PEN_COORDINATOR_FACSIMILE="(250)953-0450" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON="$SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_CRON_LOCK_AT_LEAST_FOR="50s" --from-literal=SCHEDULED_JOBS_MARK_PROCESSED_BATCHES_ACTIVE_LOCK_AT_MOST_FOR="55s" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON="$SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON_LOCK_AT_LEAST_FOR="100s" --from-literal=SCHEDULED_JOBS_PROCESS_LOADED_BATCHES_FOR_REPEATS_CRON_LOCK_AT_MOST_FOR="110s" --from-literal=SKIP_VALIDATION_FOR_DISTRICT_CODES="102,104" --from-literal=STUDENT_THRESHOLD_GENERATE_PDF="500" --from-literal=THREADS_MIN_SUBSCRIBER="$THREADS_MIN_SUBSCRIBER" --from-literal=THREADS_MAX_SUBSCRIBER="$THREADS_MAX_SUBSCRIBER" --from-literal=SAGAS_MAX_PENDING="$SAGAS_MAX_PENDING" --from-literal=SAGAS_MAX_PARALLEL="$SAGAS_MAX_PARALLEL" --dry-run -o yaml | oc apply -f - echo echo Setting environment variables for $APP_NAME-$SOAM_KC_REALM_ID application -oc -n $PEN_NAMESPACE-$envValue set env --from=configmap/$APP_NAME-config-map dc/$APP_NAME-$SOAM_KC_REALM_ID +oc -n $OPENSHIFT_NAMESPACE-$envValue set env --from=configmap/$APP_NAME-config-map dc/$APP_NAME-$SOAM_KC_REALM_ID echo Creating config map "$APP_NAME"-flb-sc-config-map -oc create -n "$PEN_NAMESPACE"-"$envValue" configmap "$APP_NAME"-flb-sc-config-map --from-literal=fluent-bit.conf="$FLB_CONFIG" --from-literal=parsers.conf="$PARSER_CONFIG" --dry-run -o yaml | oc apply -f - +oc create -n "$OPENSHIFT_NAMESPACE"-"$envValue" configmap "$APP_NAME"-flb-sc-config-map --from-literal=fluent-bit.conf="$FLB_CONFIG" --from-literal=parsers.conf="$PARSER_CONFIG" --dry-run -o yaml | oc apply -f - echo Removing un-needed config entries -oc -n "$PEN_NAMESPACE"-"$envValue" set env dc/"$APP_NAME"-$SOAM_KC_REALM_ID KEYCLOAK_PUBLIC_KEY- +oc -n "$OPENSHIFT_NAMESPACE"-"$envValue" set env dc/"$APP_NAME"-$SOAM_KC_REALM_ID KEYCLOAK_PUBLIC_KEY- diff --git a/tools/jenkins/Jenkinsfile-api b/tools/jenkins/Jenkinsfile-api deleted file mode 100644 index cf07497e..00000000 --- a/tools/jenkins/Jenkinsfile-api +++ /dev/null @@ -1,108 +0,0 @@ -pipeline{ - agent any - environment{ - extJSHelper = ''; - DEBUG_OUTPUT = 'false' - - NAMESPACE='c2mvws' - COMMON_NAMESPACE='mvubjx' - TOOLS = "${NAMESPACE}-tools" - DEV = "${NAMESPACE}-dev" - - APP_NAME = 'pen-reg-batch-api' - REPO_NAME = "educ-${APP_NAME}" - OWNER = 'bcgov' - JOB_NAME = 'master' - TAG = 'latest' - TARGET_ENV = 'dev' - STAGING_ENV = 'Dev' - TARGET_ENVIRONMENT = "${NAMESPACE}-${TARGET_ENV}" - - APP_DOMAIN = 'pathfinder.gov.bc.ca' - SOURCE_REPO_REF = 'master' - SOURCE_REPO_URL = 'https://github.com/${OWNER}/${REPO_NAME}.git' - DC_URL = "https://raw.githubusercontent.com/${OWNER}/${REPO_NAME}/master/tools/openshift/api.dc.yaml" - MIN_REPLICAS = "1" - MAX_REPLICAS = "1" - MIN_CPU = "100m" - MAX_CPU = "300m" - MIN_MEM = "800Mi" - MAX_MEM = "1600Mi" - } - stages{ - stage('Initialize') { - steps { - script { - if(DEBUG_OUTPUT.equalsIgnoreCase('true')) { - // Force OpenShift Plugin directives to be verbose - openshift.logLevel(1) - - // Print all environment variables - echo 'DEBUG - All pipeline environment variables:' - echo sh(returnStdout: true, script: 'env') - } - - sh "wget -O - https://raw.githubusercontent.com/bcgov/EDUC-INFRA-COMMON/master/openshift/common-deployment/deployHelpers.js > deployHelpers.js" - extJSHelper = evaluate readFile('deployHelpers.js') - } - } - } - stage('Build App') { - steps { - script { - openshift.withCluster() { - openshift.withProject(TOOLS) { - try { - echo "Building API..." - def bcBackend = openshift.process('-f', 'tools/openshift/api.bc.yaml', "REPO_NAME=${REPO_NAME}-${JOB_NAME}", "JOB_NAME=${JOB_NAME}", "SOURCE_REPO_URL=${SOURCE_REPO_URL}", "SOURCE_REPO_REF=${SOURCE_REPO_REF}") - openshift.apply(bcBackend).narrow('bc').startBuild('-w').logs('-f') - - openshift.tag("${REPO_NAME}-${JOB_NAME}:latest", "${REPO_NAME}-${JOB_NAME}:${JOB_NAME}") - } catch (e) { - echo "API build failed" - throw e - } - } - } - } - } - post { - success { - echo 'Cleanup BuildConfigs' - script { - openshift.withCluster() { - openshift.withProject(TOOLS) { - def bcApi = openshift.selector('bc', "${REPO_NAME}-${JOB_NAME}") - - if(bcApi.exists()) { - echo "Removing BuildConfig ${REPO_NAME}-${JOB_NAME}" - bcApi.delete() - } - } - } - } - } - failure { - echo 'Build stage failed' - } - } - } - stage('Promote and configure DEV') { - steps{ - script{ - extJSHelper.performPenRegApiDeploy(STAGING_ENV, TARGET_ENVIRONMENT, "${REPO_NAME}", "${APP_NAME}", JOB_NAME, TAG, TOOLS, TARGET_ENVIRONMENT, APP_DOMAIN, "${DC_URL}", "${MIN_REPLICAS}", "${MAX_REPLICAS}", "${MIN_CPU}", "${MAX_CPU}", "${MIN_MEM}", "${MAX_MEM}", "${TARGET_ENV}", "${NAMESPACE}", "${COMMON_NAMESPACE}") - } - } - post{ - success{ - echo 'Deployment to Dev was successful' - } - failure{ - echo 'Deployment to Dev failed' - } - } - } - } -} - - diff --git a/tools/jenkins/Jenkinsfile-api-ocp4 b/tools/jenkins/Jenkinsfile-api-ocp4 deleted file mode 100644 index 7f2d029c..00000000 --- a/tools/jenkins/Jenkinsfile-api-ocp4 +++ /dev/null @@ -1,108 +0,0 @@ -pipeline{ - agent any - environment{ - extJSHelper = ''; - DEBUG_OUTPUT = 'false' - - NAMESPACE='8878b4' - COMMON_NAMESPACE='75e61b' - TOOLS = "${NAMESPACE}-tools" - DEV = "${NAMESPACE}-dev" - - APP_NAME = 'pen-reg-batch-api' - REPO_NAME = "educ-${APP_NAME}" - OWNER = 'bcgov' - JOB_NAME = 'master' - TAG = 'latest' - TARGET_ENV = 'dev' - STAGING_ENV = 'Dev' - TARGET_ENVIRONMENT = "${NAMESPACE}-${TARGET_ENV}" - - APP_DOMAIN = 'apps.silver.devops.gov.bc.ca' - SOURCE_REPO_REF = 'master' - SOURCE_REPO_URL = 'https://github.com/${OWNER}/${REPO_NAME}.git' - DC_URL = "https://raw.githubusercontent.com/${OWNER}/${REPO_NAME}/master/tools/openshift/api.dc.ocp4.yaml" - MIN_REPLICAS = "1" - MAX_REPLICAS = "1" - MIN_CPU = "250m" - MAX_CPU = "500m" - MIN_MEM = "1024Mi" - MAX_MEM = "2048Mi" - } - stages{ - stage('Initialize') { - steps { - script { - if(DEBUG_OUTPUT.equalsIgnoreCase('true')) { - // Force OpenShift Plugin directives to be verbose - openshift.logLevel(1) - - // Print all environment variables - echo 'DEBUG - All pipeline environment variables:' - echo sh(returnStdout: true, script: 'env') - } - - sh "wget -O - https://raw.githubusercontent.com/bcgov/EDUC-INFRA-COMMON/master/openshift/common-deployment/deployHelpers.js > deployHelpers.js" - extJSHelper = evaluate readFile('deployHelpers.js') - } - } - } - stage('Build App') { - steps { - script { - openshift.withCluster() { - openshift.withProject(TOOLS) { - try { - echo "Building API..." - def bcBackend = openshift.process('-f', 'https://raw.githubusercontent.com/${OWNER}/${REPO_NAME}/master/tools/openshift/api.bc.yaml', "REPO_NAME=${REPO_NAME}-${JOB_NAME}", "JOB_NAME=${JOB_NAME}", "SOURCE_REPO_URL=${SOURCE_REPO_URL}", "SOURCE_REPO_REF=${SOURCE_REPO_REF}") - openshift.apply(bcBackend).narrow('bc').startBuild('-w').logs('-f') - - openshift.tag("${REPO_NAME}-${JOB_NAME}:latest", "${REPO_NAME}-${JOB_NAME}:${JOB_NAME}") - } catch (e) { - echo "API build failed" - throw e - } - } - } - } - } - post { - success { - echo 'Cleanup BuildConfigs' - script { - openshift.withCluster() { - openshift.withProject(TOOLS) { - def bcApi = openshift.selector('bc', "${REPO_NAME}-${JOB_NAME}") - - if(bcApi.exists()) { - echo "Removing BuildConfig ${REPO_NAME}-${JOB_NAME}" - bcApi.delete() - } - } - } - } - } - failure { - echo 'Build stage failed' - } - } - } - stage('Promote and configure DEV') { - steps{ - script{ - extJSHelper.performPenRegApiDeploy(STAGING_ENV, TARGET_ENVIRONMENT, "${REPO_NAME}", "${APP_NAME}", JOB_NAME, TAG, TOOLS, TARGET_ENVIRONMENT, APP_DOMAIN, "${DC_URL}", "${MIN_REPLICAS}", "${MAX_REPLICAS}", "${MIN_CPU}", "${MAX_CPU}", "${MIN_MEM}", "${MAX_MEM}", "${TARGET_ENV}", "${NAMESPACE}", "${COMMON_NAMESPACE}") - } - } - post{ - success{ - echo 'Deployment to Dev was successful' - } - failure{ - echo 'Deployment to Dev failed' - } - } - } - } -} - - diff --git a/tools/openshift/api.bc.yaml b/tools/openshift/api.bc.yaml deleted file mode 100644 index 0c15e2c5..00000000 --- a/tools/openshift/api.bc.yaml +++ /dev/null @@ -1,73 +0,0 @@ ---- -apiVersion: template.openshift.io/v1 -kind: Template -labels: - template: '${REPO_NAME}-template' -metadata: - name: '${REPO_NAME}-bc' -objects: - - apiVersion: v1 - kind: ImageStream - metadata: - annotations: - openshift.io/generated-by: OpenShiftNewBuild - creationTimestamp: - labels: - build: "${REPO_NAME}" - name: "${REPO_NAME}" - spec: - lookupPolicy: - local: false - - apiVersion: v1 - kind: BuildConfig - metadata: - annotations: - openshift.io/generated-by: OpenShiftNewBuild - creationTimestamp: - labels: - build: "${REPO_NAME}" - name: "${REPO_NAME}" - spec: - completionDeadlineSeconds: 1200 - successfulBuildsHistoryLimit: 3 - failedBuildsHistoryLimit: 3 - nodeSelector: - output: - to: - kind: ImageStreamTag - name: "${REPO_NAME}:latest" - postCommit: {} - resources: - requests: - cpu: 100m - memory: 2Gi - limits: - cpu: 1000m - memory: 4Gi - runPolicy: SerialLatestOnly - source: - git: - ref: "${SOURCE_REPO_REF}" - uri: "${SOURCE_REPO_URL}" - type: Git - strategy: - dockerStrategy: - pullSecret: - name: artifactory-creds - env: - - name: BUILD_LOGLEVEL - value: '2' - type: Docker -parameters: - - name: REPO_NAME - description: Application repository name - required: true - - name: JOB_NAME - description: Job identifier (i.e. 'pr-5' OR 'master') - required: true - - name: SOURCE_REPO_REF - description: Git Pull Request Reference (i.e. 'pull/CHANGE_ID/head') - required: true - - name: SOURCE_REPO_URL - description: Git Repository URL - required: true diff --git a/tools/openshift/api.dc.ocp4.yaml b/tools/openshift/api.dc.ocp4.yaml deleted file mode 100644 index 2196aef6..00000000 --- a/tools/openshift/api.dc.ocp4.yaml +++ /dev/null @@ -1,198 +0,0 @@ ---- -apiVersion: template.openshift.io/v1 -kind: Template -labels: - template: "${REPO_NAME}-template" -metadata: - name: "${REPO_NAME}-${JOB_NAME}-dc" -objects: -- apiVersion: v1 - kind: DeploymentConfig - metadata: - labels: - app: "${APP_NAME}-${JOB_NAME}" - name: "${APP_NAME}-${JOB_NAME}" - spec: - replicas: ${{MIN_REPLICAS}} - selector: - app: "${APP_NAME}-${JOB_NAME}" - deploymentConfig: "${APP_NAME}-${JOB_NAME}" - strategy: - resources: {} - type: Rolling - template: - metadata: - annotations: - openshift.io/generated-by: penregbatchapi - prometheus.io/path: /actuator/prometheus - prometheus.io/port: '8080' - prometheus.io/scrape: 'true' - labels: - app: "${APP_NAME}-${JOB_NAME}" - deploymentConfig: "${APP_NAME}-${JOB_NAME}" - spec: - containers: - - image: image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/${REPO_NAME}-${JOB_NAME}:${TAG} - imagePullPolicy: Always - volumeMounts: - - name: tls-certs - mountPath: "/etc/tls-certs" - readOnly: true - - name: log-storage - mountPath: /logs - readinessProbe: - tcpSocket: - port: 8080 - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 20 - successThreshold: 1 - livenessProbe: - httpGet: - path: /actuator/health - port: 8080 - initialDelaySeconds: 300 - periodSeconds: 30 - timeoutSeconds: 5 - failureThreshold: 5 - successThreshold: 1 - name: "${APP_NAME}-${JOB_NAME}" - ports: - - containerPort: ${{CONTAINER_PORT}} - protocol: TCP - resources: - requests: - cpu: "${MIN_CPU}" - memory: "${MIN_MEM}" - limits: - cpu: "${MAX_CPU}" - memory: "${MAX_MEM}" - - image: artifacts.developer.gov.bc.ca/docker-remote/fluent/fluent-bit:1.5.7 - name: "${APP_NAME}-${JOB_NAME}-fluent-bit-sidecar" - imagePullPolicy: Always - imagePullSecrets: - - name: artifactory-creds - volumeMounts: - - name: log-storage - mountPath: /mnt/log - - name: flb-sc-config-volume - mountPath: /fluent-bit/etc/ - readinessProbe: - tcpSocket: - port: 2020 - initialDelaySeconds: 10 - periodSeconds: 30 - timeoutSeconds: 5 - failureThreshold: 5 - successThreshold: 1 - livenessProbe: - httpGet: - path: / - port: 2020 - initialDelaySeconds: 10 - periodSeconds: 30 - timeoutSeconds: 5 - failureThreshold: 5 - successThreshold: 1 - ports: - - containerPort: 2020 - protocol: TCP - name: metrics - resources: - requests: - cpu: "25m" - memory: "50Mi" - limits: - cpu: "50m" - memory: "100Mi" - volumes: - - name: tls-certs - secret: - secretName: pen-reg-batch-api-cert - - name: log-storage - emptyDir: {} - - name: flb-sc-config-volume - configMap: - name: "${APP_NAME}-flb-sc-config-map" - test: false - triggers: - - type: ConfigChange -- apiVersion: v1 - kind: Service - metadata: - annotations: - service.alpha.openshift.io/serving-cert-secret-name: "pen-reg-batch-api-cert" - labels: - app: "${APP_NAME}-${JOB_NAME}" - name: "${APP_NAME}-${JOB_NAME}" - spec: - ports: - - name: ${CONTAINER_PORT}-tcp - port: ${{CONTAINER_PORT}} - protocol: TCP - selector: - app: "${APP_NAME}-${JOB_NAME}" - deploymentconfig: "${APP_NAME}-${JOB_NAME}" -- apiVersion: autoscaling/v2beta1 - kind: HorizontalPodAutoscaler - metadata: - name: "${APP_NAME}-${JOB_NAME}-cpu-autoscaler" - spec: - scaleTargetRef: - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig - name: "${APP_NAME}-${JOB_NAME}" - subresource: scale - minReplicas: ${{MIN_REPLICAS}} - maxReplicas: ${{MAX_REPLICAS}} - metrics: - - type: Resource - resource: - name: cpu - targetAverageUtilization: 200 -parameters: -- name: REPO_NAME - description: Application repository name - required: true -- name: JOB_NAME - description: Job identifier (i.e. 'backend' OR 'frontend') - required: true -- name: NAMESPACE - description: Target namespace reference (i.e. 'k8vopl-dev') - required: true -- name: APP_NAME - description: Application name - required: true -- name: HOST_ROUTE - description: The host the route will use to expose service outside cluster - required: true -- name: CONTAINER_PORT - description: The port on which the application will be accessible - value: "8080" - required: false -- name: TAG - description: The identifying tag for this specific deployment - required: true -- name: HOST_PATH - description: The path appended to the HOST_ROUTE where the root of this project will be served - value: "/" - required: false -- name: MIN_REPLICAS - description: The minimum amount of replicas - required: true -- name: MAX_REPLICAS - description: The maximum amount of replicas - required: true -- name: MIN_CPU - description: The minimum amount of cpu - required: true -- name: MAX_CPU - description: The maximum amount of cpu - required: true -- name: MIN_MEM - description: The minimum amount of memory - required: true -- name: MAX_MEM - description: The maximum amount of memory - required: true diff --git a/tools/openshift/api.dc.yaml b/tools/openshift/api.dc.yaml index 247b86eb..b3d43692 100644 --- a/tools/openshift/api.dc.yaml +++ b/tools/openshift/api.dc.yaml @@ -2,21 +2,21 @@ apiVersion: template.openshift.io/v1 kind: Template labels: - template: "${REPO_NAME}-template" + template: "${REPO_NAME}-template" metadata: - name: "${REPO_NAME}-${JOB_NAME}-dc" + name: "${REPO_NAME}-${BRANCH}-dc" objects: - apiVersion: v1 kind: DeploymentConfig metadata: labels: - app: "${APP_NAME}-${JOB_NAME}" - name: "${APP_NAME}-${JOB_NAME}" + app: "${APP_NAME}-${BRANCH}" + name: "${APP_NAME}-${BRANCH}" spec: replicas: ${{MIN_REPLICAS}} selector: - app: "${APP_NAME}-${JOB_NAME}" - deploymentConfig: "${APP_NAME}-${JOB_NAME}" + app: "${APP_NAME}-${BRANCH}" + deploymentConfig: "${APP_NAME}-${BRANCH}" strategy: resources: {} type: Rolling @@ -28,11 +28,11 @@ objects: prometheus.io/port: '8080' prometheus.io/scrape: 'true' labels: - app: "${APP_NAME}-${JOB_NAME}" - deploymentConfig: "${APP_NAME}-${JOB_NAME}" + app: "${APP_NAME}-${BRANCH}" + deploymentConfig: "${APP_NAME}-${BRANCH}" spec: containers: - - image: docker-registry.default.svc:5000/${NAMESPACE}/${REPO_NAME}-${JOB_NAME}:${TAG} + - image: image-registry.openshift-image-registry.svc:5000/${NAMESPACE}/${REPO_NAME}-${BRANCH}:${TAG} imagePullPolicy: Always volumeMounts: - name: tls-certs @@ -57,7 +57,7 @@ objects: timeoutSeconds: 5 failureThreshold: 5 successThreshold: 1 - name: "${APP_NAME}-${JOB_NAME}" + name: "${APP_NAME}-${BRANCH}" ports: - containerPort: ${{CONTAINER_PORT}} protocol: TCP @@ -68,9 +68,11 @@ objects: limits: cpu: "${MAX_CPU}" memory: "${MAX_MEM}" - - image: fluent/fluent-bit - name: "${APP_NAME}-${JOB_NAME}-fluent-bit-sidecar" + - image: artifacts.developer.gov.bc.ca/docker-remote/fluent/fluent-bit:1.5.7 + name: "${APP_NAME}-${BRANCH}-fluent-bit-sidecar" imagePullPolicy: Always + imagePullSecrets: + - name: artifactory-creds volumeMounts: - name: log-storage mountPath: /mnt/log @@ -122,25 +124,25 @@ objects: annotations: service.alpha.openshift.io/serving-cert-secret-name: "pen-reg-batch-api-cert" labels: - app: "${APP_NAME}-${JOB_NAME}" - name: "${APP_NAME}-${JOB_NAME}" + app: "${APP_NAME}-${BRANCH}" + name: "${APP_NAME}-${BRANCH}" spec: ports: - name: ${CONTAINER_PORT}-tcp port: ${{CONTAINER_PORT}} protocol: TCP selector: - app: "${APP_NAME}-${JOB_NAME}" - deploymentconfig: "${APP_NAME}-${JOB_NAME}" -- apiVersion: autoscaling/v2beta1 + app: "${APP_NAME}-${BRANCH}" + deploymentconfig: "${APP_NAME}-${BRANCH}" +- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: - name: "${APP_NAME}-${JOB_NAME}-cpu-autoscaler" + name: "${APP_NAME}-${BRANCH}-cpu-autoscaler" spec: scaleTargetRef: apiVersion: apps.openshift.io/v1 kind: DeploymentConfig - name: "${APP_NAME}-${JOB_NAME}" + name: "${APP_NAME}-${BRANCH}" subresource: scale minReplicas: ${{MIN_REPLICAS}} maxReplicas: ${{MAX_REPLICAS}} @@ -148,12 +150,14 @@ objects: - type: Resource resource: name: cpu - targetAverageUtilization: 200 + target: + type: Utilization + averageUtilization: 200 parameters: - name: REPO_NAME description: Application repository name required: true -- name: JOB_NAME +- name: BRANCH description: Job identifier (i.e. 'backend' OR 'frontend') required: true - name: NAMESPACE @@ -162,9 +166,6 @@ parameters: - name: APP_NAME description: Application name required: true -- name: HOST_ROUTE - description: The host the route will use to expose service outside cluster - required: true - name: CONTAINER_PORT description: The port on which the application will be accessible value: "8080" @@ -172,10 +173,6 @@ parameters: - name: TAG description: The identifying tag for this specific deployment required: true -- name: HOST_PATH - description: The path appended to the HOST_ROUTE where the root of this project will be served - value: "/" - required: false - name: MIN_REPLICAS description: The minimum amount of replicas required: true diff --git a/tools/openshift/pen-reg-batch-api-pipeline.bc.yaml b/tools/openshift/pen-reg-batch-api-pipeline.bc.yaml deleted file mode 100644 index c290bd10..00000000 --- a/tools/openshift/pen-reg-batch-api-pipeline.bc.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: template.openshift.io/v1 -kind: Template -labels: - template: 'pen-reg-batch-api-template' -metadata: - name: 'pen-reg-batch-api-template' -objects: - - apiVersion: v1 - kind: BuildConfig - metadata: - labels: - build: pen-reg-batch-api-pipeline - name: pen-reg-batch-api-pipeline - spec: - source: - git: - ref: master - uri: 'https://github.com/bcgov/EDUC-PEN-REG-BATCH-API' - type: Git - strategy: - jenkinsPipelineStrategy: - jenkinsfilePath: tools/jenkins/Jenkinsfile-api