diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f816783..231d696 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,56 +33,27 @@ jobs: validate-configs: runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 30 + permissions: + contents: read + env: + PGDOG_IMAGE: ghcr.io/pgdogdev/pgdog-enterprise:main-ent steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Checkout pgdog-enterprise - uses: actions/checkout@v4 - with: - repository: pgdogdev/pgdog-enterprise - ref: main-ent - path: pgdog-source - token: ${{ secrets.PGDOG_ENTERPRISE_TOKEN }} - - name: Install Helm uses: azure/setup-helm@v4 with: - version: 'latest' + version: latest - name: Install yq uses: mikefarah/yq@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Cache Rust dependencies - uses: actions/cache@v4 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - pgdog-source/target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('pgdog-source/**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - - name: Install CMake 3.31 - run: | - sudo apt update && sudo apt install mold -y - sudo apt remove cmake - sudo pip3 install cmake==3.31.6 - - - name: Build pgdog - run: cargo build --bin pgdog - working-directory: pgdog-source + - name: Pull pgdog image + run: docker pull "$PGDOG_IMAGE" - - name: Validate configs + - name: Validate generated pgdog configs run: | set -eo pipefail for values_file in test/values-*.yaml; do @@ -90,6 +61,9 @@ jobs: echo "==> Validating config for $name..." rm -f /tmp/pgdog.toml ./test/generate-config.sh "$values_file" /tmp/pgdog.toml - ./pgdog-source/target/debug/pgdog --config=/tmp/pgdog.toml configcheck + docker run --rm \ + -v /tmp/pgdog.toml:/tmp/pgdog.toml:ro \ + "$PGDOG_IMAGE" \ + /usr/local/bin/pgdog --config=/tmp/pgdog.toml configcheck done echo "==> All configs valid!" diff --git a/Chart.yaml b/Chart.yaml index eb1d72c..b1cb622 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: pgdog -version: v0.67 +version: v0.68 appVersion: "0.1.44" diff --git a/scripts/schema-overrides.yaml b/scripts/schema-overrides.yaml index 03935b4..a70b56c 100644 --- a/scripts/schema-overrides.yaml +++ b/scripts/schema-overrides.yaml @@ -505,65 +505,6 @@ grafanaRemoteWrite.queueConfig.maxBackoff: serviceMonitor.enabled: type: boolean -# --- Gateway labels/scheduling --- -gateway.labels: - type: object -gateway.selectorLabels: - type: object -gateway.nodeSelector: - type: object -gateway.tolerations: - type: array - items: - type: object -gateway.affinity: - type: object -gateway.service.annotations: - type: object - -# --- Gateway --- -gateway.enabled: - type: boolean -gateway.connectFromPgdog: - type: boolean -gateway.image.pullPolicy: - enum: ["Always", "IfNotPresent", "Never"] -gateway.image.name: - type: string -gateway.port: - type: integer - minimum: 1 - maximum: 65535 -gateway.bindAddress: - type: string -gateway.service.type: - enum: ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"] -gateway.tls.existingSecret: - type: string -gateway.tls.certPath: - type: string -gateway.tls.keyPath: - type: string -gateway.control.url: - type: string -gateway.control.token: - type: string -gateway.stats.activeQueriesInterval: - type: integer - minimum: 0 -gateway.stats.pingInterval: - type: integer - minimum: 0 -gateway.stats.pushInterval: - type: integer - minimum: 0 -gateway.stats.configInterval: - type: integer - minimum: 0 -gateway.stats.queryStatsInterval: - type: integer - minimum: 0 - # --- Prometheus collector labels/scheduling --- prometheusCollector.labels: type: object diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 780ae1a..e5e161d 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -60,32 +60,6 @@ app.kubernetes.io/component: pgdog {{- end }} {{- end }} -{{/* -Common labels for gateway -*/}} -{{- define "pgdog.gateway.labels" -}} -{{- if .Values.gateway.labels }} -{{- toYaml .Values.gateway.labels }} -{{- else -}} -app.kubernetes.io/name: {{ include "pgdog.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.kubernetes.io/component: gateway -{{- end }} -{{- end }} - -{{/* -Selector labels for gateway -*/}} -{{- define "pgdog.gateway.selectorLabels" -}} -{{- if .Values.gateway.selectorLabels }} -{{- toYaml .Values.gateway.selectorLabels }} -{{- else -}} -app.kubernetes.io/name: {{ include "pgdog.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.kubernetes.io/component: gateway -{{- end }} -{{- end }} - {{/* Common labels for prometheus-collector */}} diff --git a/templates/config.yaml b/templates/config.yaml index f344862..527eb50 100644 --- a/templates/config.yaml +++ b/templates/config.yaml @@ -4,25 +4,44 @@ metadata: name: {{ include "pgdog.fullname" . }} data: # This is pgdog.toml. You can configure anything here, incl. databases. - # Note: don't change the port value, since it's pulled from Values. pgdog.toml: | [general] + {{- if hasKey .Values "port" }} port = {{ include "pgdog.intval" .Values.port }} - workers = {{ include "pgdog.intval" (.Values.workers | default 2) }} - default_pool_size = {{ include "pgdog.intval" (.Values.defaultPoolSize | default 10) }} - log_format = {{ .Values.logFormat | default "text" | quote }} - log_level = {{ .Values.logLevel | default "info" | quote }} + {{- end }} + {{- if hasKey .Values "workers" }} + workers = {{ include "pgdog.intval" .Values.workers }} + {{- end }} + {{- if hasKey .Values "defaultPoolSize" }} + default_pool_size = {{ include "pgdog.intval" .Values.defaultPoolSize }} + {{- end }} + {{- if hasKey .Values "logFormat" }} + log_format = {{ .Values.logFormat | quote }} + {{- end }} + {{- if hasKey .Values "logLevel" }} + log_level = {{ .Values.logLevel | quote }} + {{- end }} {{- if hasKey .Values "minPoolSize" }} min_pool_size = {{ include "pgdog.intval" .Values.minPoolSize }} {{- end }} - pooler_mode = {{ .Values.poolerMode | default "transaction" | quote }} - {{- if .Values.healthcheckPort }} + {{- if hasKey .Values "poolerMode" }} + pooler_mode = {{ .Values.poolerMode | quote }} + {{- end }} + {{- if hasKey .Values "healthcheckPort" }} healthcheck_port = {{ include "pgdog.intval" .Values.healthcheckPort }} {{- end }} - healthcheck_interval = {{ include "pgdog.intval" (.Values.healthcheckInterval | default "30_000") }} - idle_healthcheck_interval = {{ include "pgdog.intval" (.Values.idleHealthcheckInterval | default "30_000") }} - idle_healthcheck_delay = {{ include "pgdog.intval" (.Values.idleHealthcheckDelay | default "5_000") }} - healthcheck_timeout = {{ include "pgdog.intval" (.Values.healthcheckTimeout | default "5_000") }} + {{- if hasKey .Values "healthcheckInterval" }} + healthcheck_interval = {{ include "pgdog.intval" .Values.healthcheckInterval }} + {{- end }} + {{- if hasKey .Values "idleHealthcheckInterval" }} + idle_healthcheck_interval = {{ include "pgdog.intval" .Values.idleHealthcheckInterval }} + {{- end }} + {{- if hasKey .Values "idleHealthcheckDelay" }} + idle_healthcheck_delay = {{ include "pgdog.intval" .Values.idleHealthcheckDelay }} + {{- end }} + {{- if hasKey .Values "healthcheckTimeout" }} + healthcheck_timeout = {{ include "pgdog.intval" .Values.healthcheckTimeout }} + {{- end }} {{- if hasKey .Values "banTimeout" }} ban_timeout = {{ include "pgdog.intval" .Values.banTimeout }} {{- end }} @@ -32,10 +51,16 @@ data: {{- if hasKey .Values "banReplicaLagBytes" }} ban_replica_lag_bytes = {{ include "pgdog.intval" .Values.banReplicaLagBytes }} {{- end }} - rollback_timeout = {{ include "pgdog.intval" (.Values.rollbackTimeout | default "5_000") }} - load_balancing_strategy = {{ .Values.loadBalancingStrategy | default "round_robin" | quote }} - read_write_strategy = {{ .Values.readWriteStrategy | default "conservative" | quote }} - {{- if .Values.readWriteSplit }} + {{- if hasKey .Values "rollbackTimeout" }} + rollback_timeout = {{ include "pgdog.intval" .Values.rollbackTimeout }} + {{- end }} + {{- if hasKey .Values "loadBalancingStrategy" }} + load_balancing_strategy = {{ .Values.loadBalancingStrategy | quote }} + {{- end }} + {{- if hasKey .Values "readWriteStrategy" }} + read_write_strategy = {{ .Values.readWriteStrategy | quote }} + {{- end }} + {{- if hasKey .Values "readWriteSplit" }} read_write_split = {{ .Values.readWriteSplit | quote }} {{- end }} {{- if .Values.tlsGenerateSelfSignedCert }} @@ -49,18 +74,26 @@ data: tls_private_key = {{ .Values.tlsPrivateKey | quote }} {{- end }} {{- end }} - tls_client_required = {{ hasKey .Values "tlsClientRequired" | ternary .Values.tlsClientRequired "false" }} - tls_verify = {{ .Values.tlsVerify | default "prefer" | quote }} + {{- if hasKey .Values "tlsClientRequired" }} + tls_client_required = {{ .Values.tlsClientRequired }} + {{- end }} + {{- if hasKey .Values "tlsVerify" }} + tls_verify = {{ .Values.tlsVerify | quote }} + {{- end }} {{- if and .Values.rdsCertificateBundle .Values.rdsCertificateBundle.enabled }} tls_server_ca_certificate = "/etc/pgdog-rds-ca/rds-ca-bundle.pem" {{- else if .Values.tlsServerCaCertificate }} tls_server_ca_certificate = {{ .Values.tlsServerCaCertificate | quote }} {{- end}} - shutdown_timeout = {{ include "pgdog.intval" (.Values.shutdownTimeout | default "60_000") }} - {{- if .Values.shutdownTerminationTimeout }} + {{- if hasKey .Values "shutdownTimeout" }} + shutdown_timeout = {{ include "pgdog.intval" .Values.shutdownTimeout }} + {{- end }} + {{- if hasKey .Values "shutdownTerminationTimeout" }} shutdown_termination_timeout = {{ include "pgdog.intval" .Values.shutdownTerminationTimeout }} {{- end }} - prepared_statements = {{ .Values.preparedStatements | default "extended" | quote }} + {{- if hasKey .Values "preparedStatements" }} + prepared_statements = {{ .Values.preparedStatements | quote }} + {{- end }} {{- with .Values.queryParser }} query_parser = {{ . | quote }} {{- else }} @@ -68,119 +101,153 @@ data: query_parser_enabled = {{ . }} {{- end }} {{- end }} - {{- if .Values.queryParserEngine }} + {{- if hasKey .Values "queryParserEngine" }} query_parser_engine = {{ .Values.queryParserEngine | quote }} {{- end }} - {{- if .Values.logMinDurationParse }} + {{- if hasKey .Values "logMinDurationParse" }} log_min_duration_parse = {{ include "pgdog.intval" .Values.logMinDurationParse }} {{- end }} - {{- if .Values.logQuerySampleLength }} + {{- if hasKey .Values "logQuerySampleLength" }} log_query_sample_length = {{ include "pgdog.intval" .Values.logQuerySampleLength }} {{- end }} - {{- if .Values.regexParserLimit }} + {{- if hasKey .Values "regexParserLimit" }} regex_parser_limit = {{ include "pgdog.intval" .Values.regexParserLimit }} {{- end }} - {{- if .Values.preparedStatementsLimit }} + {{- if hasKey .Values "preparedStatementsLimit" }} prepared_statements_limit = {{ include "pgdog.intval" .Values.preparedStatementsLimit }} {{- end}} - {{- if .Values.queryCacheLimit }} + {{- if hasKey .Values "queryCacheLimit" }} query_cache_limit = {{ include "pgdog.intval" .Values.queryCacheLimit }} {{- end }} - passthrough_auth = {{ .Values.passthroughAuth | default "disabled" | quote }} - connect_timeout = {{ include "pgdog.intval" (.Values.connectTimeout | default "5_000") }} - connect_attempts = {{ include "pgdog.intval" (.Values.connectAttempts | default 1) }} - connect_attempt_delay = {{ include "pgdog.intval" (.Values.connectAttemptDelay | default 0) }} - {{- if .Values.queryTimeout }} + {{- if hasKey .Values "passthroughAuth" }} + passthrough_auth = {{ .Values.passthroughAuth | quote }} + {{- end }} + {{- if hasKey .Values "connectTimeout" }} + connect_timeout = {{ include "pgdog.intval" .Values.connectTimeout }} + {{- end }} + {{- if hasKey .Values "connectAttempts" }} + connect_attempts = {{ include "pgdog.intval" .Values.connectAttempts }} + {{- end }} + {{- if hasKey .Values "connectAttemptDelay" }} + connect_attempt_delay = {{ include "pgdog.intval" .Values.connectAttemptDelay }} + {{- end }} + {{- if hasKey .Values "queryTimeout" }} query_timeout = {{ include "pgdog.intval" .Values.queryTimeout }} {{- end }} - {{- if .Values.clientIdleInTransactionTimeout }} + {{- if hasKey .Values "clientIdleInTransactionTimeout" }} client_idle_in_transaction_timeout = {{ include "pgdog.intval" .Values.clientIdleInTransactionTimeout }} {{- end }} - checkout_timeout = {{ include "pgdog.intval" (.Values.checkoutTimeout | default "5_000") }} - dry_run = {{ hasKey .Values "dryRun" | ternary .Values.dryRun "false" }} + {{- if hasKey .Values "checkoutTimeout" }} + checkout_timeout = {{ include "pgdog.intval" .Values.checkoutTimeout }} + {{- end }} + {{- if hasKey .Values "dryRun" }} + dry_run = {{ .Values.dryRun }} + {{- end }} {{- if hasKey .Values "twoPhaseCommit" }} two_phase_commit = {{ .Values.twoPhaseCommit }} {{- end }} {{- if hasKey .Values "twoPhaseCommitAuto" }} two_phase_commit_auto = {{ .Values.twoPhaseCommitAuto }} {{- end }} - {{- if .Values.twoPhaseCommitWalDir }} + {{- if hasKey .Values "twoPhaseCommitWalDir" }} two_phase_commit_wal_dir = {{ .Values.twoPhaseCommitWalDir | quote }} {{- end }} - {{- if .Values.twoPhaseCommitWalSegmentSize }} + {{- if hasKey .Values "twoPhaseCommitWalSegmentSize" }} two_phase_commit_wal_segment_size = {{ include "pgdog.intval" .Values.twoPhaseCommitWalSegmentSize }} {{- end }} - {{- if .Values.twoPhaseCommitWalFsyncInterval }} + {{- if hasKey .Values "twoPhaseCommitWalFsyncInterval" }} two_phase_commit_wal_fsync_interval = {{ include "pgdog.intval" .Values.twoPhaseCommitWalFsyncInterval }} {{- end }} - {{- if .Values.twoPhaseCommitWalCheckpointInterval }} + {{- if hasKey .Values "twoPhaseCommitWalCheckpointInterval" }} two_phase_commit_wal_checkpoint_interval = {{ include "pgdog.intval" .Values.twoPhaseCommitWalCheckpointInterval }} {{- end }} - {{- if .Values.systemCatalogs }} + {{- if hasKey .Values "systemCatalogs" }} system_catalogs = {{ .Values.systemCatalogs | quote }} {{- end }} {{- if hasKey .Values "omnishardedSticky" }} omnisharded_sticky = {{ .Values.omnishardedSticky }} {{- end }} - {{- if .Values.reshardingCopyFormat }} + {{- if hasKey .Values "reshardingCopyFormat" }} resharding_copy_format = {{ .Values.reshardingCopyFormat | quote }} {{- end }} - {{- if .Values.reshardingParallelCopies }} + {{- if hasKey .Values "reshardingParallelCopies" }} resharding_parallel_copies = {{ include "pgdog.intval" .Values.reshardingParallelCopies }} {{- end }} - {{- if .Values.reshardingCopyRetryMaxAttempts }} + {{- if hasKey .Values "reshardingCopyRetryMaxAttempts" }} resharding_copy_retry_max_attempts = {{ include "pgdog.intval" .Values.reshardingCopyRetryMaxAttempts }} {{- end }} - {{- if .Values.reshardingCopyRetryMinDelay }} + {{- if hasKey .Values "reshardingCopyRetryMinDelay" }} resharding_copy_retry_min_delay = {{ include "pgdog.intval" .Values.reshardingCopyRetryMinDelay }} {{- end }} {{- if hasKey .Values "reloadSchemaOnDdl" }} reload_schema_on_ddl = {{ .Values.reloadSchemaOnDdl }} {{- end }} - {{- if .Values.loadSchema }} + {{- if hasKey .Values "loadSchema" }} load_schema = {{ .Values.loadSchema | quote }} {{- end }} - {{- if .Values.idleTimeout }} + {{- if hasKey .Values "idleTimeout" }} idle_timeout = {{ include "pgdog.intval" .Values.idleTimeout }} {{- end }} - {{- if .Values.clientIdleTimeout }} + {{- if hasKey .Values "clientIdleTimeout" }} client_idle_timeout = {{ include "pgdog.intval" .Values.clientIdleTimeout }} {{- end }} - {{- if .Values.clientLoginTimeout }} + {{- if hasKey .Values "clientLoginTimeout" }} client_login_timeout = {{ include "pgdog.intval" .Values.clientLoginTimeout }} {{- end }} - mirror_queue = {{ include "pgdog.intval" (.Values.mirrorQueue | default 128) }} - mirror_exposure = {{ .Values.mirrorExposure | default "1.0" }} - auth_type = {{ .Values.authType | default "scram" | quote }} - cross_shard_disabled = {{ hasKey .Values "crossShardDisabled" | ternary .Values.crossShardDisabled "false" }} - {{- if .Values.dnsTtl }} + {{- if hasKey .Values "mirrorQueue" }} + mirror_queue = {{ include "pgdog.intval" .Values.mirrorQueue }} + {{- end }} + {{- if hasKey .Values "mirrorExposure" }} + mirror_exposure = {{ .Values.mirrorExposure }} + {{- end }} + {{- if hasKey .Values "authType" }} + auth_type = {{ .Values.authType | quote }} + {{- end }} + {{- if hasKey .Values "crossShardDisabled" }} + cross_shard_disabled = {{ .Values.crossShardDisabled }} + {{- end }} + {{- if hasKey .Values "dnsTtl" }} dns_ttl = {{ include "pgdog.intval" .Values.dnsTtl }} {{- end }} - {{- if .Values.pubSubChannelSize }} + {{- if hasKey .Values "pubSubChannelSize" }} pub_sub_channel_size = {{ include "pgdog.intval" .Values.pubSubChannelSize }} {{- end }} - openmetrics_port = {{ include "pgdog.intval" (.Values.openMetricsPort | default 9090) }} - openmetrics_namespace = {{ .Values.openMetricsNamespace | default "pgdog_" | quote }} - server_lifetime = {{ include "pgdog.intval" (.Values.serverLifetime | default 86400000) }} - server_lifetime_jitter = {{ include "pgdog.intval" (.Values.serverLifetimeJitter | default 0) }} - log_connections = {{ hasKey .Values "logConnections" | ternary .Values.logConnections "true" }} - log_disconnections = {{ hasKey .Values "logDisconnections" | ternary .Values.logDisconnections "true" }} - {{- if .Values.logDedupThreshold }} + {{- if hasKey .Values "openMetricsPort" }} + openmetrics_port = {{ include "pgdog.intval" .Values.openMetricsPort }} + {{- end }} + {{- if hasKey .Values "openMetricsNamespace" }} + openmetrics_namespace = {{ .Values.openMetricsNamespace | quote }} + {{- end }} + {{- if hasKey .Values "serverLifetime" }} + server_lifetime = {{ include "pgdog.intval" .Values.serverLifetime }} + {{- end }} + {{- if hasKey .Values "serverLifetimeJitter" }} + server_lifetime_jitter = {{ include "pgdog.intval" .Values.serverLifetimeJitter }} + {{- end }} + {{- if hasKey .Values "logConnections" }} + log_connections = {{ .Values.logConnections }} + {{- end }} + {{- if hasKey .Values "logDisconnections" }} + log_disconnections = {{ .Values.logDisconnections }} + {{- end }} + {{- if hasKey .Values "logDedupThreshold" }} log_dedup_threshold = {{ include "pgdog.intval" .Values.logDedupThreshold }} {{- end }} - {{- if .Values.logDedupWindow }} + {{- if hasKey .Values "logDedupWindow" }} log_dedup_window = {{ include "pgdog.intval" .Values.logDedupWindow }} {{- end }} - {{- if .Values.statsPeriod }} + {{- if hasKey .Values "statsPeriod" }} stats_period = {{ include "pgdog.intval" .Values.statsPeriod }} {{- end }} - {{- if .Values.connectionRecovery }} + {{- if hasKey .Values "connectionRecovery" }} connection_recovery = {{ .Values.connectionRecovery | quote }} {{- end }} - {{- if .Values.clientConnectionRecovery }} + {{- if hasKey .Values "clientConnectionRecovery" }} client_connection_recovery = {{ .Values.clientConnectionRecovery | quote }} {{- end }} - expanded_explain = {{ hasKey .Values "expandedExplain" | ternary .Values.expandedExplain "false" }} + {{- if hasKey .Values "expandedExplain" }} + expanded_explain = {{ .Values.expandedExplain }} + {{- end }} {{- if hasKey .Values "lsnCheckDelay" }} lsn_check_delay = {{ include "pgdog.intval" .Values.lsnCheckDelay }} {{- end }} @@ -190,13 +257,13 @@ data: {{- if hasKey .Values "lsnCheckTimeout" }} lsn_check_timeout = {{ include "pgdog.intval" .Values.lsnCheckTimeout }} {{- end }} - {{- if .Values.rewriteShardKeyUpdates }} + {{- if hasKey .Values "rewriteShardKeyUpdates" }} rewrite_shard_key_updates = {{ .Values.rewriteShardKeyUpdates | quote }} {{- end }} {{- if hasKey .Values "uniqueIdMin" }} unique_id_min = {{ include "pgdog.intval" .Values.uniqueIdMin }} {{- end }} - {{- if .Values.uniqueIdFunction }} + {{- if hasKey .Values "uniqueIdFunction" }} unique_id_function = {{ .Values.uniqueIdFunction | quote }} {{- end }} {{- if hasKey .Values "cutoverTrafficStopThreshold" }} @@ -211,7 +278,7 @@ data: {{- if hasKey .Values "cutoverTimeout" }} cutover_timeout = {{ include "pgdog.intval" .Values.cutoverTimeout }} {{- end }} - {{- if .Values.cutoverTimeoutAction }} + {{- if hasKey .Values "cutoverTimeoutAction" }} cutover_timeout_action = {{ .Values.cutoverTimeoutAction | quote }} {{- end }} {{- if hasKey .Values "cutoverSaveConfig" }} @@ -222,45 +289,49 @@ data: [[databases]] name = {{ .name | quote }} host = {{ .host | quote }} - port = {{ include "pgdog.intval" (.port | default 5432) }} - shard = {{ include "pgdog.intval" (.shard | default 0) }} - {{- if .databaseName }} + {{- if hasKey . "port" }} + port = {{ include "pgdog.intval" .port }} + {{- end }} + {{- if hasKey . "shard" }} + shard = {{ include "pgdog.intval" .shard }} + {{- end }} + {{- if hasKey . "databaseName" }} database_name = {{ .databaseName | quote }} {{- end }} - {{- if .user }} + {{- if hasKey . "user" }} user = {{ .user | quote }} {{- end }} - {{- if .password }} + {{- if hasKey . "password" }} password = {{ .password | quote }} {{- end }} - {{- if .poolSize }} + {{- if hasKey . "poolSize" }} pool_size = {{ include "pgdog.intval" .poolSize }} {{- end }} - {{- if .minPoolSize }} + {{- if hasKey . "minPoolSize" }} min_pool_size = {{ include "pgdog.intval" .minPoolSize }} {{- end }} - {{- if .poolerMode }} + {{- if hasKey . "poolerMode" }} pooler_mode = {{ .poolerMode | quote }} {{- end }} - {{- if .statementTimeout }} + {{- if hasKey . "statementTimeout" }} statement_timeout = {{ include "pgdog.intval" .statementTimeout }} {{- end }} - {{- if .idleTimeout }} + {{- if hasKey . "idleTimeout" }} idle_timeout = {{ include "pgdog.intval" .idleTimeout }} {{- end }} - {{- if .readOnly }} + {{- if hasKey . "readOnly" }} read_only = {{ .readOnly }} {{- end }} - {{- if .role }} + {{- if hasKey . "role" }} role = {{ .role | quote }} {{- end }} - {{- if .serverLifetime }} + {{- if hasKey . "serverLifetime" }} server_lifetime = {{ include "pgdog.intval" .serverLifetime }} {{- end }} - {{- if .reshardingOnly }} + {{- if hasKey . "reshardingOnly" }} resharding_only = {{ .reshardingOnly }} {{- end }} - {{- if .lbWeight }} + {{- if hasKey . "lbWeight" }} lb_weight = {{ include "pgdog.intval" .lbWeight }} {{- end }} {{- end }} @@ -269,13 +340,15 @@ data: [[mirroring]] source_db = {{ .sourceDb | quote }} destination_db = {{ .destinationDb | quote }} - {{- if or .queueLength .queueDepth }} - queue_length = {{ include "pgdog.intval" (.queueLength | default .queueDepth) }} + {{- if hasKey . "queueLength" }} + queue_length = {{ include "pgdog.intval" .queueLength }} + {{- else if hasKey . "queueDepth" }} + queue_length = {{ include "pgdog.intval" .queueDepth }} {{- end}} - {{- if .exposure }} + {{- if hasKey . "exposure" }} exposure = {{ .exposure }} {{- end }} - {{- if .level }} + {{- if hasKey . "level" }} level = {{ .level | quote }} {{- end }} {{- end }} @@ -283,7 +356,7 @@ data: {{- range .Values.shardedSchemas }} [[sharded_schemas]] database = {{ .database | quote }} - {{- if .name }} + {{- if hasKey . "name" }} name = {{ .name | quote }} {{- end }} shard = {{ include "pgdog.intval" .shard }} @@ -292,7 +365,7 @@ data: {{- range .Values.shardedTables }} [[sharded_tables]] database = {{ .database | quote }} - {{- if .name }} + {{- if hasKey . "name" }} name = {{ .name | quote }} {{- end }} column = {{ .column | quote }} @@ -305,13 +378,13 @@ data: column = {{ .column | quote }} kind = {{ .kind | quote }} shard = {{ include "pgdog.intval" .shard }} - {{- if .values }} + {{- if hasKey . "values" }} values = {{ .values| toToml }} {{- end }} - {{- if .start }} + {{- if hasKey . "start" }} start = {{ include "pgdog.intval" .start }} {{- end }} - {{- if .end }} + {{- if hasKey . "end" }} end = {{ include "pgdog.intval" .end }} {{- end}} {{- end }} @@ -319,12 +392,35 @@ data: {{- range .Values.omnishardedTables }} [[omnisharded_tables]] database = {{ .database | quote }} - {{- if .sticky }} + {{- if hasKey . "sticky" }} sticky = {{ .sticky }} {{- end }} tables = {{ .tables | toToml }} {{- end }} + {{- with .Values.autodiscovery }} + [autodiscovery] + {{- if hasKey . "enabled" }} + enabled = {{ .enabled }} + {{- end }} + {{- if hasKey . "checkInterval" }} + check_interval = {{ include "pgdog.intval" .checkInterval }} + {{- end }} + {{- if hasKey . "checkDelay" }} + check_delay = {{ include "pgdog.intval" .checkDelay }} + {{- end }} + {{- if hasKey . "checkTimeout" }} + check_timeout = {{ include "pgdog.intval" .checkTimeout }} + {{- end }} + {{- range .databases }} + [[autodiscovery.databases]] + name = {{ .name | quote }} + {{- if hasKey . "replicasOnly" }} + replicas_only = {{ .replicasOnly }} + {{- end }} + {{- end }} + {{- end }} + {{- range .Values.plugins }} [[plugins]] name = {{ .name | quote }} @@ -373,43 +469,42 @@ data: password = {{ .Values.adminPassword | quote }} {{- end }} - {{- if and .Values.gateway.enabled .Values.gateway.connectFromPgdog }} - [gateway] - address = "{{ include "pgdog.fullname" . }}-gateway.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.gateway.port | default 8443 }}" - {{- end }} - {{- if .Values.qos }} [qos] - enabled = {{ hasKey .Values.qos "enabled" | ternary .Values.qos.enabled "false" }} - max_entries = {{ include "pgdog.intval" (.Values.qos.maxEntries | default "10_000") }} + {{- if hasKey .Values.qos "enabled" }} + enabled = {{ .Values.qos.enabled }} + {{- end }} + {{- if hasKey .Values.qos "maxEntries" }} + max_entries = {{ include "pgdog.intval" .Values.qos.maxEntries }} + {{- end }} {{- end }} {{- with .Values.queryStats }} {{- if .enabled }} [query_stats] enabled = {{ .enabled }} - {{- if .maxEntries }} + {{- if hasKey . "maxEntries" }} max_entries = {{ include "pgdog.intval" .maxEntries }} {{- end }} - {{- if .queryPlansThreshold }} + {{- if hasKey . "queryPlansThreshold" }} query_plans_threshold = {{ include "pgdog.intval" .queryPlansThreshold }} {{- end }} - {{- if .queryPlansCache }} + {{- if hasKey . "queryPlansCache" }} query_plans_cache = {{ include "pgdog.intval" .queryPlansCache }} {{- end }} - {{- if .queryPlansSampleRate }} + {{- if hasKey . "queryPlansSampleRate" }} query_plans_sample_rate = {{ .queryPlansSampleRate }} {{- end }} - {{- if .queryPlansMaxAge }} + {{- if hasKey . "queryPlansMaxAge" }} query_plans_max_age = {{ include "pgdog.intval" .queryPlansMaxAge }} {{- end }} - {{- if .maxErrors }} + {{- if hasKey . "maxErrors" }} max_errors = {{ include "pgdog.intval" .maxErrors }} {{- end }} - {{- if .maxErrorAge }} + {{- if hasKey . "maxErrorAge" }} max_error_age = {{ include "pgdog.intval" .maxErrorAge }} {{- end }} - {{- if .idleInTransactionThreshold }} + {{- if hasKey . "idleInTransactionThreshold" }} idle_in_transaction_threshold = {{ include "pgdog.intval" .idleInTransactionThreshold }} {{- end }} {{- end }} @@ -418,31 +513,31 @@ data: {{- with .Values.control }} {{- if .enabled }} [control] - {{- if .endpoint }} + {{- if hasKey . "endpoint" }} endpoint = {{ .endpoint | quote }} {{- end }} - {{- if .token }} + {{- if hasKey . "token" }} token = {{ .token | quote }} {{- end }} - {{- if .metricsInterval }} + {{- if hasKey . "metricsInterval" }} metrics_interval = {{ include "pgdog.intval" .metricsInterval }} {{- end }} - {{- if .statsInterval }} + {{- if hasKey . "statsInterval" }} stats_interval = {{ include "pgdog.intval" .statsInterval }} {{- end }} - {{- if .activeQueriesInterval }} + {{- if hasKey . "activeQueriesInterval" }} active_queries_interval = {{ include "pgdog.intval" .activeQueriesInterval }} {{- end }} - {{- if .errorsInterval }} + {{- if hasKey . "errorsInterval" }} errors_interval = {{ include "pgdog.intval" .errorsInterval }} {{- end }} - {{- if .requestTimeout }} + {{- if hasKey . "requestTimeout" }} request_timeout = {{ include "pgdog.intval" .requestTimeout }} {{- end }} - {{- if .queryTimingsChunkSize }} + {{- if hasKey . "queryTimingsChunkSize" }} query_timings_chunk_size = {{ include "pgdog.intval" .queryTimingsChunkSize }} {{- end }} - {{- if .queryTimingsNewQueryQueueSize }} + {{- if hasKey . "queryTimingsNewQueryQueueSize" }} query_timings_new_query_queue_size = {{ include "pgdog.intval" .queryTimingsNewQueryQueueSize }} {{- end }} {{- end }} @@ -450,10 +545,18 @@ data: {{- if .Values.rewrite }} [rewrite] - enabled = {{ hasKey .Values.rewrite "enabled" | ternary .Values.rewrite.enabled "false" }} - shard_key = {{ .Values.rewrite.shardKey | default "error" | quote }} - split_inserts = {{ .Values.rewrite.splitInserts | default "error" | quote }} - primary_key = {{ .Values.rewrite.primaryKey | default "ignore" | quote }} + {{- if hasKey .Values.rewrite "enabled" }} + enabled = {{ .Values.rewrite.enabled }} + {{- end }} + {{- if hasKey .Values.rewrite "shardKey" }} + shard_key = {{ .Values.rewrite.shardKey | quote }} + {{- end }} + {{- if hasKey .Values.rewrite "splitInserts" }} + split_inserts = {{ .Values.rewrite.splitInserts | quote }} + {{- end }} + {{- if hasKey .Values.rewrite "primaryKey" }} + primary_key = {{ .Values.rewrite.primaryKey | quote }} + {{- end }} {{- end }} {{- if .Values.multiTenant }} @@ -463,19 +566,19 @@ data: {{- if .Values.otel }} [otel] - {{- if .Values.otel.endpoint }} + {{- if hasKey .Values.otel "endpoint" }} endpoint = {{ .Values.otel.endpoint | quote }} {{- end }} - {{- if .Values.otel.namespace }} + {{- if hasKey .Values.otel "namespace" }} namespace = {{ .Values.otel.namespace | quote }} {{- end }} - {{- if .Values.otel.datadogApiKey }} + {{- if hasKey .Values.otel "datadogApiKey" }} datadog_api_key = {{ .Values.otel.datadogApiKey | quote }} {{- end }} - {{- if .Values.otel.pushInterval }} + {{- if hasKey .Values.otel "pushInterval" }} push_interval = {{ include "pgdog.intval" .Values.otel.pushInterval }} {{- end }} - {{- if .Values.otel.headers }} + {{- if hasKey .Values.otel "headers" }} [otel.headers] {{- range $k, $v := .Values.otel.headers }} {{ $k }} = {{ $v | quote }} diff --git a/templates/gateway/gateway-config.yaml b/templates/gateway/gateway-config.yaml deleted file mode 100644 index cd49abb..0000000 --- a/templates/gateway/gateway-config.yaml +++ /dev/null @@ -1,35 +0,0 @@ -{{- if .Values.gateway.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "pgdog.fullname" . }}-gateway - labels: - {{- include "pgdog.gateway.labels" . | nindent 6 }} -data: - config.toml: | - [server] - bind_address = {{ .Values.gateway.bindAddress | default "0.0.0.0" | quote }} - port = {{ .Values.gateway.port | default 8443 }} - - [tls] - {{- if .Values.gateway.tls.existingSecret }} - cert_path = "/etc/gateway/tls/tls.crt" - key_path = "/etc/gateway/tls/tls.key" - {{- else }} - cert_path = {{ .Values.gateway.tls.certPath | default "/etc/ssl/certs/ssl-cert-snakeoil.pem" | quote }} - key_path = {{ .Values.gateway.tls.keyPath | default "/etc/ssl/private/ssl-cert-snakeoil.key" | quote }} - {{- end }} - - {{- if .Values.gateway.control.url }} - [control] - url = {{ .Values.gateway.control.url | quote }} - token = {{ .Values.gateway.control.token | quote }} - {{- end }} - - [stats] - active_queries_interval = {{ .Values.gateway.stats.activeQueriesInterval | default 1000 }} - ping_interval = {{ .Values.gateway.stats.pingInterval | default 1000 }} - push_interval = {{ .Values.gateway.stats.pushInterval | default 1000 }} - config_interval = {{ .Values.gateway.stats.configInterval | default 1000 }} - query_stats_interval = {{ .Values.gateway.stats.queryStatsInterval | default 60_000 }} -{{- end }} diff --git a/templates/gateway/gateway-deployment.yaml b/templates/gateway/gateway-deployment.yaml deleted file mode 100644 index e700a28..0000000 --- a/templates/gateway/gateway-deployment.yaml +++ /dev/null @@ -1,68 +0,0 @@ -{{- if .Values.gateway.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "pgdog.fullname" . }}-gateway - labels: - {{- include "pgdog.gateway.labels" . | nindent 4 }} -spec: - replicas: 1 - selector: - matchLabels: - {{- include "pgdog.gateway.selectorLabels" . | nindent 6 }} - template: - metadata: - labels: - {{- include "pgdog.gateway.selectorLabels" . | nindent 8 }} - spec: - {{- if .Values.serviceAccount.create }} - serviceAccountName: {{ include "pgdog.serviceAccountName" . }} - {{- end }} - containers: - - name: gateway - {{- if .Values.gateway.image.name }} - image: {{ .Values.gateway.image.name }} - {{- else }} - image: "{{ .Values.gateway.image.repository }}:{{ .Values.gateway.image.tag }}" - {{- end }} - imagePullPolicy: {{ .Values.gateway.image.pullPolicy | default .Values.image.pullPolicy }} - command: ["/usr/local/bin/gateway"] - args: - - "/etc/gateway/config.toml" - ports: - - name: gateway - containerPort: {{ .Values.gateway.port | default 8443 }} - {{- if .Values.gateway.resources }} - resources: - {{- toYaml .Values.gateway.resources | nindent 12 }} - {{- end }} - volumeMounts: - - name: config - mountPath: /etc/gateway - {{- if .Values.gateway.tls.existingSecret }} - - name: tls - mountPath: /etc/gateway/tls - readOnly: true - {{- end }} - volumes: - - name: config - configMap: - name: {{ include "pgdog.fullname" . }}-gateway - {{- if .Values.gateway.tls.existingSecret }} - - name: tls - secret: - secretName: {{ .Values.gateway.tls.existingSecret }} - {{- end }} - {{- with .Values.gateway.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.gateway.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.gateway.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} diff --git a/templates/gateway/gateway-service.yaml b/templates/gateway/gateway-service.yaml deleted file mode 100644 index e6d65a9..0000000 --- a/templates/gateway/gateway-service.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.gateway.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "pgdog.fullname" . }}-gateway - {{- if .Values.gateway.service.annotations }} - annotations: - {{- toYaml .Values.gateway.service.annotations | nindent 4 }} - {{- end }} - labels: - {{- include "pgdog.gateway.labels" . | nindent 4 }} -spec: - type: {{ .Values.gateway.service.type | default "ClusterIP" }} - selector: - {{- include "pgdog.gateway.selectorLabels" . | nindent 4 }} - ports: - - name: gateway - protocol: TCP - port: {{ .Values.gateway.port | default 8443 }} - targetPort: {{ .Values.gateway.port | default 8443 }} -{{- end }} diff --git a/test/values-autodiscovery.yaml b/test/values-autodiscovery.yaml new file mode 100644 index 0000000..75ebf07 --- /dev/null +++ b/test/values-autodiscovery.yaml @@ -0,0 +1,15 @@ +autodiscovery: + enabled: true + checkInterval: 15000 + checkDelay: 0 + checkTimeout: 14000 + databases: + - name: primary + replicasOnly: true + - name: analytics + +databases: + - name: primary + host: primary.example.com + - name: analytics + host: analytics.example.com diff --git a/test/values-full.yaml b/test/values-full.yaml index 9f584bb..cba10f8 100644 --- a/test/values-full.yaml +++ b/test/values-full.yaml @@ -4,6 +4,37 @@ replicas: 3 env: - name: RUST_LOG value: trace +workers: 4 +defaultPoolSize: 20 +minPoolSize: 2 +poolerMode: transaction +healthcheckInterval: 30_000 +idleHealthcheckInterval: 30_000 +idleHealthcheckDelay: 5_000 +loadBalancingStrategy: round_robin +readWriteStrategy: conservative +readWriteSplit: include_primary +preparedStatements: extended +preparedStatementsLimit: 1000 +queryCacheLimit: 500 +passthroughAuth: disabled +connectAttempts: 2 +connectAttemptDelay: 100 +dryRun: false +loadSchema: auto +mirrorQueue: 256 +mirrorExposure: 1.0 +authType: scram +crossShardDisabled: false +dnsTtl: 30_000 +pubSubChannelSize: 1024 +openMetricsPort: 9090 +openMetricsNamespace: pgdog_ +logConnections: true +logDisconnections: true +logDedupThreshold: 100 +logDedupWindow: 1_000 +expandedExplain: false queryParserEngine: "pg_query_raw" regexParserLimit: 1000 logMinDurationParse: 100 @@ -25,16 +56,39 @@ port: 6432 healthcheckPort: 8080 logFormat: json logLevel: debug +tlsClientRequired: false +tlsVerify: prefer +adminPassword: admin-secret + +tcpKeepalive: true +tcpTime: 7200 +tcpInterval: 75 +tcpRetries: 9 databases: - name: primary host: postgres-primary.example.com port: 5432 + shard: 0 + databaseName: app + user: app_user + password: secret123 + poolSize: 20 + minPoolSize: 2 + poolerMode: transaction + statementTimeout: 30_000 + idleTimeout: 120_000 + readOnly: false + serverLifetime: 86_400_000 - name: replica host: postgres-replica.example.com port: 5432 role: replica + - name: primary + host: postgres-shard1.example.com + port: 5432 + shard: 1 users: - username: app_user @@ -49,9 +103,32 @@ shardedTables: column: id dataType: bigint +shardedSchemas: + - database: primary + name: tenant_a + shard: 0 + +shardedMappings: + - database: primary + column: id + kind: list + values: ["1", "2", "3"] + shard: 0 + - database: primary + column: id + kind: range + start: 4 + end: 100 + shard: 1 + mirrors: - sourceDb: primary destinationDb: replica + queueDepth: 128 + +qos: + enabled: true + maxEntries: 10_000 omnishardedTables: - database: primary diff --git a/test/values-query-parser-enabled.yaml b/test/values-query-parser-enabled.yaml new file mode 100644 index 0000000..91e5715 --- /dev/null +++ b/test/values-query-parser-enabled.yaml @@ -0,0 +1,7 @@ +# Test deprecated queryParserEnabled rendering when queryParser is absent. +queryParserEnabled: true + +databases: + - name: primary + host: postgres.example.com + port: 5432 diff --git a/test/values-tls-paths.yaml b/test/values-tls-paths.yaml new file mode 100644 index 0000000..f9a65f1 --- /dev/null +++ b/test/values-tls-paths.yaml @@ -0,0 +1,9 @@ +# Test explicit TLS path settings in pgdog.toml. +tlsCertificate: /etc/ssl/certs/ssl-cert-snakeoil.pem +tlsPrivateKey: /etc/ssl/private/ssl-cert-snakeoil.key +tlsServerCaCertificate: /etc/ssl/certs/ca-certificates.crt + +databases: + - name: primary + host: postgres.example.com + port: 5432 diff --git a/values.yaml b/values.yaml index 14c125e..712163a 100644 --- a/values.yaml +++ b/values.yaml @@ -189,6 +189,13 @@ logFormat: text # Defaults to `info`. logLevel: "info" +# loadBalancingStrategy controls how read queries are distributed across +# replicas. +# +# PgDog defaults to `random`; the chart keeps its historical default of +# `round_robin` by setting this explicitly. +loadBalancingStrategy: round_robin + # serverLifetime is the maximum amount of time (in milliseconds) a server # connection is allowed to exist. Connections exceeding this limit are closed # once they are checked back into the pool. @@ -459,76 +466,6 @@ grafanaRemoteWrite: # maxBackoff is the maximum retry delay maxBackoff: 5s -# Gateway configuration (Enterprise Edition) -# The gateway provides query stats collection and monitoring capabilities -# NOTE: Gateway runs as a single replica only -gateway: - # enabled controls whether to deploy the gateway - enabled: false - # labels allows overriding gateway resource labels (defaults to app.kubernetes.io/* format) - labels: {} - # selectorLabels allows overriding gateway selector labels - # WARNING: Changing selectors requires recreating Deployments - selectorLabels: {} - # image contains the Docker image properties for the gateway - image: - # repository is the Docker image repository - repository: ghcr.io/pgdogdev/pgdog-enterprise/gateway - # tag is the Docker image tag - tag: "main-ent" - # pullPolicy specifies when to use cached version of the image - pullPolicy: Always - # name is the full image name (if set, takes precedence) - # name: ghcr.io/pgdogdev/gateway:latest - # port on which the gateway will run - port: 8443 - # bindAddress is the address the gateway binds to - bindAddress: "0.0.0.0" - # resources define resource requests and limits for the gateway container - resources: - requests: - cpu: 1000m - memory: 1Gi - limits: - cpu: 1000m - memory: 1Gi - # tls configuration for the gateway - tls: - # existingSecret references an existing TLS secret (must contain tls.crt and tls.key) - existingSecret: "" - # certPath is the path to the certificate file (if not using existingSecret) - # Defaults to snakeoil certificate if not specified - certPath: "" - # keyPath is the path to the private key file (if not using existingSecret) - # Defaults to snakeoil key if not specified - keyPath: "" - # control configuration for the gateway - control: - # url is the WebSocket endpoint for control communication - url: "" - # token is the authentication token for control communication - token: "" - # stats configuration intervals (in milliseconds) - stats: - activeQueriesInterval: 1000 - pingInterval: 1000 - pushInterval: 1000 - configInterval: 1000 - # service contains the Kubernetes service configuration for gateway - service: - # type specifies the type of Kubernetes service - type: ClusterIP - # annotations allows adding custom annotations to the service - annotations: {} - # nodeSelector allows scheduling pods on nodes with specific labels - nodeSelector: {} - # tolerations allows pods to be scheduled on nodes with matching taints - tolerations: [] - # affinity rules for pod scheduling - affinity: {} - # connectFromPgdog enables pgdog to connect to the gateway - # When enabled, pgdog.toml will include a [gateway] section - connectFromPgdog: false # Query stats (PgDog EE) queryStats: # enabled enables pgdog query stats (EE version only)