diff --git a/charts/rawls/Chart.yaml b/charts/rawls/Chart.yaml index 67cecd69a..89644350b 100644 --- a/charts/rawls/Chart.yaml +++ b/charts/rawls/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: rawls -version: 0.8.0 +version: 0.8.1 appVersion: latest description: Chart for Rawls service in Terra type: application diff --git a/charts/rawls/README.md b/charts/rawls/README.md index 98137b627..0563cf75a 100644 --- a/charts/rawls/README.md +++ b/charts/rawls/README.md @@ -1,6 +1,6 @@ # rawls -![Version: 0.5.0](https://img.shields.io/badge/Version-0.5.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) +![Version: 0.8.1](https://img.shields.io/badge/Version-0.8.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) Chart for Rawls service in Terra @@ -15,7 +15,7 @@ Chart for Rawls service in Terra |-----|------|---------|-------------| | deploymentDefaults.enabled | bool | `true` | Whether a declared deployment is enabled. If false, no resources will be created | | deploymentDefaults.expose | bool | `false` | Whether to create a Service for this deployment | -| deploymentDefaults.imageTag | string | `nil` | Image tag to be used when deploying Pods @defautl global.applicationVersion | +| deploymentDefaults.imageTag | string | `nil` | Image tag to be used when deploying Pods @default global.applicationVersion | | deploymentDefaults.legacyResourcePrefix | string | `nil` | What prefix to use to refer to secrets rendered from firecloud-develop @default deploymentDefaults.name | | deploymentDefaults.name | string | `nil` | A name for the deployment that will be substituted into resuorce definitions. Example: `"rawls1-reader"` | | deploymentDefaults.probes.liveness.enabled | bool | `true` | | @@ -38,10 +38,20 @@ Chart for Rawls service in Terra | ingress.sslPolicy | string | `"tls12-ssl-policy"` | (string) Name of an existing google ssl policy to associate with an ingress frontend-config | | ingress.staticIpName | string | `nil` | Required. GCP resource name for ingress static ip | | ingress.timeoutSec | int | `120` | Number of seconds to timeout on requests to the ingress | +| migration.dryRun | bool | `true` | When true, merely print migration SQL; when false, execute it | +| migration.enabled | bool | `false` | Whether to run a Liquibase migration job pre-sync | +| migration.failBasedOnLiquibase | bool | `true` | When true, fail the job (and ArgoCD sync!) if the Liquibase command fails | +| migration.imageTag | string | `nil` | Override the image tag to run the migration on @default global.applicationVersion WARNING: App may behave unexpectedly if its database has been migrated to a different version than the app | +| migration.secretPrefix | string | `"rawls-backend"` | Prefix for ctmpl and env secrets NOTE: Generally equals some deploymentDefaults.name, as secrets are per-deployment but migrations are per-namespace | +| migration.serviceAccount | string | `"rawls-sa"` | Name of the k8s SA to use for the job | +| migration.syncWave | string | `"-1"` | Wave to run migration as a sync hook (presumably after SA's RBAC wave) NOTE: Sync hook, not PreSync, so that SA/RBAC can be made normally via an earlier wave | | resources.limits.cpu | int | `8` | Number of CPU units to limit the deployment to | | resources.limits.memory | string | `"16Gi"` | Memory to limit the deployment to | | resources.requests.cpu | int | `8` | Number of CPU units to request for the deployment | | resources.requests.memory | string | `"16Gi"` | Memory to request for the deployment | +| vault.migration.dbPasswordKey | string | `"slick_db_password"` | | +| vault.migration.dbUsernameKey | string | `"slick_db_user"` | Key in Vault secret to DB username | +| vault.migration.path | string | `nil` | Vault path to secret containing DB credentials | ---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.5.0](https://github.com/norwoodj/helm-docs/releases/v1.5.0) diff --git a/charts/rawls/templates/migration/job.yaml b/charts/rawls/templates/migration/job.yaml new file mode 100644 index 000000000..101cb4291 --- /dev/null +++ b/charts/rawls/templates/migration/job.yaml @@ -0,0 +1,87 @@ +{{- if .Values.migration.enabled }} +{{- $imageTag := .Values.migration.imageTag | default .Values.global.applicationVersion -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: rawls-liquibase-migration + annotations: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-wave: "{{ .Values.migration.syncWave }}" + labels: {{- include "rawls.labels" . | nindent 4 }} +spec: + backoffLimit: 2 + template: + metadata: + name: rawls-liquibase-migration + labels: {{- include "rawls.labels" . | nindent 8 }} + spec: + # Allow migration-liquibase to kill migration-sqlproxy's process + shareProcessNamespace: true + restartPolicy: Never + serviceAccountName: {{ .Values.migration.serviceAccount }} + hostAliases: + - ip: 127.0.0.1 + hostnames: + - sqlproxy + volumes: + - name: app-ctmpls + secret: + secretName: {{ .Values.migration.secretPrefix }}-app-ctmpls + - name: sqlproxy-ctmpls + secret: + secretName: {{ .Values.migration.secretPrefix }}-sqlproxy-ctmpls + containers: + - name: rawls-migration-liquibase + image: "gcr.io/broad-dsp-gcr-public/rawls:{{ $imageTag }}" + command: ['bash', '-c'] + # Sleep for 15s to allow CloudSQL proxy time to start up. See DDO-1284 / BT-296 + # The `find /rawls -name 'rawls*.jar'` is from Rawls's own Dockerfile CMD + # References templated liquibase.properties, see https://docs.google.com/document/d/19ethQWyH29H-jUWwgFoCxKfjmzcG-NCmSgXNAUJAYaU/edit# + args: + - |- + sleep 15s && \ + java -cp $(find /rawls -name 'rawls*.jar') liquibase.integration.commandline.Main \ + --defaultsFile='/etc/liquibase.properties' \ + --classpath="$(find /rawls -name 'rawls*.jar')" \ + --username="$DB_USERNAME" \ + --password="$DB_PASSWORD" \ + {{ .Values.migration.dryRun | ternary "updateSQL" "update" }}; \ + EXIT={{ .Values.migration.failBasedOnLiquibase | ternary "$?" "0" }}; \ + pkill -SIGTERM cloud_sql_proxy; \ + exit $EXIT + env: + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: rawls-sql-secrets + key: db-username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: rawls-sql-secrets + key: db-password + volumeMounts: + - mountPath: /etc/liquibase.properties + subPath: liquibase.properties + name: app-ctmpls + readOnly: true + - name: rawls-migration-sqlproxy + # alpine provides `sh` + image: gcr.io/cloudsql-docker/gce-proxy:1.23.0-alpine + envFrom: + - secretRef: + name: {{ .Values.migration.secretPrefix }}-sqlproxy-env + volumeMounts: + - mountPath: /etc/sqlproxy-service-account.json + subPath: sqlproxy-service-account.json + name: sqlproxy-ctmpls + readOnly: true + command: ['sh', '-c'] + args: + - |- + /cloud_sql_proxy ${CLOUDSQL_LOGGING:-"-verbose"} \ + -max_connections=${CLOUDSQL_MAXCONNS:-0} \ + -instances="${CLOUDSQL_CONNECTION_LIST:-${GOOGLE_PROJECT}:${CLOUDSQL_ZONE}:${CLOUDSQL_INSTANCE}=tcp:0.0.0.0:${PORT:-3306}}" \ + -credential_file=${CLOUDSQL_CREDENTIAL_FILE:-"/etc/sqlproxy-service-account.json"} +{{- end -}} diff --git a/charts/rawls/templates/migration/secretDefinition.yaml b/charts/rawls/templates/migration/secretDefinition.yaml new file mode 100644 index 000000000..5271f5c7b --- /dev/null +++ b/charts/rawls/templates/migration/secretDefinition.yaml @@ -0,0 +1,20 @@ +{{- if .Values.migration.enabled }} +apiVersion: secrets-manager.tuenti.io/v1alpha1 +kind: SecretDefinition +metadata: + name: rawls-migration-secretdef + labels: {{- include "rawls.labels" . | nindent 4 }} + annotations: + argocd.argoproj.io/sync-wave: "{{ .Values.migration.syncWave }}" +spec: + name: rawls-sql-secrets + keysMap: + db-username: + key: {{ .Values.vault.migration.dbUsernameKey }} + path: {{ required "A valid vault.migration.path is required" .Values.vault.migration.path }} + encoding: text + db-password: + key: {{ .Values.vault.migration.dbPasswordKey }} + path: {{ required "A valid vault.migration.path is required" .Values.vault.migration.path }} + encoding: text +{{- end -}} diff --git a/charts/rawls/templates/role.yaml b/charts/rawls/templates/role.yaml index 6fe61031a..5829eb265 100644 --- a/charts/rawls/templates/role.yaml +++ b/charts/rawls/templates/role.yaml @@ -2,6 +2,8 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: rawls-role + annotations: + argocd.argoproj.io/sync-wave: "-2" labels: {{ include "rawls.labels" . | indent 4 }} rules: diff --git a/charts/rawls/templates/roleBinding.yaml b/charts/rawls/templates/roleBinding.yaml index 05d83af13..421e6dd79 100644 --- a/charts/rawls/templates/roleBinding.yaml +++ b/charts/rawls/templates/roleBinding.yaml @@ -2,6 +2,8 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: rawls-sa-binding + annotations: + argocd.argoproj.io/sync-wave: "-2" labels: {{ include "rawls.labels" . | indent 4 }} subjects: diff --git a/charts/rawls/templates/serviceAccount.yaml b/charts/rawls/templates/serviceAccount.yaml index 93750fa72..66cb6106d 100644 --- a/charts/rawls/templates/serviceAccount.yaml +++ b/charts/rawls/templates/serviceAccount.yaml @@ -2,5 +2,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: rawls-sa + annotations: + argocd.argoproj.io/sync-wave: "-2" labels: {{ include "rawls.labels" . | indent 4 }} \ No newline at end of file diff --git a/charts/rawls/values.yaml b/charts/rawls/values.yaml index 69fd4861c..80feae294 100644 --- a/charts/rawls/values.yaml +++ b/charts/rawls/values.yaml @@ -41,7 +41,7 @@ deploymentDefaults: # Example: `"rawls1-reader"` name: null # deploymentDefaults.imageTag -- Image tag to be used when deploying Pods - # @defautl global.applicationVersion + # @default global.applicationVersion imageTag: null # deploymentDefaults.replicas -- Number of replicas for the deployment replicas: 0 @@ -92,3 +92,33 @@ deploymentDefaults: periodSeconds: 10 failureThreshold: 1080 # 3 hours before restarted, to prevent liveness probes from interrupting long-running liquibase migrations successThreshold: 1 + +vault: + # Migration credentials only referenced if migration.enabled == true + migration: + # vault.migration.path -- Vault path to secret containing DB credentials + path: null + # vault.migration.dbUsernameKey -- Key in Vault secret to DB username + dbUsernameKey: "slick_db_user" + # vault.migration.DbPasswordKey -- Key in Vault secret to DB password + dbPasswordKey: "slick_db_password" + +migration: + # migration.enabled -- Whether to run a Liquibase migration job pre-sync + enabled: false + # migration.dryRun -- When true, merely print migration SQL; when false, execute it + dryRun: true + # migration.failBasedOnLiquibase -- When true, fail the job (and ArgoCD sync!) if the Liquibase command fails + failBasedOnLiquibase: true + # migration.imageTag -- Override the image tag to run the migration on + # @default global.applicationVersion + # WARNING: App may behave unexpectedly if its database has been migrated to a different version than the app + imageTag: null + # migration.secretPrefix -- Prefix for ctmpl and env secrets + # NOTE: Generally equals some deploymentDefaults.name, as secrets are per-deployment but migrations are per-namespace + secretPrefix: "rawls-backend" + # migration.serviceAccount -- Name of the k8s SA to use for the job + serviceAccount: "rawls-sa" + # migration.syncWave -- Wave to run migration as a sync hook (presumably after SA's RBAC wave) + # NOTE: Sync hook, not PreSync, so that SA/RBAC can be made normally via an earlier wave + syncWave: "-1"