Skip to content

Commit

Permalink
[utils] Add support for different database types
Browse files Browse the repository at this point in the history
Add an option to choose database type and generate different configurations
for ProxySQL and oslo.db connection

The following options are available:
- mariadb
- pxc-db

To choose the different database type
- Variable dbType should be set
- Chart (pxc-db or mariadb) should be present in the dependencies

To make this selection possible following things changed:
- Added helper function utils.db_host
- Added helper function utils.db_url
- Extended helper function db_credentials
- Added helpers `utils._db_url_*` and `utils._db_host_*` for mariadb and pxc-db

One specific case is supported which doesn't require a chart dependency:
```
proxysql:
  force_enable:
    - mariadb
```
This is currently being used in the Placement chart, because
Placement reuses nova_api database instance

Other changes in this commit:
- Improve readability of the db_host_pxc and db_url_pxc functions
- Update proxysql sidecar docs
  • Loading branch information
s10 committed Sep 30, 2024
1 parent 42b4911 commit 150dc28
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 81 deletions.
2 changes: 1 addition & 1 deletion openstack/utils/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: v1
description: A Helm chart for Kubernetes
name: utils
version: 0.18.4
version: 0.19.0
11 changes: 5 additions & 6 deletions openstack/utils/proxysql_sidecar.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The two modes differ in the following way:
- `unix_socket` connects to the side-car container via a unix socket file on a shared volume.
This should be the fastest, but has the disadvantage that works only with the side-car present, as the url
is referring to said file.
- `host_alias` uses a host alias for the short hostname (ie. `<app>-mariadb`) to redirect the application to the localhost
- `host_alias` uses a host alias for the short hostname (ie. `<app>-mariadb` or `<app>-db`) to redirect the application to the localhost
where the side-car container is listening on the default port. But the very same url also works without a side-car
container, if the host-alias is not set. So we do not have to annotate all pods, we just have to make sure,
that the annotations are consistent for a single pod.
Expand All @@ -24,16 +24,15 @@ The two modes differ in the following way:

The configuration for the ProxySQL process needs to be stored in a Secret as
generated by the macro `proxysql_secret`.
If only one mariadb instance with one schema and user is used, it suffices to create a yaml file with
If only one DB instance with one schema and user is used, it suffices to create a yaml file with
```
{{ include "proxysql_secret" . }}
```
When multiple databases / schemas or users are used, the mariadb dependency needs to be updated at least to version 0.4.0,
and the users and databases need to be defined in the respective `databases` and `users` fields.
When multiple databases / schemas or users are used the users and databases need to be defined in the respective `databases` and `users` fields.
There can be multiple databases/schema on the same host, but a user always needs to map directly to one host & database.

To enable monitoring for proxysql, the `mariadb.users` field needs to contain a user with the key `proxysql_monitor`.
If there are multiple mariadb instances, each of them needs to have the field entered and all of them have to have the same
If there are multiple DB instances, each of them needs to have the field entered and all of them have to have the same
values.

Following the pattern of all macros in utils, the values are coming from the context
Expand All @@ -46,7 +45,7 @@ proxysql:
imageTag: "2.4.1-debian" # Most current at the time of writing this
restapi_port: 6070 # On which port to expose the rest-api (and prometheus metrics)
prometheus_memory_metrics_interval: 61 # See: https://proxysql.com/documentation/global-variables/admin-variables/#admin-prometheus_memory_metrics_interval
max_connections_per_proc: (max_pool_size + max_overflow) # The maximum number of connections proxysql will open to a mariadb host
max_connections_per_proc: (max_pool_size + max_overflow) # The maximum number of connections proxysql will open to a DB host
# per process. With the default assumption being one process per pod.
# The settings are modelled after the sqlalchemy pool, which is a per process pool
```
Expand Down
178 changes: 145 additions & 33 deletions openstack/utils/templates/_hosts.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,70 @@
{{ include "_resolve_secret" (tuple . true) }}
{{- end -}}

{{define "db_url" }}
{{- if kindIs "map" . -}}
postgresql+psycopg2://{{default .Values.dbUser .Values.global.dbUser}}:{{(default .Values.dbPassword .Values.global.dbPassword) | default (tuple . (default .Values.dbUser .Values.global.dbUser) | include "postgres.password_for_user")}}@{{.Chart.Name}}-postgresql.{{ include "svc_fqdn" . }}:5432/{{.Values.postgresql.postgresDatabase}}
{{- else }}
{{- $envAll := index . 0 }}
{{- $name := index . 1 }}
{{- $user := index . 2 }}
{{- $password := index . 3 }}
{{- with $envAll -}}
postgresql+psycopg2://{{$user}}:{{$password | urlquery}}@{{.Chart.Name}}-postgresql.{{ include "svc_fqdn" . }}:5432/{{$name}}
{{- end }}
{{- end -}}
?connect_timeout=10&keepalives_idle=5&keepalives_interval=5&keepalives_count=10
{{- end}}

{{- define "db_credentials" }}
{{- if kindIs "map" . }}
{{- if and .Values.mariadb.users .Values.mariadb.databases }}
{{- $db := first .Values.mariadb.databases }}
{{- $user := get .Values.mariadb.users $db | required (printf ".Values.mariadb.%v.name & .password are required (key comes from first database in .Values.mariadb.databases)" $db) }}
{{- $user.name | required (printf ".Values.mariadb.%v.name is required!" $db ) }}:{{ $user.password | required (printf ".Values.mariadb.%v.password is required!" $db ) }}
{{- $envAll := .context }}
{{- $dbType := .dbType }}
{{- if kindIs "map" $envAll }}
{{- $dbConfig := dict }}
{{- if eq $dbType "mariadb" }}
{{- $dbConfig = $envAll.Values.mariadb }}
{{- else if eq $dbType "pxc-db" }}
{{- $dbConfig = $envAll.Values.pxc_db }}
{{- end }}
{{- if and $dbConfig.users $dbConfig.databases }}
{{- $db := first $dbConfig.databases }}
{{- $user := get $dbConfig.users $db | required (printf ".Values.db.%v.name & .password are required (key comes from first database in databases array)" $db) }}
{{- $user.name | required (printf ".Values.db.%v.name is required!" $db ) }}:{{ $user.password | required (printf ".Values.db.%v.password is required!" $db ) }}
{{- else }}
{{- coalesce .Values.dbUser .Values.global.dbUser "root" }}:{{ coalesce .Values.dbPassword .Values.global.dbPassword .Values.mariadb.root_password | required ".Values.mariadb.root_password is required!" }}
{{- coalesce $envAll.Values.dbUser $envAll.Values.global.dbUser "root" }}:{{ coalesce $envAll.Values.dbPassword $envAll.Values.global.dbPassword $dbConfig.root_password | required ".Values.db.root_password is required!" }}
{{- end }}
{{- else }}
{{- $user := index . 2 }}
{{- $password := index . 3 }}
{{- $user := index $envAll 2 }}
{{- $password := index $envAll 3 }}
{{- include "resolve_secret_urlquery" $user }}:{{ include "resolve_secret_urlquery" $password }}
{{- end }}
{{- end }}

{{/*
Choose different db_url function depending on dbType value
Default: mariadb
*/}}
{{- define "utils.db_url" }}
{{- $dbUrlHelpers := dict
"mariadb" "utils._db_url_mariadb"
"pxc-db" "utils._db_url_pxc_db"
}}
{{- $dbType := default "mariadb" .Values.dbType }}
{{- $dbUrl := index $dbUrlHelpers $dbType }}
{{- include $dbUrl . }}
{{- end }}

{{/*
Choose different db_host function depending on dbType value
Default: mariadb
*/}}
{{- define "utils.db_host" }}
{{- $dbHostHelpers := dict
"mariadb" "utils._db_host_mariadb"
"pxc-db" "utils._db_host_pxc_db"
}}
{{- $dbType := default "mariadb" .Values.dbType }}
{{- $dbHost := index $dbHostHelpers $dbType }}
{{- include $dbHost . }}
{{- end }}

{{/*
Alias for for backward compatibility
*/}}
{{- define "db_host_mysql" }}
{{- include "utils.db_host" . }}
{{- end }}

{{/*
Service hostname for mariadb
Example: service-mariadb
*/}}
{{- define "utils._db_host_mariadb" }}
{{- if kindIs "map" . }}
{{- .Values.mariadb.name }}
{{- else }}
Expand All @@ -68,27 +100,54 @@ postgresql+psycopg2://{{$user}}:{{$password | urlquery}}@{{.Chart.Name}}-postgre
{{- end }}-mariadb
{{- end }}

{{/*
Service hostname for pxc-db
Example: service-db
*/}}
{{- define "utils._db_host_pxc_db" }}
{{- if kindIs "map" . }}
{{- .Values.pxc_db.name }}
{{- else }}
{{- $envAll := index . 0 }}
{{- if lt 4 (len .) }}
{{- index . 4 }}
{{- else }}
{{- $envAll.Values.pxc_db.name }}
{{- end }}
{{- end }}-db
{{- end }}

{{/*
Alias for backward compatibility
*/}}
{{- define "db_url_mysql" }}
{{- include "utils.db_url" . }}
{{- end }}

{{/*
Use .Values.mariadb for connection URL generation
*/}}
{{- define "utils._db_url_mariadb" }}
{{- if kindIs "map" . }}
{{- if and .Values.mariadb.users .Values.mariadb.databases }}
{{- $db := first .Values.mariadb.databases }}
{{- $user := get .Values.mariadb.users $db | required (printf ".Values.mariadb.%v.name & .password are required (key comes from first database in .Values.mariadb.databases)" $db) }}
{{- tuple . $db $user.name (required (printf "User with key %v requires password" $db) $user.password) | include "db_url_mysql" }}
{{- tuple . $db $user.name (required (printf "User with key %v requires password" $db) $user.password) | include "utils._db_url_mariadb" }}
{{- else }}
{{- tuple . (coalesce .Values.dbName .Values.db_name) (coalesce .Values.dbUser .Values.global.dbUser "root" | include "resolve_secret_urlquery") (coalesce .Values.dbPassword .Values.global.dbPassword .Values.mariadb.root_password | include "resolve_secret_urlquery" | required ".Values.mariadb.root_password is required!") .Values.mariadb.name | include "db_url_mysql" }}
{{- tuple . (coalesce .Values.dbName .Values.db_name) (coalesce .Values.dbUser .Values.global.dbUser "root" | include "resolve_secret_urlquery") (coalesce .Values.dbPassword .Values.global.dbPassword .Values.mariadb.root_password | include "resolve_secret_urlquery" | required ".Values.mariadb.root_password is required!") .Values.mariadb.name | include "utils._db_url_mariadb" }}
{{- end }}
{{- else -}}
mysql+pymysql://{{ include "db_credentials" . }}@
mysql+pymysql://{{ include "db_credentials" (dict "context" . "dbType" "mariadb") }}@
{{- $allArgs := . }}
{{- $schemaName := index . 1 }}
{{- with $envAll := index . 0 }}
{{- if not .Values.proxysql }}
{{- include "db_host_mysql" $allArgs }}
{{- include "utils._db_host_mariadb" $allArgs }}
{{- else if not .Values.proxysql.mode }}
{{- include "db_host_mysql" $allArgs }}
{{- include "utils._db_host_mariadb" $allArgs }}
{{- else if ne $envAll.Values.proxysql.mode "unix_socket" }}
{{- if mustHas $envAll.Values.proxysql.mode (list "unix_socket" "host_alias") }}
{{- include "db_host_mysql" $allArgs }}
{{- include "utils._db_host_mariadb" $allArgs }}
{{- else }}
{{ fail (printf "Unknown value for .Values.proxysql.mode: got \"%v\"" $envAll.Values.proxysql.mode) }}
{{- end }}
Expand All @@ -102,12 +161,65 @@ mysql+pymysql://{{ include "db_credentials" . }}@
{{- end -}}
charset=utf8
{{- end }}
{{- end}}
{{- end }}

# Please keep as it is, special case when it has to reference the db_region value.
{{define "db_host_pxc"}}{{.Release.Name}}-percona-pxc.{{.Release.Namespace}}.svc.kubernetes.{{.Values.global.db_region}}.{{.Values.global.tld}}{{end}}
{{/*
Use .Values.pxc_db for connection URL generation
*/}}
{{- define "utils._db_url_pxc_db" }}
{{- if kindIs "map" . }}
{{- if and .Values.pxc_db.users .Values.pxc_db.databases }}
{{- $db := first .Values.pxc_db.databases }}
{{- $user := get .Values.pxc_db.users $db | required (printf ".Values.pxc_db.%v.name & .password are required (key comes from first database in .Values.pxc_db.databases)" $db) }}
{{- tuple . $db $user.name (required (printf "User with key %v requires password" $db) $user.password) | include "utils._db_url_pxc_db" }}
{{- else }}
{{- tuple . (coalesce .Values.dbName .Values.db_name) (coalesce .Values.dbUser .Values.global.dbUser "root" | include "resolve_secret_urlquery") (coalesce .Values.dbPassword .Values.global.dbPassword .Values.pxc_db.root_password | include "resolve_secret_urlquery" | required ".Values.pxc_db.root_password is required!") .Values.pxc_db.name | include "utils._db_url_pxc_db" }}
{{- end }}
{{- else -}}
mysql+pymysql://{{ include "db_credentials" (dict "context" . "dbType" "pxc-db") }}@
{{- $allArgs := . }}
{{- $schemaName := index . 1 }}
{{- with $envAll := index . 0 }}
{{- if not .Values.proxysql }}
{{- include "utils._db_host_pxc_db" $allArgs }}
{{- else if not .Values.proxysql.mode }}
{{- include "utils._db_host_pxc_db" $allArgs }}
{{- else if ne $envAll.Values.proxysql.mode "unix_socket" }}
{{- if mustHas $envAll.Values.proxysql.mode (list "unix_socket" "host_alias") }}
{{- include "utils._db_host_pxc_db" $allArgs }}
{{- else }}
{{ fail (printf "Unknown value for .Values.proxysql.mode: got \"%v\"" $envAll.Values.proxysql.mode) }}
{{- end }}
{{- end -}}
/{{ $schemaName }}?
{{- if .Values.proxysql }}
{{- if eq .Values.proxysql.mode "unix_socket" -}}
unix_socket=/run/proxysql/mysql.sock&
{{- end }}
{{- end }}
{{- end -}}
charset=utf8
{{- end }}
{{- end }}

{{define "db_url_pxc" }}mysql+pymysql://{{- include "resolve_secret_urlquery" .Values.percona_cluster.db_user -}}:{{- include "resolve_secret_urlquery" .Values.percona_cluster.dbPassword -}}@{{include "db_host_pxc" .}}/{{.Values.percona_cluster.db_name}}?charset=utf8{{end}}
{{/*
Alias for backward compatibility
*/}}
{{- define "db_url_pxc" }}
{{- include "utils._db_url_pxc_global" . }}
{{- end }}

{{/*
Custom DB URL for the global services using percona_cluster
*/}}
{{- define "utils._db_url_pxc_global" }}
{{- $prefix := "mysql+pymysql" }}
{{- $username := include "resolve_secret_urlquery" .Values.percona_cluster.db_user }}
{{- $password := include "resolve_secret_urlquery" .Values.percona_cluster.dbPassword }}
{{- $db_host := printf "%s-percona-pxc.%s.svc.kubernetes.%s.%s" .Release.Name .Release.Namespace .Values.global.db_region .Values.global.tld }}
{{- $db_name := .Values.percona_cluster.db_name }}
{{- $prefix }}://{{ $username }}:{{ $password }}@{{ $db_host }}/{{ $db_name }}?charset=utf8
{{- end }}

{{define "nova_db_host"}}nova-mariadb.{{ include "svc_fqdn" . }}{{end}}
{{define "nova_api_endpoint_host_admin"}}nova-api.{{ include "svc_fqdn" . }}{{end}}
Expand Down
8 changes: 1 addition & 7 deletions openstack/utils/templates/_ini_sections.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,8 @@ max_overflow = {{ .Values.max_overflow | default .Values.global.max_overflow | d
{{- define "ini_sections.database" }}

[database]
{{- if not .Values.postgresql }}
connection = {{ include "db_url_mysql" . }}
{{- else if not .Values.postgresql.enabled }}
connection = {{ include "db_url_mysql" . }}
connection = {{ include "utils.db_url" . }}
{{- include "ini_sections.database_options_mysql" . }}
{{- else }}
connection = {{ include "db_url" . }}
{{- end }}
{{- end }}

{{- define "ini_sections.cache" }}
Expand Down
33 changes: 22 additions & 11 deletions openstack/utils/templates/_proxysql.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,34 @@
{{- define "utils.proxysql.pod_settings" }}
{{- if .Values.proxysql }}
{{- if .Values.proxysql.mode }}
{{- $envAll := . }}
{{- $dbs := dict }}
{{- range $d := $envAll.Chart.Dependencies }}
{{- $envAll := . }}
{{- $dbs := dict }}
{{/* Default: create mariadb and db hostAliases based on present chart dependencies */}}
{{- range $d := $envAll.Chart.Dependencies }}
{{- if hasPrefix "mariadb" $d.Name }}
{{- $_ := set $dbs $d.Name (get $envAll.Values $d.Name) }}
{{- $_ := set $dbs $d.Name (merge (get $envAll.Values $d.Name) (dict "hostAliasesSuffix" "mariadb")) }}
{{- end }}
{{- end }}
{{- range $d := $envAll.Values.proxysql.force_enable }}
{{- $_ := set $dbs $d (get $envAll.Values $d) }}
{{- end }}
{{- $dbKeys := keys $dbs | sortAlpha }}
{{- if hasPrefix "pxc" $d.Name }}
{{- $_ := set $dbs $d.Name (merge (get $envAll.Values $d.Name) (dict "hostAliasesSuffix" "db")) }}
{{- end }}
{{- end }}
{{/* Option: add hostAliases base on proxysql.force_enable values */}}
{{- range $d := $envAll.Values.proxysql.force_enable }}
{{- if hasPrefix "mariadb" $d }}
{{- $_ := set $dbs $d (merge (get $envAll.Values $d) (dict "hostAliasesSuffix" "mariadb")) }}
{{- else if hasPrefix "pxc" $d }}
{{- $_ := set $dbs $d (merge (get $envAll.Values $d) (dict "hostAliasesSuffix" "db")) }}
{{- else }}
{{ fail (printf "unknown database type: %s" $d) }}
{{- end }}
{{- end }}
{{- $dbKeys := keys $dbs | sortAlpha }}
hostAliases:
- ip: "127.0.0.1"
hostnames:
{{- range $index, $dbKey := $dbKeys }}
{{- range $index, $dbKey := $dbKeys }}
{{- $db := get $dbs $dbKey }}
- {{ print $db.name "-mariadb" | quote }}
- {{ printf "%s-%s" $db.name $db.hostAliasesSuffix | quote }}
{{- end }}
{{- end }}
{{- end }}
Expand Down
29 changes: 24 additions & 5 deletions openstack/utils/templates/_proxysql_secret.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,34 @@
{{- $max_pool_size := coalesce .Values.max_pool_size .Values.global.max_pool_size 50 }}
{{- $max_overflow := coalesce .Values.max_overflow .Values.global.max_overflow 5 }}
{{- $max_connections := .Values.proxysql.max_connections_per_proc | default (add $max_pool_size $max_overflow) }}

{{/* Default: use mariadb dependencies chart values */}}
{{- $dbs := dict }}
{{- range $d := $envAll.Chart.Dependencies }}
{{- if hasPrefix "mariadb" $d.Name }}
{{- $_ := set $dbs $d.Name (get $envAll.Values $d.Name) }}
{{- $_ := set $dbs $d.Name (merge (get $envAll.Values $d.Name) (dict "serviceSuffix" "mariadb")) }}
{{- end }}
{{- end }}
{{- range $d := $envAll.Values.proxysql.force_enable }}
{{- $_ := set $dbs $d (get $envAll.Values $d) }}
{{/* Option 1: use pxc-db dependencies chart values conditionally */}}
{{- if and ($envAll.Values.dbType ) (eq $envAll.Values.dbType "pxc-db") }}
{{- $dbs = dict }}
{{- range $d := $envAll.Chart.Dependencies }}
{{- if hasPrefix "pxc" $d.Name }}
{{- $_ := set $dbs $d.Name (merge (get $envAll.Values $d.Name) (dict "serviceSuffix" "db-haproxy")) }}
{{- end }}
{{- end }}
{{- end }}
{{/* Option 2: use override from proxysql.force_enable value */}}
{{- if $envAll.Values.proxysql.force_enable }}
{{- $dbs = dict }}
{{- range $d := $envAll.Values.proxysql.force_enable }}
{{- if hasPrefix "mariadb" $d }}
{{- $_ := set $dbs $d (merge (get $envAll.Values $d) (dict "serviceSuffix" "mariadb")) }}
{{- else if hasPrefix "pxc" $d }}
{{- $_ := set $dbs $d (merge (get $envAll.Values $d) (dict "serviceSuffix" "db-haproxy")) }}
{{- else }}
{{ fail (printf "unknown database type: %s" $d) }}
{{- end }}
{{- end }}
{{- end }}
{{- $dbKeys := keys $dbs | sortAlpha }}
apiVersion: v1
Expand All @@ -31,7 +50,7 @@ metadata:
{{- end }}
data:
proxysql.cnf: |
{{ include "utils.snippets.set_proxysql_config" (dict "max_connections" $max_connections "dbs" $dbs "dbKeys" $dbKeys "global" $ ) | b64enc | trim | indent 4 }}
{{ include "utils.snippets.set_proxysql_config" (dict "max_connections" $max_connections "dbs" $dbs "dbKeys" $dbKeys "global" $ ) | b64enc | trim | indent 4 }}
{{- end }}
{{- end }}
{{- end }}
Loading

0 comments on commit 150dc28

Please sign in to comment.