From 384294013bb8fd4aebe8ca4f55a647288af2aaf7 Mon Sep 17 00:00:00 2001 From: Jawad Qureshi Date: Tue, 18 Oct 2022 18:10:20 -0500 Subject: [PATCH 1/3] Orchestration cleanup --- .gitignore | 2 + .secrets.baseline | 49 +++--- README.md | 19 +-- helm/ambassador/Chart.yaml | 6 +- helm/arborist/Chart.yaml | 6 +- helm/argo-wrapper/Chart.yaml | 6 +- helm/audit/Chart.yaml | 4 +- helm/aws-es-proxy/Chart.yaml | 4 +- helm/db-setup/Chart.yaml | 6 +- helm/db-setup/templates/_db_setup.tpl | 61 ++++++-- helm/db-setup/values.yaml | 23 +-- helm/dicom-server/Chart.yaml | 2 +- helm/dicom-viewer/Chart.yaml | 2 +- helm/fence/Chart.yaml | 6 +- helm/fence/fence-config/fence-config.yaml | 2 +- helm/fence/templates/fence-deployment.yaml | 4 +- helm/fence/values.yaml | 2 +- helm/gen3-test-data-job/Chart.yaml | 6 +- helm/gen3/Chart.lock | 41 ++--- helm/gen3/Chart.yaml | 144 +++++++++--------- helm/gen3/charts/ambassador-0.1.0.tgz | Bin 3009 -> 0 bytes helm/gen3/charts/arborist-0.1.0.tgz | Bin 3649 -> 0 bytes helm/gen3/charts/argo-wrapper-0.1.0.tgz | Bin 3085 -> 0 bytes helm/gen3/charts/audit-0.1.0.tgz | Bin 3953 -> 0 bytes helm/gen3/charts/fence-0.1.0.tgz | Bin 36821 -> 0 bytes helm/gen3/charts/guppy-0.1.0.tgz | Bin 3598 -> 0 bytes helm/gen3/charts/hatchery-0.1.0.tgz | Bin 4081 -> 0 bytes helm/gen3/charts/indexd-0.1.0.tgz | Bin 8187 -> 0 bytes helm/gen3/charts/manifestservice-0.1.0.tgz | Bin 4024 -> 0 bytes helm/gen3/charts/metadata-0.1.0.tgz | Bin 3657 -> 0 bytes helm/gen3/charts/peregrine-0.1.0.tgz | Bin 8627 -> 0 bytes helm/gen3/charts/pidgin-0.1.0.tgz | Bin 2982 -> 0 bytes helm/gen3/charts/portal-0.1.0.tgz | Bin 109099 -> 0 bytes helm/gen3/charts/requestor-0.1.0.tgz | Bin 3417 -> 0 bytes helm/gen3/charts/revproxy-0.1.0.tgz | Bin 15871 -> 0 bytes helm/gen3/charts/sheepdog-0.1.0.tgz | Bin 9250 -> 0 bytes helm/gen3/charts/ssjdispatcher-0.1.0.tgz | Bin 4435 -> 0 bytes helm/gen3/values.yaml | 10 +- helm/guppy/Chart.yaml | 6 +- helm/hatchery/Chart.yaml | 6 +- helm/indexd/Chart.yaml | 6 +- helm/indexd/templates/deployment.yaml | 3 + helm/indexd/templates/indexd-secret.yaml | 7 + helm/indexd/templates/pre-install.yaml | 2 + helm/manifestservice/Chart.yaml | 4 +- helm/metadata/Chart.yaml | 6 +- helm/peregrine/Chart.yaml | 6 +- .../peregrine/templates/peregrine-secret.yaml | 9 +- helm/peregrine/values.yaml | 27 ---- helm/pidgin/Chart.yaml | 6 +- helm/portal/Chart.yaml | 6 +- helm/portal/templates/configMap.yaml | 18 +++ helm/portal/templates/deployment.yaml | 18 ++- helm/portal/values.yaml | 27 ++-- helm/requestor/Chart.yaml | 6 +- helm/requestor/templates/deployment.yaml | 12 +- .../requestor/templates/requestor-secret.yaml | 17 +-- helm/revproxy/Chart.yaml | 6 +- helm/sheepdog/Chart.lock | 6 + helm/sheepdog/Chart.yaml | 12 +- helm/sheepdog/templates/db-init.yaml | 3 + helm/sheepdog/templates/sheepdog-secret.yaml | 8 +- helm/ssjdispatcher/Chart.yaml | 6 +- helm/terraform-runner-job/Chart.yaml | 6 +- helm/terraform-runner-job/templates/jobs.yaml | 9 +- helm/wts/Chart.lock | 6 +- helm/wts/Chart.yaml | 11 +- helm/wts/charts/db-setup-0.1.0.tgz | Bin 1218 -> 0 bytes helm/wts/templates/appInit.yaml | 1 - helm/wts/templates/db-init.yaml | 3 + helm/wts/templates/secret.yaml | 2 +- helm/wts/values.yaml | 32 ++-- wip/acronymbot/Chart.yaml | 2 +- wip/cogwheel/Chart.yaml | 6 +- 74 files changed, 414 insertions(+), 302 deletions(-) delete mode 100644 helm/gen3/charts/ambassador-0.1.0.tgz delete mode 100644 helm/gen3/charts/arborist-0.1.0.tgz delete mode 100644 helm/gen3/charts/argo-wrapper-0.1.0.tgz delete mode 100644 helm/gen3/charts/audit-0.1.0.tgz delete mode 100644 helm/gen3/charts/fence-0.1.0.tgz delete mode 100644 helm/gen3/charts/guppy-0.1.0.tgz delete mode 100644 helm/gen3/charts/hatchery-0.1.0.tgz delete mode 100644 helm/gen3/charts/indexd-0.1.0.tgz delete mode 100644 helm/gen3/charts/manifestservice-0.1.0.tgz delete mode 100644 helm/gen3/charts/metadata-0.1.0.tgz delete mode 100644 helm/gen3/charts/peregrine-0.1.0.tgz delete mode 100644 helm/gen3/charts/pidgin-0.1.0.tgz delete mode 100644 helm/gen3/charts/portal-0.1.0.tgz delete mode 100644 helm/gen3/charts/requestor-0.1.0.tgz delete mode 100644 helm/gen3/charts/revproxy-0.1.0.tgz delete mode 100644 helm/gen3/charts/sheepdog-0.1.0.tgz delete mode 100644 helm/gen3/charts/ssjdispatcher-0.1.0.tgz create mode 100644 helm/portal/templates/configMap.yaml create mode 100644 helm/sheepdog/Chart.lock create mode 100644 helm/sheepdog/templates/db-init.yaml delete mode 100644 helm/wts/charts/db-setup-0.1.0.tgz delete mode 100644 helm/wts/templates/appInit.yaml create mode 100644 helm/wts/templates/db-init.yaml diff --git a/.gitignore b/.gitignore index acfc0957..fad70505 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ postgres.txt +**/charts/ +values.yaml \ No newline at end of file diff --git a/.secrets.baseline b/.secrets.baseline index 0607e230..bc050c61 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2022-09-19T14:03:53Z", + "generated_at": "2022-10-18T23:08:35Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -63,14 +63,14 @@ "hashed_secret": "04024ac03c114027f1116abedeb4bb78b01a31db", "is_secret": false, "is_verified": false, - "line_number": 84, + "line_number": 85, "type": "Secret Keyword" }, { "hashed_secret": "0c9967f3918994e95ab61396a76a7d10f783c8f7", "is_secret": false, "is_verified": false, - "line_number": 108, + "line_number": 109, "type": "Secret Keyword" } ], @@ -95,28 +95,34 @@ "helm/db-setup/templates/_db_setup.tpl": [ { "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "is_secret": false, "is_verified": false, - "line_number": 24, + "line_number": 70, "type": "Secret Keyword" } ], "helm/db-setup/values.yaml": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "a70646783e43f444ba3430a4110bb7bdd65bdb3a", + "is_secret": false, "is_verified": false, - "line_number": 6, + "line_number": 16, "type": "Secret Keyword" }, { - "hashed_secret": "a70646783e43f444ba3430a4110bb7bdd65bdb3a", + "hashed_secret": "874947acc1ffd819b836f6e049b2f1ab8303cb6c", + "is_secret": false, "is_verified": false, - "line_number": 12, + "line_number": 20, "type": "Secret Keyword" - }, + } + ], + "helm/dicom-server/values.yaml": [ { - "hashed_secret": "874947acc1ffd819b836f6e049b2f1ab8303cb6c", + "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "is_secret": false, "is_verified": false, - "line_number": 15, + "line_number": 69, "type": "Secret Keyword" } ], @@ -274,17 +280,19 @@ ], "helm/peregrine/values.yaml": [ { - "hashed_secret": "c286f6974f94aab4cfaf2ef49ee0465a8495f563", + "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_secret": false, "is_verified": false, - "line_number": 4, + "line_number": 170, "type": "Secret Keyword" - }, + } + ], + "helm/requestor/values.yaml": [ { "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_secret": false, "is_verified": false, - "line_number": 195, + "line_number": 111, "type": "Secret Keyword" } ], @@ -344,15 +352,10 @@ ], "helm/wts/values.yaml": [ { - "hashed_secret": "7f8d4ff76d11ef5e9aa633658ed42694b91d3da9", - "is_verified": false, - "line_number": 116, - "type": "Secret Keyword" - }, - { - "hashed_secret": "a70646783e43f444ba3430a4110bb7bdd65bdb3a", + "hashed_secret": "206c80413b9a96c1312cc346b7d2517b84463edd", + "is_secret": false, "is_verified": false, - "line_number": 122, + "line_number": 134, "type": "Secret Keyword" } ] diff --git a/README.md b/README.md index f94ac455..d11e4224 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,14 @@ kubectl run postgres-postgresql-client --rm --tty -i --restart='Never' --namespa Once you get a PSQL shell into postgres create databses by running the following ``` -CREATE DATBASE arborist; -CREATE DATBASE audit; -CREATE DATBASE fence; -CREATE DATBASE indexd; -CREATE DATBASE metadata; -CREATE DATBASE peregrine; -CREATE DATBASE sheepdog; +CREATE DATABASE arborist; +CREATE DATABASE audit; +CREATE DATABASE fence; +CREATE DATABASE indexd; +CREATE DATABASE metadata; +CREATE DATABASE peregrine; +CREATE DATABASE sheepdog; +CREATE DATABASE requestor; ``` @@ -72,10 +73,10 @@ After configuration is complete, take note of the client ID that was created. Yo ## Helm chart deployment -### Install all charts +### Install Gen3 ``` cd ./helm -for i in $(ls); do helm upgrade --install $i ./$i; done +helm upgrade --install gen3 ./gen3 -f values.yaml ``` ### Install fence with google login secrets diff --git a/helm/ambassador/Chart.yaml b/helm/ambassador/Chart.yaml index 18018a4f..65b0542d 100644 --- a/helm/ambassador/Chart.yaml +++ b/helm/ambassador/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: ambassador -description: A Helm chart for Kubernetes +description: A Helm chart for deploying ambassador for gen3 # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "1.4.2" diff --git a/helm/arborist/Chart.yaml b/helm/arborist/Chart.yaml index 9d400923..558b9c0b 100644 --- a/helm/arborist/Chart.yaml +++ b/helm/arborist/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: arborist -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 arborist # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.05" \ No newline at end of file +appVersion: "2022.10" \ No newline at end of file diff --git a/helm/argo-wrapper/Chart.yaml b/helm/argo-wrapper/Chart.yaml index 145a49cc..71738137 100644 --- a/helm/argo-wrapper/Chart.yaml +++ b/helm/argo-wrapper/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: argo-wrapper -description: A Helm chart for Argo Wrapper Service +description: A Helm chart for gen3 Argo Wrapper Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "master" +appVersion: "2022.10" diff --git a/helm/audit/Chart.yaml b/helm/audit/Chart.yaml index 4cd2aef5..67c5f74e 100644 --- a/helm/audit/Chart.yaml +++ b/helm/audit/Chart.yaml @@ -15,11 +15,11 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 2022.05 +appVersion: "2022.10" diff --git a/helm/aws-es-proxy/Chart.yaml b/helm/aws-es-proxy/Chart.yaml index 58829a7a..bb8dc186 100644 --- a/helm/aws-es-proxy/Chart.yaml +++ b/helm/aws-es-proxy/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: aws-es-proxy -description: A Helm chart for AWS ES Proxy Service +description: A Helm chart for AWS ES Proxy Service for gen3 # A chart can be either an 'application' or a 'library' chart. # @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/helm/db-setup/Chart.yaml b/helm/db-setup/Chart.yaml index 991e18cb..bce4131b 100644 --- a/helm/db-setup/Chart.yaml +++ b/helm/db-setup/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: db-setup -description: A Helm chart for Kubernetes +description: A Helm chart for provisioning databases in gen3 # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: library # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "master" diff --git a/helm/db-setup/templates/_db_setup.tpl b/helm/db-setup/templates/_db_setup.tpl index 8b187f1c..98927e1c 100644 --- a/helm/db-setup/templates/_db_setup.tpl +++ b/helm/db-setup/templates/_db_setup.tpl @@ -1,17 +1,30 @@ +{{/* + Postgres Password lookup +*/}} +{{- define "postgres.master.password" -}} +{{- $localpass := (lookup "v1" "Secret" "postgres" "postgres-postgresql" ) -}} +{{- if $localpass }} +{{- default (index $localpass.data "postgres-password" | b64dec) }} +{{- else }} +{{- default $.Values.global.postgres.master.password }} +{{- end }} +{{- end }} + + + {{- define "db-setup.setup-job" -}} apiVersion: batch/v1 kind: Job metadata: - name: db-setup + name: {{ .Chart.Name }}-dbcreate + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": hook-succeeded spec: template: metadata: labels: app: gen3job - annotations: - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "-5" - "helm.sh/hook-delete-policy": hook-succeeded spec: restartPolicy: OnFailure containers: @@ -19,13 +32,41 @@ spec: image: quay.io/cdis/awshelper:master imagePullPolicy: Always command: ["/bin/bash", "-c"] + env: + - name: PGPASSWORD + value: "{{ include "postgres.master.password" . }}" + - name: PGUSER + value: "{{ $.Values.global.postgres.master.username }}" + - name: PGPORT + value: "{{ $.Values.global.postgres.master.port }}" + - name: PGHOST + value: "{{ $.Values.global.postgres.host }}" args: - | - export PGPASSWORD="{{ $.Values.postgres.master.password }}" {{- range .Values.postgres.databases }} - psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -tc "SELECT 1 FROM pg_database WHERE datname = '{{ .databaseName }}'" | grep -q 1 || psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -c "CREATE DATABASE {{ .databaseName }};" - psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -tc "SELECT 1 FROM pg_user WHERE usename = '{{ .username }}'" | grep -q 1 || psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -c "CREATE USER {{ .username }} WITH PASSWORD '{{ .password }}';" - psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -c "GRANT ALL ON DATABASE {{ .databaseName }} TO {{ .username }} WITH GRANT OPTION;" - psql -h {{ $.Values.postgres.host }} -U {{ $.Values.postgres.master.username }} -p {{ $.Values.postgres.master.port }} -d {{ .databaseName }} -c "CREATE EXTENSION ltree; ALTER ROLE {{ .username }} WITH LOGIN" + if psql -lqt | cut -d \| -f 1 | grep -qw {{ .databaseName }}; then + echo "Database named {{ .databaseName }} already exists." + else + psql -tc "SELECT 1 FROM pg_database WHERE datname = '{{ .databaseName }}'" | grep -q 1 || psql -c "CREATE DATABASE {{ .databaseName }};" + psql -tc "SELECT 1 FROM pg_user WHERE usename = '{{ .username }}'" | grep -q 1 || psql -c "CREATE USER {{ .username }} WITH PASSWORD '{{ .password }}';" + psql -c "GRANT ALL ON DATABASE {{ .databaseName }} TO {{ .username }} WITH GRANT OPTION;" + psql -d {{ .databaseName }} -c "CREATE EXTENSION ltree; ALTER ROLE {{ .username }} WITH LOGIN" + fi {{- end }} +{{- end }} + +{{ define "db-setup.secret" }} +{{- range .Values.postgres.databases }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .service }}-dbcreds + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/resource-policy": "keep" +stringData: + database: "{{ .databaseName }}" + username: "{{ .username }}" + password: "{{ .password }}" +{{- end -}} {{- end -}} \ No newline at end of file diff --git a/helm/db-setup/values.yaml b/helm/db-setup/values.yaml index a2d8c7b3..1a595331 100644 --- a/helm/db-setup/values.yaml +++ b/helm/db-setup/values.yaml @@ -1,15 +1,20 @@ +global: + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + port: 5432 + # If password is left empty the lookup function will look for postgres master password + password: + postgres: - host: postgres-postgresql.postgres.svc.cluster.local - - master: - username: postgres - password: postgres - port: 5432 - + # An array of databases to create. databases: - - databaseName: wts + - service: wts + databaseName: wts username: wts password: wts_password - - databaseName: indexd + - service: indexd + databaseName: indexd username: indexd password: indexd_password \ No newline at end of file diff --git a/helm/dicom-server/Chart.yaml b/helm/dicom-server/Chart.yaml index e14931c4..f5014981 100644 --- a/helm/dicom-server/Chart.yaml +++ b/helm/dicom-server/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: dicom-server -description: A Helm chart for AWS Dicom Server +description: A Helm chart for gen3 Dicom Server # A chart can be either an 'application' or a 'library' chart. # diff --git a/helm/dicom-viewer/Chart.yaml b/helm/dicom-viewer/Chart.yaml index 020fcdde..7f8012b9 100644 --- a/helm/dicom-viewer/Chart.yaml +++ b/helm/dicom-viewer/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: dicom-viewer -description: A Helm chart for AWS Dicom Viewer +description: A Helm chart for gen3 Dicom Viewer # A chart can be either an 'application' or a 'library' chart. # diff --git a/helm/fence/Chart.yaml b/helm/fence/Chart.yaml index ca9b5879..9b15ad2b 100644 --- a/helm/fence/Chart.yaml +++ b/helm/fence/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: fence -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 Fence # A chart can be either an 'application' or a 'library' chart. # @@ -15,9 +15,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 2022.05 \ No newline at end of file +appVersion: "2022.10" \ No newline at end of file diff --git a/helm/fence/fence-config/fence-config.yaml b/helm/fence/fence-config/fence-config.yaml index db24752e..ee3b33da 100644 --- a/helm/fence/fence-config/fence-config.yaml +++ b/helm/fence/fence-config/fence-config.yaml @@ -24,7 +24,7 @@ # ////////////////////////////////////////////////////////////////////////////////////// APP_NAME: 'Gen3 Data Commons' # Where fence microservice is deployed -BASE_URL: 'http://localhost/user' +BASE_URL: 'https://localhost/user' # postgres db to connect to # connection url format: # postgresql://[user[:password]@][netloc][:port][/dbname] diff --git a/helm/fence/templates/fence-deployment.yaml b/helm/fence/templates/fence-deployment.yaml index d5847a00..7df97d02 100644 --- a/helm/fence/templates/fence-deployment.yaml +++ b/helm/fence/templates/fence-deployment.yaml @@ -41,7 +41,7 @@ spec: httpGet: path: /_status port: http - initialDelaySeconds: 30 + initialDelaySeconds: 60 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: @@ -89,7 +89,7 @@ spec: if fence-create migrate --help > /dev/null 2>&1; then if ! grep -E 'ENABLE_DB_MIGRATION"?: *false' /var/www/fence/fence-config.yaml; then echo "Running db migration: fence-create migrate" - cat /var/www/fence/fence-config.yaml | grep DB + cd /fence fence-create migrate else echo "Db migration disabled in fence-config" diff --git a/helm/fence/values.yaml b/helm/fence/values.yaml index fc6776af..3a88a865 100644 --- a/helm/fence/values.yaml +++ b/helm/fence/values.yaml @@ -304,7 +304,7 @@ privacy_policy: FENCE_CONFIG: APP_NAME: 'Gen3 Data Commons' - BASE_URL: 'http://localhost/user' + BASE_URL: 'https://localhost/user' # A URL-safe base64-encoded 32-byte key for encrypting keys in db diff --git a/helm/gen3-test-data-job/Chart.yaml b/helm/gen3-test-data-job/Chart.yaml index bcf0e126..feeefb98 100644 --- a/helm/gen3-test-data-job/Chart.yaml +++ b/helm/gen3-test-data-job/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: gen3-test-data-job -description: A Helm chart for Kubernetes +description: A Helm chart for generating dummy data in gen3 # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" diff --git a/helm/gen3/Chart.lock b/helm/gen3/Chart.lock index abbd081e..597d1273 100644 --- a/helm/gen3/Chart.lock +++ b/helm/gen3/Chart.lock @@ -1,54 +1,57 @@ dependencies: - name: ambassador repository: file://../ambassador - version: 0.1.0 + version: 0.0.1 - name: arborist repository: file://../arborist - version: 0.1.0 + version: 0.0.1 - name: argo-wrapper repository: file://../argo-wrapper - version: 0.1.0 + version: 0.0.1 - name: audit repository: file://../audit - version: 0.1.0 + version: 0.0.1 - name: fence repository: file://../fence - version: 0.1.0 + version: 0.0.1 - name: guppy repository: file://../guppy - version: 0.1.0 + version: 0.0.1 - name: hatchery repository: file://../hatchery - version: 0.1.0 + version: 0.0.1 - name: indexd repository: file://../indexd - version: 0.1.0 + version: 0.0.1 - name: manifestservice repository: file://../manifestservice - version: 0.1.0 + version: 0.0.1 - name: metadata repository: file://../metadata - version: 0.1.0 + version: 0.0.1 - name: peregrine repository: file://../peregrine - version: 0.1.0 + version: 0.0.1 - name: pidgin repository: file://../pidgin - version: 0.1.0 + version: 0.0.1 - name: portal repository: file://../portal - version: 0.1.0 + version: 0.0.1 - name: requestor repository: file://../requestor - version: 0.1.0 + version: 0.0.1 - name: revproxy repository: file://../revproxy - version: 0.1.0 + version: 0.0.1 - name: sheepdog repository: file://../sheepdog - version: 0.1.0 + version: 0.0.1 - name: ssjdispatcher repository: file://../ssjdispatcher - version: 0.1.0 -digest: sha256:7363cb3f2fc0db97142131a851ea7e637772ee83ce1d33164b9886fd4745678a -generated: "2022-09-19T14:49:52.41625-06:00" + version: 0.0.1 +- name: wts + repository: file://../wts + version: 0.0.1 +digest: sha256:94301835cea4dfeb07a462246b7574f9526f0808feb692272f36d0661677cab2 +generated: "2022-10-18T12:52:15.089837-05:00" diff --git a/helm/gen3/Chart.yaml b/helm/gen3/Chart.yaml index 00ac5541..ad52b512 100644 --- a/helm/gen3/Chart.yaml +++ b/helm/gen3/Chart.yaml @@ -4,74 +4,78 @@ description: An Umbrella Chart to conditionally deploy Gen3 Services #Dependancies dependencies: - - name: ambassador - version: "0.1.0" - repository: "file://../ambassador" - condition: ambassador.enabled - - name: arborist - version: "0.1.0" - repository: "file://../arborist" - condition: arborist.enabled - - name: argo-wrapper - version: "0.1.0" - repository: "file://../argo-wrapper" - condition: argo-wrapper.enabled - - name: audit - version: "0.1.0" - repository: "file://../audit" - condition: audit.enabled - - name: fence - version: "0.1.0" - repository: "file://../fence" - condition: fence.enabled - - name: guppy - version: "0.1.0" - repository: "file://../guppy" - condition: guppy.enabled - - name: hatchery - version: "0.1.0" - repository: "file://../hatchery" - condition: hatchery.enabled - - name: indexd - version: "0.1.0" - repository: "file://../indexd" - condition: indexd.enabled - - name: manifestservice - version: "0.1.0" - repository: "file://../manifestservice" - condition: manifestservice.enabled - - name: metadata - version: "0.1.0" - repository: "file://../metadata" - condition: metadata.enabled - - name: peregrine - version: "0.1.0" - repository: "file://../peregrine" - condition: peregrine.enabled - - name: pidgin - version: "0.1.0" - repository: "file://../pidgin" - condition: pidgin.enabled - - name: portal - version: "0.1.0" - repository: "file://../portal" - condition: portal.enabled - - name: requestor - version: "0.1.0" - repository: "file://../requestor" - condition: requestor.enabled - - name: revproxy - version: "0.1.0" - repository: "file://../revproxy" - condition: revproxy.enabled - - name: sheepdog - version: "0.1.0" - repository: "file://../sheepdog" - condition: sheepdog.enabled - - name: ssjdispatcher - version: "0.1.0" - repository: "file://../ssjdispatcher" - condition: ssjdispatcher.enabled +- name: ambassador + version: "0.0.1" + repository: "file://../ambassador" + condition: ambassador.enabled +- name: arborist + version: "0.0.1" + repository: "file://../arborist" + condition: arborist.enabled +- name: argo-wrapper + version: "0.0.1" + repository: "file://../argo-wrapper" + condition: argo-wrapper.enabled +- name: audit + version: "0.0.1" + repository: "file://../audit" + condition: audit.enabled +- name: fence + version: "0.0.1" + repository: "file://../fence" + condition: fence.enabled +- name: guppy + version: "0.0.1" + repository: "file://../guppy" + condition: guppy.enabled +- name: hatchery + version: "0.0.1" + repository: "file://../hatchery" + condition: hatchery.enabled +- name: indexd + version: "0.0.1" + repository: "file://../indexd" + condition: indexd.enabled +- name: manifestservice + version: "0.0.1" + repository: "file://../manifestservice" + condition: manifestservice.enabled +- name: metadata + version: "0.0.1" + repository: "file://../metadata" + condition: metadata.enabled +- name: peregrine + version: "0.0.1" + repository: "file://../peregrine" + condition: peregrine.enabled +- name: pidgin + version: "0.0.1" + repository: "file://../pidgin" + condition: pidgin.enabled +- name: portal + version: "0.0.1" + repository: "file://../portal" + condition: portal.enabled +- name: requestor + version: "0.0.1" + repository: "file://../requestor" + condition: requestor.enabled +- name: revproxy + version: "0.0.1" + repository: "file://../revproxy" + condition: revproxy.enabled +- name: sheepdog + version: "0.0.1" + repository: "file://../sheepdog" + condition: sheepdog.enabled +- name: ssjdispatcher + version: "0.0.1" + repository: "file://../ssjdispatcher" + condition: ssjdispatcher.enabled +- name: wts + version: "0.0.1" + repository: "file://../wts" + condition: wts.enabled #A chart can be either an 'application' or a 'library' chart. # @@ -86,10 +90,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" \ No newline at end of file +appVersion: "master" \ No newline at end of file diff --git a/helm/gen3/charts/ambassador-0.1.0.tgz b/helm/gen3/charts/ambassador-0.1.0.tgz deleted file mode 100644 index 3ede71a79b39d101dd60bacaa0bf9b4556f7cd63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3009 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 DqnFm1 diff --git a/helm/gen3/charts/arborist-0.1.0.tgz b/helm/gen3/charts/arborist-0.1.0.tgz deleted file mode 100644 index 611052797d5d1981871312d884f90928b33eea14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3649 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 bPuuU?eYZPor800960d{L6K073u&LzpZA diff --git a/helm/gen3/charts/audit-0.1.0.tgz b/helm/gen3/charts/audit-0.1.0.tgz deleted file mode 100644 index 257fb7cf5292f3ffa120da1966ed618b81896c15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3953 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 LG5eX708Rh^Eau45 diff --git a/helm/gen3/charts/fence-0.1.0.tgz b/helm/gen3/charts/fence-0.1.0.tgz deleted file mode 100644 index f8207594152e7c8cc30865fd3d28243470b4ac87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36821 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

yQOoJ|rpGUZd4saoKiWzU4~_$|$V^gi~@J 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 U{!Pn20{{U3|LR|SZvadH01=P}p8x;= diff --git a/helm/gen3/charts/hatchery-0.1.0.tgz b/helm/gen3/charts/hatchery-0.1.0.tgz deleted file mode 100644 index 6c629c1f62a986f1fcd5e1d3edd534ce217a9a19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4081 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 diff --git a/helm/gen3/charts/manifestservice-0.1.0.tgz b/helm/gen3/charts/manifestservice-0.1.0.tgz deleted file mode 100644 index a40a9b0f52dd470a7adbf2f41ad05b972c0f29cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4024 zcmV;p4@dAHiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PH;dbKAC({h5Eo9^*Gnaur4SGmkU58P|4GPZQf0JGtp}Iv$8z zNvI)!0YKTRx^*Z5?-`s;r~;~hz^}XS-u6a9PKnl-z=$#nu#Yh#5@ALp zB}0Y^w16Q(N|eF`DAxk!B9owTnlhqM1)isnVXTFGONPi)eqm zi>)5r6aH)!oRgU_j-J(ekr^6I>%byR?M;W0#Blu9?CqMzdn?AQqSnDVPmK+RN-#1^+9 z)8L;7r7a}@J^Lkcy1j>2WSTMzn1~6p&jC`RCpoYiU^*h`mpu;T%(DE@44)!*)aPuC z&5ke?!Ee7?ZbJ_g#uBw#a%1YAX37E8$b42z-9@G6kxUB}6Gr*Clf6^Q-=noeDuRLO zAXl}HFf{ZLIYzyA^5KJ~jQ(lKKS3FrrHs*@97Bf#dxujY=gT2&Q(6*@<9T%+-wS4F z{E#L@+v8pT?l?RpSErdYXa>di51h;hWoAtggr3JrsZkpd_;XZdOVez~Xk2~I6v_#* z6lK--?9IW^#`*s4*}?hS-5(F$dL9{#D5u)en2KbVYr0$O0!Sr}P)bbpGfDaQG@f9R z8KMuzT$J4hR~Tp3RmjiOCDQRk7reEIL{eZrLpiO^lU>eft`VZzp_&pMPY$k9bIPqG z)SmU=0_WDhsC5E}6eTfe;E*>SI4u`7`g$D-$2Bcd!Nhp}iKdwdyGMsV9h{z>pB}vbc(`|PzIS}|)8U)*lijnQ8%SqF_Q%LK z`fk|8HY^qvii?hdUcj{@-J?K>%-1gPvgh9SuIbe+$Do z$c%H!$L6s@h{beDj7ssYuX{j85PWoR3xx-g+grG~u@I8*F~XWT*bu#5fVM{6zyegz zfps!m??mhL`r1si)*h>wfl=4jfZWU%_50V?ZYqlxZf>rx9kOZ$2kNyyGKFT2Sa3}! zSKuFs1W$z2eo1oS2pj9|@Zpv5BjM#G1hvHS~H$lvPS%1VhMs z=f4I=W$(=m^aL2?XNY|5Uk571I51e%Z{hC&&xyG43;$CYOq9ngOK`y&1fz^GYmOj* zo0}Ic5)V&W1RC_}tH`7prnz^JGQ4mC{495lH=ATYv9QyN(hLPx3dD(wPeC-oURS zgP3r*G){*d?bZomRF{bFzj(LREQa3Y7wqBp)gBh6bzvJV(p6?(eOl=C3L^mi^|gO} zor~sk$`ibTV&7SfsfAoZ_`*tFV8zb~nSax98ma|FhUC^J+chs0&+=t%1^GNV-akLu zeRt4eTPl)O4?hE+q-oIf{mj7Ex3RQh=MRgct!?MA#n715aBHc!O;MACXku~aEOm?A zJ3czwJv=&i-=&FCk*v1TwSrfjdMRf=N=r+rrOIxns>*%#KT<_?vE769ogfUtU=Y0u zUxh~eGKDT0P%}ElJt-((iDE-VZzSX;kx7kwGe@-6WJ+D>e`}NbFV&X&f9LL{Q3X1^ zXDIM4|8FbYZu@^b+fV-AqqOVm{!8!RDkVIz#?FYHF?Hs%jj;sY%YLqk6C6>#RN3_^ zC>u`QQ2fwbX@M^@t)%6cCB-Z4MKosq};@ zcs`t4j_eAm z3ntf`@8V&}*BoT&^Hun6jBfsU&8{JOz52#hG?v_ONZQ8E(b?$yLgG?MxgLT457qmJ z@>{svq^lpZ?vIVbSKC!1F?lM>?5N$@{Fpc>8_!x{cP(_awe2OsZ3 zq5q#g_~-tYiWj?@XVX`m*3OMP^!f0-{Za3m~;Yi0w=0q(TBrSF#c zN%L&cwJLLq#%Wj>@)eb%G-vZod9tT+$u|~heMB+X|N_(;8H2jGAGYhd3|}Y3@5LzxTZe} z?0)`X;gzBj!GezX)>i!M+j9Re!IX*l6#2c&LGJSZ24UFp|8_Q?;(w3R>h&KaO;vw3 z@GdA%BG@nY-z#1{qcV@#&P7y*#WRkP%}KQ~IYwMAsh-p%tgZmdppHxTR2kuFv=+aT zDT4q$1E)MeuHjWRtR{{C-KpVPsG$qM4XtPEn)4QP=Kzaj6vC5d@M>J^WB_X|oZWBD zU&Q3Ez+P-@=R8IJuo_Jo>BFyF&+VDD+J4>!SYoSX;1(&$5#=x~`XC>2N2;wx(5;Xq zMO9d(o>%X#q^e?+bZYa<{-=!0jg^lRs`@SPXgyqC55j-??Qtg=V<&>qcpkwnyCic} zgUHi_RqNmo@>z{LgZ28MDtKHa=x#+-2fhVoBPn+)!V>ZpY&Lk+&Hy(8S$UGbXpGK~ zqf#eQ46!+IqILSF%GZ`txWb5Y7blM-(Y)db20zB^W^_MMr*x_)e5NU+1!Sg zSb_9s>qFF}@ECsEL(iEl z+Ki3zEr+GxbPXmSR4+?gHmHKh2cecUt~088UvDpPD{N)2 zC{@cXs#h2i_qDPXc_mYtRaH}Vg54QPGRE2@OP8`5MJ?y>&K2HLoA;HAbhSM9UFQmP zJzkVyx&ALoE$(jv?$H06;nq(3{XYz!>c1bQ-BHO?MC;a!UOUPY0V^rLa-^EY#;2}V z05$UbwSXYu$pR&1MKnC;Lc?=~(;3P=F-?g?@c--eAQ-&rg+2s(Bqc-2sHUibU$Pexkj=&IO)lxyc^l?wIOV_UxdJIa{o2)bDF z&sABI$Db=>$WdPkd13U{#VZ$FA2cd5x~AKF(CM6WQO?;Of>#>3tq5+yI;J=Se(2cP z?SoXO`hgscj=)IQ39yj$(*A`|Q#ay#WraJln$+A+VBF+6+P&&_Le0W0&eZ2Obrh2)x8B~4m^g)^t$Bf~fYiJNx zT(~eZ*_y=#5^ed6SAQXI#4Wn3CaZP3H~3~9WOHFE}pEAcDIOQjl?0 zFW_6Y5v~nMe1SY^2PW>)b}LcZo(rIMX{gzjsf%W_5s`&n0G>^UDBbwN6fO*}r=>cn zI$D8-9MlD{?w+pA?+*9+|5KvtsdcvH{(oUHixf{RG5NZ;fjj*FaA&6#|5+bw?SxPM z|6{bq{qG`>b87A03TZ!g1u4JdeVmd{8G1@f%E$ZpxY{M32tN0UJWr{2O5f_--D^3w z?++39H3y^f%1lt*i-DUP|Az`=c`<7hECp~22f0+|?l#T&1eL%X=DD6G01qt4BGUP(2~)O;we%AzcL&pCqMzBi!X z|6UZM$+0q>tMlQO%Z(PRM05IdQI2(lGn9|3LfY~l7=}{&lO7K?$DQ_nW2^o9Pg^^i zPxAj5?HQa9tx#f6Bi7TXamueeCP?}YT#7%uV5VY` eVE=FD3_P``_SF8Z+W!Rr0RR8Py&t3iRsaAiiu8a0 diff --git a/helm/gen3/charts/metadata-0.1.0.tgz b/helm/gen3/charts/metadata-0.1.0.tgz deleted file mode 100644 index b2cece469f0eadd3bf3344fae405db9c8271de24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3657 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 diff --git a/helm/gen3/charts/pidgin-0.1.0.tgz b/helm/gen3/charts/pidgin-0.1.0.tgz deleted file mode 100644 index 425ab5b2abef20c6aa9b467085f346f818045cdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2982 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

sYkOR~bro)-l=b#;F0Yb)$~gqh(gusUFO15g?*9 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 diff --git a/helm/gen3/charts/revproxy-0.1.0.tgz b/helm/gen3/charts/revproxy-0.1.0.tgz deleted file mode 100644 index e0321c338494592a324e2efbb7e20df4f2127fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15871 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 NfgeqOAm$(;{vT~Xh}-}G diff --git a/helm/gen3/charts/sheepdog-0.1.0.tgz b/helm/gen3/charts/sheepdog-0.1.0.tgz deleted file mode 100644 index 7425dfe5af8d7bba74745a2ed1939ce4d2e2f2b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9250 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 E0JoY%YXATM diff --git a/helm/gen3/charts/ssjdispatcher-0.1.0.tgz b/helm/gen3/charts/ssjdispatcher-0.1.0.tgz deleted file mode 100644 index a82352a23fc856caf56eb6cf310f8274832f6db4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4435 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 diff --git a/helm/gen3/values.yaml b/helm/gen3/values.yaml index d4e47a40..51c9dc25 100644 --- a/helm/gen3/values.yaml +++ b/helm/gen3/values.yaml @@ -1,3 +1,11 @@ +global: + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + # Default values for gen3. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -19,7 +27,7 @@ fence: enabled: true guppy: - enabled: true + enabled: false hatchery: enabled: true diff --git a/helm/guppy/Chart.yaml b/helm/guppy/Chart.yaml index 585e5954..6f526c54 100644 --- a/helm/guppy/Chart.yaml +++ b/helm/guppy/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: guppy -description: A Helm chart for Guppy Service +description: A Helm chart for gen3 Guppy Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.08" +appVersion: "2022.10" diff --git a/helm/hatchery/Chart.yaml b/helm/hatchery/Chart.yaml index 72e6f25b..5d081070 100644 --- a/helm/hatchery/Chart.yaml +++ b/helm/hatchery/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: hatchery -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 Hatchery # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.05" +appVersion: "2022.10" diff --git a/helm/indexd/Chart.yaml b/helm/indexd/Chart.yaml index 576caccc..801593ae 100644 --- a/helm/indexd/Chart.yaml +++ b/helm/indexd/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: indexd -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 indexd # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "master" \ No newline at end of file +appVersion: "2022.10" \ No newline at end of file diff --git a/helm/indexd/templates/deployment.yaml b/helm/indexd/templates/deployment.yaml index ecd7ab28..6207db02 100644 --- a/helm/indexd/templates/deployment.yaml +++ b/helm/indexd/templates/deployment.yaml @@ -49,6 +49,9 @@ spec: httpGet: path: /_status port: http + initialDelaySeconds: 30 + periodSeconds: 60 + timeoutSeconds: 30 readinessProbe: httpGet: path: /_status diff --git a/helm/indexd/templates/indexd-secret.yaml b/helm/indexd/templates/indexd-secret.yaml index 18884ebc..bc2adfe3 100644 --- a/helm/indexd/templates/indexd-secret.yaml +++ b/helm/indexd/templates/indexd-secret.yaml @@ -2,6 +2,9 @@ apiVersion: v1 kind: Secret metadata: name: indexd-secret + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-10" type: Opaque data: {{ (.Files.Glob "indexd-secret/*").AsSecrets | indent 2 }} @@ -10,6 +13,9 @@ apiVersion: v1 kind: Secret metadata: name: indexd-creds + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-10" type: Opaque stringData: creds.json: |- @@ -30,6 +36,7 @@ kind: Secret metadata: name: indexd-service-creds annotations: + "helm.sh/hook": "pre-install,pre-upgrade" "helm.sh/hook-weight": "-10" type: Opaque stringData: diff --git a/helm/indexd/templates/pre-install.yaml b/helm/indexd/templates/pre-install.yaml index 5e536517..c87f4e9f 100644 --- a/helm/indexd/templates/pre-install.yaml +++ b/helm/indexd/templates/pre-install.yaml @@ -9,6 +9,8 @@ metadata: # creds.json # name: indexd-userdb + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" spec: backoffLimit: 0 template: diff --git a/helm/manifestservice/Chart.yaml b/helm/manifestservice/Chart.yaml index 1f440253..7ae2d9cf 100644 --- a/helm/manifestservice/Chart.yaml +++ b/helm/manifestservice/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" diff --git a/helm/metadata/Chart.yaml b/helm/metadata/Chart.yaml index 526a174a..71f5c7d0 100644 --- a/helm/metadata/Chart.yaml +++ b/helm/metadata/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: metadata -description: A Helm chart for Metadata Service +description: A Helm chart for gen3 Metadata Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: 2022.05 +appVersion: "2022.10" diff --git a/helm/peregrine/Chart.yaml b/helm/peregrine/Chart.yaml index 7ba5bbb7..452e35cb 100644 --- a/helm/peregrine/Chart.yaml +++ b/helm/peregrine/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: peregrine -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 Peregrine service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.05" +appVersion: "2022.10" diff --git a/helm/peregrine/templates/peregrine-secret.yaml b/helm/peregrine/templates/peregrine-secret.yaml index 03a2d4e4..43cc3ff9 100644 --- a/helm/peregrine/templates/peregrine-secret.yaml +++ b/helm/peregrine/templates/peregrine-secret.yaml @@ -12,16 +12,17 @@ metadata: name: peregrine-creds type: Opaque stringData: + # TODO: FIX FENCE_PASSWORD creds.json: |- { - "fence_host": {{ default "fence-postgresql" .Values.secrets.fence.db.host | quote }}, + "fence_host": {{ .Values.database.host | quote }}, "fence_username": {{ default "postgres" .Values.secrets.fence.db.username | quote }}, - "fence_password": {{ default .Values.global.postgresql.auth.postgresPassword .Values.secrets.fence.db.password | quote }}, - "fence_database": {{ default .Values.global.postgresql.auth.database .Values.secrets.fence.db.database | quote }}, + "fence_password": {{ include "peregrine.postgres.password" . | quote }}, + "fence_database": {{ default "fence" .Values.secrets.fence.db.database | quote }}, "db_host": {{ .Values.database.host | quote }}, "db_username": {{ .Values.database.user | quote}}, "db_password": {{ include "peregrine.postgres.password" . | quote }}, "db_database": {{ .Values.database.dbname | quote }}, "gdcapi_secret_key": {{ default (randAlphaNum 50) .Values.secrets.gdcapi_secret_key | quote }}, - "hostname": {{ default "ingress.local" .Values.hostname | quote}} + "hostname": {{ default "localhost" .Values.hostname | quote}} } diff --git a/helm/peregrine/values.yaml b/helm/peregrine/values.yaml index cfd04c0a..54fdc682 100644 --- a/helm/peregrine/values.yaml +++ b/helm/peregrine/values.yaml @@ -1,12 +1,3 @@ -global: - postgresql: - auth: - postgresPassword: "password!123" - database: "peregrine" - -postgres: - enabled: false - # Default values for peregrine. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -49,24 +40,6 @@ service: type: ClusterIP port: 80 -ingress: - enabled: true - className: "" - annotations: { - nginx.ingress.kubernetes.io/rewrite-target: /$2, - kubernetes.io/ingress.class: "nginx" - } - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: ingress.local - paths: - - path: /peregrine(/|$)(.*) - pathType: Prefix - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local resources: {} # We usually recommend not to specify default resources and to leave this as a conscious diff --git a/helm/pidgin/Chart.yaml b/helm/pidgin/Chart.yaml index 27ec77c2..47817da5 100644 --- a/helm/pidgin/Chart.yaml +++ b/helm/pidgin/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: pidgin -description: A Helm chart for Pidgin Service +description: A Helm chart for gen3 Pidgin Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.08" +appVersion: "2022.10" diff --git a/helm/portal/Chart.yaml b/helm/portal/Chart.yaml index 6beaf776..36633f3a 100644 --- a/helm/portal/Chart.yaml +++ b/helm/portal/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: portal -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 data-portal # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" diff --git a/helm/portal/templates/configMap.yaml b/helm/portal/templates/configMap.yaml new file mode 100644 index 00000000..ab730274 --- /dev/null +++ b/helm/portal/templates/configMap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: docker-command +data: + dockerStart.sh: + #!/bin/sh + # + # Little startup script fetches data dictionary, and runs the relay + # compiler, then webpack before launching nginx + # + set -eu + + export NODE_ENV=production; + + bash runWebpack.sh + + /usr/sbin/nginx -g 'daemon off;' \ No newline at end of file diff --git a/helm/portal/templates/deployment.yaml b/helm/portal/templates/deployment.yaml index 89e16d57..9331869d 100644 --- a/helm/portal/templates/deployment.yaml +++ b/helm/portal/templates/deployment.yaml @@ -31,19 +31,19 @@ spec: # imagePullPolicy: Never # livenessProbe: # httpGet: - # path: /portal/ + # path: / # port: 80 # initialDelaySeconds: 60 # periodSeconds: 30 # timeoutSeconds: 30 # failureThreshold: 30 - # readinessProbe: - # httpGet: - # path: /portal/ - # port: 80 - # initialDelaySeconds: 30 - # periodSeconds: 60 - # timeoutSeconds: 30 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 30 + periodSeconds: 60 + timeoutSeconds: 30 # TODO: re-add resources ports: - containerPort: 80 @@ -52,6 +52,8 @@ spec: - /bin/bash - ./dockerStart.sh env: + - name: NODE_ENV + value: dev - name: HOSTNAME value: revproxy-service # disable npm 7's brand new update notifier to prevent Portal from stuck at starting up diff --git a/helm/portal/values.yaml b/helm/portal/values.yaml index 6674734a..26324ef5 100644 --- a/helm/portal/values.yaml +++ b/helm/portal/values.yaml @@ -112,16 +112,6 @@ affinity: automountServiceAccountToken: false -volumes: - - name: config-volume - secret: - secretName: "portal-config" - - name: sponsor-img-volume - secret: - secretName: "portal-sponsor-config" - - name: privacy-policy - configMap: - name: "privacy-policy" resources: @@ -134,9 +124,26 @@ resources: portalApp: "dev" +volumes: + - name: docker-config + configMap: + name: docker-command + - name: config-volume + secret: + secretName: "portal-config" + - name: sponsor-img-volume + secret: + secretName: "portal-sponsor-config" + - name: privacy-policy + configMap: + name: "privacy-policy" + env: volumeMounts: + - name: "docker-config" + mountPath: "/data-portal/dockerStart.sh" + subPath: "dockerStart.sh" - name: "config-volume" mountPath: "/data-portal/data/config/gitops.json" subPath: "gitops.json" diff --git a/helm/requestor/Chart.yaml b/helm/requestor/Chart.yaml index 46614c48..1ef212f6 100644 --- a/helm/requestor/Chart.yaml +++ b/helm/requestor/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: requestor -description: A Helm chart for Requestor Service +description: A Helm chart for gen3 Requestor Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.08" +appVersion: "2022.10" diff --git a/helm/requestor/templates/deployment.yaml b/helm/requestor/templates/deployment.yaml index 84de4733..ccad623c 100644 --- a/helm/requestor/templates/deployment.yaml +++ b/helm/requestor/templates/deployment.yaml @@ -70,7 +70,7 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} initContainers: - - name: {{ .Values.initContainerName }} + - name: requestor-db-migrate image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.volumeMounts }} @@ -81,8 +81,8 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} - command: {{ .Values.command }} - {{- with .Values.args }} - args: - {{- toYaml . | nindent 12}} - {{- end }} \ No newline at end of file + command: ["/bin/sh"] + args: + - "-c" + - | + /env/bin/alembic upgrade head \ No newline at end of file diff --git a/helm/requestor/templates/requestor-secret.yaml b/helm/requestor/templates/requestor-secret.yaml index ecedcefe..eec42442 100644 --- a/helm/requestor/templates/requestor-secret.yaml +++ b/helm/requestor/templates/requestor-secret.yaml @@ -13,15 +13,14 @@ stringData: } requestor-config.yaml: |- - { - # Server + # Server - DEBUG: true + DEBUG: true - # Database + # Database - DB_HOST: {{ .Values.secrets.host | quote }}, - DB_USER: {{ .Values.secrets.user | quote }}, - DB_PASSWORD: {{ include "requestor.postgres.password" . | quote }}, - DB_DATABASE: {{ .Values.secrets.database | quote }} - } \ No newline at end of file + DB_HOST: {{ .Values.secrets.host | quote }} + DB_USER: {{ .Values.secrets.user | quote }} + DB_PASSWORD: {{ include "requestor.postgres.password" . | quote }} + DB_DATABASE: {{ .Values.secrets.database | quote }} + \ No newline at end of file diff --git a/helm/revproxy/Chart.yaml b/helm/revproxy/Chart.yaml index 2b4aa4d1..42fc5592 100644 --- a/helm/revproxy/Chart.yaml +++ b/helm/revproxy/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: revproxy -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 revproxy # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" diff --git a/helm/sheepdog/Chart.lock b/helm/sheepdog/Chart.lock new file mode 100644 index 00000000..a3070d8c --- /dev/null +++ b/helm/sheepdog/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: db-setup + repository: file://../db-setup + version: 0.0.1 +digest: sha256:049df0e16d26bc9a96ed517d3a5be85e8f261a20631b0bf7398e6708fc904692 +generated: "2022-10-18T18:04:31.969906-05:00" diff --git a/helm/sheepdog/Chart.yaml b/helm/sheepdog/Chart.yaml index 300898c4..1bb5bea2 100644 --- a/helm/sheepdog/Chart.yaml +++ b/helm/sheepdog/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: sheepdog -description: A Helm chart for Sheepdog Service +description: A Helm chart for gen3 Sheepdog Service # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,16 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "master" +appVersion: "2022.10" + +dependencies: + - name: db-setup + version: 0.0.1 + repository: file://../db-setup + condition: db_creation.enabled diff --git a/helm/sheepdog/templates/db-init.yaml b/helm/sheepdog/templates/db-init.yaml new file mode 100644 index 00000000..efb72198 --- /dev/null +++ b/helm/sheepdog/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "db-setup.setup-job" . }} +--- +{{ include "db-setup.secret" . -}} \ No newline at end of file diff --git a/helm/sheepdog/templates/sheepdog-secret.yaml b/helm/sheepdog/templates/sheepdog-secret.yaml index 455c278d..ea9b256d 100644 --- a/helm/sheepdog/templates/sheepdog-secret.yaml +++ b/helm/sheepdog/templates/sheepdog-secret.yaml @@ -2,6 +2,9 @@ apiVersion: v1 kind: Secret metadata: name: sheepdog-secret + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-10" type: Opaque data: {{ (.Files.Glob "sheepdog-secret/*").AsSecrets | indent 2 }} @@ -10,6 +13,9 @@ apiVersion: v1 kind: Secret metadata: name: sheepdog-creds + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-weight": "-10" type: Opaque stringData: creds.json: |- @@ -25,5 +31,5 @@ stringData: "db_database": {{ .Values.secrets.sheepdog.database | quote }}, "gdcapi_secret_key": {{ default (randAlphaNum 50) .Values.secrets.gdcapi.secretKey | quote }}, - "hostname": {{ default "ingress.local" .Values.hostname | quote}} + "hostname": {{ default "localhost" .Values.hostname | quote}} } \ No newline at end of file diff --git a/helm/ssjdispatcher/Chart.yaml b/helm/ssjdispatcher/Chart.yaml index a90338e7..1ad87cf7 100644 --- a/helm/ssjdispatcher/Chart.yaml +++ b/helm/ssjdispatcher/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: ssjdispatcher -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 ssjdispatcher # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" diff --git a/helm/terraform-runner-job/Chart.yaml b/helm/terraform-runner-job/Chart.yaml index 60d84467..a8b74404 100644 --- a/helm/terraform-runner-job/Chart.yaml +++ b/helm/terraform-runner-job/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: terraform-runner-job -description: A Helm chart for Kubernetes +description: A Helm chart for provisioning prequisites cloud resources for gen3 # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "feat_tf1X_jq" diff --git a/helm/terraform-runner-job/templates/jobs.yaml b/helm/terraform-runner-job/templates/jobs.yaml index fd0dd774..9238bd05 100644 --- a/helm/terraform-runner-job/templates/jobs.yaml +++ b/helm/terraform-runner-job/templates/jobs.yaml @@ -24,11 +24,8 @@ spec: resources: {{- toYaml .Values.resources | nindent 12 }} env: - - name: gen3Env - valueFrom: - configMapKeyRef: - name: global - key: environment + - name: USE_TF_1 + value: "True" - name: JENKINS_HOME value: "devterm" - name: GEN3_HOME @@ -53,7 +50,7 @@ spec: export LC_ALL=C.UTF-8 export LANG=C.UTF-8 source "${GEN3_HOME}/gen3/gen3setup.sh" - gen3 workon default "${resouce_name}_${workspace_name}" + gen3 workon default "helm" gen3 cd cp /config.tfvars ./config.tfvars {{ if .Values.terraform.destroy }} diff --git a/helm/wts/Chart.lock b/helm/wts/Chart.lock index b995cbfd..6003d543 100644 --- a/helm/wts/Chart.lock +++ b/helm/wts/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: db-setup repository: file://../db-setup - version: 0.1.0 -digest: sha256:ebe24f94c9bc192b19cebb4b52d53702323feddb93c21facccc99147b748ff10 -generated: "2022-09-16T12:58:43.964836-04:00" + version: 0.0.1 +digest: sha256:049df0e16d26bc9a96ed517d3a5be85e8f261a20631b0bf7398e6708fc904692 +generated: "2022-10-18T15:18:59.981283-05:00" diff --git a/helm/wts/Chart.yaml b/helm/wts/Chart.yaml index 632378f6..a407415d 100644 --- a/helm/wts/Chart.yaml +++ b/helm/wts/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: wts -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 workspace token service # A chart can be either an 'application' or a 'library' chart. # @@ -15,15 +15,16 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "2022.10" dependencies: - name: db-setup - version: 0.1.0 - repository: file://../db-setup \ No newline at end of file + version: 0.0.1 + repository: file://../db-setup + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/wts/charts/db-setup-0.1.0.tgz b/helm/wts/charts/db-setup-0.1.0.tgz deleted file mode 100644 index 80036fa411d10dddd39ca179bfe55da93d7d14c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1218 zcmV;z1U>s7iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PI-NZ`(E#&$IrD`;-sp_XQOt#dZRy=!2KIZMG~9Y&RV+3;`uw zBqkKekd)ml@&5KfQslU<+deF9GQhtFnLHhTyd!zXlhfEUXiMcEE!Z7T1_ruOs5bo}W`&$q^x+QB+8cX$7@Q>$Ob?#pRs@NH7 z!=#8{y6aG-7Tu79dn9mDG>K-)*0MglLta2q9TvEd8h$Bb)B-IUN6-QzXb+TQZxlwr zS*)qPai%S6Ktd8YPwn;w_gKXLl=2eIcS!)>ivMmeT#5fq*b6uD|0AHJv6)5_IRLpd zHiA~-wT){|+9om6ge1H)7B%5Aq1*v*018@3Dh`0spl(t@JE|5dYRpXPbX6?1jiA@< z>^4j(wKS%tG00nVPin%MH7irJk_YygHRo+_4FwY^eoR+bmV^&Pjc~#B)Eo7ku!w() zh2qqr@z2xvyp|EG9wiriBmO(R?&|&D>+bDt;{QkB_SS zw9b~6voh^&sRw``tMm+~Z%_N<@rU8)@U?q;3;!i&O|7uF6&l+}n<`;GcR%5&4wd0+t~q!)tevpBsbD?_@BRAs_Xf2YzE)LVRjnPZ)NBIocyK&8m_P_` zM#Eo0W#_Gx@ZsHHG^nnWn)WrkxV;6ke8a$e{=$Vj$TTYOt|5fGyC?G{0ry}u=uZZ4 z*q`)&>W>Go#@<)%^IiCg=zh^lgUgG)G{tjV@b}}v2v+Qb4@Z-C(8f~Z#!}3@cqSW> zfctjTKbb)P_!x#KUp+f88Ls!TVHloHj)o`C#IJO%150~0_-!&c86OQ#fLo3D3i`*B z!3ajfsP|44NSvP?*gk3Gk?zW;ii-e=!` zyPZw__am?kr_@^1!hn^~>_5zM6cCq;r%Ys^XmUj}G{o74NzM$IQdL1^psGzcWL(Bj zRCOT}*-OyKsby0HMQy$$ry_N>L10#waqvH-@q&HC6lTok@Spz^7z%y^Qq&_WlR%*c z&IA&N9FEV&R%&#%;XoFJ6mWJhhLmaJkc?Tsem3SiB>q$T^|KY^nO{BHu9*t|fheZQ zRjJ^DaWu{jF*D`tkeFUMJH!@MTWXd$JAXOba7HzgrGcZvfpLh^@)8s45SAkK8+9!& g9WphEOwr%`%eBD<8$4(H9RL9T|5r=cTL2mW0MK<#zW@LL diff --git a/helm/wts/templates/appInit.yaml b/helm/wts/templates/appInit.yaml deleted file mode 100644 index 40edce2e..00000000 --- a/helm/wts/templates/appInit.yaml +++ /dev/null @@ -1 +0,0 @@ -{{- include "db-setup.-setup-job" . -}} \ No newline at end of file diff --git a/helm/wts/templates/db-init.yaml b/helm/wts/templates/db-init.yaml new file mode 100644 index 00000000..efb72198 --- /dev/null +++ b/helm/wts/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "db-setup.setup-job" . }} +--- +{{ include "db-setup.secret" . -}} \ No newline at end of file diff --git a/helm/wts/templates/secret.yaml b/helm/wts/templates/secret.yaml index 738d1b05..1689cc63 100644 --- a/helm/wts/templates/secret.yaml +++ b/helm/wts/templates/secret.yaml @@ -24,7 +24,7 @@ stringData: "wts_base_url": "https://{{ .Values.hostname }}/wts/", "encryption_key": "{{ .Values.encpryption_key | default (randAlphaNum 32 | b64enc) }}", "secret_key": "{{ .Values.secret_key | default (randAlphaNum 32 | b64enc) }}", - "fence_base_url": "http://fence-service/", + "fence_base_url": "https://localhost/user", "oidc_client_id": "{{ .Values.oidc_client_id | default (randAlphaNum 32) }}", "oidc_client_secret": "{{ .Values.oidc_client_secret | default (randAlphaNum 32) }}", "external_oidc": [] diff --git a/helm/wts/values.yaml b/helm/wts/values.yaml index d9586cfb..d68f30eb 100644 --- a/helm/wts/values.yaml +++ b/helm/wts/values.yaml @@ -1,3 +1,11 @@ +global: + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + # Default values for wts. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -8,12 +16,14 @@ image: repository: quay.io/cdis/workspace-token-service pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. - tag: "2022.09" + tag: "" imagePullSecrets: [] nameOverride: "" fullnameOverride: "" + + hostname: localhost oidc_client_id: oidc_client_secret: @@ -108,15 +118,17 @@ secrets: # "db_database": "wts_default" # } +# Whether or not to run database creation job +# The job is idempotant +db_creation: true + postgres: - host: postgres-postgresql.postgres.svc.cluster.local - - master: - username: postgres - password: TEnTIpzG2I - port: 5432 - databases: - - databaseName: wts + # Array of databases for service + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + - service: wts + databaseName: wts username: wts - password: wts_password \ No newline at end of file + # If left empty it will be auto-generated + # TODO: complete auto-generate feature in db-setup + password: testpass \ No newline at end of file diff --git a/wip/acronymbot/Chart.yaml b/wip/acronymbot/Chart.yaml index ba43e43c..162210aa 100644 --- a/wip/acronymbot/Chart.yaml +++ b/wip/acronymbot/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: acronymbot -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 acronymbot # A chart can be either an 'application' or a 'library' chart. # diff --git a/wip/cogwheel/Chart.yaml b/wip/cogwheel/Chart.yaml index b492e5eb..87fb8367 100644 --- a/wip/cogwheel/Chart.yaml +++ b/wip/cogwheel/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: cogwheel -description: A Helm chart for Kubernetes +description: A Helm chart for gen3 cogwheel # A chart can be either an 'application' or a 'library' chart. # @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.07" +appVersion: "2022.10" From 3e1d51d7e50261661a05fdc947ef9707bb681179 Mon Sep 17 00:00:00 2001 From: Jawad Qureshi Date: Mon, 24 Oct 2022 14:38:16 -0500 Subject: [PATCH 2/3] Orchestration updates --- .secrets.baseline | 134 ++- helm/arborist/Chart.lock | 6 + helm/arborist/Chart.yaml | 7 +- helm/arborist/templates/_helpers.tpl | 2 +- helm/arborist/templates/arborist-creds.yaml | 15 - helm/arborist/templates/db-init.yaml | 3 + helm/arborist/templates/deployment.yaml | 6 - helm/arborist/values.yaml | 91 +- helm/audit/Chart.lock | 6 + helm/audit/Chart.yaml | 6 + helm/audit/templates/_helpers.tpl | 2 +- helm/audit/templates/db-init.yaml | 3 + helm/audit/templates/secrets.yaml | 8 +- helm/audit/values.yaml | 51 +- helm/{db-setup => common}/.helmignore | 0 helm/{db-setup => common}/Chart.yaml | 2 +- helm/common/templates/_db_setup_job.tpl | 88 ++ helm/common/templates/_postgres_secrets.tpl | 94 ++ helm/common/templates/_secrets.tpl | 140 +++ helm/db-setup/templates/_db_setup.tpl | 72 -- helm/db-setup/values.yaml | 20 - helm/fence/Chart.lock | 6 + helm/fence/Chart.yaml | 8 +- helm/fence/fence-config/fence-config.yaml | 912 ------------------ .../fence_google_app_creds_secret.json | 0 helm/fence/templates/_helpers.tpl | 2 +- helm/fence/templates/db-init.yaml | 3 + helm/fence/templates/fence-config.yaml | 7 +- helm/fence/templates/fence-creds.yaml | 8 +- helm/fence/values.yaml | 28 +- helm/indexd/Chart.lock | 6 + helm/indexd/Chart.yaml | 9 +- helm/indexd/templates/_helpers.tpl | 2 +- helm/indexd/templates/db-init.yaml | 3 + helm/indexd/templates/indexd-secret.yaml | 8 +- helm/indexd/values.yaml | 33 +- helm/manifestservice/templates/NOTES.txt | 23 +- helm/manifestservice/templates/ingress.yaml | 61 -- helm/manifestservice/values.yaml | 17 - helm/metadata/Chart.lock | 6 + helm/metadata/Chart.yaml | 6 + helm/metadata/templates/_helpers.tpl | 2 +- helm/metadata/templates/db-init.yaml | 3 + helm/metadata/templates/secrets.yaml | 12 +- helm/metadata/values.yaml | 34 +- helm/peregrine/Chart.lock | 6 + helm/peregrine/Chart.yaml | 7 + helm/peregrine/peregrine-secret/wsgi.py | 101 +- helm/peregrine/templates/_helpers.tpl | 7 +- helm/peregrine/templates/db-init.yaml | 3 + helm/peregrine/templates/deployment.yaml | 96 +- .../peregrine/templates/peregrine-secret.yaml | 23 +- helm/peregrine/values.yaml | 113 +-- helm/pidgin/Chart.lock | 6 + helm/pidgin/Chart.yaml | 7 + helm/pidgin/templates/db-init.yaml | 3 + helm/pidgin/values.yaml | 18 +- helm/requestor/Chart.lock | 6 + helm/requestor/Chart.yaml | 7 + helm/requestor/templates/db-init.yaml | 3 + helm/requestor/values.yaml | 20 +- helm/revproxy/templates/ingress.yaml | 2 +- helm/sheepdog/Chart.lock | 8 +- helm/sheepdog/Chart.yaml | 5 +- helm/sheepdog/sheepdog-secret/wsgi.py | 91 +- helm/sheepdog/sheepdog-secret/wsgi_copy.py | 72 ++ helm/sheepdog/templates/db-init.yaml | 4 +- helm/sheepdog/templates/deployment.yaml | 82 +- helm/sheepdog/templates/pre-install.yaml | 71 +- helm/sheepdog/templates/sheepdog-secret.yaml | 6 +- helm/sheepdog/values.yaml | 22 +- helm/ssjdispatcher/templates/ingress.yaml | 61 -- helm/wts/Chart.lock | 8 +- helm/wts/Chart.yaml | 5 +- helm/wts/templates/_helpers.tpl | 2 +- helm/wts/templates/db-init.yaml | 4 +- helm/wts/templates/deployment.yaml | 64 +- helm/wts/templates/secret.yaml | 7 - helm/wts/values.yaml | 42 +- 79 files changed, 1228 insertions(+), 1709 deletions(-) create mode 100644 helm/arborist/Chart.lock delete mode 100644 helm/arborist/templates/arborist-creds.yaml create mode 100644 helm/arborist/templates/db-init.yaml create mode 100644 helm/audit/Chart.lock create mode 100644 helm/audit/templates/db-init.yaml rename helm/{db-setup => common}/.helmignore (100%) rename helm/{db-setup => common}/Chart.yaml (98%) create mode 100644 helm/common/templates/_db_setup_job.tpl create mode 100644 helm/common/templates/_postgres_secrets.tpl create mode 100644 helm/common/templates/_secrets.tpl delete mode 100644 helm/db-setup/templates/_db_setup.tpl delete mode 100644 helm/db-setup/values.yaml create mode 100644 helm/fence/Chart.lock delete mode 100644 helm/fence/fence-config/fence-config.yaml delete mode 100644 helm/fence/fence-google-creds/fence_google_app_creds_secret.json create mode 100644 helm/fence/templates/db-init.yaml create mode 100644 helm/indexd/Chart.lock create mode 100644 helm/indexd/templates/db-init.yaml delete mode 100644 helm/manifestservice/templates/ingress.yaml create mode 100644 helm/metadata/Chart.lock create mode 100644 helm/metadata/templates/db-init.yaml create mode 100644 helm/peregrine/Chart.lock create mode 100644 helm/peregrine/templates/db-init.yaml create mode 100644 helm/pidgin/Chart.lock create mode 100644 helm/pidgin/templates/db-init.yaml create mode 100644 helm/requestor/Chart.lock create mode 100644 helm/requestor/templates/db-init.yaml create mode 100644 helm/sheepdog/sheepdog-secret/wsgi_copy.py delete mode 100644 helm/ssjdispatcher/templates/ingress.yaml diff --git a/.secrets.baseline b/.secrets.baseline index bc050c61..b0276bad 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2022-10-18T23:08:35Z", + "generated_at": "2022-10-24T19:37:51Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -74,64 +74,90 @@ "type": "Secret Keyword" } ], - "helm/arborist/values.yaml": [ + "helm/audit/templates/secrets.yaml": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "57d8659e51a2da40fda65f6a4cc294cc3f59cf6d", "is_secret": false, "is_verified": false, - "line_number": 116, + "line_number": 25, "type": "Secret Keyword" } ], - "helm/audit/values.yaml": [ + "helm/common/templates/_db_setup_job.tpl": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 167, + "line_number": 85, "type": "Secret Keyword" } ], - "helm/db-setup/templates/_db_setup.tpl": [ + "helm/common/templates/_postgres_secrets.tpl": [ + { + "hashed_secret": "07b87392697bbdd9d97f6cd887f901820a0150df", + "is_secret": false, + "is_verified": false, + "line_number": 27, + "type": "Secret Keyword" + }, + { + "hashed_secret": "e343239977fa87adac52528619fc6bf2e1a82ee7", + "is_secret": false, + "is_verified": false, + "line_number": 55, + "type": "Secret Keyword" + }, { "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 70, + "line_number": 92, "type": "Secret Keyword" } ], - "helm/db-setup/values.yaml": [ + "helm/common/templates/_secrets.tpl": [ { - "hashed_secret": "a70646783e43f444ba3430a4110bb7bdd65bdb3a", + "hashed_secret": "e540cdd1328b2b21e29a95405c301b9313b7c346", "is_secret": false, "is_verified": false, - "line_number": 16, + "line_number": 96, "type": "Secret Keyword" }, { - "hashed_secret": "874947acc1ffd819b836f6e049b2f1ab8303cb6c", + "hashed_secret": "67caac52553e052426982b6f096e73318b151765", "is_secret": false, "is_verified": false, - "line_number": 20, + "line_number": 115, "type": "Secret Keyword" - } - ], - "helm/dicom-server/values.yaml": [ + }, { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "17849dced8de4397e88a8b1c746477aead486a2b", "is_secret": false, "is_verified": false, - "line_number": 69, + "line_number": 116, + "type": "Secret Keyword" + }, + { + "hashed_secret": "df39b4caf493869772ff3a0f95cca6a9ae7934dc", + "is_secret": false, + "is_verified": false, + "line_number": 117, + "type": "Secret Keyword" + }, + { + "hashed_secret": "07b87392697bbdd9d97f6cd887f901820a0150df", + "is_secret": false, + "is_verified": false, + "line_number": 119, "type": "Secret Keyword" } ], - "helm/fence/fence-config/fence-config.yaml": [ + "helm/dicom-server/values.yaml": [ { - "hashed_secret": "5d07e1b80e448a213b392049888111e1779a52db", + "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_secret": false, "is_verified": false, - "line_number": 587, + "line_number": 69, "type": "Secret Keyword" } ], @@ -169,7 +195,7 @@ ], "helm/fence/templates/fence-creds.yaml": [ { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "hashed_secret": "c2dae5a3c7ce218639b38d8a0256f02fe81d439e", "is_secret": false, "is_verified": false, "line_number": 11, @@ -191,18 +217,11 @@ } ], "helm/fence/values.yaml": [ - { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", - "is_secret": false, - "is_verified": false, - "line_number": 29, - "type": "Secret Keyword" - }, { "hashed_secret": "5d07e1b80e448a213b392049888111e1779a52db", "is_secret": false, "is_verified": false, - "line_number": 864, + "line_number": 870, "type": "Secret Keyword" } ], @@ -233,12 +252,12 @@ "type": "Basic Auth Credentials" } ], - "helm/indexd/values.yaml": [ + "helm/indexd/templates/indexd-secret.yaml": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "c2dae5a3c7ce218639b38d8a0256f02fe81d439e", "is_secret": false, "is_verified": false, - "line_number": 108, + "line_number": 25, "type": "Secret Keyword" } ], @@ -251,15 +270,6 @@ "type": "Secret Keyword" } ], - "helm/metadata/values.yaml": [ - { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", - "is_secret": false, - "is_verified": false, - "line_number": 146, - "type": "Secret Keyword" - } - ], "helm/peregrine/peregrine-secret/config_helper.py": [ { "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", @@ -274,38 +284,29 @@ "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", "is_secret": false, "is_verified": false, - "line_number": 46, + "line_number": 45, "type": "Basic Auth Credentials" } ], - "helm/peregrine/values.yaml": [ - { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", - "is_secret": false, - "is_verified": false, - "line_number": 170, - "type": "Secret Keyword" - } - ], - "helm/requestor/values.yaml": [ + "helm/sheepdog/sheepdog-secret/config_helper.py": [ { - "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", + "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", "is_secret": false, "is_verified": false, - "line_number": 111, - "type": "Secret Keyword" + "line_number": 66, + "type": "Basic Auth Credentials" } ], - "helm/sheepdog/sheepdog-secret/config_helper.py": [ + "helm/sheepdog/sheepdog-secret/wsgi.py": [ { - "hashed_secret": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f", + "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", "is_secret": false, "is_verified": false, - "line_number": 66, + "line_number": 45, "type": "Basic Auth Credentials" } ], - "helm/sheepdog/sheepdog-secret/wsgi.py": [ + "helm/sheepdog/sheepdog-secret/wsgi_copy.py": [ { "hashed_secret": "347cd9c53ff77d41a7b22aa56c7b4efaf54658e3", "is_secret": false, @@ -319,7 +320,7 @@ "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_secret": false, "is_verified": false, - "line_number": 132, + "line_number": 150, "type": "Secret Keyword" } ], @@ -349,15 +350,6 @@ "line_number": 29, "type": "Secret Keyword" } - ], - "helm/wts/values.yaml": [ - { - "hashed_secret": "206c80413b9a96c1312cc346b7d2517b84463edd", - "is_secret": false, - "is_verified": false, - "line_number": 134, - "type": "Secret Keyword" - } ] }, "version": "0.13.1", diff --git a/helm/arborist/Chart.lock b/helm/arborist/Chart.lock new file mode 100644 index 00000000..52a7fd5c --- /dev/null +++ b/helm/arborist/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:a25c79b74ec6d89ca5c732e4222f8726ed02aa6a4a21f376afc499e53696c9b5 +generated: "2022-10-20T21:34:32.587406-05:00" diff --git a/helm/arborist/Chart.yaml b/helm/arborist/Chart.yaml index 558b9c0b..b875d331 100644 --- a/helm/arborist/Chart.yaml +++ b/helm/arborist/Chart.yaml @@ -21,4 +21,9 @@ version: 0.0.1 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.10" \ No newline at end of file +appVersion: "2022.10" + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common \ No newline at end of file diff --git a/helm/arborist/templates/_helpers.tpl b/helm/arborist/templates/_helpers.tpl index e58113bc..db6153b5 100644 --- a/helm/arborist/templates/_helpers.tpl +++ b/helm/arborist/templates/_helpers.tpl @@ -69,6 +69,6 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} \ No newline at end of file diff --git a/helm/arborist/templates/arborist-creds.yaml b/helm/arborist/templates/arborist-creds.yaml deleted file mode 100644 index 2df92a4f..00000000 --- a/helm/arborist/templates/arborist-creds.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: arborist-creds -type: Opaque -stringData: - dbcreds.json: |- - { - "db_host": {{ .Values.database.host | quote }}, - "db_username": {{ .Values.database.user | quote}}, - "db_password": {{ include "arborist.postgres.password" . | quote }}, - "db_database": {{ .Values.database.dbname | quote }} - } - - diff --git a/helm/arborist/templates/db-init.yaml b/helm/arborist/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/arborist/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/arborist/templates/deployment.yaml b/helm/arborist/templates/deployment.yaml index a91d1032..26dfb3c5 100644 --- a/helm/arborist/templates/deployment.yaml +++ b/helm/arborist/templates/deployment.yaml @@ -59,14 +59,8 @@ spec: - "-c" - | # set env vars - export PGDATABASE=$(cat /var/www/arborist/dbcreds.json | jq -r '.db_database') - export PGUSER=$(cat /var/www/arborist/dbcreds.json | jq -r '.db_username') - export PGPASSWORD=$(cat /var/www/arborist/dbcreds.json | jq -r '.db_password') - export PGHOST=$(cat /var/www/arborist/dbcreds.json | jq -r '.db_host') - export PGPORT="5432" export PGSSLMODE="disable" - # bring the database schema up to the latest version /go/src/github.com/uc-cdis/arborist/migrations/latest diff --git a/helm/arborist/values.yaml b/helm/arborist/values.yaml index d78b2151..f2314f8e 100644 --- a/helm/arborist/values.yaml +++ b/helm/arborist/values.yaml @@ -1,7 +1,24 @@ - # Default values for arborist. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +global: + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + host: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: arborist + username: arborist + port: 5432 + # If left empty password will be auto-generated + password: + replicaCount: 1 @@ -41,25 +58,6 @@ service: type: ClusterIP port: 80 -ingress: - enabled: true - className: "" - annotations: { - nginx.ingress.kubernetes.io/rewrite-target: /$2, - kubernetes.io/ingress.class: "nginx" - } - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: ingress.local - paths: - - path: /authz(/|$)(.*) - pathType: Prefix - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little @@ -89,29 +87,46 @@ affinity: {} volumes: - name: creds-volume secret: - secretName: "arborist-creds" + secretName: "arborist-dbcreds" volumeMounts: -- name: "creds-volume" - readOnly: true - mountPath: "/var/www/arborist/dbcreds.json" - subPath: dbcreds.json +# TODO: REMOVE? env: +# TODO: Revisit this? - name: JWKS_ENDPOINT value: "http://fence-service/.well-known/jwks" +- name: PGPASSWORD + valueFrom: + secretKeyRef: + name: arborist-dbcreds + key: password + optional: false +- name: PGUSER + valueFrom: + secretKeyRef: + name: arborist-dbcreds + key: username + optional: false +- name: PGDATABASE + valueFrom: + secretKeyRef: + name: arborist-dbcreds + key: database + optional: false +- name: PGHOST + valueFrom: + secretKeyRef: + name: arborist-dbcreds + key: host + optional: false +- name: PGPORT + valueFrom: + secretKeyRef: + name: arborist-dbcreds + key: port + optional: false +- name: PGSSLMODE + value: disable - -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - - # Actual fence db creds - user: postgres - password: postgres - dbname: arborist \ No newline at end of file diff --git a/helm/audit/Chart.lock b/helm/audit/Chart.lock new file mode 100644 index 00000000..5722364c --- /dev/null +++ b/helm/audit/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:34.028897-05:00" diff --git a/helm/audit/Chart.yaml b/helm/audit/Chart.yaml index 67c5f74e..636f2c95 100644 --- a/helm/audit/Chart.yaml +++ b/helm/audit/Chart.yaml @@ -22,4 +22,10 @@ version: 0.0.1 # follow Semantic Versioning. They should reflect the version the application is using. appVersion: "2022.10" +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled + diff --git a/helm/audit/templates/_helpers.tpl b/helm/audit/templates/_helpers.tpl index 22c49889..65a9c211 100644 --- a/helm/audit/templates/_helpers.tpl +++ b/helm/audit/templates/_helpers.tpl @@ -79,6 +79,6 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} \ No newline at end of file diff --git a/helm/audit/templates/db-init.yaml b/helm/audit/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/audit/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/audit/templates/secrets.yaml b/helm/audit/templates/secrets.yaml index 83d21ae9..97e193ec 100644 --- a/helm/audit/templates/secrets.yaml +++ b/helm/audit/templates/secrets.yaml @@ -20,7 +20,7 @@ stringData: #################### # DATABASE # #################### - DB_HOST: {{ .Values.database.host | quote }} - DB_USER: {{ .Values.database.user | quote}} - DB_PASSWORD: {{ include "audit.postgres.password" . | quote }} - DB_DATABASE: {{ .Values.database.dbname | quote }} + DB_HOST: {{ include "gen3.service-postgres" (dict "key" "host" "service" $.Chart.Name "context" $) | quote }} + DB_USER: {{include "gen3.service-postgres" (dict "key" "username" "service" $.Chart.Name "context" $) | quote}} + DB_PASSWORD: {{include "gen3.service-postgres" (dict "key" "password" "service" $.Chart.Name "context" $) | quote }} + DB_DATABASE: {{include "gen3.service-postgres" (dict "key" "database" "service" $.Chart.Name "context" $)| quote }} diff --git a/helm/audit/values.yaml b/helm/audit/values.yaml index f195f12a..f9cbec28 100644 --- a/helm/audit/values.yaml +++ b/helm/audit/values.yaml @@ -1,6 +1,26 @@ # Default values for audit. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: audit + username: audit + host: + port: 5432 + # If left empty password will be auto-generated + password: + + replicaCount: 1 @@ -41,23 +61,6 @@ service: type: ClusterIP port: 80 -ingress: - enabled: true - annotations: { - nginx.ingress.kubernetes.io/rewrite-target: /$2, - kubernetes.io/ingress.class: "nginx" - } - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: ingress.local - paths: - - path: "/audit(/|$)(.*)" - pathType: Prefix - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local resources: requests: @@ -152,17 +155,3 @@ secrets: sqs: url: "http://sqs.com" region: "us-east-1" - - -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - - # Actual fence db creds - user: postgres - password: postgres - dbname: audit \ No newline at end of file diff --git a/helm/db-setup/.helmignore b/helm/common/.helmignore similarity index 100% rename from helm/db-setup/.helmignore rename to helm/common/.helmignore diff --git a/helm/db-setup/Chart.yaml b/helm/common/Chart.yaml similarity index 98% rename from helm/db-setup/Chart.yaml rename to helm/common/Chart.yaml index bce4131b..d6f450ed 100644 --- a/helm/db-setup/Chart.yaml +++ b/helm/common/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -name: db-setup +name: common description: A Helm chart for provisioning databases in gen3 # A chart can be either an 'application' or a 'library' chart. diff --git a/helm/common/templates/_db_setup_job.tpl b/helm/common/templates/_db_setup_job.tpl new file mode 100644 index 00000000..cc45f329 --- /dev/null +++ b/helm/common/templates/_db_setup_job.tpl @@ -0,0 +1,88 @@ +# DB Setup Job +{{- define "common.db-setup-job" -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Chart.Name }}-dbcreate + annotations: + "helm.sh/hook": "pre-install" #,pre-upgrade" +spec: + template: + metadata: + labels: + app: gen3job + spec: + restartPolicy: OnFailure + containers: + - name: db-setup + image: quay.io/cdis/awshelper:master + imagePullPolicy: Always + command: ["/bin/bash", "-c"] + env: + - name: PGPASSWORD + value: "{{ include "gen3.master-postgres" (dict "key" "password" "context" $) }}" + - name: PGUSER + value: "{{ include "gen3.master-postgres" (dict "key" "username" "context" $) }}" + - name: PGPORT + value: "{{ include "gen3.master-postgres" (dict "key" "port" "context" $) }}" + - name: PGHOST + value: "{{ include "gen3.master-postgres" (dict "key" "host" "context" $) }}" + - name: SERVICE_PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: SERVICE_PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + - name: SERVICE_PGPASS + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + args: + - | + env + echo "SERVICE_PGDB=$SERVICE_PGDB" + echo "SERVICE_PGUSER=$SERVICE_PGUSER" + if psql -lqt | cut -d \| -f 1 | grep -qw $SERVICE_PGDB; then + echo "Database exists" + PGPASSWORD=$SERVICE_PGPASS psql -d $SERVICE_PGDB -h $PGHOST -p $PGPORT -U $SERVICE_PGUSER -c "\conninfo" + else + echo "database does not exist" + psql -tc "SELECT 1 FROM pg_database WHERE datname = '$SERVICE_PGDB'" | grep -q 1 || psql -c "CREATE DATABASE $SERVICE_PGDB;" + psql -tc "SELECT 1 FROM pg_user WHERE usename = '$SERVICE_PGUSER'" | grep -q 1 || psql -c "CREATE USER $SERVICE_PGUSER WITH PASSWORD '$SERVICE_PGPASS';" + psql -c "GRANT ALL ON DATABASE $SERVICE_PGDB TO $SERVICE_PGUSER WITH GRANT OPTION;" + psql -d $SERVICE_PGDB -c "CREATE EXTENSION ltree; ALTER ROLE $SERVICE_PGUSER WITH LOGIN" + PGPASSWORD=$SERVICE_PGPASS psql -d $SERVICE_PGDB -h $PGHOST -p $PGPORT -U $SERVICE_PGUSER -c "\conninfo" + fi +{{- end }} + + +{{/* +Create k8s secrets for connecting to postgres +*/}} +# DB Secrets +{{- define "common.db-secret" -}} +{{- if not (lookup "v1" "Secret" .Release.Namespace (printf "%s-%s" .Chart.Name "dbcreds")) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $.Chart.Name }}-dbcreds + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/resource-policy": "keep" + "helm.sh/hook-weight": "-10" +stringData: + host: {{ include "gen3.service-postgres" (dict "key" "host" "service" $.Chart.Name "context" $) }} + database: "{{ include "gen3.service-postgres" (dict "key" "database" "service" $.Chart.Name "context" $) }}" + username: "{{ include "gen3.service-postgres" (dict "key" "username" "service" $.Chart.Name "context" $) }}" + password: "{{ include "gen3.service-postgres" (dict "key" "password" "service" $.Chart.Name "context" $) }}" + port: "{{ include "gen3.service-postgres" (dict "key" "port" "service" $.Chart.Name "context" $) }}" +{{- end -}} +{{- end }} \ No newline at end of file diff --git a/helm/common/templates/_postgres_secrets.tpl b/helm/common/templates/_postgres_secrets.tpl new file mode 100644 index 00000000..4cf5c8f1 --- /dev/null +++ b/helm/common/templates/_postgres_secrets.tpl @@ -0,0 +1,94 @@ +{{/* + Postgres service secret lookup. + Usage: + {{ include "gen3.service-postgres" (dict "key" "password" "service" "fence" "context" $) }} + + + Params: + - key - String - Required - Name of the key in the secret. + - service - String - Which service are you looking up secret for? + - context - Context - Required - Parent context. + + + Lookups for postgres service secret is done in this order, until it finds a value: + - Secret provided via `.Values.postgres` (Can be database, username, password, host, port) + - Lookup secret `{{service}}-dbcreds` with key `password` + - Generate a random string, as we can assume this is a fresh install at that point. + +*/}} +{{- define "gen3.service-postgres" -}} + {{- $chartName := default "" .context.Chart.Name }} + {{- $valuesPostgres := get .context.Values.postgres .key}} + {{- $localSecretPass := get ((lookup "v1" "Secret" .context.Release.Namespace (cat .service "-dbcreds")).data) .key }} + + {{- $randomPassword := "" }} + {{- $valuesGlobalPostgres := get .context.Values.global.postgres.master .key}} + {{- if eq .key "password" }} + {{- $randomPassword = randAlphaNum 20 }} + {{- $valuesGlobalPostgres = "" }} + {{- end }} + {{- $password := coalesce $valuesPostgres $localSecretPass $randomPassword $valuesGlobalPostgres}} + {{- printf "%v" $password -}} +{{- end }} + + +{{/* +Postgres Master Secret Lookup + +Usage: + {{ include "gen3.master-postgres" (dict "key" "database" "context" $) }} + + Lookups for secret is done in this order, until it finds a value: + - Secret provided via `.Values.global.master.postgres` (Can be database, username, password, host, port) + - Lookup secret `postgres-postgresql` with property `postgres-password` in `postgres` namespace. (This is for develop installation of gen3) + + + # https://helm.sh/docs/chart_template_guide/function_list/#coalesce +*/}} +{{- define "gen3.master-postgres" }} + {{- $chartName := default "" .context.Chart.Name }} + + {{- $valuesPostgres := get .context.Values.global.postgres.master .key}} + {{- $secret := (lookup "v1" "Secret" "postgres" "postgres-postgresql" )}} + {{- $devPostgresSecret := "" }} + {{- if $secret }} + {{- $devPostgresSecret = (index $secret.data "postgres-password") | b64dec }} + {{- end }} + {{- $value := coalesce $valuesPostgres $devPostgresSecret }} + {{- printf "%v" $value -}} +{{- end }} + + + + + + +{{/* + Postgres User lookup +*/}} +{{- define "peregrine.postgres.user" -}} +{{- $localpass := (lookup "v1" "Secret" "postgres" "postgres-postgresql" ) -}} +{{- if $localpass }} +{{- default (index $localpass.data "postgres-password" | b64dec) }} +{{- else }} +{{- default .Values.postgres.password }} +{{- end }} +{{- end }} + + +{{- if not (lookup "v1" "Secret" .Release.Namespace (printf "%s-%s" .Chart.Name "dbcreds")) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Chart.Name }}-dbcreds + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/resource-policy": "keep" + "helm.sh/hook-weight": "-10" +stringData: + host: {{ default .Values.global.postgres.host .Values.postgres.host }} + database: "{{ default .Chart.Name .Values.postgres.dbname }}" + username: "{{ default .Chart.Name .Values.postgres.user }}" + password: "{{ default (randAlphaNum 24 | nospace) .Values.postgres.password }}" + port: "{{ default 5432 .Values.postgres.port }}" +{{- end -}} \ No newline at end of file diff --git a/helm/common/templates/_secrets.tpl b/helm/common/templates/_secrets.tpl new file mode 100644 index 00000000..837aa104 --- /dev/null +++ b/helm/common/templates/_secrets.tpl @@ -0,0 +1,140 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" $.context.Release.Namespace .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | quote }} + {{- else }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" $.context.Release.Namespace .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/helm/db-setup/templates/_db_setup.tpl b/helm/db-setup/templates/_db_setup.tpl deleted file mode 100644 index 98927e1c..00000000 --- a/helm/db-setup/templates/_db_setup.tpl +++ /dev/null @@ -1,72 +0,0 @@ -{{/* - Postgres Password lookup -*/}} -{{- define "postgres.master.password" -}} -{{- $localpass := (lookup "v1" "Secret" "postgres" "postgres-postgresql" ) -}} -{{- if $localpass }} -{{- default (index $localpass.data "postgres-password" | b64dec) }} -{{- else }} -{{- default $.Values.global.postgres.master.password }} -{{- end }} -{{- end }} - - - -{{- define "db-setup.setup-job" -}} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ .Chart.Name }}-dbcreate - annotations: - "helm.sh/hook": "pre-install,pre-upgrade" - "helm.sh/hook-delete-policy": hook-succeeded -spec: - template: - metadata: - labels: - app: gen3job - spec: - restartPolicy: OnFailure - containers: - - name: db-setup - image: quay.io/cdis/awshelper:master - imagePullPolicy: Always - command: ["/bin/bash", "-c"] - env: - - name: PGPASSWORD - value: "{{ include "postgres.master.password" . }}" - - name: PGUSER - value: "{{ $.Values.global.postgres.master.username }}" - - name: PGPORT - value: "{{ $.Values.global.postgres.master.port }}" - - name: PGHOST - value: "{{ $.Values.global.postgres.host }}" - args: - - | - {{- range .Values.postgres.databases }} - if psql -lqt | cut -d \| -f 1 | grep -qw {{ .databaseName }}; then - echo "Database named {{ .databaseName }} already exists." - else - psql -tc "SELECT 1 FROM pg_database WHERE datname = '{{ .databaseName }}'" | grep -q 1 || psql -c "CREATE DATABASE {{ .databaseName }};" - psql -tc "SELECT 1 FROM pg_user WHERE usename = '{{ .username }}'" | grep -q 1 || psql -c "CREATE USER {{ .username }} WITH PASSWORD '{{ .password }}';" - psql -c "GRANT ALL ON DATABASE {{ .databaseName }} TO {{ .username }} WITH GRANT OPTION;" - psql -d {{ .databaseName }} -c "CREATE EXTENSION ltree; ALTER ROLE {{ .username }} WITH LOGIN" - fi - {{- end }} -{{- end }} - -{{ define "db-setup.secret" }} -{{- range .Values.postgres.databases }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ .service }}-dbcreds - annotations: - "helm.sh/hook": "pre-install,pre-upgrade" - "helm.sh/resource-policy": "keep" -stringData: - database: "{{ .databaseName }}" - username: "{{ .username }}" - password: "{{ .password }}" -{{- end -}} -{{- end -}} \ No newline at end of file diff --git a/helm/db-setup/values.yaml b/helm/db-setup/values.yaml deleted file mode 100644 index 1a595331..00000000 --- a/helm/db-setup/values.yaml +++ /dev/null @@ -1,20 +0,0 @@ -global: - postgres: - host: postgres-postgresql.postgres.svc.cluster.local - master: - username: postgres - port: 5432 - # If password is left empty the lookup function will look for postgres master password - password: - -postgres: - # An array of databases to create. - databases: - - service: wts - databaseName: wts - username: wts - password: wts_password - - service: indexd - databaseName: indexd - username: indexd - password: indexd_password \ No newline at end of file diff --git a/helm/fence/Chart.lock b/helm/fence/Chart.lock new file mode 100644 index 00000000..0d7b33f1 --- /dev/null +++ b/helm/fence/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:35.742578-05:00" diff --git a/helm/fence/Chart.yaml b/helm/fence/Chart.yaml index 9b15ad2b..75e40506 100644 --- a/helm/fence/Chart.yaml +++ b/helm/fence/Chart.yaml @@ -20,4 +20,10 @@ version: 0.0.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: "2022.10" \ No newline at end of file +appVersion: "2022.10" + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/fence/fence-config/fence-config.yaml b/helm/fence/fence-config/fence-config.yaml deleted file mode 100644 index ee3b33da..00000000 --- a/helm/fence/fence-config/fence-config.yaml +++ /dev/null @@ -1,912 +0,0 @@ ---- -############################### Fence Configuration #################################### -# This file contains various configurations for the Fence microservice. -# -# README: -# - This is initially configured for minimal local development with reasonable defaults. -# - Descriptions for each of the configurations (if any) will be *above* the variable as -# comments. -# - Some configuration variables will have examples commented out below them. -# - This is broken up into 2 main sections for REQUIRED and OPTIONAL configurations. -# - Optional configs will note what features or endpoints they support -# - Underneath each main section the variables are logically grouped under named -# sections. -# -# NOTE: Login is NOT ready out of the box. Fill out REQUIRED configurations first - -######################################################################################## -# REQUIRED CONFIGURATIONS # -######################################################################################## - -# ////////////////////////////////////////////////////////////////////////////////////// -# GENERAL -# - Fill out all variables! -# ////////////////////////////////////////////////////////////////////////////////////// -APP_NAME: 'Gen3 Data Commons' -# Where fence microservice is deployed -BASE_URL: 'https://localhost/user' -# postgres db to connect to -# connection url format: -# postgresql://[user[:password]@][netloc][:port][/dbname] -DB: 'postgresql://postgres:password!123@fence-postgresql:5432/fence' - -# A URL-safe base64-encoded 32-byte key for encrypting keys in db -# in python you can use the following script to generate one: -# import base64 -# import os -# key = base64.urlsafe_b64encode(os.urandom(32)) -# print(key) -ENCRYPTION_KEY: '' - -# ////////////////////////////////////////////////////////////////////////////////////// -# DEBUG & SECURITY SETTINGS -# - Modify based on whether you're in a dev environment or in production -# ////////////////////////////////////////////////////////////////////////////////////// -# flask's debug setting -# WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) -DEBUG: true -# if true, will automatically login a user with username "test" -# WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) -MOCK_AUTH: false -# if true, will fake a successful login response from Google in /login/google -# NOTE: this will also modify the behavior of /link/google endpoints -# WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) -# will login as the username set in cookie DEV_LOGIN_COOKIE_NAME -MOCK_GOOGLE_AUTH: false -DEV_LOGIN_COOKIE_NAME: "dev_login" -# if true, will ignore anything configured in STORAGE_CREDENTIALS -MOCK_STORAGE: true -# allow OIDC traffic on http for development. By default it requires https. -# -# WARNING: ONLY set to true when fence will be deployed in such a way that it will -# ONLY receive traffic from internal clients and can safely use HTTP. -AUTHLIB_INSECURE_TRANSPORT: true -# enable Prometheus Metrics for observability purposes -# -# WARNING: Any counters, gauges, histograms, etc. should be carefully -# reviewed to make sure its labels do not contain any PII / PHI -ENABLE_PROMETHEUS_METRICS: false - -# set if you want browsers to only send cookies with requests over HTTPS -SESSION_COOKIE_SECURE: true - -ENABLE_CSRF_PROTECTION: true - -# Signing key for WTForms to sign CSRF tokens with -WTF_CSRF_SECRET_KEY: '{{ENCRYPTION_KEY}}' - -# fence (at the moment) attempts a migration on startup. setting this to false will disable that -# WARNING: ONLY set to false if you do NOT want to automatically migrate your database. -# You should be careful about incompatible versions of your db schema with what -# fence expects. In other words, things could be broken if you update to a later -# fence that expects a schema your database isn't migrated to. -# NOTE: We are working to improve the migration process in the near future -ENABLE_DB_MIGRATION: true - -# ////////////////////////////////////////////////////////////////////////////////////// -# OPEN ID CONNECT (OIDC) -# - Fully configure at least one client so login works -# - WARNING: Be careful changing the *_ALLOWED_SCOPES as you can break basic -# and optional functionality -# ////////////////////////////////////////////////////////////////////////////////////// -OPENID_CONNECT: - # any OIDC IDP that does not differ from the generic implementation can be - # configured without code changes - generic_oidc_idp: # choose a unique ID and replace this key - name: 'some_idp' # optional; display name for this IDP - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/some_idp/login' # replace IDP name - # use `discovery` to configure IDPs that do not expose a discovery - # endpoint. One of `discovery_url` or `discovery` should be configured - discovery_url: 'https://server.com/.well-known/openid-configuration' - discovery: - authorization_endpoint: '' - token_endpoint: '' - jwks_uri: '' - user_id_field: '' # optional (default "sub"); claims field to get the user_id from - email_field: '' # optional (default "email"); claims field to get the user email from - scope: '' # optional (default "openid") - # These Google values must be obtained from Google's Cloud Console - # Follow: https://developers.google.com/identity/protocols/OpenIDConnect - # - # You'll need to obtain a Client ID and Client Secret. Set the redirect URIs - # in Google to be '{{BASE_URL}}/login/google/login', but expand BASE_URL to - # whatever you set it to above. - google: - discovery_url: 'https://accounts.google.com/.well-known/openid-configuration' - client_id: '' - client_secret: '' - # this is be the allowed redirect back to fence, should not need to change - redirect_url: '{{BASE_URL}}/login/google/login/' - scope: 'openid email' - # if mock is true, will fake a successful login response from Google in /login/google - # NOTE: this will also modify the behavior of /link/google endpoints - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - # will login as the username set in cookie DEV_LOGIN_COOKIE_NAME or default provided - # here - mock: '{{MOCK_GOOGLE_AUTH}}' # for backwards compatibility with older cfg files - mock_default_user: 'test@example.com' - # Support for multi-tenant fence (another fence is this fence's IDP) - # If this fence instance is a client of another fence, fill this cfg out. - # REMOVE if not needed - fence: - # this api_base_url should be the root url for the OTHER fence - # something like: https://example.com - api_base_url: '' - # this client_id and client_secret should be obtained by registering THIS fence as - # a new client of the OTHER fence - client_id: '' - client_secret: '' - client_kwargs: - # openid is required to use OIDC flow - scope: 'openid' - # callback after logging in through the other fence - redirect_uri: '{{BASE_URL}}/login/fence/login' - # The next 3 should not need to be changed if the provider is following - # Oauth2 endpoint naming conventions - authorize_url: '{{api_base_url}}/oauth2/authorize' - access_token_url: '{{api_base_url}}/oauth2/token' - refresh_token_url: '{{api_base_url}}/oauth2/token' - # Custom name to display for consent screens. If not provided, will use `fence`. - # If the other fence is using NIH Login, you should make name: `NIH Login` - name: '' - # if mock is true, will fake a successful login response for login - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - mock: false - mock_default_user: 'test@example.com' - # this is needed to enable InCommon login, if some LOGIN_OPTIONS are configured with idp=fence and a list of shib_idps: - shibboleth_discovery_url: 'https://login.bionimbus.org/Shibboleth.sso/DiscoFeed' - # you can setup up an orcid client here: https://orcid.org/developer-tools - orcid: - discovery_url: 'https://orcid.org/.well-known/openid-configuration' - client_id: '' - client_secret: '' - # make sure you put the FULL url for this deployment in the allowed redirects in - # ORCID.org. DO NOT include {{BASE_URL}} at ORCID.org, you need to actually put the - # full url - redirect_url: '{{BASE_URL}}/login/orcid/login/' - scope: 'openid' - # if mock is true, will fake a successful login response for login - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - mock: false - mock_default_user: '0000-0002-2601-8132' - ras: - discovery_url: 'https://sts.nih.gov/.well-known/openid-configuration' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/ras/callback' - scope: 'openid email profile ga4gh_passport_v1' - # if mock is true, will fake a successful login response for login - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - mock: false - mock_default_user: 'test@example.com' - # Create a client in Azure here: - # https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview - # Currently supports organizational account only, so when registering a new App in - # Azure, make sure to select the `Accounts in any organizational directory` for - # supported account types. - microsoft: - discovery_url: 'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration' - # after registering a new appl, client_id can be found as - # "APPLICATION (CLIENT) ID" in Microsoft Azure - client_id: '' - # You have a generate a secret in Azure for this app, there should be a - # "Certificates & secrets" section where you can create a "New client secret" - client_secret: '' - # make sure you put the FULL url for this deployment in the allowed redirects in - # your app in Azure. DO NOT include {{BASE_URL}} in Azure, you need to actually put the - # full url - redirect_url: '{{BASE_URL}}/login/microsoft/login/' - scope: 'openid email' - # if mock is true, will fake a successful login response for login - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - mock: false - mock_default_user: 'test@example.com' - # For information on configuring an Okta tenant as an OIDC IdP refer to Okta documentation at: - # https://developer.okta.com/docs/reference/api/oidc/#2-okta-as-the-identity-platform-for-your-app-or-api - okta: - discovery_url: '' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/okta/login/' - scope: 'openid email' - cognito: - # You must create a user pool in order to have a discovery url - discovery_url: 'https://cognito-idp.{REGION}.amazonaws.com/{USER-POOL-ID}/.well-known/openid-configuration' - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/cognito/login/' - scope: 'openid email' - # In the case where Cognito is being used solely as an intermediary to a single IdP, - # and that IdP is a SAML IdP with no 'email_verified' outgoing claim, but it is safe - # to assume all emails from this SAML IdP are in fact verified, we may set this to True - assume_emails_verified: False - # CILogon subscribers can create and manage OIDC clients using COmanage Registry. - # Free tier users may request OIDC clients at https://cilogon.org/oauth2/register - cilogon: - discovery_url: 'https://cilogon.org/.well-known/openid-configuration' - client_id: '' - client_secret: '' - # When registering the Callback URLs for your CILogon OIDC client be - # sure to include the FULL url for this deployment, including the https:// scheme - # and server FQDN. - redirect_url: '{{BASE_URL}}/login/cilogon/login/' - scope: 'openid email profile' - # if mock is true, will fake a successful login response for login - # WARNING: DO NOT ENABLE IN PRODUCTION (for testing purposes only) - mock: false - mock_default_user: 'http://cilogon.org/serverT/users/64703' - synapse: - discovery_url: '' - client_id: '' - client_secret: '' - redirect_url: '' - scope: 'openid' - shibboleth: - client_id: '' - client_secret: '' - redirect_url: '{{BASE_URL}}/login/shib/login' - -# these are the *possible* scopes a client can be given, NOT scopes that are -# given to all clients. You can be more restrictive during client creation -CLIENT_ALLOWED_SCOPES: - - "openid" - - "user" - - "data" - - "google_credentials" - - "google_service_account" - - "google_link" - - "ga4gh_passport_v1" - -# these are the scopes that CAN be included in a user's own access_token -USER_ALLOWED_SCOPES: - - "fence" - - "openid" - - "user" - - "data" - - "admin" - - "google_credentials" - - "google_service_account" - - "google_link" - - "ga4gh_passport_v1" - -# these are the scopes that a browser session can create for a user (very -# similar to USER_ALLOWED_SCOPES, as the session will actually create access_tokens -# for an actively logged in user) -SESSION_ALLOWED_SCOPES: - - "openid" - - "user" - - "credentials" - - "data" - - "admin" - - "google_credentials" - - "google_service_account" - - "google_link" - - "ga4gh_passport_v1" - -# ////////////////////////////////////////////////////////////////////////////////////// -# LOGIN -# - Modify based on which OIDC provider(s) you configured above -# - NOTE: You can have multiple IDPs for users to login with, but one has to be set -# as the default -# ////////////////////////////////////////////////////////////////////////////////////// - -# List of enabled login options (used by data-portal to display login buttons). -# Each option must be configured with a "name" and an "idp". -# - "idp" must be a configured provider in OPENID_CONNECT section. -# Multiple options can be configured with the same idp. -# - if provider_id is "fence", "fence_idp" can be any of the providers -# supported by the other Fence. If not specified, will default to NIH login. -# - if provider_id is "fence" and fence_idp is "shibboleth", a list of -# "shib_idps" can be configured for InCommon login. If not specified, will -# default to NIH login. -# - Optional parameters: "desc" (description) and "secondary" (boolean - can -# be used by the frontend to display secondary buttons differently). -LOGIN_OPTIONS: [] # !!! remove the empty list to enable login options! - # - name: 'Login from Google' - # desc: 'description' - # idp: google - # secondary: True - # - name: 'ORCID Login' - # idp: orcid - # - name: 'Microsoft Login' - # idp: microsoft - # - name: 'Okta Login' - # idp: okta - # # Cognito login: You may want to edit the name to reflect Cognito's IdP, - # # especially if Cognito is only using one IdP - # - name: 'Login from Cognito' - # desc: 'Amazon Cognito login' - # idp: cognito - # - name: 'Login from RAS' - # idp: ras - # - name: 'NIH Login' - # idp: fence - # fence_idp: shibboleth - # - name: 'ORCID Login through other Fence' - # idp: fence - # fence_idp: orcid - # - name: 'CILogon Login' - # idp: cilogon - # - name: 'InCommon Login' - # idp: fence - # fence_idp: shibboleth - # # "shib_idps" can be '*' or a list of one or more entity IDs - # shib_idps: - # - urn:mace:incommon:nih.gov - # - urn:mace:incommon:uchicago.edu -# The following can be used for shibboleth login, simply uncomment. -# NOTE: Don't enable shibboleth if the deployment is not protected by -# shibboleth module, the shib module takes care of preventing header -# spoofing. - # - name: 'Shibboleth Login' - # idp: shibboleth - -# Default login provider: -# - must be configured in LOGIN_OPTIONS and OPENID_CONNECT -# - if several options in LOGIN_OPTIONS are defined for this IDP, will default -# to the first one. -DEFAULT_LOGIN_IDP: null - -# Default login URL: DEPRECATED and replaced by LOGIN_OPTIONS + DEFAULT_LOGIN_IDP configs -# - Google? Use: '{{BASE_URL}}/login/google' -# - Multi-tenant fence (e.g. another fence instance)? Use: '{{BASE_URL}}/login/fence' -# - Sibboleth? Use: '{{BASE_URL}}/login/shib' -DEFAULT_LOGIN_URL: '{{BASE_URL}}/login/google' - -# `LOGIN_REDIRECT_WHITELIST` is a list of extra whitelisted URLs which can be redirected -# to by the `/login/*` endpoints. Fence automatically populates this with the redirect -# URLs for any registered OAuth clients, and its own URL. When validating the redirects, -# fence chesk whether the domain for the redirect matches a domain in the whitelist (so -# only the domains for the additional desired redirects are necessary here). -LOGIN_REDIRECT_WHITELIST: [] - -### DEPRECATED and replaced by OPENID_CONNECT + LOGIN_OPTIONS configs -ENABLED_IDENTITY_PROVIDERS: {} - - -# ////////////////////////////////////////////////////////////////////////////////////// -# LIBRARY CONFIGURATION (authlib & flask) -# - Already contains reasonable defaults -# ////////////////////////////////////////////////////////////////////////////////////// -# authlib-specific configs for OIDC flow and JWTs -# NOTE: the OAUTH2_JWT_KEY cfg gets set automatically by fence if keys are setup -# correctly -OAUTH2_JWT_ALG: 'RS256' -OAUTH2_JWT_ENABLED: true -OAUTH2_JWT_ISS: '{{BASE_URL}}' -OAUTH2_PROVIDER_ERROR_URI: '/api/oauth2/errors' - -# used for flask, "path mounted under by the application / web server" -# since we deploy as microservices, fence is typically under {{base}}/user -# this is also why our BASE_URL default ends in /user -APPLICATION_ROOT: '/user' - - -# ////////////////////////////////////////////////////////////////////////////////////// -# Tokens, Lifetimes, & Expirations -# - Already contains reasonable defaults -# ////////////////////////////////////////////////////////////////////////////////////// -# The name of the browser cookie in which the access token will be stored. -ACCESS_TOKEN_COOKIE_NAME: "access_token" - -# The name of the browser cookie in which the session token will be stored. -# Note that the session token also stores information for the -# ``flask.session`` in the ``context`` field of the token. -SESSION_COOKIE_NAME: "fence" - -# The domain of the browser cookie in which the session token will be stored. -# Leave unset (not empty string!) for normal single-site deployment. -SESSION_COOKIE_DOMAIN: - -OAUTH2_TOKEN_EXPIRES_IN: - "authorization_code": 1200 - "implicit": 1200 - -# The number of seconds after an access token is issued until it expires. -ACCESS_TOKEN_EXPIRES_IN: 1200 - -# The number of seconds after a refresh token is issued until it expires. -REFRESH_TOKEN_EXPIRES_IN: 2592000 - -# The number of seconds after which a browser session is considered stale. -SESSION_TIMEOUT: 1800 - -# The maximum session lifetime in seconds. -SESSION_LIFETIME: 28800 - -# The number of seconds the user's Google service account key used for -# url signing will last before being expired/rotated -# 30 days: 2592000 seconds -GOOGLE_SERVICE_ACCOUNT_KEY_FOR_URL_SIGNING_EXPIRES_IN: 2592000 - -# The number of seconds after a User's Google Service account is added to bucket -# access until it expires. -# 7 days: 604800 seconds -GOOGLE_USER_SERVICE_ACCOUNT_ACCESS_EXPIRES_IN: 604800 - -# The number of seconds after a User's Google account is added to bucket -# access until it expires. -GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN: 86400 - -# The number of seconds after a pre-signed url is issued until it expires. -MAX_PRESIGNED_URL_TTL: 3600 - -# The number of seconds after an API KEY is issued until it expires. -MAX_API_KEY_TTL: 2592000 - -# The number of seconds after an access token is issued until it expires. -MAX_ACCESS_TOKEN_TTL: 3600 - -# TEMPORARY: The maximum number of projects allowed in token claims. -# This config var should be removed after sheepdog and peregrine support -# auth checks against Arborist, and no longer check the token. -TOKEN_PROJECTS_CUTOFF: 10 - -# If set to true, will generate an new access token each time when a browser session update happens -RENEW_ACCESS_TOKEN_BEFORE_EXPIRATION: false - -# The maximum lifetime of a Gen3 passport in seconds -GEN3_PASSPORT_EXPIRES_IN: 43200 - -######################################################################################## -# OPTIONAL CONFIGURATIONS # -######################################################################################## - -# For displaying a privacy policy to users, we can either link to the URL specified by -# PRIVACY_POLICY_URL, or default to the `static/privacy_policy.md` file in fence. -PRIVACY_POLICY_URL: null - -# ////////////////////////////////////////////////////////////////////////////////////// -# RELIABILITY OPTS -# ////////////////////////////////////////////////////////////////////////////////////// -# Configurations related to resiliency, fault-tolerance and availability -# This is the number of requests per second that the Nginx proxy will accept before reaching fence -# The value defined in fence-config-public.yaml takes precedence over this one -# In the absence of this OVERRIDE prefixed config, the legacy NGINX_RATE_LIMIT from the k8s deployment yaml is applied -OVERRIDE_NGINX_RATE_LIMIT: 18 - -# ////////////////////////////////////////////////////////////////////////////////////// -# SUPPORT INFO -# ////////////////////////////////////////////////////////////////////////////////////// -# If you want an email address to show up when an unhandled error occurs, provide one -# here. Something like: support@example.com -SUPPORT_EMAIL_FOR_ERRORS: null - -# ////////////////////////////////////////////////////////////////////////////////////// -# SHIBBOLETH -# - Support using `shibboleth` in LOGIN_OPTIONS -# - Contains defaults for using NIH's Login. -# ////////////////////////////////////////////////////////////////////////////////////// -# assumes shibboleth is deployed under {{BASE_URL}}/shibboleth -SHIBBOLETH_HEADER: 'persistent_id' -SSO_URL: 'https://auth.nih.gov/affwebservices/public/saml2sso?SPID={{BASE_URL}}/shibboleth&RelayState=' -ITRUST_GLOBAL_LOGOUT: 'https://auth.nih.gov/siteminderagent/smlogout.asp?mode=nih&AppReturnUrl=' - -# ////////////////////////////////////////////////////////////////////////////////////// -# dbGaP USER SYNCING SUPPORT -# - Support syncing authorization information from dbGaP -# ////////////////////////////////////////////////////////////////////////////////////// -# "dbGaP project serves as an access gateway for researchers seeking to gain -# access to genotype and phenotype data" -# -# User syncing and access can also be done throught a User Access file. See -# fence's README for more information -dbGaP: - - info: - host: '' - username: '' - password: '' - port: 22 - proxy: '' - proxy_user: '' - protocol: 'sftp' - decrypt_key: '' - # parse out the consent from the dbgap accession number such that something - # like "phs000123.v1.p1.c2" becomes "phs000123.c2". - # - # NOTE: when this is "false" the above would become "phs000123" - parse_consent_code: true - # A consent of "c999" can indicate access to that study's "exchange area data" - # and when a user has access to one study's exchange area data, they - # have access to the parent study's "common exchange area data" that is not study - # specific. The following config is whether or not to parse/handle "c999" codes - # for access to the common exchange area data - # - # NOTE: When enabled you MUST also provide a mapping to the - # `study_common_exchange_areas` from study -> parent common exchange area resource - enable_common_exchange_area_access: false - # The below configuration is a mapping from studies to their "common exchange area data" - # Fence project name a user gets access to when parsing c999 exchange area codes (and - # subsequently gives access to an Arborist resource representing this common area - # as well) - study_common_exchange_areas: - 'example': 'test_common_exchange_area' - # 'studyX': 'test_common_exchange_area' - # 'studyY': 'test_common_exchange_area' - # 'studyZ': 'test_common_exchange_area' - # A mapping from the dbgap study / Fence project to which authorization namespaces the - # actual data lives in. For example, `studyX` data may exist in multiple organizations, so - # we need to know how to map authorization to all orgs resources - study_to_resource_namespaces: - '_default': ['/'] - 'test_common_exchange_area': ['/dbgap/'] - # above are for default support and exchange area support - # below are further examples - # - # 'studyX': ['/orgA/', '/orgB/'] - # 'studyX.c2': ['/orgB/', '/orgC/'] - # 'studyZ': ['/orgD/'] -# Regex to match an assession number that has consent information in forms like: -# phs00301123.c999 -# phs000123.v3.p1.c3 -# phs000123.c3 -# phs00301123.v3.p4.c999 -# Will NOT MATCH forms like: phs000123 -# -# WARNING: Do not change this without consulting the code that uses it -DBGAP_ACCESSION_WITH_CONSENT_REGEX: '(?Pphs[0-9]+)(.(?Pv[0-9]+)){0,1}(.(?Pp[0-9]+)){0,1}.(?Pc[0-9]+)' - -# ////////////////////////////////////////////////////////////////////////////////////// -# STORAGE BACKENDS AND CREDENTIALS -# - Optional: Used for `/admin` & `/credentials` endpoints for user management. -# Also used during User Syncing process to automate managing Storage -# access for users. -# ////////////////////////////////////////////////////////////////////////////////////// -# When true, this modifies usersync (not fence service itself) such that when syncing user -# access to a Google storage backend happens in "bulk" by doing a diff *per google group* -# between what's in Google and what's expected. Then it adds, removes only as necessary. -# This is in contrast to the default logic which does blind updates per user and ignores -# 409s from Google. -# NOTE: This reduces the number of API calls to Google in the general case, but increases -# memory usages by usersync (as it has to track all the Google groups and user access) -GOOGLE_BULK_UPDATES: false - -# Configuration for various storage systems for the backend -# NOTE: Remove the {} and supply backends if needed. Example in comments below -STORAGE_CREDENTIALS: {} -# Google Cloud Storage backend -# -# 'google': -# backend: 'google' -# # this should be the project id where the Google Groups for data access are managed -# google_project_id: 'some-project-id-12378923' - -# Cleversafe data storage backend -# -# 'cleversafe-server-a': -# backend: 'cleversafe' -# aws_access_key_id: '' -# aws_secret_access_key: '' -# host: 'somemanager.osdc.io' -# public_host: 'someobjstore.example.com' -# port: 443 -# is_secure: true -# username: 'someone' -# password: 'somepass' -# is_mocked: true - -# ////////////////////////////////////////////////////////////////////////////////////// -# AWS BUCKETS AND CREDENTIALS -# - Support `/data` endpoints -# ////////////////////////////////////////////////////////////////////////////////////// -AWS_CREDENTIALS: {} -# NOTE: Remove the {} and supply creds if needed. Example in comments below -# 'CRED1': -# aws_access_key_id: '' -# aws_secret_access_key: '' -# 'CRED2': -# aws_access_key_id: '' -# aws_secret_access_key: '' - -# NOTE: the region is optonal for s3_buckets, however it should be specified to avoid a -# call to GetBucketLocation which you make lack the AWS ACLs for. -# public buckets do not need the region field. -# the cred values should be keys in section `AWS_CREDENTIALS`. -S3_BUCKETS: {} -# NOTE: Remove the {} and supply buckets if needed. Example in comments below -# bucket1: -# cred: 'CRED1' -# region: 'us-east-1' -# # optionally you can manually specify an s3-compliant endpoint for this bucket -# endpoint_url: 'https://cleversafe.example.com/' -# bucket2: -# cred: 'CRED2' -# region: 'us-east-1' -# bucket3: -# cred: '*' # public bucket -# bucket4: -# cred: 'CRED1' -# region: 'us-east-1' -# role-arn: 'arn:aws:iam::role1' - -# `DATA_UPLOAD_BUCKET` specifies an S3 bucket to which data files are uploaded, -# using the `/data/upload` endpoint. This must be one of the first keys under -# `S3_BUCKETS` (since these are the buckets fence has credentials for). -DATA_UPLOAD_BUCKET: 'bucket1' - -# ////////////////////////////////////////////////////////////////////////////////////// -# PROXY -# - Optional: If the api is behind firewall that needs to set http proxy -# ////////////////////////////////////////////////////////////////////////////////////// -# NOTE: leave as-is to not use proxy -# this is only used by the Google Oauth2Client at the moment if provided -HTTP_PROXY: - host: null - port: 3128 - -# ////////////////////////////////////////////////////////////////////////////////////// -# MICROSERVICE PATHS -# - Support `/data` endpoints & authz functionality -# ////////////////////////////////////////////////////////////////////////////////////// -# url where indexd microservice is running (for signed urls primarily) -# NOTE: Leaving as null will force fence to default to {{BASE_URL}}/index -# example value: 'https://example.com/index' -INDEXD: null - -# this is the username which fence uses to make authenticated requests to indexd -INDEXD_USERNAME: 'fence' -# this is the password which fence uses to make authenticated requests to indexd -INDEXD_PASSWORD: '' - -# ////////////////////////////////////////////////////////////////////////////////////// -# AZURE STORAGE BLOB CONFIGURATION -# - Support Azure Blob Data Access Methods -# ////////////////////////////////////////////////////////////////////////////////////// - -# https://docs.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&tabs=azure-portal#view-account-access-keys -# AZ_BLOB_CREDENTIALS: 'fake connection string' -AZ_BLOB_CREDENTIALS: - -# AZ_BLOB_CONTAINER_URL: 'https://storageaccount.blob.core.windows.net/container/' -# this is the container used for uploading, and should match the storage account -# used in the connection string for AZ_BLOB_CREDENTIALS -AZ_BLOB_CONTAINER_URL: 'https://myfakeblob.blob.core.windows.net/my-fake-container/' - -# url where authz microservice is running -ARBORIST: null - -# url where the audit-service is running -AUDIT_SERVICE: 'http://audit-service' -ENABLE_AUDIT_LOGS: - presigned_url: false - login: false -# `PUSH_AUDIT_LOGS_CONFIG.type` is one of: [api, aws_sqs]. -# - if type == api: logs are created by hitting the log creation endpoint. -# - if type == aws_sqs: logs are pushed to an SQS and `aws_sqs_config` fields -# `sqs_url` and `region` are required. Field `aws_cred` is optional and it -# should be a key in section `AWS_CREDENTIALS`. -PUSH_AUDIT_LOGS_CONFIG: - type: aws_sqs - aws_sqs_config: - sqs_url: - region: - aws_cred: - -# ////////////////////////////////////////////////////////////////////////////////////// -# CLOUD API LIBRARY (CIRRUS) AND GOOGLE CONFIGURATION -# - Support Google Data Access Methods -# ////////////////////////////////////////////////////////////////////////////////////// -# Setting this up allows fence to create buckets, manage Google groups, etc. -# See directions here for setting up cirrus: https://github.com/uc-cdis/cirrus -CIRRUS_CFG: - GOOGLE_API_KEY: '' - GOOGLE_PROJECT_ID: '' - GOOGLE_APPLICATION_CREDENTIALS: '' - GOOGLE_STORAGE_CREDS: '' - GOOGLE_ADMIN_EMAIL: '' - GOOGLE_IDENTITY_DOMAIN: '' - GOOGLE_CLOUD_IDENTITY_ADMIN_EMAIL: '' - -# Prefix to namespace Google Groups on a single Cloud Identity (see cirrus -# setup for more info on Cloud Identity) -# -# NOTE: Make this short! Less than 8 characters if possible. Google has -# length restrictions on group names. -GOOGLE_GROUP_PREFIX: '' - -# Prefix to namespace Google Service Accounts in a single Google Cloud Platform Project. -# This is primarily to support multiple instances of fence references the same Google -# project. If that is not something you need to support, then you can leave this blank. -# -# NOTE: Make this short! Less than 8 characters if possible. Google has -# length restrictions on service account names. -GOOGLE_SERVICE_ACCOUNT_PREFIX: '' - -# A Google Project identitifier representing the default project to bill to for -# accessing Google Requester Pays buckets (for signed urls and/or temporary service account -# credentials). If this is provided and the API call for -# Google access does not include a `userProject`, this will be used instead. -# -# WARNING: Setting this WITHOUT setting "ENABLE_AUTOMATIC_BILLING_*" to `true` below, -# means that clients and end-users will be responsible for making sure that -# the service account used in either of these methods actually has billing -# permission in the specified project. -BILLING_PROJECT_FOR_SIGNED_URLS: -BILLING_PROJECT_FOR_SA_CREDS: - -# Setting this to `true` will make Fence automatically attempt to create a Custom Role -# in the billing project and give the necessary Google Service Account that role -# (which will allow it to bill to the project). -# -# NOTE: The Fence SA will need the necessary permissions in the specified project to -# both create a custom role and update the Project's IAM Policy to include the -# necessary SA. At the time of writing, there are pre-defined roles in Google's -# IAM that provide the necessary permissions. Those are "Project IAM Admin" and -# "Role Administrator" -# -# NOTE2: It may be possible to further restrict the permissions in the future to -# be more fine-grained. -# -ENABLE_AUTOMATIC_BILLING_PERMISSION_SIGNED_URLS: false -ENABLE_AUTOMATIC_BILLING_PERMISSION_SA_CREDS: false - -# ////////////////////////////////////////////////////////////////////////////////////// -# EMAIL -# - Support for sending emails from fence. Used for user certificates -# and `/google/service_accounts` endpoints -# ////////////////////////////////////////////////////////////////////////////////////// -# Gun Mail Service (for sending emails from fence) -# -# NOTE: Example in comments below -GUN_MAIL: - 'datacommons.io': - smtp_hostname: 'smtp.mailgun.org' - api_key: '' - default_login: 'postmaster@mailgun.example.com' - api_url: 'https://api.mailgun.net/v3/mailgun.example.com' - smtp_password: '' - -# For emails regarding users certificates -EMAIL_SERVER: 'localhost' -SEND_FROM: 'example@gmail.com' -SEND_TO: 'example@gmail.com' - -# ////////////////////////////////////////////////////////////////////////////////////// -# DATA ACCESS: GOOGLE LINKING & SERVICE ACCOUNT REGISTRATION -# - Support `/google/service_accounts` endpoints -# ////////////////////////////////////////////////////////////////////////////////////// -# whether or not to allow access to the /link/google endpoints -ALLOW_GOOGLE_LINKING: true - -# A Google Project with controlled data access will be determined INVALID if -# if it has a parent organization UNLESS that parent organization's ID is in this -# whitelist. -# -# NOTE: Remove the [] and Google Organization IDs if needed. Example in comments below -WHITE_LISTED_GOOGLE_PARENT_ORGS: [] -# - '12345678910' - -# A Google Project with Google Service Accounts determined INVALID will result in the -# the entire project being invalid UNLESS that service accounts's email is in this -# whitelist. -# -# NOTE: Remove the [] and service account emails if needed. Example in comments below -WHITE_LISTED_SERVICE_ACCOUNT_EMAILS: [] -# - 'example@developer.gserviceaccount.com' -# - 'example@test.iam.gserviceaccount.com' - -# when service accounts or google projects are determined invalid, an email is sent -# to the project owners. These settings are for that email -REMOVE_SERVICE_ACCOUNT_EMAIL_NOTIFICATION: - enable: false - # this domain MUST exist in GUN_MAIL config - domain: 'example.com' - from: 'do-not-reply@example.com' - subject: 'User service account removal notification' - # the {} gets replaced dynamically in the Python code to be the Project ID - content: > - Service accounts were removed from access control data because some users or - service accounts of GCP Project {} are not authorized to access the data sets - associated to the service accounts, or do not adhere to the security policies. - # this admin email will be included as a recipient to *any* email to anyone about - # service account removal. - # - # WARNING: This is NOT a bcc so the email is visible to the end-user - admin: - - 'admin@example.edu' - -PROBLEM_USER_EMAIL_NOTIFICATION: - # this domain MUST exist in GUN_MAIL config - domain: 'example.com' - from: 'do-not-reply@example.com' - subject: 'Account access error notification' - # the {} gets replaced dynamically in the Python code to be the Project ID - content: > - The Data Commons Framework utilizes dbGaP for data access authorization. - Another member of a Google project you belong to ({}) is attempting to - register a service account to the following additional datasets ({}). - Please contact dbGaP to request access. - # this admin email will be included as a recipient to *any* email to anyone about - # service account removal. - # - # WARNING: This is NOT a bcc so the email is visible to the end-user - admin: - - 'admin@example.edu' - -# Service account email domains that represent a service account that Google owns. -# These are usually created when a sepcific GCP service is enabled. -# This is used for Service Account Validation for Data Access. -GOOGLE_MANAGED_SERVICE_ACCOUNT_DOMAINS: - - 'dataflow-service-producer-prod.iam.gserviceaccount.com' - - 'cloudbuild.gserviceaccount.com' - - 'cloud-ml.google.com.iam.gserviceaccount.com' - - 'container-engine-robot.iam.gserviceaccount.com' - - 'dataflow-service-producer-prod.iam.gserviceaccount.com' - - 'sourcerepo-service-accounts.iam.gserviceaccount.com' - - 'dataproc-accounts.iam.gserviceaccount.com' - - 'gae-api-prod.google.com.iam.gserviceaccount.com' - - 'genomics-api.google.com.iam.gserviceaccount.com' - - 'containerregistry.iam.gserviceaccount.com' - - 'container-analysis.iam.gserviceaccount.com' - - 'cloudservices.gserviceaccount.com' - - 'stackdriver-service.iam.gserviceaccount.com' - - 'appspot.gserviceaccount.com' - - 'partnercontent.gserviceaccount.com' - - 'trifacta-gcloud-prod.iam.gserviceaccount.com' - - 'gcf-admin-robot.iam.gserviceaccount.com' - - 'compute-system.iam.gserviceaccount.com' - - 'gcp-sa-websecurityscanner.iam.gserviceaccount.com' - - 'storage-transfer-service.iam.gserviceaccount.com' - - 'firebase-sa-management.iam.gserviceaccount.com' - - 'firebase-rules.iam.gserviceaccount.com' - - 'gcp-sa-cloudbuild.iam.gserviceaccount.com' - - 'gcp-sa-automl.iam.gserviceaccount.com' - - 'gcp-sa-datalabeling.iam.gserviceaccount.com' - - 'gcp-sa-cloudscheduler.iam.gserviceaccount.com' - -# The types of service accounts that are allowed to be registered at -# /google/service_accounts endpoints -ALLOWED_USER_SERVICE_ACCOUNT_DOMAINS: - # compute engine default service account - - 'developer.gserviceaccount.com' - # app engine default service account - - 'appspot.gserviceaccount.com' - # user-managed service account - - 'iam.gserviceaccount.com' - -# Synapse integration and DREAM challenge mapping. Team is from Synapse, and group is -# providing the actual permission in Arborist. User will be added to the group for TTL -# seconds if the team matches. -DREAM_CHALLENGE_TEAM: 'DREAM' -DREAM_CHALLENGE_GROUP: 'DREAM' -SYNAPSE_URI: 'https://repo-prod.prod.sagebase.org/auth/v1' -SYNAPSE_JWKS_URI: -# deprecated, use the discovery_url in the OPENID_CONNECT block for the synapse client -SYNAPSE_DISCOVERY_URL: -SYNAPSE_AUTHZ_TTL: 86400 - -# Role caching for generating presigned urls if max role session increase is true -# then we can increase the amount of time that a session is valid for -MAX_ROLE_SESSION_INCREASE: false -ASSUME_ROLE_CACHE_SECONDS: 1800 - -# Optional user registration feature: Ask users to register (provide firstname/lastname/org/email) on login. -# If user registers, add them to configured Arborist group; idea is that the Arborist group -# will have access to download data. -REGISTER_USERS_ON: false -REGISTERED_USERS_GROUP: '' -# RAS refresh_tokens expire in 15 days -RAS_REFRESH_EXPIRATION: 1296000 -# List of JWT issuers from which Fence will accept GA4GH visas -GA4GH_VISA_ISSUER_ALLOWLIST: - - '{{BASE_URL}}' - - 'https://sts.nih.gov' - - 'https://stsstg.nih.gov' -# Number of projects that can be registered to a Google Service Accont -SERVICE_ACCOUNT_LIMIT: 6 - -# Global sync visas during login -# None(Default): Allow per client i.e. a fence client can pick whether or not to sync their visas during login with parse_visas param in /authorization endpoint -# True: Parse for all clients i.e. a fence client will always sync their visas during login -# False: Parse for no clients i.e. a fence client will not be able to sync visas during login even with parse_visas param -GLOBAL_PARSE_VISAS_ON_LOGIN: -# Settings for usersync with visas -USERSYNC: - sync_from_visas: false - # fallback to dbgap sftp when there are no valid visas for a user i.e. if they're expired or if they're malformed - fallback_to_dbgap_sftp: false - visa_types: - ras: ["https://ras.nih.gov/visas/v1", "https://ras.nih.gov/visas/v1.1"] -RAS_USERINFO_ENDPOINT: '/openid/connect/v1.1/userinfo' \ No newline at end of file diff --git a/helm/fence/fence-google-creds/fence_google_app_creds_secret.json b/helm/fence/fence-google-creds/fence_google_app_creds_secret.json deleted file mode 100644 index e69de29b..00000000 diff --git a/helm/fence/templates/_helpers.tpl b/helm/fence/templates/_helpers.tpl index 315d19b5..1eeaac06 100644 --- a/helm/fence/templates/_helpers.tpl +++ b/helm/fence/templates/_helpers.tpl @@ -69,6 +69,6 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} \ No newline at end of file diff --git a/helm/fence/templates/db-init.yaml b/helm/fence/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/fence/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/fence/templates/fence-config.yaml b/helm/fence/templates/fence-config.yaml index 355060f5..291a3802 100644 --- a/helm/fence/templates/fence-config.yaml +++ b/helm/fence/templates/fence-config.yaml @@ -4,8 +4,13 @@ metadata: name: fence-config stringData: fence-config.yaml: | + {{- $username := include "gen3.service-postgres" (dict "key" "username" "service" $.Chart.Name "context" $) }} + {{- $password := include "gen3.service-postgres" (dict "key" "password" "service" $.Chart.Name "context" $) }} + {{- $host := include "gen3.service-postgres" (dict "key" "host" "service" $.Chart.Name "context" $) }} + {{- $port := include "gen3.service-postgres" (dict "key" "port" "service" $.Chart.Name "context" $) }} + {{- $database := include "gen3.service-postgres" (dict "key" "database" "service" $.Chart.Name "context" $) }} BASE_URL: '{{ .Values.FENCE_CONFIG.BASE_URL }}' - DB: 'postgresql://{{ .Values.database.user }}:{{ include "fence.postgres.password" . }}@{{ .Values.database.host }}:{{ .Values.database.port }}/{{ .Values.database.dbname }}' + DB: 'postgresql://{{ $username }}:{{ $password }}@{{ $host }}:{{ $port }}/{{ $database }}' {{- with .Values.FENCE_CONFIG }} {{- toYaml . | nindent 4 }} {{ end }} diff --git a/helm/fence/templates/fence-creds.yaml b/helm/fence/templates/fence-creds.yaml index ccbffd91..75687b92 100644 --- a/helm/fence/templates/fence-creds.yaml +++ b/helm/fence/templates/fence-creds.yaml @@ -6,10 +6,10 @@ type: Opaque stringData: creds.json: |- { - "db_host": "{{ .Values.database.host }}", - "db_username": "{{ .Values.database.user }}", - "db_password": "{{ .Values.database.password }}", - "db_database": "{{ .Values.database.dbname }}", + "db_host": "{{ include "gen3.service-postgres" (dict "key" "host" "service" $.Chart.Name "context" $) }}", + "db_username": "{{include "gen3.service-postgres" (dict "key" "username" "service" $.Chart.Name "context" $) }}", + "db_password": "{{include "gen3.service-postgres" (dict "key" "password" "service" $.Chart.Name "context" $) }}", + "db_database": "{{ include "gen3.service-postgres" (dict "key" "database" "service" $.Chart.Name "context" $)}}", "hostname": "{{ .Values.hostname }}", "indexd_password": "", "google_client_secret": "YOUR.GOOGLE.SECRET", diff --git a/helm/fence/values.yaml b/helm/fence/values.yaml index 3a88a865..11a0865f 100644 --- a/helm/fence/values.yaml +++ b/helm/fence/values.yaml @@ -1,6 +1,23 @@ # Default values for fence. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: fence + username: fence + port: 5432 + # If left empty password will be auto-generated + password: replicaCount: 1 @@ -16,18 +33,7 @@ fullnameOverride: "" hostname: localhost -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - # Actual fence db creds - user: postgres - password: postgres - dbname: fence serviceAccount: # Specifies whether a service account should be created diff --git a/helm/indexd/Chart.lock b/helm/indexd/Chart.lock new file mode 100644 index 00000000..9edc4c55 --- /dev/null +++ b/helm/indexd/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:38.85688-05:00" diff --git a/helm/indexd/Chart.yaml b/helm/indexd/Chart.yaml index 801593ae..a80853b8 100644 --- a/helm/indexd/Chart.yaml +++ b/helm/indexd/Chart.yaml @@ -21,4 +21,11 @@ version: 0.0.1 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2022.10" \ No newline at end of file +appVersion: "2022.10" + + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/indexd/templates/_helpers.tpl b/helm/indexd/templates/_helpers.tpl index ccb8ed11..dcb848be 100644 --- a/helm/indexd/templates/_helpers.tpl +++ b/helm/indexd/templates/_helpers.tpl @@ -70,7 +70,7 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} diff --git a/helm/indexd/templates/db-init.yaml b/helm/indexd/templates/db-init.yaml new file mode 100644 index 00000000..7dc1039e --- /dev/null +++ b/helm/indexd/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{ include "common.db-secret" . }} \ No newline at end of file diff --git a/helm/indexd/templates/indexd-secret.yaml b/helm/indexd/templates/indexd-secret.yaml index bc2adfe3..b243edbd 100644 --- a/helm/indexd/templates/indexd-secret.yaml +++ b/helm/indexd/templates/indexd-secret.yaml @@ -20,10 +20,10 @@ type: Opaque stringData: creds.json: |- { - "db_host": {{ .Values.database.host | quote }}, - "db_username": {{ .Values.database.user | quote}}, - "db_password": {{ include "indexd.postgres.password" . | quote }}, - "db_database": {{ .Values.database.dbname | quote }}, + "db_host": "{{ include "gen3.service-postgres" (dict "key" "host" "service" $.Chart.Name "context" $) }}", + "db_username": "{{include "gen3.service-postgres" (dict "key" "username" "service" $.Chart.Name "context" $) }}", + "db_password": "{{include "gen3.service-postgres" (dict "key" "password" "service" $.Chart.Name "context" $) }}", + "db_database": "{{ include "gen3.service-postgres" (dict "key" "database" "service" $.Chart.Name "context" $)}}", "user_db": { "fence": {{ include "indexd-fence-creds" . | quote }}, "gdcapi": {{ include "indexd-sheepdog-creds" . | quote }}, diff --git a/helm/indexd/values.yaml b/helm/indexd/values.yaml index aa60904c..b50077d2 100644 --- a/helm/indexd/values.yaml +++ b/helm/indexd/values.yaml @@ -1,8 +1,26 @@ - # Default values for indexd. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: indexd + username: indexd + host: + port: 5432 + # If left empty password will be auto-generated + password: + replicaCount: 1 image: @@ -95,19 +113,6 @@ env: - name: "GEN3_DEBUG" value: "false" -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - - # Actual fence db creds - user: postgres - password: postgres - dbname: indexd - secrets: userdb: fence: diff --git a/helm/manifestservice/templates/NOTES.txt b/helm/manifestservice/templates/NOTES.txt index fa4abb0a..70b82c54 100644 --- a/helm/manifestservice/templates/NOTES.txt +++ b/helm/manifestservice/templates/NOTES.txt @@ -1,22 +1 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "manifestservice.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "manifestservice.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "manifestservice.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "manifestservice.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} +{{ .Chart.Name }} has been deployed \ No newline at end of file diff --git a/helm/manifestservice/templates/ingress.yaml b/helm/manifestservice/templates/ingress.yaml deleted file mode 100644 index 68201246..00000000 --- a/helm/manifestservice/templates/ingress.yaml +++ /dev/null @@ -1,61 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "manifestservice.fullname" . -}} -{{- $svcPort := .Values.service.port -}} -{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} - {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} - {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} - {{- end }} -{{- end }} -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - {{- include "manifestservice.labels" . | nindent 4 }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ .Values.ingress.className }} - {{- end }} - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} - http: - paths: - {{- range .paths }} - - path: {{ .path }} - {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: {{ .pathType }} - {{- end }} - backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} - service: - name: {{ $fullName }} - port: - number: {{ $svcPort }} - {{- else }} - serviceName: {{ $fullName }} - servicePort: {{ $svcPort }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} diff --git a/helm/manifestservice/values.yaml b/helm/manifestservice/values.yaml index c6122c61..333b82a7 100644 --- a/helm/manifestservice/values.yaml +++ b/helm/manifestservice/values.yaml @@ -18,22 +18,6 @@ serviceAccount: annotations: {} name: "" -ingress: - enabled: false - className: "" - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - autoscaling: enabled: false @@ -81,7 +65,6 @@ volumes: terminationGracePeriodSeconds: 50 - env: - name: REQUESTS_CA_BUNDLE value: /etc/ssl/certs/ca-certificates.crt diff --git a/helm/metadata/Chart.lock b/helm/metadata/Chart.lock new file mode 100644 index 00000000..ef02940e --- /dev/null +++ b/helm/metadata/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:40.594362-05:00" diff --git a/helm/metadata/Chart.yaml b/helm/metadata/Chart.yaml index 71f5c7d0..52ddd4a8 100644 --- a/helm/metadata/Chart.yaml +++ b/helm/metadata/Chart.yaml @@ -22,3 +22,9 @@ version: 0.0.1 # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "2022.10" + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/metadata/templates/_helpers.tpl b/helm/metadata/templates/_helpers.tpl index 817d13b2..8e99ad6d 100644 --- a/helm/metadata/templates/_helpers.tpl +++ b/helm/metadata/templates/_helpers.tpl @@ -71,7 +71,7 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} diff --git a/helm/metadata/templates/db-init.yaml b/helm/metadata/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/metadata/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/metadata/templates/secrets.yaml b/helm/metadata/templates/secrets.yaml index 24cd9a30..fcde0e48 100644 --- a/helm/metadata/templates/secrets.yaml +++ b/helm/metadata/templates/secrets.yaml @@ -7,15 +7,15 @@ stringData: base64Authz.txt: {{ $randomPass | b64enc | quote }} dbcreds.json: | { - "db_host": {{ .Values.database.host | quote }}, - "db_username": {{ .Values.database.user | quote}}, + "db_host": {{ .Values.postgres.host | quote }}, + "db_username": {{ .Values.postgres.user | quote}}, "db_password": {{ include "metadata.postgres.password" . | quote }}, - "db_database": {{ .Values.database.dbname | quote }} + "db_database": {{ .Values.postgres.dbname | quote }} } metadata.env: | DEBUG={{ .Values.debug}} - DB_HOST={{ .Values.database.host }} - DB_USER={{ .Values.database.user }} + DB_HOST={{ .Values.postgres.host }} + DB_USER={{ .Values.postgres.user }} DB_PASSWORD={{ include "metadata.postgres.password" . }} - DB_DATABASE={{ .Values.database.dbname }} + DB_DATABASE={{ .Values.postgres.dbname }} ADMIN_LOGINS={{ $randomPass }} \ No newline at end of file diff --git a/helm/metadata/values.yaml b/helm/metadata/values.yaml index 336cedc7..09169334 100644 --- a/helm/metadata/values.yaml +++ b/helm/metadata/values.yaml @@ -1,7 +1,25 @@ # Default values for metadata. # This is a YAML-formatted file. # Declare variables to be passed into your templates. - +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + database: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: metadata + username: metadata + host: + port: 5432 + # If left empty password will be auto-generated + password: # Deployment @@ -131,17 +149,3 @@ service: port: 80 targetPort: 80 name: http - -#Configmap -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - - # Actual fence db creds - user: postgres - password: postgres - dbname: metadata \ No newline at end of file diff --git a/helm/peregrine/Chart.lock b/helm/peregrine/Chart.lock new file mode 100644 index 00000000..ee2e57ed --- /dev/null +++ b/helm/peregrine/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:12:56.035146-05:00" diff --git a/helm/peregrine/Chart.yaml b/helm/peregrine/Chart.yaml index 452e35cb..6a035831 100644 --- a/helm/peregrine/Chart.yaml +++ b/helm/peregrine/Chart.yaml @@ -22,3 +22,10 @@ version: 0.0.1 # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "2022.10" + + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/peregrine/peregrine-secret/wsgi.py b/helm/peregrine/peregrine-secret/wsgi.py index aee30ece..0defccd4 100644 --- a/helm/peregrine/peregrine-secret/wsgi.py +++ b/helm/peregrine/peregrine-secret/wsgi.py @@ -5,82 +5,83 @@ from peregrine.api import app, app_init from os import environ -import config_helper +# import config_helper APP_NAME='peregrine' -def load_json(file_name): - return config_helper.load_json(file_name, APP_NAME) +# def load_json(file_name): +# return config_helper.load_json(file_name, APP_NAME) -conf_data = load_json('creds.json') +# conf_data = load_json('creds.json') config = app.config -config["AUTH"] = 'https://auth.service.consul:5000/v3/' -config["AUTH_ADMIN_CREDS"] = None -config["INTERNAL_AUTH"] = None +# config["AUTH"] = 'https://auth.service.consul:5000/v3/' +# config["AUTH_ADMIN_CREDS"] = None +# config["INTERNAL_AUTH"] = None # ARBORIST deprecated, replaced by ARBORIST_URL # ARBORIST_URL is initialized in app_init() directly -config["ARBORIST"] = "http://arborist-service/" +# config["ARBORIST"] = "http://arborist-service/" -# Signpost: deprecated, replaced by index client. -config['SIGNPOST'] = { - 'host': environ.get('SIGNPOST_HOST') or 'http://indexd-service', - 'version': 'v0', - 'auth': ('gdcapi', conf_data.get( 'indexd_password', '{{indexd_password}}')), -} config['INDEX_CLIENT'] = { 'host': environ.get('INDEX_CLIENT_HOST') or 'http://indexd-service', 'version': 'v0', - 'auth': ('gdcapi', conf_data.get( 'indexd_password', '{{indexd_password}}')), + # 'auth': ('gdcapi', environ.get( "PGHOST") ), } -config["FAKE_AUTH"] = False +# config["FAKE_AUTH"] = environ.get( "FAKE_AUTH", False) config["PSQLGRAPH"] = { - 'host': conf_data.get( 'db_host', '{{db_host}}' ), - 'user': conf_data.get( 'db_username', '{{db_username}}' ), - 'password': conf_data.get( 'db_password', '{{db_password}}' ), - 'database': conf_data.get( 'db_database', '{{db_database}}' ), + 'host': environ.get( "PGHOST"), + 'user': environ.get( "PGUSER"), + 'password': environ.get( "PGPASSWORD"), + 'database': environ.get( "PGDB"), } -config['HMAC_ENCRYPTION_KEY'] = conf_data.get( 'hmac_key', '{{hmac_key}}' ) -config['FLASK_SECRET_KEY'] = conf_data.get( 'gdcapi_secret_key', '{{gdcapi_secret_key}}' ) -config['PSQL_USER_DB_CONNECTION'] = 'postgresql://%s:%s@%s:5432/%s' % tuple([ conf_data.get(key, key) for key in ['fence_username', 'fence_password', 'fence_host', 'fence_database']]) +config['HMAC_ENCRYPTION_KEY'] = environ.get( "HMAC_ENCRYPTION_KEY") +config['FLASK_SECRET_KEY'] = environ.get( "FLASK_SECRET_KEY") + +fence_username = environ.get( "FENCE_DB_USER") +fence_password = environ.get( "FENCE_DB_PASS") +fence_host = environ.get( "FENCE_DB_HOST") +fence_database = environ.get( "FENCE_DB_DBNAME") +config['PSQL_USER_DB_CONNECTION'] = 'postgresql://%s:%s@%s:5432/%s' % (fence_username, fence_password, fence_host, fence_database) config['DICTIONARY_URL'] = environ.get('DICTIONARY_URL','https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json') -config['SUBMISSION'] = { - 'bucket': conf_data.get( 'bagit_bucket', '{{bagit_bucket}}' ) -} +# config['SUBMISSION'] = { +# 'bucket': conf_data.get( 'bagit_bucket', '{{bagit_bucket}}' ) +# } -config['STORAGE'] = { - "s3": - { - "access_key": conf_data.get( 's3_access', '{{s3_access}}' ), - 'secret_key': conf_data.get( 's3_secret', '{{s3_secret}}' ) - } -} +# config['STORAGE'] = { +# "s3": +# { +# "access_key": conf_data.get( 's3_access', '{{s3_access}}' ), +# 'secret_key': conf_data.get( 's3_secret', '{{s3_secret}}' ) +# } +# } -config['OIDC_ISSUER'] = 'https://%s/user' % conf_data['hostname'] +hostname = environ.get("CONF_HOSTNAME") +config['OIDC_ISSUER'] = 'https://%s/user' % hostname -config['OAUTH2'] = { - 'client_id': conf_data.get('oauth2_client_id', '{{oauth2_client_id}}'), - 'client_secret': conf_data.get('oauth2_client_secret', '{{oauth2_client_secret}}'), - 'api_base_url': 'https://%s/user/' % conf_data['hostname'], - 'authorize_url': 'https://%s/user/oauth2/authorize' % conf_data['hostname'], - 'access_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], - 'refresh_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], - 'client_kwargs': { - 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'], - 'scope': 'openid data user', - }, - # deprecated key values, should be removed after all commons use new oidc - 'internal_oauth_provider': 'http://fence-service/oauth2/', - 'oauth_provider': 'https://%s/user/oauth2/' % conf_data['hostname'], - 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'] -} +# config['OAUTH2'] = { +# 'client_id': conf_data.get('oauth2_client_id', '{{oauth2_client_id}}'), +# 'client_secret': conf_data.get('oauth2_client_secret', '{{oauth2_client_secret}}'), +# 'api_base_url': 'https://%s/user/' % conf_data['hostname'], +# 'authorize_url': 'https://%s/user/oauth2/authorize' % hostname, +# 'access_token_url': 'https://%s/user/oauth2/token' % hostname, +# 'refresh_token_url': 'https://%s/user/oauth2/token' % hostname, +# 'client_kwargs': { +# 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % hostname, +# 'scope': 'openid data user', +# }, +# # deprecated key values, should be removed after all commons use new oidc +# 'internal_oauth_provider': 'http://fence-service/oauth2/', +# 'oauth_provider': 'https://%s/user/oauth2/' % hostname, +# 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % hostname +# } config['USER_API'] = environ.get('FENCE_URL') or 'http://fence-service/' # use the USER_API URL instead of the public issuer URL to accquire JWT keys config['FORCE_ISSUER'] = True +print(config) app_init(app) application = app application.debug = (environ.get('GEN3_DEBUG') == "True") diff --git a/helm/peregrine/templates/_helpers.tpl b/helm/peregrine/templates/_helpers.tpl index 144b0965..1f786d38 100644 --- a/helm/peregrine/templates/_helpers.tpl +++ b/helm/peregrine/templates/_helpers.tpl @@ -66,11 +66,12 @@ Create the name of the service account to use Postgres Password lookup */}} {{- define "peregrine.postgres.password" -}} -{{- $localpass := (lookup "v1" "Secret" "postgres" "postgres-postgresql" ) -}} +{{- $masterpass := (lookup "v1" "Secret" "postgres" "postgres-postgresql" ) -}} +# {{- $localpass := (lookup "v1" "Secret" .Release.Namespace "{{ .Chart.Name }}-dbcreds" ) -}} {{- if $localpass }} -{{- default (index $localpass.data "postgres-password" | b64dec) }} +{{- default (index $masterpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} diff --git a/helm/peregrine/templates/db-init.yaml b/helm/peregrine/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/peregrine/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/peregrine/templates/deployment.yaml b/helm/peregrine/templates/deployment.yaml index b1c41b78..a52790da 100644 --- a/helm/peregrine/templates/deployment.yaml +++ b/helm/peregrine/templates/deployment.yaml @@ -38,9 +38,101 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - {{- toYaml .Values.env | nindent 12 }} + - name: FENCE_DB_USER + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: username + optional: false + - name: FENCE_DB_PASS + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: password + optional: false + - name: FENCE_DB_HOST + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: host + optional: false + - name: FENCE_DB_DBNAME + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: database + optional: false + - name: FLASK_SECRET_KEY + value: "TODO: FIX THIS!!!" + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: host + optional: false + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + - name: PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + - name: GEN3_UWSGI_TIMEOUT + value: "600" + - name: DICTIONARY_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: dictionary_url + optional: true + - name: PUBLIC_DATASETS + valueFrom: + configMapKeyRef: + name: manifest-global + key: public_datasets + optional: true + - name: INDEX_CLIENT_HOST + valueFrom: + configMapKeyRef: + name: manifest-global + key: indexd_url + optional: true + - name: GRAPHQL_TIMEOUT + valueFrom: + configMapKeyRef: + name: manifest-peregrine + key: peregrine_timeout + optional: true + - name: FENCE_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: fence_url + optional: true + - name: ARBORIST_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: arborist_url + optional: true + - name: GEN3_SIDECAR + value: "False" volumeMounts: - {{- toYaml .Values.volumeMounts | nindent 12 }} + - name: "config-volume" + readOnly: true + mountPath: "/var/www/peregrine/wsgi.py" + subPath: "wsgi.py" ports: - name: http containerPort: 80 diff --git a/helm/peregrine/templates/peregrine-secret.yaml b/helm/peregrine/templates/peregrine-secret.yaml index 43cc3ff9..fa24590d 100644 --- a/helm/peregrine/templates/peregrine-secret.yaml +++ b/helm/peregrine/templates/peregrine-secret.yaml @@ -4,25 +4,4 @@ metadata: name: peregrine-secret type: Opaque data: -{{ (.Files.Glob "peregrine-secret/*").AsSecrets | indent 2 }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: peregrine-creds -type: Opaque -stringData: - # TODO: FIX FENCE_PASSWORD - creds.json: |- - { - "fence_host": {{ .Values.database.host | quote }}, - "fence_username": {{ default "postgres" .Values.secrets.fence.db.username | quote }}, - "fence_password": {{ include "peregrine.postgres.password" . | quote }}, - "fence_database": {{ default "fence" .Values.secrets.fence.db.database | quote }}, - "db_host": {{ .Values.database.host | quote }}, - "db_username": {{ .Values.database.user | quote}}, - "db_password": {{ include "peregrine.postgres.password" . | quote }}, - "db_database": {{ .Values.database.dbname | quote }}, - "gdcapi_secret_key": {{ default (randAlphaNum 50) .Values.secrets.gdcapi_secret_key | quote }}, - "hostname": {{ default "localhost" .Values.hostname | quote}} - } +{{ (.Files.Glob "peregrine-secret/*").AsSecrets | indent 2 }} \ No newline at end of file diff --git a/helm/peregrine/values.yaml b/helm/peregrine/values.yaml index 54fdc682..da48976a 100644 --- a/helm/peregrine/values.yaml +++ b/helm/peregrine/values.yaml @@ -1,7 +1,24 @@ # Default values for peregrine. # This is a YAML-formatted file. -# Declare variables to be passed into your templates. - +global: + postgres: + master: + host: postgres-postgresql.postgres.svc.cluster.local + username: postgres + port: 5432 + # If password is left empty the lookup function will look for postgres master password + password: + +db_create: true +postgres: + host: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: peregrine + username: peregrine + port: 5432 + # If left empty password will be auto-generated + password: + replicaCount: 1 image: @@ -68,57 +85,8 @@ affinity: {} env: -- name: GEN3_UWSGI_TIMEOUT - value: "600" -- name: DICTIONARY_URL - valueFrom: - configMapKeyRef: - name: manifest-global - key: dictionary_url - optional: true -#needed to be adjusted to use the gen3 umbrella chart or local var ^ -#adding a var in helpers.tpl for later- Elise -- name: PUBLIC_DATASETS - valueFrom: - configMapKeyRef: - name: manifest-global - key: public_datasets - optional: true -# Signpost is deprecated; replace this w INDEX_CLIENT_HOST block -- name: SIGNPOST_HOST - valueFrom: - configMapKeyRef: - name: manifest-global - key: indexd_url - optional: true -- name: INDEX_CLIENT_HOST - valueFrom: - configMapKeyRef: - name: manifest-global - key: indexd_url - optional: true -- name: GRAPHQL_TIMEOUT - valueFrom: - configMapKeyRef: - name: manifest-peregrine - key: peregrine_timeout - optional: true -- name: FENCE_URL - valueFrom: - configMapKeyRef: - name: manifest-global - key: fence_url - optional: true -- name: ARBORIST_URL - valueFrom: - configMapKeyRef: - name: manifest-global - key: arborist_url - optional: true -- name: GEN3_DEBUG - value: "False" -- name: GEN3_SIDECAR - value: "False" + + volumes: - name: shared-data @@ -126,46 +94,7 @@ volumes: - name: config-volume secret: secretName: "peregrine-secret" -- name: creds-volume - secret: - secretName: "peregrine-creds" -- name: config-helper - configMap: - name: config-helper volumeMounts: -- name: "shared-data" - mountPath: "/var/run/gen3" -- name: "config-volume" - readOnly: true - mountPath: "/var/www/peregrine/wsgi.py" - subPath: "wsgi.py" -- name: "creds-volume" - readOnly: true - mountPath: "/var/www/peregrine/creds.json" - subPath: creds.json -- name: "config-volume" - readOnly: true - mountPath: "/var/www/peregrine/config_helper.py" - subPath: config_helper.py - -secrets: - fence: - db: - host: - user: - pass: - - -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - # Credentials used to initialize fence db if it doesn't exist. - master_user: postgres - master_pass: postgres - # Actual fence db creds - user: postgres - password: postgres - dbname: peregrine \ No newline at end of file diff --git a/helm/pidgin/Chart.lock b/helm/pidgin/Chart.lock new file mode 100644 index 00000000..274a5f2b --- /dev/null +++ b/helm/pidgin/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:43.297641-05:00" diff --git a/helm/pidgin/Chart.yaml b/helm/pidgin/Chart.yaml index 47817da5..53cfa799 100644 --- a/helm/pidgin/Chart.yaml +++ b/helm/pidgin/Chart.yaml @@ -22,3 +22,10 @@ version: 0.0.1 # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "2022.10" + + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/pidgin/templates/db-init.yaml b/helm/pidgin/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/pidgin/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/pidgin/values.yaml b/helm/pidgin/values.yaml index e83442b8..9144a563 100644 --- a/helm/pidgin/values.yaml +++ b/helm/pidgin/values.yaml @@ -1,7 +1,23 @@ # Default values for pidgin. # This is a YAML-formatted file. # Declare variables to be passed into your templates. - +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: pidgin + username: pidgin + port: 5432 + # If left empty password will be auto-generated + password: # Deployment diff --git a/helm/requestor/Chart.lock b/helm/requestor/Chart.lock new file mode 100644 index 00000000..2d4691a8 --- /dev/null +++ b/helm/requestor/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 0.0.1 +digest: sha256:9447ea9a4ddee41221215f9d511d904829f457523bc78ddaa817c161e934f27f +generated: "2022-10-20T21:34:44.799398-05:00" diff --git a/helm/requestor/Chart.yaml b/helm/requestor/Chart.yaml index 1ef212f6..77d1dee4 100644 --- a/helm/requestor/Chart.yaml +++ b/helm/requestor/Chart.yaml @@ -22,3 +22,10 @@ version: 0.0.1 # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "2022.10" + + +dependencies: +- name: common + version: 0.0.1 + repository: file://../common + condition: db_creation.enabled \ No newline at end of file diff --git a/helm/requestor/templates/db-init.yaml b/helm/requestor/templates/db-init.yaml new file mode 100644 index 00000000..e53cb144 --- /dev/null +++ b/helm/requestor/templates/db-init.yaml @@ -0,0 +1,3 @@ +{{- include "common.db-setup-job" . }} +--- +{{- include "common.db-secret" . }} diff --git a/helm/requestor/values.yaml b/helm/requestor/values.yaml index 4ff5db46..0c3c4af3 100644 --- a/helm/requestor/values.yaml +++ b/helm/requestor/values.yaml @@ -1,7 +1,23 @@ # Default values for requestor. # This is a YAML-formatted file. # Declare variables to be passed into your templates. - +global: + # Default values are for postgres deployed as a helm chart + postgres: + host: postgres-postgresql.postgres.svc.cluster.local + master: + username: postgres + password: + port: 5432 + +db_create: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: requestor + username: requestor + port: 5432 + # If left empty password will be auto-generated + password: # Deployment @@ -108,5 +124,5 @@ service: secrets: host: postgres-postgresql.postgres.svc.cluster.local user: postgres - password: postgres + password: database: requestor \ No newline at end of file diff --git a/helm/revproxy/templates/ingress.yaml b/helm/revproxy/templates/ingress.yaml index 3f06f51d..b7850dba 100644 --- a/helm/revproxy/templates/ingress.yaml +++ b/helm/revproxy/templates/ingress.yaml @@ -4,7 +4,7 @@ metadata: name: revproxy spec: rules: - - host: localhost + - host: {{ default .Values.global.hostname .Values.hostname }} http: paths: - path: / diff --git a/helm/sheepdog/Chart.lock b/helm/sheepdog/Chart.lock index a3070d8c..71060338 100644 --- a/helm/sheepdog/Chart.lock +++ b/helm/sheepdog/Chart.lock @@ -1,6 +1,6 @@ dependencies: -- name: db-setup - repository: file://../db-setup +- name: common + repository: file://../common version: 0.0.1 -digest: sha256:049df0e16d26bc9a96ed517d3a5be85e8f261a20631b0bf7398e6708fc904692 -generated: "2022-10-18T18:04:31.969906-05:00" +digest: sha256:a25c79b74ec6d89ca5c732e4222f8726ed02aa6a4a21f376afc499e53696c9b5 +generated: "2022-10-20T21:34:46.434949-05:00" diff --git a/helm/sheepdog/Chart.yaml b/helm/sheepdog/Chart.yaml index 1bb5bea2..744f45d3 100644 --- a/helm/sheepdog/Chart.yaml +++ b/helm/sheepdog/Chart.yaml @@ -24,7 +24,6 @@ version: 0.0.1 appVersion: "2022.10" dependencies: - - name: db-setup + - name: common version: 0.0.1 - repository: file://../db-setup - condition: db_creation.enabled + repository: file://../common \ No newline at end of file diff --git a/helm/sheepdog/sheepdog-secret/wsgi.py b/helm/sheepdog/sheepdog-secret/wsgi.py index 6d00d0c8..17ce0c00 100644 --- a/helm/sheepdog/sheepdog-secret/wsgi.py +++ b/helm/sheepdog/sheepdog-secret/wsgi.py @@ -5,68 +5,85 @@ from sheepdog.api import app, app_init from os import environ -import config_helper +# import config_helper APP_NAME='sheepdog' -def load_json(file_name): - return config_helper.load_json(file_name, APP_NAME) +# def load_json(file_name): +# return config_helper.load_json(file_name, APP_NAME) -conf_data = load_json('creds.json') +# conf_data = load_json('creds.json') config = app.config -config["AUTH"] = 'https://auth.service.consul:5000/v3/' -config["AUTH_ADMIN_CREDS"] = None -config["INTERNAL_AUTH"] = None +# config["AUTH"] = 'https://auth.service.consul:5000/v3/' +# config["AUTH_ADMIN_CREDS"] = None +# config["INTERNAL_AUTH"] = None # ARBORIST deprecated, replaced by ARBORIST_URL # ARBORIST_URL is initialized in app_init() directly -config["ARBORIST"] = "http://arborist-service/" +# config["ARBORIST"] = "http://arborist-service/" -# Signpost: deprecated, replaced by index client. -config['SIGNPOST'] = { - 'host': environ.get('SIGNPOST_HOST') or 'http://indexd-service', - 'version': 'v0', - 'auth': ('gdcapi', environ.get('INDEXD_PASS')), -} config['INDEX_CLIENT'] = { 'host': environ.get('INDEX_CLIENT_HOST') or 'http://indexd-service', 'version': 'v0', - 'auth': ('gdcapi', environ.get('INDEXD_PASS')), + 'auth': (environ.get( "INDEXD_USER", 'gdcapi'), environ.get( "INDEXD_PASS") ), } -config["FAKE_AUTH"] = False + config["PSQLGRAPH"] = { - 'host': conf_data['db_host'], - 'user': conf_data['db_username'], - 'password': conf_data['db_password'], - 'database': conf_data['db_database'], + 'host': environ.get( "PGHOST"), + 'user': environ.get( "PGUSER"), + 'password': environ.get( "PGPASSWORD"), + 'database': environ.get( "PGDB"), } -config['HMAC_ENCRYPTION_KEY'] = conf_data.get('hmac_key', '{{hmac_key}}') -config['FLASK_SECRET_KEY'] = conf_data.get('gdcapi_secret_key', '{{gdcapi_secret_key}}') -config['PSQL_USER_DB_CONNECTION'] = 'postgresql://%s:%s@%s:5432/%s' % tuple([ conf_data.get(key, key) for key in ['fence_username', 'fence_password', 'fence_host', 'fence_database']]) -config['OIDC_ISSUER'] = 'https://%s/user' % conf_data['hostname'] +config['HMAC_ENCRYPTION_KEY'] = environ.get( "HMAC_ENCRYPTION_KEY") +config['FLASK_SECRET_KEY'] = environ.get( "FLASK_SECRET_KEY") + +fence_username = environ.get( "FENCE_DB_USER") +fence_password = environ.get( "FENCE_DB_PASS") +fence_host = environ.get( "FENCE_DB_HOST") +fence_database = environ.get( "FENCE_DB_DBNAME") +config['PSQL_USER_DB_CONNECTION'] = 'postgresql://%s:%s@%s:5432/%s' % (fence_username, fence_password, fence_host, fence_database) + +config['DICTIONARY_URL'] = environ.get('DICTIONARY_URL','https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json') + +# config['SUBMISSION'] = { +# 'bucket': conf_data.get( 'bagit_bucket', '{{bagit_bucket}}' ) +# } + +# config['STORAGE'] = { +# "s3": +# { +# "access_key": conf_data.get( 's3_access', '{{s3_access}}' ), +# 'secret_key': conf_data.get( 's3_secret', '{{s3_secret}}' ) +# } +# } + +# NOT BEING USED? +hostname = environ.get("CONF_HOSTNAME", "localhost") +config['OIDC_ISSUER'] = 'https://%s/user' % hostname +# TODO: REMOVE THIS??? config['OAUTH2'] = { - 'client_id': conf_data.get('oauth2_client_id', '{{oauth2_client_id}}'), - 'client_secret': conf_data.get('oauth2_client_secret', '{{oauth2_client_secret}}'), - 'api_base_url': 'https://%s/user/' % conf_data['hostname'], - 'authorize_url': 'https://%s/user/oauth2/authorize' % conf_data['hostname'], - 'access_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], - 'refresh_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], + 'client_id': "conf_data.get('oauth2_client_id', '{{oauth2_client_id}}')", + 'client_secret': "conf_data.get('oauth2_client_secret', '{{oauth2_client_secret}}')", + 'api_base_url': 'https://%s/user/' % hostname, + 'authorize_url': 'https://%s/user/oauth2/authorize' % hostname, + 'access_token_url': 'https://%s/user/oauth2/token' % hostname, + 'refresh_token_url': 'https://%s/user/oauth2/token' % hostname, 'client_kwargs': { - 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'], + 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % hostname, 'scope': 'openid data user', }, # deprecated key values, should be removed after all commons use new oidc 'internal_oauth_provider': 'http://fence-service/oauth2/', - 'oauth_provider': 'https://%s/user/oauth2/' % conf_data['hostname'], - 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'] + 'oauth_provider': 'https://%s/user/oauth2/' % hostname, + 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % hostname } + config['USER_API'] = environ.get('FENCE_URL') or 'http://fence-service/' # use the USER_API URL instead of the public issuer URL to accquire JWT keys -config['FORCE_ISSUER'] = True -config['DICTIONARY_URL'] = environ.get('DICTIONARY_URL','https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json') - +# config['FORCE_ISSUER'] = True +print(config) app_init(app) application = app -application.debug = (environ.get('GEN3_DEBUG') == "True") \ No newline at end of file +application.debug = (environ.get('GEN3_DEBUG') == "True") diff --git a/helm/sheepdog/sheepdog-secret/wsgi_copy.py b/helm/sheepdog/sheepdog-secret/wsgi_copy.py new file mode 100644 index 00000000..6d00d0c8 --- /dev/null +++ b/helm/sheepdog/sheepdog-secret/wsgi_copy.py @@ -0,0 +1,72 @@ +##################################################### +# DO NOT CHANGE THIS FILE # +# config updates should be done in the service code # +##################################################### + +from sheepdog.api import app, app_init +from os import environ +import config_helper + +APP_NAME='sheepdog' +def load_json(file_name): + return config_helper.load_json(file_name, APP_NAME) + +conf_data = load_json('creds.json') +config = app.config + +config["AUTH"] = 'https://auth.service.consul:5000/v3/' +config["AUTH_ADMIN_CREDS"] = None +config["INTERNAL_AUTH"] = None + +# ARBORIST deprecated, replaced by ARBORIST_URL +# ARBORIST_URL is initialized in app_init() directly +config["ARBORIST"] = "http://arborist-service/" + +# Signpost: deprecated, replaced by index client. +config['SIGNPOST'] = { + 'host': environ.get('SIGNPOST_HOST') or 'http://indexd-service', + 'version': 'v0', + 'auth': ('gdcapi', environ.get('INDEXD_PASS')), +} +config['INDEX_CLIENT'] = { + 'host': environ.get('INDEX_CLIENT_HOST') or 'http://indexd-service', + 'version': 'v0', + 'auth': ('gdcapi', environ.get('INDEXD_PASS')), +} +config["FAKE_AUTH"] = False +config["PSQLGRAPH"] = { + 'host': conf_data['db_host'], + 'user': conf_data['db_username'], + 'password': conf_data['db_password'], + 'database': conf_data['db_database'], +} + +config['HMAC_ENCRYPTION_KEY'] = conf_data.get('hmac_key', '{{hmac_key}}') +config['FLASK_SECRET_KEY'] = conf_data.get('gdcapi_secret_key', '{{gdcapi_secret_key}}') +config['PSQL_USER_DB_CONNECTION'] = 'postgresql://%s:%s@%s:5432/%s' % tuple([ conf_data.get(key, key) for key in ['fence_username', 'fence_password', 'fence_host', 'fence_database']]) +config['OIDC_ISSUER'] = 'https://%s/user' % conf_data['hostname'] + +config['OAUTH2'] = { + 'client_id': conf_data.get('oauth2_client_id', '{{oauth2_client_id}}'), + 'client_secret': conf_data.get('oauth2_client_secret', '{{oauth2_client_secret}}'), + 'api_base_url': 'https://%s/user/' % conf_data['hostname'], + 'authorize_url': 'https://%s/user/oauth2/authorize' % conf_data['hostname'], + 'access_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], + 'refresh_token_url': 'https://%s/user/oauth2/token' % conf_data['hostname'], + 'client_kwargs': { + 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'], + 'scope': 'openid data user', + }, + # deprecated key values, should be removed after all commons use new oidc + 'internal_oauth_provider': 'http://fence-service/oauth2/', + 'oauth_provider': 'https://%s/user/oauth2/' % conf_data['hostname'], + 'redirect_uri': 'https://%s/api/v0/oauth2/authorize' % conf_data['hostname'] +} +config['USER_API'] = environ.get('FENCE_URL') or 'http://fence-service/' +# use the USER_API URL instead of the public issuer URL to accquire JWT keys +config['FORCE_ISSUER'] = True +config['DICTIONARY_URL'] = environ.get('DICTIONARY_URL','https://s3.amazonaws.com/dictionary-artifacts/datadictionary/develop/schema.json') + +app_init(app) +application = app +application.debug = (environ.get('GEN3_DEBUG') == "True") \ No newline at end of file diff --git a/helm/sheepdog/templates/db-init.yaml b/helm/sheepdog/templates/db-init.yaml index efb72198..e53cb144 100644 --- a/helm/sheepdog/templates/db-init.yaml +++ b/helm/sheepdog/templates/db-init.yaml @@ -1,3 +1,3 @@ -{{- include "db-setup.setup-job" . }} +{{- include "common.db-setup-job" . }} --- -{{ include "db-setup.secret" . -}} \ No newline at end of file +{{- include "common.db-secret" . }} diff --git a/helm/sheepdog/templates/deployment.yaml b/helm/sheepdog/templates/deployment.yaml index 6cdd6030..095fb200 100644 --- a/helm/sheepdog/templates/deployment.yaml +++ b/helm/sheepdog/templates/deployment.yaml @@ -72,6 +72,74 @@ spec: # - "-c" # - "sleep infinity" env: + - name: FENCE_DB_USER + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: username + optional: false + - name: FENCE_DB_PASS + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: password + optional: false + - name: FENCE_DB_HOST + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: host + optional: false + - name: FENCE_DB_DBNAME + valueFrom: + secretKeyRef: + name: fence-dbcreds + key: database + optional: false + - name: FLASK_SECRET_KEY + value: "TODO: FIX THIS!!!" + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: host + optional: false + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + - name: PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + - name: PUBLIC_DATASETS + valueFrom: + configMapKeyRef: + name: manifest-global + key: public_datasets + optional: true + # - name: INDEX_CLIENT_HOST + # valueFrom: + # configMapKeyRef: + # name: manifest-global + # key: indexd_url + # optional: true + - name: FENCE_URL + valueFrom: + configMapKeyRef: + name: manifest-global + key: fence_url + optional: true - name: INDEXD_PASS valueFrom: secretKeyRef: @@ -98,13 +166,13 @@ spec: - name: AUTH_NAMESPACE value: {{ . }} {{- end }} - - name: REQUESTS_CA_BUNDLE - # - # override python 'requests' SSL certificate bundle - # to use system trusted certs - # which includes our private certificate authority - # - value: /etc/ssl/certs/ca-certificates.crt + # - name: REQUESTS_CA_BUNDLE + # # + # # override python 'requests' SSL certificate bundle + # # to use system trusted certs + # # which includes our private certificate authority + # # + # value: /etc/ssl/certs/ca-certificates.crt - name: GEN3_DEBUG value: "True" {{- with .Values.ddTraceEnabled }} diff --git a/helm/sheepdog/templates/pre-install.yaml b/helm/sheepdog/templates/pre-install.yaml index a3a688ef..5ec2f0c5 100644 --- a/helm/sheepdog/templates/pre-install.yaml +++ b/helm/sheepdog/templates/pre-install.yaml @@ -1,59 +1,70 @@ apiVersion: batch/v1 kind: Job metadata: - name: gdcdb-create + name: sheepdog-dbinit + annotations: + "helm.sh/hook": "pre-install" #,pre-upgrade" spec: backoffLimit: 0 template: metadata: - annotations: - # This is what defines this resource as a hook. Without this line, the - # job is considered part of the release. - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "-5" - "helm.sh/hook-delete-policy": hook-succeeded labels: app: gen3job spec: automountServiceAccountToken: false - volumes: - - name: creds-volume - secret: - secretName: "sheepdog-creds" + # volumes: + # - name: creds-volume + # secret: + # secretName: "sheepdog-creds" containers: - name: sheepdog image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" env: - name: DICTIONARY_URL value: {{ .Values.dictionaryUrl }} - volumeMounts: - - name: "creds-volume" - readOnly: true - mountPath: "/var/www/sheepdog/creds.json" - subPath: creds.json - imagePullPolicy: Always + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: host + optional: false + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + - name: PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + # volumeMounts: + # - name: "creds-volume" + # readOnly: true + # mountPath: "/var/www/sheepdog/creds.json" + # subPath: creds.json + # imagePullPolicy: Always command: ["/bin/bash" ] args: - "-c" # Script always succeeds if it runs (echo exits with 0) - | - eval $(python 2> /dev/null <=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} - {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} - {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} - {{- end }} -{{- end }} -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - {{- include "ssjdispatcher.labels" . | nindent 4 }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ .Values.ingress.className }} - {{- end }} - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} - http: - paths: - {{- range .paths }} - - path: {{ .path }} - {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: {{ .pathType }} - {{- end }} - backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} - service: - name: {{ $fullName }} - port: - number: {{ $svcPort }} - {{- else }} - serviceName: {{ $fullName }} - servicePort: {{ $svcPort }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} diff --git a/helm/wts/Chart.lock b/helm/wts/Chart.lock index 6003d543..d251d368 100644 --- a/helm/wts/Chart.lock +++ b/helm/wts/Chart.lock @@ -1,6 +1,6 @@ dependencies: -- name: db-setup - repository: file://../db-setup +- name: common + repository: file://../common version: 0.0.1 -digest: sha256:049df0e16d26bc9a96ed517d3a5be85e8f261a20631b0bf7398e6708fc904692 -generated: "2022-10-18T15:18:59.981283-05:00" +digest: sha256:a25c79b74ec6d89ca5c732e4222f8726ed02aa6a4a21f376afc499e53696c9b5 +generated: "2022-10-20T21:34:47.899465-05:00" diff --git a/helm/wts/Chart.yaml b/helm/wts/Chart.yaml index a407415d..1b71326d 100644 --- a/helm/wts/Chart.yaml +++ b/helm/wts/Chart.yaml @@ -24,7 +24,6 @@ version: 0.0.1 appVersion: "2022.10" dependencies: - - name: db-setup + - name: common version: 0.0.1 - repository: file://../db-setup - condition: db_creation.enabled \ No newline at end of file + repository: file://../common \ No newline at end of file diff --git a/helm/wts/templates/_helpers.tpl b/helm/wts/templates/_helpers.tpl index 7dd6486d..d13a9fca 100644 --- a/helm/wts/templates/_helpers.tpl +++ b/helm/wts/templates/_helpers.tpl @@ -69,6 +69,6 @@ Create the name of the service account to use {{- if $localpass }} {{- default (index $localpass.data "postgres-password" | b64dec) }} {{- else }} -{{- default .Values.database.password }} +{{- default .Values.postgres.password }} {{- end }} {{- end }} \ No newline at end of file diff --git a/helm/wts/templates/db-init.yaml b/helm/wts/templates/db-init.yaml index efb72198..e53cb144 100644 --- a/helm/wts/templates/db-init.yaml +++ b/helm/wts/templates/db-init.yaml @@ -1,3 +1,3 @@ -{{- include "db-setup.setup-job" . }} +{{- include "common.db-setup-job" . }} --- -{{ include "db-setup.secret" . -}} \ No newline at end of file +{{- include "common.db-secret" . }} diff --git a/helm/wts/templates/deployment.yaml b/helm/wts/templates/deployment.yaml index 0df03cb7..72c1c6be 100644 --- a/helm/wts/templates/deployment.yaml +++ b/helm/wts/templates/deployment.yaml @@ -60,10 +60,6 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - - name: "wts-secret" - readOnly: true - mountPath: "/var/www/wts/dbcreds.json" - subPath: dbcreds.json - name: "wts-secret" readOnly: true mountPath: "/var/www/wts/appcreds.json" @@ -83,12 +79,36 @@ spec: path: /_status port: 80 env: - - name: POSTGRES_CREDS_FILE - value: "/var/www/wts/dbcreds.json" - name: SECRET_CONFIG value: "/var/www/wts/appcreds.json" - name: AUTH_PLUGINS value: k8s + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: host + optional: false + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + - name: PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + - name: SQLALCHEMY_DATABASE_URI + value: postgresql://$(PGUSER):$(PGPASSWORD)@$(PGHOST):5432/$(PGDB) resources: {{- toYaml .Values.resources | nindent 12 }} initContainers: @@ -96,17 +116,37 @@ spec: imagePullPolicy: Always image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" volumeMounts: - - name: "wts-secret" - readOnly: true - mountPath: "/var/www/wts/dbcreds.json" - subPath: dbcreds.json - name: "wts-secret" readOnly: true mountPath: "/var/www/wts/appcreds.json" subPath: appcreds.json env: - - name: POSTGRES_CREDS_FILE - value: "/var/www/wts/dbcreds.json" + - name: PGHOST + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: host + optional: false + - name: PGUSER + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: username + optional: false + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: password + optional: false + - name: PGDB + valueFrom: + secretKeyRef: + name: {{ .Chart.Name }}-dbcreds + key: database + optional: false + - name: SQLALCHEMY_DATABASE_URI + value: postgresql://$(PGUSER):$(PGPASSWORD)@$(PGHOST):5432/$(PGDB) - name: SECRET_CONFIG value: "/var/www/wts/appcreds.json" resources: diff --git a/helm/wts/templates/secret.yaml b/helm/wts/templates/secret.yaml index 1689cc63..76901964 100644 --- a/helm/wts/templates/secret.yaml +++ b/helm/wts/templates/secret.yaml @@ -28,11 +28,4 @@ stringData: "oidc_client_id": "{{ .Values.oidc_client_id | default (randAlphaNum 32) }}", "oidc_client_secret": "{{ .Values.oidc_client_secret | default (randAlphaNum 32) }}", "external_oidc": [] - } - dbcreds.json: | - { - "db_host": {{ .Values.database.host | quote }}, - "db_username": {{ .Values.database.user | quote}}, - "db_password": {{ include "wts.postgres.password" . | quote }}, - "db_database": {{ .Values.database.dbname | quote }} } \ No newline at end of file diff --git a/helm/wts/values.yaml b/helm/wts/values.yaml index d68f30eb..382f9980 100644 --- a/helm/wts/values.yaml +++ b/helm/wts/values.yaml @@ -1,4 +1,5 @@ global: + # Default values are for postgres deployed as a helm chart postgres: host: postgres-postgresql.postgres.svc.cluster.local master: @@ -6,6 +7,18 @@ global: password: port: 5432 + +# Whether or not to run database creation job +# The job is idempotant +db_creation: true +postgres: + # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you + database: wts + username: wts + # If left empty it will be auto-generated + password: + + # Default values for wts. # This is a YAML-formatted file. # Declare variables to be passed into your templates. @@ -13,10 +26,10 @@ global: replicaCount: 1 image: - repository: quay.io/cdis/workspace-token-service - pullPolicy: Always + repository: quay.io/cdis/wts + pullPolicy: Never # Overrides the image tag whose default is the chart appVersion. - tag: "" + tag: "jqtest" imagePullSecrets: [] nameOverride: "" @@ -26,7 +39,7 @@ fullnameOverride: "" hostname: localhost oidc_client_id: -oidc_client_secret: +oidc_client_secret: serviceAccount: # Specifies whether a service account should be created @@ -60,13 +73,6 @@ securityContext: {} # runAsNonRoot: true # runAsUser: 1000 -database: - port: 5432 - host: postgres-postgresql.postgres.svc.cluster.local - - user: postgres - password: - dbname: wts service: type: ClusterIP @@ -118,17 +124,3 @@ secrets: # "db_database": "wts_default" # } -# Whether or not to run database creation job -# The job is idempotant -db_creation: true - -postgres: - databases: - # Array of databases for service - # If db does not exist in postgres cluster and db_creation is set ot true then these databases will be created for you - - service: wts - databaseName: wts - username: wts - # If left empty it will be auto-generated - # TODO: complete auto-generate feature in db-setup - password: testpass \ No newline at end of file From 1e4cb9ef509c2843e33101fdc88fbf8d60a187b0 Mon Sep 17 00:00:00 2001 From: Jawad Qureshi Date: Mon, 24 Oct 2022 16:24:20 -0500 Subject: [PATCH 3/3] Update README.md --- .secrets.baseline | 6 +++--- README.md | 19 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index b0276bad..b9b20b03 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2022-10-24T19:37:51Z", + "generated_at": "2022-10-24T21:24:09Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -63,14 +63,14 @@ "hashed_secret": "04024ac03c114027f1116abedeb4bb78b01a31db", "is_secret": false, "is_verified": false, - "line_number": 85, + "line_number": 84, "type": "Secret Keyword" }, { "hashed_secret": "0c9967f3918994e95ab61396a76a7d10f783c8f7", "is_secret": false, "is_verified": false, - "line_number": 109, + "line_number": 108, "type": "Secret Keyword" } ], diff --git a/README.md b/README.md index d11e4224..f94ac455 100644 --- a/README.md +++ b/README.md @@ -36,14 +36,13 @@ kubectl run postgres-postgresql-client --rm --tty -i --restart='Never' --namespa Once you get a PSQL shell into postgres create databses by running the following ``` -CREATE DATABASE arborist; -CREATE DATABASE audit; -CREATE DATABASE fence; -CREATE DATABASE indexd; -CREATE DATABASE metadata; -CREATE DATABASE peregrine; -CREATE DATABASE sheepdog; -CREATE DATABASE requestor; +CREATE DATBASE arborist; +CREATE DATBASE audit; +CREATE DATBASE fence; +CREATE DATBASE indexd; +CREATE DATBASE metadata; +CREATE DATBASE peregrine; +CREATE DATBASE sheepdog; ``` @@ -73,10 +72,10 @@ After configuration is complete, take note of the client ID that was created. Yo ## Helm chart deployment -### Install Gen3 +### Install all charts ``` cd ./helm -helm upgrade --install gen3 ./gen3 -f values.yaml +for i in $(ls); do helm upgrade --install $i ./$i; done ``` ### Install fence with google login secrets