Skip to content

Commit 78cf606

Browse files
authored
Merge pull request #17 from aehrc/fix/guard-scaled-readonly-override
2 parents 888f51c + fd908cd commit 78cf606

3 files changed

Lines changed: 77 additions & 1 deletion

File tree

charts/ontoserver/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ The chart supports four deployment combinations controlled by `ontoserver.deploy
8383
> on any scaled deployment**: setting `ontoserver.deployment.scaled` makes the server reject writes
8484
> regardless of what else is configured, so a scaled read-write server is not a topology that exists.
8585
> The chart therefore refuses to render `type: scaled` with `isReadOnly: false` rather than deploy
86-
> something that cannot work.
86+
> something that cannot work, and rejects any `ontoserver.config` or `ontoserver.secretConfig` entry
87+
> that attempts to re-enable writes on a scaled deployment.
8788
>
8889
> Load content with a **single-instance read-write** deployment, then publish it to a syndication
8990
> server and serve it from a **scaled read-only** cluster. See

charts/ontoserver/templates/validate-values.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,28 @@
124124
{{- fail "Scaled deployments must set ontoserver.deployment.isReadOnly: true. Ontoserver forces read-only on a scaled deployment, and each replica has its own Lucene index, so content written through the round-robin Service is only indexed on the replica that served the write and $expand/$validate-code fail on the others. Load content with a single-instance read-write deployment, then serve it scaled and read-only." }}
125125
{{- end }}
126126

127+
{{- /* The chart sets ontoserver.internal.deployment.scaledReadOnly itself on scaled deployments.
128+
The config passthroughs render after that entry in the container's env list, and a later
129+
duplicate wins, so a passthrough copy would silently override the chart and re-enable the
130+
unsupported scaled read-write topology while still passing the isReadOnly guard above.
131+
Reject it instead of rendering a manifest that contradicts itself.
132+
133+
Matching is normalised because Spring resolves a property from the environment in several
134+
forms: the dotted name, an older all-lowercase spelling of it, and the uppercase underscored
135+
form. Lowercasing and folding _ and - to . collapses all of them to one comparison.
136+
137+
Not checked, because it cannot be: existingSecretConfig and externalSecret contents are
138+
opaque at render time. They arrive via envFrom, which Kubernetes applies *before* the
139+
container's own env, so the chart's entry still wins there. */ -}}
140+
{{- $reserved := "ontoserver.internal.deployment.scaledreadonly" }}
141+
{{- range $section, $entries := dict "ontoserver.config" (.Values.ontoserver.config | default dict) "ontoserver.secretConfig" (.Values.ontoserver.secretConfig | default dict) }}
142+
{{- range $key, $value := $entries }}
143+
{{- if eq ($key | lower | replace "_" "." | replace "-" ".") $reserved }}
144+
{{- fail (printf "%s must not set %s. Scaled read-write is not supported: Ontoserver forces read-only on a scaled deployment and the chart sets this itself, so a passthrough copy would only produce a manifest whose env list contradicts itself. Remove the entry. To serve content read-write, use a single-instance deployment." $section $key) }}
145+
{{- end }}
146+
{{- end }}
147+
{{- end }}
148+
127149
{{- if and (eq .Values.ontoserver.deployment.kind "StatefulSet") .Values.ontoserver.deployment.persistence.files.existingVolume.enabled }}
128150
{{- fail "StatefulSet deployments do not support ontoserver.deployment.persistence.files.existingVolume. Each replica needs its own volume; use dynamic provisioning via storageClass or a Deployment for single-instance prebound volumes." }}
129151
{{- end }}

charts/ontoserver/tests/validate_values_test.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,59 @@ tests:
204204
- failedTemplate:
205205
errorMessage: "Scaled deployments must set ontoserver.deployment.isReadOnly: true. Ontoserver forces read-only on a scaled deployment, and each replica has its own Lucene index, so content written through the round-robin Service is only indexed on the replica that served the write and $expand/$validate-code fail on the others. Load content with a single-instance read-write deployment, then serve it scaled and read-only."
206206

207+
# The chart sets scaledReadOnly itself, and the config passthroughs render after it, so a
208+
# duplicate would win at runtime and re-enable scaled read-write while still passing the
209+
# isReadOnly guard. Each accepted spelling must be rejected.
210+
- it: rejects a scaledReadOnly override in ontoserver.config
211+
values:
212+
- fixtures/scaled-values.yaml
213+
set:
214+
ontoserver.config:
215+
ontoserver.internal.deployment.scaledReadOnly: "false"
216+
asserts:
217+
- failedTemplate:
218+
errorPattern: "ontoserver\\.config must not set .*Scaled read-write is not supported"
219+
220+
- it: rejects the older lowercase scaledReadonly spelling
221+
values:
222+
- fixtures/scaled-values.yaml
223+
set:
224+
ontoserver.config:
225+
ontoserver.internal.deployment.scaledReadonly: "false"
226+
asserts:
227+
- failedTemplate:
228+
errorPattern: "must not set .*Scaled read-write is not supported"
229+
230+
- it: rejects the uppercase underscored environment form
231+
values:
232+
- fixtures/scaled-values.yaml
233+
set:
234+
ontoserver.config:
235+
ONTOSERVER_INTERNAL_DEPLOYMENT_SCALEDREADONLY: "false"
236+
asserts:
237+
- failedTemplate:
238+
errorPattern: "must not set ONTOSERVER_INTERNAL_DEPLOYMENT_SCALEDREADONLY"
239+
240+
- it: rejects a scaledReadOnly override in ontoserver.secretConfig
241+
values:
242+
- fixtures/scaled-values.yaml
243+
set:
244+
ontoserver.secretConfig:
245+
ontoserver.internal.deployment.scaledReadOnly: "false"
246+
asserts:
247+
- failedTemplate:
248+
errorPattern: "ontoserver\\.secretConfig must not set"
249+
250+
# The guard must not catch unrelated passthrough entries.
251+
- it: allows other ontoserver.config entries on a scaled deployment
252+
values:
253+
- fixtures/scaled-values.yaml
254+
set:
255+
ontoserver.config:
256+
ontoserver.fhir.closureTable.max: "500"
257+
asserts:
258+
- notFailedTemplate: {}
259+
207260
# A single-instance deployment is the supported way to load content, so read-write there
208261
# must stay legal — the guard has to key on `type`, not on isReadOnly alone.
209262
- it: allows a single read-write deployment

0 commit comments

Comments
 (0)