Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diracx issue 147 postgres integration #115

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ Note that this configuration is trivial and does not follow production recommand
|------------|------|---------|
| | cert-manager-issuer | *.*.* |
| https://charts.bitnami.com/bitnami/ | mysql | 9.11.0 |
| https://charts.bitnami.com/bitnami/ | postgresql | 11.7.6 |
| https://charts.bitnami.com/bitnami/ | rabbitmq | 12.0.10 |
| https://charts.dexidp.io/ | dex | 0.14.2 |
| https://charts.jetstack.io | cert-manager | 1.13.1 |
Expand Down Expand Up @@ -426,6 +427,12 @@ Note that this configuration is trivial and does not follow production recommand
| opentelemetry-collector.presets.logsCollection.enabled | bool | `false` | |
| podAnnotations | object | `{}` | |
| podSecurityContext | object | `{}` | |
| postgresql.auth.existingSecret | string | `"postgresql-secret"` | |
| postgresql.auth.username | string | `"sqldiracx"` | |
| postgresql.enabled | bool | `false` | |
| postgresql.primary.initdb.scriptsConfigMap | string | `"postgresql-init-diracx-dbs"` | |
| postgresql.primary.initdb.user | string | `"postgres"` | |
| postgresql.primary.pgHbaConfiguration | string | `"local all all trust\nhost all all localhost trust\nhost all all 0.0.0.0/0 md5"` | |
| prometheus.alertmanager.enabled | bool | `false` | |
| prometheus.enabled | bool | `false` | |
| prometheus.kube-state-metrics.enabled | bool | `false` | |
Expand Down
3 changes: 3 additions & 0 deletions diracx/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ dependencies:
- name: mysql
repository: https://charts.bitnami.com/bitnami/
version: 9.11.0
- name: postgresql
repository: https://charts.bitnami.com/bitnami/
version: 11.7.6
- name: cert-manager
repository: https://charts.jetstack.io
version: v1.13.1
Expand Down
4 changes: 4 additions & 0 deletions diracx/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ dependencies:
repository: https://charts.bitnami.com/bitnami/
condition: mysql.enabled

- name: postgresql
version: 11.7.6
repository: https://charts.bitnami.com/bitnami/
condition: postgresql.enabled

- name: cert-manager
version: 1.13.1
Expand Down
Binary file added diracx/charts/postgresql-11.7.6.tgz
Binary file not shown.
7 changes: 6 additions & 1 deletion diracx/templates/diracx/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,19 @@ spec:
{{- end }}
{{- end }}
{{- end }}
{{- if or .Values.mysql.enabled .Values.opensearch.enabled .Values.minio.enabled }}
{{- if or .Values.mysql.enabled .Values.postgresql.enabled .Values.opensearch.enabled .Values.minio.enabled }}
initContainers:
{{- end }}
{{- if .Values.mysql.enabled }}
- name: wait-for-mysql
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'until nc -vz {{ .Release.Name }}-mysql 3306; do echo "Waiting for mysql..."; sleep 3; done;']
{{- else if .Values.postgresql.enabled }}
- name: wait-for-postgresql
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'until nc -vz {{ .Release.Name }}-postgresql 5432; do echo "Waiting for postgresql..."; sleep 3; done;']
{{- end }}
{{- if .Values.opensearch.enabled }}
- name: wait-for-opensearch
Expand Down
34 changes: 34 additions & 0 deletions diracx/templates/diracx/diracx-postgresql-init-dbs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgresql-init-diracx-dbs
data:
# Create the databases for DiracX and grant privileges
init-diracx-dbs.sql: |
{{- range $dbName, $dbSettings := .Values.diracx.sqlDbs.dbs }}
SELECT 'CREATE DATABASE "{{ $dbName }}"'
WHERE NOT EXISTS (
SELECT FROM pg_database
WHERE datname = '{{ $dbName }}'
);\gexec

\c "{{ $dbName }}";

ALTER DEFAULT PRIVILEGES
FOR USER postgres
IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE
ON TABLES
TO "{{ $.Values.postgresql.auth.username }}";

ALTER DEFAULT PRIVILEGES
FOR USER postgres
IN SCHEMA public
GRANT USAGE
ON SEQUENCES
TO "{{ $.Values.postgresql.auth.username }}";

GRANT CONNECT, TEMPORARY
ON DATABASE "{{ $dbName }}"
TO "{{ $.Values.postgresql.auth.username }}";
{{- end }}
159 changes: 105 additions & 54 deletions diracx/templates/diracx/init-secrets/_init-secrets.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ IFS=$'\n\t'

namespace={{ .Release.Namespace }}
release={{ .Release.Name }}
connStart=""

pushd $(mktemp -d)

Expand Down Expand Up @@ -48,6 +49,23 @@ function generate_secret_if_needed(){
fi
}

# Args database_instance
function set_sql_connection_driver(){
case $1 in
"MySQL")
connStart="mysql+aiomysql"
;;
"PostgreSQL")
connStart="postgresql+asyncpg"
;;
*)
# Throw some kind of error
echo "SQL Database \"" $1 "\" unknown" 1>&2
exit 1
;;
esac
}

# Generate the token signing key
ssh-keygen -P '' -trsa -b4096 -mPEM -f"$PWD/rsa256.key"
generate_secret_if_needed diracx-token-signing-key --from-file "$PWD/rsa256.key"
Expand All @@ -61,70 +79,103 @@ generate_secret_if_needed {{ .Values.rabbitmq.auth.existingPasswordSecret }} --f
generate_secret_if_needed {{ .Values.rabbitmq.auth.existingErlangSecret }} --from-literal=rabbitmq-erlang-cookie=$(gen_random 'a-zA-Z0-9' 32)
{{- end }}

{{- $externalDB := false }}

# If we deploy MySQL ourselves
{{- if .Values.mysql.enabled }}

# Make sure that there are no default connection settings
{{ if .Values.diracx.sqlDbs.default }}
{{ fail "There should be no default connection settings if running mysql from this Chart" }}
{{ end }}

# Generate the secrets for mysql
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-root-password=$(gen_random 'a-zA-Z0-9' 32)
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-replication-password=$(gen_random 'a-zA-Z0-9' 32)
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-password=$(gen_random 'a-zA-Z0-9' 32)

# Make secrets for the sqlalchemy connection urls
mysql_password=$(kubectl get secret {{ .Values.mysql.auth.existingSecret }} -ojsonpath="{.data.mysql-password}" | base64 -d)
mysql_root_password=$(kubectl get secret {{ .Values.mysql.auth.existingSecret }} -ojsonpath="{.data.mysql-root-password}" | base64 -d)

{{- range $dbName,$dbSettings := .Values.diracx.sqlDbs.dbs }}


# Make sure there are no connection settings
{{ if $dbSettings }}
{{ fail "There should be no connection settings if running mysql from this Chart" }}
{{ end }}

generate_secret_if_needed diracx-sql-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://{{ $.Values.mysql.auth.username }}:${mysql_password}@{{ $.Release.Name }}-mysql:3306/{{ $dbName }}"
generate_secret_if_needed diracx-sql-root-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://root:${mysql_root_password}@{{ $.Release.Name }}-mysql:3306/{{ $dbName }}"
{{- end }}

# If we use an external MySQL instance
# Make sure that there are no default connection settings
{{ if .Values.diracx.sqlDbs.default }}
{{ fail "There should be no default connection settings if running mysql from this Chart" }}
{{ end }}

# Get the start of the connection string of MySQL (db+driver)
set_sql_connection_driver "MySQL"

# Generate the secrets for MySQL
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-root-password=$(gen_random 'a-zA-Z0-9' 32)
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-replication-password=$(gen_random 'a-zA-Z0-9' 32)
generate_secret_if_needed {{ .Values.mysql.auth.existingSecret }} --from-literal=mysql-password=$(gen_random 'a-zA-Z0-9' 32)

# Set the values for the sqlalchemy connection urls
user={{ $.Values.mysql.auth.username }}
root_user="root"
password=$(kubectl get secret {{ .Values.mysql.auth.existingSecret }} -ojsonpath="{.data.mysql-password}" | base64 -d)
root_password=$(kubectl get secret {{ .Values.mysql.auth.existingSecret }} -ojsonpath="{.data.mysql-root-password}" | base64 -d)
host={{ $.Release.Name }}-mysql:3306

# If we deploy PostgreSQL ourselves
{{- else if .Values.postgresql.enabled }}

# Make sure that there are no default connection settings
{{ if .Values.diracx.sqlDbs.default }}
{{ fail "There should be no default connection settings if running PostgreSQL from this Chart" }}
{{ end }}

# Get the start of the connection string of PostgreSQL (db+driver)
set_sql_connection_driver "PostgreSQL"

# Generate the secrets for PostgreSQL
generate_secret_if_needed {{ .Values.postgresql.auth.existingSecret }} --from-literal=postgres-password=$(gen_random 'a-zA-Z0-9' 32)
#generate_secret_if_needed {{ .Values.postgresql.auth.existingSecret }} --from-literal=postgresql-replication-password=$(gen_random 'a-zA-Z0-9' 32)
generate_secret_if_needed {{ .Values.postgresql.auth.existingSecret }} --from-literal=password=$(gen_random 'a-zA-Z0-9' 32)

# Set the values for the sqlalchemy connection urls
user={{ $.Values.postgresql.auth.username }}
root_user="postgres"
password=$(kubectl get secret {{ .Values.postgresql.auth.existingSecret }} -ojsonpath="{.data.password}" | base64 -d)
root_password=$(kubectl get secret {{ .Values.postgresql.auth.existingSecret }} -ojsonpath="{.data.postgres-password}" | base64 -d)
host={{ $.Release.Name }}-postgresql:5432

# If we use an external DB instance
{{- else }}

{{- $externalDB = true }}

{{- $default_db_host := $.Values.diracx.sqlDbs.default.host }}
{{- $default_db_root_user := $.Values.diracx.sqlDbs.default.rootUser }}
{{- $default_db_root_password := $.Values.diracx.sqlDbs.default.rootPassword }}
{{- $default_db_user := $.Values.diracx.sqlDbs.default.user }}
{{- $default_db_password := $.Values.diracx.sqlDbs.default.password }}
set_sql_connection_driver {{ .Values.diracx.sqlDbs.default.type }}

{{- range $dbName, $db_settings := .Values.diracx.sqlDbs.dbs }}
# Set the default values
user={{ $.Values.diracx.sqlDbs.default.user }}
root_user={{ $.Values.diracx.sqlDbs.default.rootUser }}
password={{ $.Values.diracx.sqlDbs.default.password }}
root_password={{ $.Values.diracx.sqlDbs.default.rootPassword }}
host={{ $.Values.diracx.sqlDbs.default.host }}


{{- if kindIs "map" $db_settings }}
{{- $db_host := $db_settings.host | default $default_db_host }}
{{- $db_root_user := $db_settings.rootUser | default $default_db_root_user }}
{{- $db_root_password := $db_settings.rootPassword | default $default_db_root_password }}
{{- $db_user := $db_settings.user | default $default_db_user }}
{{- $db_password := $db_settings.password | default $default_db_password }}
{{- $db_internal_name := $db_settings.internalName | default $dbName }}

generate_secret_if_needed diracx-sql-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://{{ $db_user }}:{{ $db_password }}@{{ $db_host }}/{{ $db_internal_name }}"
generate_secret_if_needed diracx-sql-root-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://{{ $db_root_user }}:{{ $db_root_password }}@{{ $db_host }}/{{ $db_internal_name }}"
{{- else }}
generate_secret_if_needed diracx-sql-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://{{ $default_db_user }}:{{ $default_db_password }}@{{ $default_db_host }}/{{ $dbName }}"
generate_secret_if_needed diracx-sql-root-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="mysql+aiomysql://{{ $default_db_root_user }}:{{ $default_db_root_password }}@{{ $default_db_host }}/{{ $dbName }}"
{{- end }}

{{- end }}
# Configure the Connections
{{- range $dbName, $dbSettings := .Values.diracx.sqlDbs.dbs }}
# If is not an external db and has settings
{{ if and (not $externalDB) $dbSettings }}
{{ fail "There should be no connection settings if running a local database from this Chart" }}
{{ end }}

db_connStart=$connStart # Configurable at database level?

{{- if kindIs "map" $dbSettings }}
db_user={{ $dbSettings.user | default $.Values.diracx.sqlDbs.default.user }}
db_root_user={{ $dbSettings.rootUser | default $.Values.diracx.sqlDbs.default.rootUser }}
db_password={{ $dbSettings.password | default $.Values.diracx.sqlDbs.default.password }}
db_root_password={{ $dbSettings.rootPassword | default $.Values.diracx.sqlDbs.default.rootPassword }}
db_host={{ $dbSettings.host | default $.Values.diracx.sqlDbs.default.host }}
db_name={{ $dbSettings.internalName | default $dbName }}
{{- else }}
db_user=$user
db_root_user=$root_user
db_password=$password
db_root_password=$root_password
db_host=$host
db_name={{ $dbName }}
{{- end }}

# User connection string
generate_secret_if_needed diracx-sql-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="${db_connStart}://${db_user}:${db_password}@${db_host}/${db_name}"

# Root connection string
generate_secret_if_needed diracx-sql-root-connection-urls \
--from-literal=DIRACX_DB_URL_{{ $dbName | upper }}="${db_connStart}://${db_root_user}:${db_root_password}@${db_host}/${db_name}"

{{- end }}


Expand Down
9 changes: 7 additions & 2 deletions diracx/templates/diracx/init-sql/job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,18 @@ spec:
{{- end }}
spec:
restartPolicy: Never
{{- if .Values.mysql.enabled }}
initContainers:
{{- if .Values.mysql.enabled }}
- name: wait-for-mysql
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'until nc -vz {{ .Release.Name }}-mysql 3306; do echo "Waiting for mysql..."; sleep 3; done;']
{{ end }}
{{- else if .Values.postgresql.enabled }}
- name: wait-for-postgresql
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'until nc -vz {{ .Release.Name }}-postgresql 5432; do echo "Waiting for postgresql..."; sleep 3; done;']
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.global.images.services }}:{{ .Values.global.images.tag | default .Chart.AppVersion }}"
Expand Down
18 changes: 18 additions & 0 deletions diracx/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ diracx:
# user: dirac
# password: password123
# host: sqlHost:123
# type: MySQL
# -- Which DiracX MySQL DBs are used?
dbs:
# AuthDB:
Expand Down Expand Up @@ -342,6 +343,8 @@ indigoiam:

##########################

# ONLY ONE CAN BE ENABLED

mysql:
enabled: true
auth:
Expand All @@ -362,6 +365,21 @@ mysql:
# failureThreshold: 30
# successThreshold: 1

postgresql:
enabled: false
auth:
existingSecret: postgresql-secret
username: sqldiracx
primary:
pgHbaConfiguration: |-
local all all trust
host all all localhost trust
host all all 0.0.0.0/0 md5
initdb:
user: postgres
scriptsConfigMap: postgresql-init-diracx-dbs


##########################

rabbitmq:
Expand Down
12 changes: 11 additions & 1 deletion run_demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function element_not_in_array() {
return $found
}

usage="${0##*/} [-h|--help] [--exit-when-done] [--offline] [--enable-coverage] [--no-mount-containerd] [--set-value key=value] [--ci-values=values.yaml] [--load-docker-image=<image_name:tag>] [--] [source directories]"
usage="${0##*/} [-h|--help] [--exit-when-done] [--offline] [--postgres] [--enable-coverage] [--no-mount-containerd] [--set-value key=value] [--ci-values=values.yaml] [--load-docker-image=<image_name:tag>] [--] [source directories]"
usage+="\n\n"
usage+=" -h|--help: Print this help message and exit\n"
usage+=" --ci-values: Path to a values.yaml file which contains diracx dev settings only enabled for CI\n"
Expand All @@ -114,6 +114,8 @@ usage+=" WARNING: There is no garbage collection so the
usage+=" --offline: Run in a mode which is suitable for fully offline use.\n"
usage+=" WARNING: This may result in some weird behaviour, see the demo documentation for details.\n"
usage+=" Implies: --mount-containerd\n"
usage+=" --postgres: Runs the demo using a the PostgreSQL database.\n"
usage+=" If not specified, it will default to MySQL.\n"
usage+=" --set-value: Set a value in the Helm values file. This can be used to override the default values.\n"
usage+=" For example, to enable coverage reporting pass: --set-value developer.enableCoverage=true\n"
usage+=" source directories: A list of directories containing Python packages to mount in the demo cluster.\n"
Expand Down Expand Up @@ -225,6 +227,14 @@ while [ -n "${1:-}" ]; do case $1 in
shift
continue ;;

--postgres)
helm_arguments+=("--set")
helm_arguments+=("postgresql.enabled=true")
helm_arguments+=("--set")
helm_arguments+=("mysql.enabled=false")
shift
continue ;;

# Double-dash: Terminate option parsing
--)
shift
Expand Down