From bc4ac879fdd4e183518ff21d52868220783392ed Mon Sep 17 00:00:00 2001 From: Dineth Date: Fri, 7 Aug 2026 12:28:28 +0530 Subject: [PATCH 1/5] add hpa for sqlserver --- .../gateway-helm-chart/templates/gateway/controller/hpa.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/hpa.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/hpa.yaml index 7039eb6b97..f01fcfe938 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/hpa.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/hpa.yaml @@ -1,8 +1,8 @@ {{- $controller := .Values.gateway.controller -}} {{- $hpa := $controller.hpa -}} {{- if and $controller.deployment.enabled $hpa.enabled }} -{{- if ne .Values.gateway.config.controller.storage.type "postgres" }} -{{- fail "gateway.controller.hpa requires gateway.config.controller.storage.type=postgres — SQLite does not support multiple replicas." }} +{{- if not (has .Values.gateway.config.controller.storage.type (list "postgres" "sqlserver")) }} +{{- fail "gateway.controller.hpa requires gateway.config.controller.storage.type to be postgres or sqlserver — SQLite does not support multiple replicas." }} {{- end }} apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler From c938ff7add492c31d706c2026d24af6f0b043492 Mon Sep 17 00:00:00 2001 From: Dineth Date: Fri, 7 Aug 2026 13:45:15 +0530 Subject: [PATCH 2/5] bump chart version --- kubernetes/helm/gateway-helm-chart/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/helm/gateway-helm-chart/Chart.yaml b/kubernetes/helm/gateway-helm-chart/Chart.yaml index 77e3d35848..0651b73f0f 100644 --- a/kubernetes/helm/gateway-helm-chart/Chart.yaml +++ b/kubernetes/helm/gateway-helm-chart/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: gateway kubeVersion: ">=1.24.0-0" description: Helm chart for deploying the Gateway Operator components -version: 1.2.0-rc +version: 1.2.0 appVersion: "1.2.0" type: application home: https://github.com/wso2/api-platform From c56dd28654e9fa286299056951dc4ab8c4f6df83 Mon Sep 17 00:00:00 2001 From: Dineth Date: Fri, 7 Aug 2026 13:58:29 +0530 Subject: [PATCH 3/5] Add max decompressed bytes configuration for request and response bodies --- .../templates/gateway/gateway-config.yaml | 6 ++++++ kubernetes/helm/gateway-helm-chart/values.yaml | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml index 28de7f02b9..14610f692b 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml @@ -277,6 +277,12 @@ data: [policy_engine] tracing_service_name = {{ $pe.tracing_service_name | default "" | quote }} + [policy_engine.request_body] + max_decompressed_bytes = {{ $pe.request_body.max_decompressed_bytes | int64 }} + + [policy_engine.response_body] + max_decompressed_bytes = {{ $pe.response_body.max_decompressed_bytes | int64 }} + [policy_engine.server] extproc_port = {{ $pe.server.extproc_port }} diff --git a/kubernetes/helm/gateway-helm-chart/values.yaml b/kubernetes/helm/gateway-helm-chart/values.yaml index 888450b92d..708b668097 100644 --- a/kubernetes/helm/gateway-helm-chart/values.yaml +++ b/kubernetes/helm/gateway-helm-chart/values.yaml @@ -442,6 +442,14 @@ gateway: # Service name reported to the tracing backend (see gateway.config.tracing below) tracing_service_name: policy-engine + # Caps decompressed bytes buffered per body (buffered mode) or per chunk + # (streaming) + request_body: + max_decompressed_bytes: 10485760 + + response_body: + max_decompressed_bytes: 10485760 + server: # ext_proc port for gRPC server extproc_port: 9001 From db9f54ef4e05ef861a9df904064986505a0f218c Mon Sep 17 00:00:00 2001 From: Dineth Date: Fri, 7 Aug 2026 19:31:56 +0530 Subject: [PATCH 4/5] Enhance storage backend configuration and remove legacy SQL Server settings --- kubernetes/helm/gateway-helm-chart/README.md | 27 ++++++++++++ .../gateway/controller/deployment.yaml | 2 +- .../templates/gateway/controller/pvc.yaml | 2 +- .../templates/gateway/gateway-config.yaml | 43 +++++++++++-------- .../helm/gateway-helm-chart/values.yaml | 35 +++++---------- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/kubernetes/helm/gateway-helm-chart/README.md b/kubernetes/helm/gateway-helm-chart/README.md index b9b3be0934..a5b51820cb 100644 --- a/kubernetes/helm/gateway-helm-chart/README.md +++ b/kubernetes/helm/gateway-helm-chart/README.md @@ -200,6 +200,33 @@ ConfigMap: A plain `APIP_GW_*` env var with no matching token in `config.toml` is ignored. +### Storage backends and scaling + +`gateway.config.controller.storage.type` selects the controller's database: + +| Type | Config block | Replicas | +| --- | --- | --- | +| `sqlite` (default) | `storage.sqlite` | Single replica only — the DB is a file on a PersistentVolume | +| `postgres` | `storage.postgres` | Multi-replica | +| `sqlserver` | `storage.database` | Multi-replica | + +Notes: + +- `gateway.controller.hpa.enabled=true` requires `postgres` or `sqlserver`; the chart fails to + render with `sqlite`, which cannot serve multiple replicas. +- The PersistentVolumeClaim backs the SQLite file only. With `postgres`/`sqlserver` no claim is + created or mounted regardless of `gateway.controller.persistence.enabled`, so replicas are not + pinned to a single node by a `ReadWriteOnce` volume. If you are switching an existing release + from `sqlite` to an external database and want to retain the old claim, annotate it with + `helm.sh/resource-policy: keep` before upgrading. +- SQL Server connection encryption is on by default + (`storage.database.options.encrypt="true"`, `trust_server_certificate="false"`), matching the + gateway-controller binary. Relax these only for a local/dev SQL Server without a trusted + certificate. +- Prefer the individual `host`/`port`/`database`/`user` fields over `dsn`: a DSN is rendered + verbatim into the ConfigMap, so an embedded password would be stored in plaintext instead of + being injected from the Secret above. + ## At-rest Encryption (Required) At-rest encryption of stored secrets is **mandatory and fail-closed**: the gateway-controller diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/deployment.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/deployment.yaml index 7414950f5d..6f8a79b1cc 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/deployment.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/deployment.yaml @@ -184,7 +184,7 @@ spec: {{- end }} volumes: - name: controller-data - {{- if $controller.persistence.enabled }} + {{- if and $controller.persistence.enabled (eq .Values.gateway.config.controller.storage.type "sqlite") }} persistentVolumeClaim: claimName: {{ if $controller.persistence.existingClaim }}{{ $controller.persistence.existingClaim }}{{ else }}{{ include "gateway-operator.fullname" . }}-controller-data{{ end }} {{- else }} diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/pvc.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/pvc.yaml index df279dd225..0adc7de0be 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/pvc.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/controller/pvc.yaml @@ -1,6 +1,6 @@ {{- $controller := .Values.gateway.controller -}} {{- $persistence := $controller.persistence -}} -{{- if and $controller.deployment.enabled $persistence.enabled (not $persistence.existingClaim) }} +{{- if and $controller.deployment.enabled $persistence.enabled (not $persistence.existingClaim) (eq .Values.gateway.config.controller.storage.type "sqlite") }} apiVersion: v1 kind: PersistentVolumeClaim metadata: diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml index 14610f692b..62e6e768ea 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml @@ -2,8 +2,11 @@ {{- $router := .Values.gateway.config.router -}} {{- $pe := .Values.gateway.config.policy_engine -}} {{- $pg := $gc.storage.postgres -}} -{{- $ss := $gc.storage.sqlserver -}} {{- $db := default (dict) $gc.storage.database -}} +{{- $dbOpts := default (dict) $db.options -}} +{{- if $gc.storage.sqlserver -}} +{{- fail "gateway.config.controller.storage.sqlserver has been removed — move these settings to gateway.config.controller.storage.database (encrypt/trust_server_certificate now live under storage.database.options)." -}} +{{- end -}} {{- $controllerHost := printf "%s-controller" (include "gateway-operator.fullname" .) -}} apiVersion: v1 kind: ConfigMap @@ -70,25 +73,31 @@ data: {{- if eq $gc.storage.type "sqlserver" }} [controller.storage.database] - driver = {{ coalesce $db.driver "sqlserver" | quote }} - {{- $sqlDsn := coalesce $db.dsn $ss.dsn }} - {{- if $sqlDsn }} - dsn = {{ $sqlDsn | quote }} + driver = {{ default "sqlserver" $db.driver | quote }} + {{- if $db.dsn }} + dsn = {{ $db.dsn | quote }} {{- else }} - host = {{ required "gateway.config.controller.storage.database.host (or storage.sqlserver.host) is required when storage.type is \"sqlserver\" and dsn is unset" (coalesce $db.host $ss.host) | quote }} - port = {{ coalesce $db.port $ss.port 1433 | int }} - database = {{ required "gateway.config.controller.storage.database.database (or storage.sqlserver.database) is required when storage.type is \"sqlserver\" and dsn is unset" (coalesce $db.database $ss.database) | quote }} - user = {{ required "gateway.config.controller.storage.database.user (or storage.sqlserver.user) is required when storage.type is \"sqlserver\" and dsn is unset" (coalesce $db.user $ss.user) | quote }} + host = {{ required "gateway.config.controller.storage.database.host is required when storage.type is \"sqlserver\" and dsn is unset" $db.host | quote }} + port = {{ default 1433 $db.port | int }} + database = {{ required "gateway.config.controller.storage.database.database is required when storage.type is \"sqlserver\" and dsn is unset" $db.database | quote }} + user = {{ required "gateway.config.controller.storage.database.user is required when storage.type is \"sqlserver\" and dsn is unset" $db.user | quote }} password = {{ `'{{ env "APIP_GW_CONTROLLER_STORAGE_DATABASE_PASSWORD" "" }}'` }} - connect_timeout = {{ coalesce $db.connect_timeout $ss.connect_timeout "5s" | quote }} - max_open_conns = {{ coalesce $db.max_open_conns $ss.max_open_conns 25 | int }} - max_idle_conns = {{ coalesce $db.max_idle_conns $ss.max_idle_conns 5 | int }} - conn_max_lifetime = {{ coalesce $db.conn_max_lifetime $ss.conn_max_lifetime "30m" | quote }} - conn_max_idle_time = {{ coalesce $db.conn_max_idle_time $ss.conn_max_idle_time "5m" | quote }} - application_name = {{ coalesce $db.application_name $ss.application_name "gateway-controller" | quote }} + connect_timeout = {{ default "5s" $db.connect_timeout | quote }} + max_open_conns = {{ default 25 $db.max_open_conns | int }} + max_idle_conns = {{ default 5 $db.max_idle_conns | int }} + conn_max_lifetime = {{ default "30m" $db.conn_max_lifetime | quote }} + conn_max_idle_time = {{ default "5m" $db.conn_max_idle_time | qu`ote }} + application_name = {{ default "gateway-controller" $db.application_name | quote }} + {{- $encrypt := "true" }} + {{- if hasKey $dbOpts "encrypt" }}{{- $v := toString (index $dbOpts "encrypt") }}{{- if $v }}{{- $encrypt = $v }}{{- end }}{{- end }} + {{- if not (has $encrypt (list "disable" "false" "true" "strict")) }} + {{- fail (printf "gateway.config.controller.storage.database.options.encrypt must be one of disable, false, true, strict — got %q" $encrypt) }} + {{- end }} + {{- $trust := "false" }} + {{- if hasKey $dbOpts "trust_server_certificate" }}{{- $v := toString (index $dbOpts "trust_server_certificate") }}{{- if $v }}{{- $trust = $v }}{{- end }}{{- end }} [controller.storage.database.options] - encrypt = {{ coalesce (index $db.options "encrypt") $ss.encrypt "disable" | quote }} - trust_server_certificate = {{ (coalesce (index $db.options "trust_server_certificate") (toString (default true $ss.trust_server_certificate))) | quote }} + encrypt = {{ $encrypt | quote }} + trust_server_certificate = {{ $trust | quote }} {{- end }} {{- end }} diff --git a/kubernetes/helm/gateway-helm-chart/values.yaml b/kubernetes/helm/gateway-helm-chart/values.yaml index 708b668097..e49adfc5b1 100644 --- a/kubernetes/helm/gateway-helm-chart/values.yaml +++ b/kubernetes/helm/gateway-helm-chart/values.yaml @@ -151,7 +151,7 @@ gateway: database: driver: sqlserver # Full DSN takes precedence over individual fields when set. - # Example: "sqlserver://user:password@host:1433?database=gateway&encrypt=disable&TrustServerCertificate=true" + # Example: "sqlserver://gateway@host:1433?database=gateway" dsn: "" host: "" @@ -167,26 +167,10 @@ gateway: application_name: gateway-controller options: - # Encryption mode: disable, false, true, strict - encrypt: disable - trust_server_certificate: "true" - - # Legacy SQL Server configuration (backward compatible fallback). - # Prefer gateway.config.controller.storage.database for new deployments. - sqlserver: - dsn: "" - host: "" - port: 1433 - database: "" - user: "" - encrypt: disable - trust_server_certificate: true - connect_timeout: 5s - max_open_conns: 25 - max_idle_conns: 5 - conn_max_lifetime: 30m - conn_max_idle_time: 5m - application_name: gateway-controller + # Encryption mode for the connection to SQL Server: disable, false, true, strict. + # Defaults to "true" (encrypted). Only set "disable"/"false" for a local/dev SQL Server without TLS. + encrypt: "true" + trust_server_certificate: "false" # Policy configuration policies: @@ -262,7 +246,7 @@ gateway: # Logging configuration logging: # Log level: "debug", "info", "warn", or "error" - level: debug + level: info # Log format: "json" or "text" # - json: Structured JSON format (recommended for production) @@ -439,7 +423,7 @@ gateway: skip_verify: false policy_engine: - # Service name reported to the tracing backend (see gateway.config.tracing below) + # Service name reported to the tracing backend tracing_service_name: policy-engine # Caps decompressed bytes buffered per body (buffered mode) or per chunk @@ -718,6 +702,8 @@ gateway: # Prometheus metrics on `port` below. enabled: false port: 9091 + # Persistent volume backing the controller's SQLite database file. + # Only used when gateway.config.controller.storage.type=sqlite persistence: enabled: true existingClaim: "" @@ -819,7 +805,8 @@ gateway: # over serviceAccount.automountServiceAccountToken). Uncomment to set. # automountServiceAccountToken: false # Horizontal Pod Autoscaler for the controller. - # Requires gateway.config.controller.storage.type=postgres — SQLite does not support multiple replicas. + # Requires gateway.config.controller.storage.type=postgres or sqlserver — SQLite does not + # support multiple replicas # When enabled, replicaCount is managed by HPA and the Deployment's replicas field is omitted. hpa: enabled: false From c803e1901dc0bfa7ee8f13fa26931362f2cd1fcf Mon Sep 17 00:00:00 2001 From: Dineth Date: Fri, 7 Aug 2026 21:34:48 +0530 Subject: [PATCH 5/5] typo --- .../gateway-helm-chart/templates/gateway/gateway-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml index 62e6e768ea..36218eea4d 100644 --- a/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml +++ b/kubernetes/helm/gateway-helm-chart/templates/gateway/gateway-config.yaml @@ -86,7 +86,7 @@ data: max_open_conns = {{ default 25 $db.max_open_conns | int }} max_idle_conns = {{ default 5 $db.max_idle_conns | int }} conn_max_lifetime = {{ default "30m" $db.conn_max_lifetime | quote }} - conn_max_idle_time = {{ default "5m" $db.conn_max_idle_time | qu`ote }} + conn_max_idle_time = {{ default "5m" $db.conn_max_idle_time | quote }} application_name = {{ default "gateway-controller" $db.application_name | quote }} {{- $encrypt := "true" }} {{- if hasKey $dbOpts "encrypt" }}{{- $v := toString (index $dbOpts "encrypt") }}{{- if $v }}{{- $encrypt = $v }}{{- end }}{{- end }}