Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
48a9a5d
feat: add ConfigMap-sourced dynamic configuration loader
vvnpn-nv Mar 26, 2026
fe33738
fix: address bugs and code quality issues in configmap_loader
vvnpn-nv Mar 26, 2026
ec56c17
test: add comprehensive tests for ConfigMap config loader
vvnpn-nv Mar 26, 2026
67ce147
fix: address review findings, add config watcher, fix test failures
vvnpn-nv Apr 1, 2026
2ddcda3
simplify: consolidate singleton config functions, fix advisory lock
vvnpn-nv Apr 1, 2026
71bb8a6
feat: add drift reconciliation for configmap-mode configs
vvnpn-nv Apr 2, 2026
d0db789
feat: add UX improvements — managed_by visibility, immediate re-apply…
vvnpn-nv Apr 3, 2026
7c8d00f
feat: reject CLI writes to configmap-managed configs with 409 Conflict
vvnpn-nv Apr 3, 2026
1a9c887
refactor: extract configmap_guard module, fix circular import, cover …
vvnpn-nv Apr 6, 2026
230f8b3
chore: remove debug print, dead code, stale comment
vvnpn-nv Apr 6, 2026
e493ec7
fix: rollback guard referenced removed configmap_loader.reject_if_man…
vvnpn-nv Apr 6, 2026
975635e
docs: add design doc for ConfigMap-sourced dynamic configuration
vvnpn-nv Apr 7, 2026
b2f0cee
fix: guard watcher startup to avoid service boot abort
vvnpn-nv Apr 7, 2026
452c4bb
feat: extend secret file references to all config credential fields
vvnpn-nv Apr 7, 2026
42a2253
feat: auto-detect Docker registry .dockerconfigjson secret format
vvnpn-nv Apr 7, 2026
a11c049
refactor: redesign ConfigMap config to in-memory + watchdog + global …
vvnpn-nv Apr 7, 2026
25dcec2
docs: rewrite design doc for v2 architecture
vvnpn-nv Apr 7, 2026
2890e97
feat: authz_sidecar reads roles from ConfigMap file instead of DB
vvnpn-nv Apr 8, 2026
fa3705b
feat: authz_sidecar uses --roles-file when dynamicConfig enabled
vvnpn-nv Apr 8, 2026
5f98c4b
feat: move product defaults to chart values, auto-derive service_base…
vvnpn-nv Apr 8, 2026
bc5bd00
feat: add default backend and pool to chart defaults
vvnpn-nv Apr 8, 2026
670fb18
docs: update design doc for v3 — authz file-backed, chart defaults
vvnpn-nv Apr 8, 2026
c0caafe
refactor: eliminate remaining DB deps in ConfigMap mode
vvnpn-nv Apr 8, 2026
321ddae
chore: fix medium review findings — remove stale docs and dead code
vvnpn-nv Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion deployments/charts/service/templates/api-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ spec:
{{- end }}
annotations:
checksum/envoy-config: {{ .Values.sidecars.envoy | toYaml | sha256sum }}
{{- if .Values.services.dynamicConfig.enabled }}
checksum/dynamic-config: {{ .Values.services.dynamicConfig | toYaml | sha256sum }}
{{- end }}
{{- include "osmo.extra-annotations" .Values.services.service | nindent 8 }}
spec:
{{- with .Values.services.service.hostAliases }}
Expand Down Expand Up @@ -149,6 +152,10 @@ spec:
- --default_admin_username
- {{ .Values.services.defaultAdmin.username | quote }}
{{- end }}
{{- if .Values.services.dynamicConfig.enabled }}
- --dynamic_config_file
- /etc/osmo/dynamic-config/config.yaml
{{- end }}
{{- range $arg := .Values.services.service.extraArgs }}
- {{ $arg | quote }}
{{- end }}
Expand Down Expand Up @@ -192,14 +199,36 @@ spec:
ports:
- name: metrics
containerPort: 9464
{{- if or .Values.services.configFile.enabled .Values.global.logs.enabled .Values.services.service.extraVolumeMounts }}
{{- if or .Values.services.configFile.enabled .Values.global.logs.enabled .Values.services.dynamicConfig.enabled .Values.services.service.extraVolumeMounts }}
volumeMounts:
{{- end }}
{{- if .Values.services.configFile.enabled}}
- mountPath: {{ .Values.services.configFile.path }}
name: mek-volume
subPath: mek.yaml
{{- end }}
{{- if .Values.services.dynamicConfig.enabled }}
- name: dynamic-config
mountPath: /etc/osmo/dynamic-config
readOnly: true
{{- range $name, $data := .Values.services.dynamicConfig.secrets }}
- name: dynamic-secret-{{ $name }}
mountPath: /etc/osmo/secrets/{{ $name }}.yaml
subPath: {{ $name }}.yaml
readOnly: true
{{- end }}
{{- if .Values.services.dynamicConfig.dataset }}
{{- range $bucketName, $bucketConfig := .Values.services.dynamicConfig.dataset.config.buckets }}
{{- if and (kindIs "map" $bucketConfig) $bucketConfig.default_credential }}
{{- if $bucketConfig.default_credential.credentialSecretName }}
- name: {{ $bucketConfig.default_credential.credentialSecretName }}
mountPath: /etc/osmo/secrets/{{ $bucketConfig.default_credential.credentialSecretName }}
readOnly: true
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.global.logs.enabled }}
- name: logs
mountPath: /logs
Expand Down Expand Up @@ -262,6 +291,28 @@ spec:
name: mek-config
name: mek-volume
{{- end}}
{{- if .Values.services.dynamicConfig.enabled }}
- name: dynamic-config
configMap:
name: {{ .Values.services.service.serviceName }}-dynamic-config
{{- range $name, $data := .Values.services.dynamicConfig.secrets }}
- name: dynamic-secret-{{ $name }}
secret:
secretName: {{ $.Values.services.service.serviceName }}-dynamic-secret-{{ $name }}
{{- end }}
{{- if .Values.services.dynamicConfig.dataset }}
{{- range $bucketName, $bucketConfig := .Values.services.dynamicConfig.dataset.config.buckets }}
{{- if and (kindIs "map" $bucketConfig) $bucketConfig.default_credential }}
{{- if $bucketConfig.default_credential.credentialSecretName }}
- name: {{ $bucketConfig.default_credential.credentialSecretName }}
secret:
secretName: {{ $bucketConfig.default_credential.credentialSecretName }}
optional: true
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
---
{{- if .Values.sidecars.envoy.enabled }}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
{{- if and .Values.services.dynamicConfig.enabled .Values.services.dynamicConfig.secrets }}
{{- range $name, $data := .Values.services.dynamicConfig.secrets }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ $.Values.services.service.serviceName }}-dynamic-secret-{{ $name }}
labels:
app: {{ $.Values.services.service.serviceName }}
type: Opaque
stringData:
{{ $name }}.yaml: |
{{- toYaml $data | nindent 4 }}
{{- end }}
{{- end }}
79 changes: 79 additions & 0 deletions deployments/charts/service/templates/dynamic-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
{{- if .Values.services.dynamicConfig.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.services.service.serviceName }}-dynamic-config
labels:
app: {{ .Values.services.service.serviceName }}
data:
config.yaml: |
managed_configs:
{{- $dc := .Values.services.dynamicConfig }}
{{- if $dc.service }}
service:
{{- toYaml $dc.service | nindent 8 }}
{{- end }}
{{- if $dc.workflow }}
workflow:
{{- toYaml $dc.workflow | nindent 8 }}
{{- end }}
{{- if $dc.dataset }}
dataset:
{{- $dataset := deepCopy $dc.dataset }}
{{- if $dataset.config }}
{{- range $bucketName, $bucketConfig := $dataset.config.buckets }}
{{- if and (kindIs "map" $bucketConfig) $bucketConfig.default_credential }}
{{- if $bucketConfig.default_credential.credentialSecretName }}
{{- $secretName := $bucketConfig.default_credential.credentialSecretName }}
{{- $_ := set $bucketConfig.default_credential "secret_file" (printf "/etc/osmo/secrets/%s/cred.yaml" $secretName) }}
{{- $_ := unset $bucketConfig.default_credential "credentialSecretName" }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- toYaml $dataset | nindent 8 }}
{{- end }}
{{- if $dc.pools }}
pools:
{{- toYaml $dc.pools | nindent 8 }}
{{- end }}
{{- if $dc.podTemplates }}
pod_templates:
{{- toYaml $dc.podTemplates | nindent 8 }}
{{- end }}
{{- if $dc.resourceValidations }}
resource_validations:
{{- toYaml $dc.resourceValidations | nindent 8 }}
{{- end }}
{{- if $dc.backends }}
backends:
{{- toYaml $dc.backends | nindent 8 }}
{{- end }}
{{- if $dc.backendTests }}
backend_tests:
{{- toYaml $dc.backendTests | nindent 8 }}
{{- end }}
{{- if $dc.groupTemplates }}
group_templates:
{{- toYaml $dc.groupTemplates | nindent 8 }}
{{- end }}
{{- if $dc.roles }}
roles:
{{- toYaml $dc.roles | nindent 8 }}
{{- end }}
{{- end }}
55 changes: 55 additions & 0 deletions deployments/charts/service/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,61 @@ services:
##
passwordSecretKey: password

## Dynamic configuration loaded from ConfigMap on service startup
## When enabled, renders a ConfigMap with all config types and mounts it into the API service.
## The service reads the file on startup and applies configs to the database.
##
## managed_by modes:
## seed: Only apply if config doesn't exist in DB (default). CLI changes are preserved.
## configmap: Always overwrite DB from ConfigMap on startup. CLI changes are ephemeral.
##
dynamicConfig:
## Enable dynamic configuration loading from ConfigMap
##
enabled: false

## Per-type configuration sections. Each section supports managed_by and config/items.
## Example:
## service:
## managed_by: seed
## config:
## service_base_url: "https://osmo.example.com"
##
## Dataset buckets support credentialSecretName to simplify secret wiring.
## Instead of manually adding extraVolumes/extraVolumeMounts, just specify
## the K8s Secret name and the chart auto-generates volume + mount:
## dataset:
## config:
## buckets:
## my-bucket:
## dataset_path: "s3://my-bucket"
## default_credential:
## credentialSecretName: my-secret-name
## The Secret should contain a cred.yaml key with access_key_id and access_key fields.
##
service: {}
workflow: {}
dataset: {}
pools: {}
podTemplates: {}
resourceValidations: {}
backends: {}
backendTests: {}
groupTemplates: {}
roles: {}

## Secret credential files mounted from K8s Secrets.
## Each entry creates a K8s Secret + volume mount at /etc/osmo/secrets/<name>.yaml
## Used by dataset bucket default_credential.secret_file references.
##
## Example:
## secrets:
## bucket-primary-cred:
## access_key_id: "AKIA..."
## access_key: "wJalrXUtn..."
##
secrets: {}

## Redis cache service configuration
## Set enabled to false if using an external Redis deployment
##
Expand Down
Loading