diff --git a/.drone.yml b/.drone.yml index 0645cb6..fdfedba 100644 --- a/.drone.yml +++ b/.drone.yml @@ -53,29 +53,6 @@ sonar_scanner: &sonar_scanner commands: - sonar-scanner -Dproject.settings=./sonar-project.properties -ui_integration_tests: &ui_integration_tests - <<: *node_image - environment: - NOTIFY_STUB: true - commands: - - yarn run test:ui-integration - -accessibility_tests: &accessibility_tests - pull: if-not-exists - image: buildkite/puppeteer:8.0.0@sha256:b6cebc17bfa8e7a7abfc3ab14d6f2ddbdf42b9e81b8ad786c6693385665998d5 - environment: - NOTIFY_STUB: true - ENVIRONMENT: DRONE - volumes: - - name: dockersock - path: /root/.dockersock - commands: - - yarn run test:accessibility - -acceptance_tests: &acceptance_tests - pull: if-not-exists - image: mcr.microsoft.com/playwright:v1.12.3-focal - steps: - name: clone_repos pull: if-not-exists @@ -292,6 +269,7 @@ steps: event: push depends_on: - get_pr_branch + - deploy_to_uat # Deploy to Staging environment - name: deploy_to_stg diff --git a/.gitignore b/.gitignore index 60e9c96..84727e0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ coverage .env output/ *.iml -anchore-reports .nyc_output .vscode .vscode-server diff --git a/Dockerfile b/Dockerfile index 38c5f6f..0d0e25d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM node:20.18.0-alpine3.20@sha256:d504f23acdda979406cf3bdbff0dff7933e5c4ec183d USER root # Update the package index and upgrade all installed packages to their latest versions -RUN apk update && apk upgrade +RUN apk update && apk upgrade --no-cache # Setup nodejs group & nodejs user RUN addgroup --system nodejs --gid 998 && \ diff --git a/bin/deploy.sh b/bin/deploy.sh index 2215fef..0cfa932 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -14,8 +14,8 @@ if [[ $1 == 'tear_down' ]]; then export KUBE_NAMESPACE=$BRANCH_ENV export DRONE_SOURCE_BRANCH=$(cat /root/.dockersock/branch_name.txt) - $kd --delete -f kube/configmaps/configmap.yml - $kd --delete -f kube/redis -f kube/app -f kube/file-vault + $kd --delete -f kube/configmaps/configmap.yml -f kube/hof-rds-api + $kd --delete -f kube/redis -f kube/html-pdf -f kube/app -f kube/file-vault echo "Torn Down Branch - $APP_NAME-$DRONE_SOURCE_BRANCH.internal.branch.sas-notprod.homeoffice.gov.uk" exit 0 fi @@ -25,22 +25,23 @@ export DRONE_SOURCE_BRANCH=$(echo $DRONE_SOURCE_BRANCH | tr '[:upper:]' '[:lower if [[ ${KUBE_NAMESPACE} == ${BRANCH_ENV} ]]; then $kd -f kube/configmaps -f kube/certs - $kd -f kube/redis -f kube/file-vault -f kube/app + $kd -f kube/redis -f kube/hof-rds-api -f kube/html-pdf -f kube/file-vault + $kd -f kube/app elif [[ ${KUBE_NAMESPACE} == ${UAT_ENV} ]]; then $kd -f kube/configmaps/configmap.yml - $kd -f kube/redis + $kd -f kube/redis -f kube/hof-rds-api -f kube/html-pdf $kd -f kube/file-vault/file-vault-service.yml -f kube/file-vault/file-vault-ingress.yml $kd -f kube/file-vault/file-vault-deployment.yml -f kube/file-vault/file-vault-network-policy.yml $kd -f kube/app elif [[ ${KUBE_NAMESPACE} == ${STG_ENV} ]]; then $kd -f kube/configmaps/configmap.yml - $kd -f kube/redis + $kd -f kube/redis -f kube/hof-rds-api -f kube/html-pdf $kd -f kube/file-vault/file-vault-service.yml -f kube/file-vault/file-vault-ingress.yml $kd -f kube/file-vault/file-vault-deployment.yml -f kube/file-vault/file-vault-network-policy.yml $kd -f kube/app elif [[ ${KUBE_NAMESPACE} == ${PROD_ENV} ]]; then $kd -f kube/configmaps/configmap.yml - $kd -f kube/redis + $kd -f kube/redis -f kube/hof-rds-api -f kube/html-pdf $kd -f kube/file-vault/file-vault-service.yml -f kube/file-vault/file-vault-ingress.yml $kd -f kube/file-vault/file-vault-deployment.yml -f kube/file-vault/file-vault-network-policy.yml $kd -f kube/app/service.yml -f kube/app/ingress-external.yml diff --git a/kube/app/deployment.yml b/kube/app/deployment.yml index 6f31ddf..1f42b12 100644 --- a/kube/app/deployment.yml +++ b/kube/app/deployment.yml @@ -68,6 +68,11 @@ spec: {{ else }} value: redis {{ end }} + - name: SESSION_SECRET + valueFrom: + secretKeyRef: + name: session-secret + key: session-secret # - name: NOTIFY_KEY # valueFrom: # secretKeyRef: @@ -75,6 +80,22 @@ spec: # key: notify-key - name: USE_MOCKS value: "false" + - name: PDF_CONVERTER_URL + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + value: https://html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }}:10443/convert + {{ else }} + value: https://html-pdf-converter:10443/convert + {{ end }} + - name: FILE_VAULT_URL + {{ if eq .KUBE_NAMESPACE .PROD_ENV }} + value: https://fv-{{ .APP_NAME }}.sas.homeoffice.gov.uk/file + {{ else if eq .KUBE_NAMESPACE .STG_ENV }} + value: https://fv-{{ .APP_NAME }}.stg.sas.homeoffice.gov.uk/file + {{ else if eq .KUBE_NAMESPACE .UAT_ENV }} + value: https://fv-{{ .APP_NAME }}.uat.sas-notprod.homeoffice.gov.uk/file + {{ else if eq .KUBE_NAMESPACE .BRANCH_ENV }} + value: https://fv-{{ .DRONE_SOURCE_BRANCH }}.branch.sas-notprod.homeoffice.gov.uk/file + {{ end }} - name: FILE_VAULT_CLIENT_SECRET valueFrom: secretKeyRef: @@ -95,20 +116,11 @@ spec: secretKeyRef: name: file-vault-user key: password - - name: SESSION_SECRET - valueFrom: - secretKeyRef: - name: session-secret - key: session-secret - - name: FILE_VAULT_URL - {{ if eq .KUBE_NAMESPACE .PROD_ENV }} - value: https://fv-{{ .APP_NAME }}.sas.homeoffice.gov.uk/file - {{ else if eq .KUBE_NAMESPACE .UAT_ENV }} - value: https://fv-{{ .APP_NAME }}.uat.sas-notprod.homeoffice.gov.uk/file - {{ else if eq .KUBE_NAMESPACE .STG_ENV }} - value: https://fv-{{ .APP_NAME }}.stg.sas.homeoffice.gov.uk/file - {{ else if eq .KUBE_NAMESPACE .BRANCH_ENV }} - value: https://fv-{{ .DRONE_SOURCE_BRANCH }}.branch.sas-notprod.homeoffice.gov.uk/file + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + - name: DATASERVICE_SERVICE_HOST + value: dataservice-{{ .DRONE_SOURCE_BRANCH }} + - name: DATASERVICE_SERVICE_PORT_HTTPS + value: "10443" {{ end }} {{ if not (eq .KUBE_NAMESPACE .BRANCH_ENV) }} livenessProbe: @@ -126,11 +138,11 @@ spec: {{ end }} resources: requests: - memory: 30Mi - cpu: 30m + memory: 256Mi + cpu: 100m limits: + cpu: 250m memory: 512Mi - cpu: 600m volumeMounts: - mountPath: /public name: public @@ -140,20 +152,22 @@ spec: image: quay.io/ukhomeofficedigital/nginx-proxy-govuk@sha256:4470064d0b1d20ae08c5fd85551576cb687f342a22d6cb456fda9b2c4ce8c8df resources: requests: - memory: 10Mi - cpu: 10m + memory: 20Mi + cpu: 20m limits: memory: 256Mi cpu: 300m env: {{ file .NGINX_SETTINGS | indent 12 }} ports: + - containerPort: 10080 - containerPort: 10443 volumeMounts: - mountPath: /public name: public securityContext: runAsNonRoot: true + volumes: - name: public emptyDir: {} diff --git a/kube/file-vault/file-vault-deployment.yml b/kube/file-vault/file-vault-deployment.yml index 7734f20..149e5e3 100644 --- a/kube/file-vault/file-vault-deployment.yml +++ b/kube/file-vault/file-vault-deployment.yml @@ -14,6 +14,11 @@ metadata: name: file-vault {{ end }} spec: + {{ if eq .KUBE_NAMESPACE .PROD_ENV }} + replicas: 2 + {{ else }} + replicas: 1 + {{ end }} selector: matchLabels: {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} @@ -115,6 +120,8 @@ spec: limits: memory: 1024Mi cpu: 200m + requests: + memory: 512Mi envFrom: - configMapRef: {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} diff --git a/kube/hof-rds-api/deployment.yml b/kube/hof-rds-api/deployment.yml new file mode 100644 index 0000000..4e26efc --- /dev/null +++ b/kube/hof-rds-api/deployment.yml @@ -0,0 +1,123 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service + {{ end }} +spec: + {{ if eq .KUBE_NAMESPACE .PROD_ENV }} + replicas: 2 + {{ else }} + replicas: 1 + {{ end }} + selector: + matchLabels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-{{ .DRONE_SOURCE_BRANCH }} + service: data-service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service + service: data-service + {{ end }} + template: + metadata: + labels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-{{ .DRONE_SOURCE_BRANCH }} + service: data-service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service + service: data-service + {{ end }} + build: "{{.DRONE_BUILD_NUMBER}}" + commit: "{{.DRONE_COMMIT_SHA}}" + spec: + containers: + - name: data-service + # release v2.0.1 + image: quay.io/ukhomeofficedigital/hof-rds-api:16bc712744851373e533d94ecf04724836be8247 + imagePullPolicy: Always + envFrom: + - configMapRef: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: {{ .APP_NAME }}-configmap-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: {{ .APP_NAME }}-configmap + {{ end }} + env: + - name: SERVICE_NAME + value: "csl" + - name: MAX_PAYLOAD_SIZE + value: "30mb" + - name: REQUEST_TIMEOUT + value: "10000" + - name: HTTPS_PORT + value: "3443" + - name: DB_HOST + valueFrom: + secretKeyRef: + key: endpoint + {{ if or (eq .KUBE_NAMESPACE .BRANCH_ENV) (eq .KUBE_NAMESPACE .UAT_ENV) }} + name: {{ .APP_NAME }}-notprod-rds + {{ else if eq .KUBE_NAMESPACE .STG_ENV }} + name: {{ .APP_NAME }}-rds-stg + {{ else }} + name: {{ .APP_NAME }}-rds-prod + {{ end }} + - name: DB_NAME + valueFrom: + secretKeyRef: + key: db_name + {{ if or (eq .KUBE_NAMESPACE .BRANCH_ENV) (eq .KUBE_NAMESPACE .UAT_ENV) }} + name: {{ .APP_NAME }}-notprod-rds + {{ else if eq .KUBE_NAMESPACE .STG_ENV }} + name: {{ .APP_NAME }}-rds-stg + {{ else }} + name: {{ .APP_NAME }}-rds-prod + {{ end }} + - name: DB_USER + valueFrom: + secretKeyRef: + key: username + {{ if or (eq .KUBE_NAMESPACE .BRANCH_ENV) (eq .KUBE_NAMESPACE .UAT_ENV) }} + name: {{ .APP_NAME }}-notprod-rds + {{ else if eq .KUBE_NAMESPACE .STG_ENV }} + name: {{ .APP_NAME }}-rds-stg + {{ else }} + name: {{ .APP_NAME }}-rds-prod + {{ end }} + - name: DB_PASS + valueFrom: + secretKeyRef: + key: password + {{ if or (eq .KUBE_NAMESPACE .BRANCH_ENV) (eq .KUBE_NAMESPACE .UAT_ENV) }} + name: {{ .APP_NAME }}-notprod-rds + {{ else if eq .KUBE_NAMESPACE .STG_ENV }} + name: {{ .APP_NAME }}-rds-stg + {{ else }} + name: {{ .APP_NAME }}-rds-prod + {{ end }} + resources: + requests: + memory: 4Gi + cpu: 200m + limits: + memory: 8Gi + cpu: 400m + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /certs + name: certs + readOnly: true + volumes: + - name: certs + secret: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + secretName: branch-tls-external + {{ else }} + secretName: data-service-cert-cmio + {{ end }} diff --git a/kube/hof-rds-api/networkpolicy.yml b/kube/hof-rds-api/networkpolicy.yml new file mode 100644 index 0000000..c8048a7 --- /dev/null +++ b/kube/hof-rds-api/networkpolicy.yml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-permit-access-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service-permit-access + {{ end }} +spec: + ingress: + - from: + - podSelector: + matchLabels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: {{ .APP_NAME }}-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: {{ .APP_NAME }} + {{ end }} + ports: + - port: 3443 + protocol: TCP + podSelector: + matchLabels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service + {{ end }} diff --git a/kube/hof-rds-api/service.yml b/kube/hof-rds-api/service.yml new file mode 100644 index 0000000..9489278 --- /dev/null +++ b/kube/hof-rds-api/service.yml @@ -0,0 +1,27 @@ +--- +apiVersion: v1 +kind: Service +metadata: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: dataservice-{{ .DRONE_SOURCE_BRANCH }} + labels: + name: dataservice-{{ .DRONE_SOURCE_BRANCH }} + role: service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: dataservice + labels: + name: dataservice + role: service + {{ end }} + +spec: + selector: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: data-service-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: data-service + {{ end }} + ports: + - name: https + port: 10443 + targetPort: 3443 diff --git a/kube/html-pdf/html-pdf-deployment.yml b/kube/html-pdf/html-pdf-deployment.yml new file mode 100644 index 0000000..9914bc4 --- /dev/null +++ b/kube/html-pdf/html-pdf-deployment.yml @@ -0,0 +1,91 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + {{ if eq .KUBE_NAMESPACE .PROD_ENV }} + name: html-pdf-converter + {{ else if eq .KUBE_NAMESPACE .BRANCH_ENV }} + annotations: + downscaler/uptime: {{ .NON_PROD_AVAILABILITY }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + annotations: + downscaler/uptime: {{ .NON_PROD_AVAILABILITY }} + name: html-pdf-converter + {{ end }} +spec: + {{ if eq .KUBE_NAMESPACE .PROD_ENV }} + replicas: 2 + {{ else }} + replicas: 1 + {{ end }} + selector: + matchLabels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: html-pdf-converter + {{ end }} + template: + metadata: + labels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + service: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: html-pdf-converter + service: html-pdf-converter + {{ end }} + spec: + containers: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + - name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + - name: html-pdf-converter + {{ end }} + # html-pdf-converter:v2.1.0 + image: quay.io/ukhomeofficedigital/html-pdf-converter@sha256:45814848f0c1d56169ab90990891b03d52d59d7558255cfca8ed2ce2a02d034e + imagePullPolicy: Always + resources: + requests: + memory: 10Mi + cpu: 10m + limits: + cpu: 250m + memory: 256Mi + env: + - name: APP_PORT + value: "8001" + securityContext: + runAsNonRoot: true + + - name: nginx-proxy + # nginx-proxy-govuk:v4 + image: quay.io/ukhomeofficedigital/nginx-proxy-govuk@sha256:4470064d0b1d20ae08c5fd85551576cb687f342a22d6cb456fda9b2c4ce8c8df + resources: + requests: + memory: 10Mi + cpu: 10m + limits: + cpu: 250m + memory: 256Mi + env: + - name: PROXY_SERVICE_HOST + value: 127.0.0.1 + - name: PROXY_SERVICE_PORT + value: "8001" + - name: ENABLE_UUID_PARAM + value: "FALSE" + - name: HTTPS_REDIRECT + value: "FALSE" + - name: NAXSI_USE_DEFAULT_RULES + value: "FALSE" + - name: PORT_IN_HOST_HEADER + value: "FALSE" + - name: ERROR_REDIRECT_CODES + value: "599" + securityContext: + runAsNonRoot: true + ports: + - containerPort: 10080 + - containerPort: 10443 diff --git a/kube/html-pdf/html-pdf-network-policy.yml b/kube/html-pdf/html-pdf-network-policy.yml new file mode 100644 index 0000000..1743834 --- /dev/null +++ b/kube/html-pdf/html-pdf-network-policy.yml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-allow-ingress-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: html-pdf-converter-allow-ingress + {{ end }} +spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + name: {{ .KUBE_NAMESPACE }} + ports: + - port: 10080 + protocol: TCP + - port: 10443 + protocol: TCP + podSelector: + matchLabels: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: html-pdf-converter + {{ end }} + policyTypes: + - Ingress diff --git a/kube/html-pdf/html-pdf-service.yml b/kube/html-pdf/html-pdf-service.yml new file mode 100644 index 0000000..46983a0 --- /dev/null +++ b/kube/html-pdf/html-pdf-service.yml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + labels: + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + role: service + {{ else }} + name: html-pdf-converter + labels: + name: html-pdf-converter + role: service + {{ end }} +spec: + ports: + - name: http + port: 10080 + - name: https + port: 10443 + selector: + {{ if eq .KUBE_NAMESPACE .BRANCH_ENV }} + name: html-pdf-converter-{{ .DRONE_SOURCE_BRANCH }} + {{ else }} + name: html-pdf-converter + {{ end }}