From 7679feea3af07a8fc00ce05d0a5f87bb6c395fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Fri, 7 Feb 2025 13:23:34 +0100 Subject: [PATCH] Define more options for postgresql connection (#168) * Define more options for postgresql connection * Create seven-chefs-knock.md --- .changeset/seven-chefs-knock.md | 5 ++ charts/openproject/templates/secret_core.yaml | 57 ++++++++++++++ charts/openproject/values.yaml | 71 ++++++++++++++++-- .../openproject/postgres_options_spec.rb | 74 +++++++++++++++++++ 4 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 .changeset/seven-chefs-knock.md create mode 100644 spec/charts/openproject/postgres_options_spec.rb diff --git a/.changeset/seven-chefs-knock.md b/.changeset/seven-chefs-knock.md new file mode 100644 index 0000000..e9de6b7 --- /dev/null +++ b/.changeset/seven-chefs-knock.md @@ -0,0 +1,5 @@ +--- +"@openproject/helm-charts": minor +--- + +Define more options for postgresql connection diff --git a/charts/openproject/templates/secret_core.yaml b/charts/openproject/templates/secret_core.yaml index 5c37a63..0e8b688 100644 --- a/charts/openproject/templates/secret_core.yaml +++ b/charts/openproject/templates/secret_core.yaml @@ -16,6 +16,63 @@ stringData: DATABASE_PORT: "{{ .Values.postgresql.connection.port }}" DATABASE_URL: "postgresql://{{ .Values.postgresql.auth.username }}@{{ .Values.postgresql.connection.host }}:{{ .Values.postgresql.connection.port }}/{{ .Values.postgresql.auth.database }}" {{- end }} + {{- if .Values.postgresql.options.pool }} + OPENPROJECT_DB_POOL: {{ .Values.postgresql.options.pool | toString }} + {{- end }} + {{- if .Values.postgresql.options.requireAuth }} + OPENPROJECT_DB_REQUIRE_AUTH: {{ .Values.postgresql.options.requireAuth | toString }} + {{- end }} + {{- if .Values.postgresql.options.channelBinding }} + OPENPROJECT_DB_CHANNEL_BINDING: {{ .Values.postgresql.options.channelBinding | toString }} + {{- end }} + {{- if .Values.postgresql.options.connectTimeout }} + OPENPROJECT_DB_CONNECT_TIMEOUT: {{ .Values.postgresql.options.connectTimeout | toString }} + {{- end }} + {{- if .Values.postgresql.options.clientEncoding }} + OPENPROJECT_DB_CLIENT_ENCODING: {{ .Values.postgresql.options.clientEncoding | toString }} + {{- end }} + {{- if .Values.postgresql.options.keepalives }} + OPENPROJECT_DB_KEEPALIVES: {{ .Values.postgresql.options.keepalives | toString }} + {{- end }} + {{- if .Values.postgresql.options.keepalivesIdle }} + OPENPROJECT_DB_KEEPALIVES_IDLE: {{ .Values.postgresql.options.keepalivesIdle | toString }} + {{- end }} + {{- if .Values.postgresql.options.keepalivesInterval }} + OPENPROJECT_DB_KEEPALIVES_INTERVAL: {{ .Values.postgresql.options.keepalivesInterval | toString }} + {{- end }} + {{- if .Values.postgresql.options.keepalivesCount }} + OPENPROJECT_DB_KEEPALIVES_COUNT: {{ .Values.postgresql.options.keepalivesCount | toString }} + {{- end }} + {{- if .Values.postgresql.options.replication }} + OPENPROJECT_DB_REPLICATION: {{ .Values.postgresql.options.replication | toString }} + {{- end }} + {{- if .Values.postgresql.options.gssencmode }} + OPENPROJECT_DB_GSSENCMODE: {{ .Values.postgresql.options.gssencmode | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslmode }} + OPENPROJECT_DB_SSLMODE: {{ .Values.postgresql.options.sslmode | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslcompression }} + OPENPROJECT_DB_SSLCOMPRESSION: {{ .Values.postgresql.options.sslcompression | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslcert }} + OPENPROJECT_DB_SSLCERT: {{ .Values.postgresql.options.sslcert | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslkey }} + OPENPROJECT_DB_SSLKEY: {{ .Values.postgresql.options.sslkey | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslpassword }} + OPENPROJECT_DB_SSLPASSWORD: {{ .Values.postgresql.options.sslpassword | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslrootcert }} + OPENPROJECT_DB_SSLROOTCERT: {{ .Values.postgresql.options.sslrootcert | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslcrl }} + OPENPROJECT_DB_SSLCRL: {{ .Values.postgresql.options.sslcrl | toString }} + {{- end }} + {{- if .Values.postgresql.options.sslMinProtocolVersion }} + OPENPROJECT_DB_SSL_MIN_PROTOCOL_VERSION: {{ .Values.postgresql.options.sslMinProtocolVersion | toString }} + {{- end }} OPENPROJECT_SEED_ADMIN_USER_PASSWORD: {{ .Values.openproject.admin_user.password | quote }} OPENPROJECT_SEED_ADMIN_USER_PASSWORD_RESET: {{ .Values.openproject.admin_user.password_reset | quote }} OPENPROJECT_SEED_ADMIN_USER_NAME: {{ .Values.openproject.admin_user.name | quote }} diff --git a/charts/openproject/values.yaml b/charts/openproject/values.yaml index b382cb9..8e5ae07 100644 --- a/charts/openproject/values.yaml +++ b/charts/openproject/values.yaml @@ -599,11 +599,72 @@ postgresql: # postgresPassword: "" - ## When using the "bundled" postgresql chart, you can configure the storageClass and other settings similar to this - ## Ref: https://github.com/bitnami/charts/blob/main/bitnami/postgresql/values.yaml - # - # global: - # storageClass: my-storage-class-name + ## + # Additional connection options + # See https://www.postgresql.org/docs/current/libpq-connect.html for additional details + options: + # Define a pool size for the Rails connection pool + # https://guides.rubyonrails.org/configuring.html#database-pooling + pool: + + # Specifies the authentication method that the client requires from the server. + requireAuth: + + # This option controls the client's use of channel binding. + channelBinding: + + # Maximum time to wait while connecting, in seconds. + connectTimeout: + + # This sets the client_encoding configuration parameter for this connection. + clientEncoding: + + # Controls whether client-side TCP keepalives are used. + keepalives: + + # Controls the number of seconds of inactivity after which TCP should send a keepalive message to the server. + keepalivesIdle: + + # Controls the number of seconds after which a TCP keepalive message that is not acknowledged by the server + # should be retransmitted. + keepalivesInterval: + + # Controls the number of TCP keepalives that can be lost before the client's connection to the server is + # considered dead + keepalivesCount: + + # This option determines whether the connection should use the replication protocol instead of the normal + # protocol. + replication: + + # This option determines whether or with what priority a secure GSS TCP/IP connection will be negotiated with the + # server. + gssencmode: + + # This option determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the + # server. + sslmode: + + # If set to 1, data sent over SSL connections will be compressed. + sslcompression: + + # This parameter specifies the file name of the client SSL certificate + sslcert: + + # This parameter specifies the location for the secret key used for the client certificate. + sslkey: + + # This parameter specifies the password for the secret key specified in sslkey + sslpassword: + + # This parameter specifies the name of a file containing SSL certificate authority (CA) certificate(s) + sslrootcert: + + # This parameter specifies the file name of the SSL server certificate revocation list (CRL). + sslcrl: + + # This parameter specifies the minimum SSL/TLS protocol version to allow for the connection + sslMinProtocolVersion: ## Configure liveness and readiness probes. ## diff --git a/spec/charts/openproject/postgres_options_spec.rb b/spec/charts/openproject/postgres_options_spec.rb new file mode 100644 index 0000000..cb3ddaa --- /dev/null +++ b/spec/charts/openproject/postgres_options_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe 'PostgreSQL options' do + let(:template) { HelmTemplate.new(default_values) } + + subject { template.dig('Secret/optest-openproject-core', 'stringData') } + + context 'when setting extraOidcSealedSecret' do + let(:default_values) do + HelmTemplate.with_defaults(<<~YAML + postgresql: + options: + pool: 5 + requireAuth: true + channelBinding: require + connectTimeout: 15 + clientEncoding: UTF8 + keepalives: 1 + keepalivesIdle: 30 + keepalivesInterval: 10 + keepalivesCount: 5 + replication: "on" + gssencmode: disable + sslmode: require + sslcompression: 1 + sslMinProtocolVersion: TLSv1.2 + sslcert: /etc/ssl/certs/client-cert.pem + sslkey: /etc/ssl/private/client-key.pem + sslpassword: my-secure-password + sslrootcert: /etc/ssl/certs/ca-cert.pem + sslcrl: /etc/ssl/crl/server-crl.pem + YAML + ) + end + + it 'adds that secret ref to relevant deployments', :aggregate_failures do + { + "OPENPROJECT_DB_POOL" => 5, + "OPENPROJECT_DB_REQUIRE_AUTH" => true, + "OPENPROJECT_DB_CHANNEL_BINDING" => "require", + "OPENPROJECT_DB_CONNECT_TIMEOUT" => 15, + "OPENPROJECT_DB_CLIENT_ENCODING" => "UTF8", + "OPENPROJECT_DB_KEEPALIVES" => 1, + "OPENPROJECT_DB_KEEPALIVES_IDLE" => 30, + "OPENPROJECT_DB_KEEPALIVES_INTERVAL" => 10, + "OPENPROJECT_DB_KEEPALIVES_COUNT" => 5, + "OPENPROJECT_DB_REPLICATION" => true, + "OPENPROJECT_DB_GSSENCMODE" => "disable", + "OPENPROJECT_DB_SSLMODE" => "require", + "OPENPROJECT_DB_SSLCOMPRESSION" => 1, + "OPENPROJECT_DB_SSLCERT" => "/etc/ssl/certs/client-cert.pem", + "OPENPROJECT_DB_SSLKEY" => "/etc/ssl/private/client-key.pem", + "OPENPROJECT_DB_SSLPASSWORD" => "my-secure-password", + "OPENPROJECT_DB_SSLROOTCERT" => "/etc/ssl/certs/ca-cert.pem", + "OPENPROJECT_DB_SSLCRL" => "/etc/ssl/crl/server-crl.pem", + "OPENPROJECT_DB_SSL_MIN_PROTOCOL_VERSION" => "TLSv1.2", + }.each do |key, val| + expect(subject[key]).to eq(val) + end + end + end + + context 'when setting no imagePullSecrets' do + let(:default_values) do + {} + end + + it 'adds the default secrets', :aggregate_failures do + db_keys = subject.keys.select { |k| k.start_with?('OPENPROJECT_DB_') } + expect(db_keys).to be_empty + end + end +end