feat: chart repo scaffold, common library and the first service charts - #8
Merged
manjudr merged 19 commits intoSep 8, 2026
Merged
Conversation
Establishes the repo-level scaffolding the charts depend on: naming and structure conventions, a lint script that rebuilds file:// dependencies before linting, and a CI workflow that runs it. .gitignore excludes Helm dependency artifacts, which are regenerated rather than committed.
oan-common holds the shared helpers every OAN chart renders through - names, labels, image references, resources, and security contexts - so the service charts stay declarative. Resources are deliberately required rather than defaulted: an unset value fails the render instead of shipping an unbounded pod. oan-template is the copy-from starting point for a new service chart.
postgresql-cnpg renders one CloudNativePG Cluster per release, with optional ScheduledBackup and Barman Cloud ObjectStore. Neither chart renders a password: every credential is a reference to a Secret, and the render fails when one is unset rather than defaulting. Applications connect as the owner of their own database, never as postgres. Extensions that require superuser are created once through bootstrap.postInitApplicationSQL, which the operator runs during bootstrap, so no long-lived role holds the privilege. postgresql-migration runs Flyway as a Job across the databases the cluster chart created. Both target directories carry no SQL yet - Sunbird RC and Keycloak each manage their own schema - so the Job currently skips them and the targets exist as a versioned home.
Imports the sunbird-rc realm from a ConfigMap on first start, with the realm content checksummed into the pod annotations so a realm change rolls the pod. An init container waits for the database, standing in for compose's depends_on: condition: service_healthy. Keycloak connects as the owner of its own keycloak database rather than sharing the registry's database as postgres, which is how the compose stack runs it. The realm JSON is Sunbird RC's export and still carries its upstream defaults: a placeholder admin-api client secret, an enabled placeholder user with a known password, and a wildcard redirect URI on the public frontend client. All three need hardening before this reaches any environment that is not local. See the chart README for the client secret step; the other two are tracked as follow-up.
registry runs Sunbird RC with its Participant schema mounted from a ConfigMap, and connects as the owner of the registry database rather than as postgres. discovery renders the Beckn discovery service, taking its whole DSN from the CNPG-generated Secret so no password is assembled or escaped in the chart. It enables readOnlyRootFilesystem, which the other service charts cannot yet. The Beckn spec is fetched by URL with a cache fallback, and the render fails when neither a URL nor an existing ConfigMap is set, since the service refuses to boot without the document. Both charts fail the render on an unset credential rather than defaulting one.
Records the chart inventory and the order releases have to go out in, since the database cluster has to exist before the migration Job and the services that connect to it.
CI publishes ghcr.io/openagrinet/discovery-service now. It used to build and scan an image and push nothing, which is the whole reason repository was empty and the render was made to fail on it. tag stays empty rather than pinned. Empty falls through to Chart.AppVersion, so the chart ships pointing at the app version it was written against, and an environment wanting a different build says so in its own values file. Pinning it here would only be right once the chart and the app stop versioning together. Records that the package is private, which the old comment had no reason to. A cluster needs a docker-registry secret named in pullSecrets, and without it the deploy looks clean while the pod sits in ImagePullBackOff -- the same late-surfacing failure the empty-repository guard exists to prevent.
Establishes the repo-level scaffolding the charts depend on: naming and structure conventions, a lint script that rebuilds file:// dependencies before linting, and a CI workflow that runs it. .gitignore excludes Helm dependency artifacts, which are regenerated rather than committed.
oan-common holds the shared helpers every OAN chart renders through - names, labels, image references, resources, and security contexts - so the service charts stay declarative. Resources are deliberately required rather than defaulted: an unset value fails the render instead of shipping an unbounded pod. oan-template is the copy-from starting point for a new service chart.
postgresql-cnpg renders one CloudNativePG Cluster per release, with optional ScheduledBackup and Barman Cloud ObjectStore. Neither chart renders a password: every credential is a reference to a Secret, and the render fails when one is unset rather than defaulting. Applications connect as the owner of their own database, never as postgres. Extensions that require superuser are created once through bootstrap.postInitApplicationSQL, which the operator runs during bootstrap, so no long-lived role holds the privilege. postgresql-migration runs Flyway as a Job across the databases the cluster chart created. Both target directories carry no SQL yet - Sunbird RC and Keycloak each manage their own schema - so the Job currently skips them and the targets exist as a versioned home.
Imports the sunbird-rc realm from a ConfigMap on first start, with the realm content checksummed into the pod annotations so a realm change rolls the pod. An init container waits for the database, standing in for compose's depends_on: condition: service_healthy. Keycloak connects as the owner of its own keycloak database rather than sharing the registry's database as postgres, which is how the compose stack runs it. The realm JSON is Sunbird RC's export and still carries its upstream defaults: a placeholder admin-api client secret, an enabled placeholder user with a known password, and a wildcard redirect URI on the public frontend client. All three need hardening before this reaches any environment that is not local. See the chart README for the client secret step; the other two are tracked as follow-up.
registry runs Sunbird RC with its Participant schema mounted from a ConfigMap, and connects as the owner of the registry database rather than as postgres. discovery renders the Beckn discovery service, taking its whole DSN from the CNPG-generated Secret so no password is assembled or escaped in the chart. It enables readOnlyRootFilesystem, which the other service charts cannot yet. The Beckn spec is fetched by URL with a cache fallback, and the render fails when neither a URL nor an existing ConfigMap is set, since the service refuses to boot without the document. Both charts fail the render on an unset credential rather than defaulting one.
Records the chart inventory and the order releases have to go out in, since the database cluster has to exist before the migration Job and the services that connect to it.
CI publishes ghcr.io/openagrinet/discovery-service now. It used to build and scan an image and push nothing, which is the whole reason repository was empty and the render was made to fail on it. tag stays empty rather than pinned. Empty falls through to Chart.AppVersion, so the chart ships pointing at the app version it was written against, and an environment wanting a different build says so in its own values file. Pinning it here would only be right once the chart and the app stop versioning together. Records that the package is private, which the old comment had no reason to. A cluster needs a docker-registry secret named in pullSecrets, and without it the deploy looks clean while the pod sits in ImagePullBackOff -- the same late-surfacing failure the empty-repository guard exists to prevent.
…b.com/OpenAgriNet/helmcharts into feat/53-chart-scaffold-common-library
Models the network-adapter service from docker-deployment/docker-compose.yml as a chart on oan-common. The adapter is stateless: its identity is a keypair in a Secret and everything else comes from the registry. Config is rendered by an init container from a ConfigMap of placeholders plus the identity Secret into an emptyDir, so the keypair is never written to a ConfigMap and never appears in a process environment. Renders fail outright on the five values whose absence would otherwise produce a pod that starts, reports Ready and does not work. HPA, PodDisruptionBudget, Ingress and the upstream readiness gates are all optional and off by default; ci/otel-ingress-values.yaml renders that other branch so lint covers it.
The chart shipped with an empty tag, which renders an image reference with no tag at all. latest keeps the draft chart installable while the discovery service has no released version to pin to.
KrutikaPhirangi
changed the base branch from
development
to
feat/4-docker-compose
September 8, 2026 05:15
Renames network-adapter to adapter-service and makes the role a value. The provider, network and experience adapters are the same image and the same config format, so what differed between them was configuration, not three charts: role now selects the handler role, the step list and the routing target. experience is the role that justifies the abstraction. It sits inside the trust boundary and accepts unsigned requests, so it runs as bap with no validateSign step, while the other two receive from the network and must verify first. Its example sets both explicitly rather than relying on the default, so the missing step reads as deliberate. discovery.url becomes routing.rules, a list, because provider fans out to several upstreams and a single target could not express that. Every rule is checked at render time for a target url, a missing trailing slash and a non-empty endpoint list. Each example sets fullnameOverride to <role>-adapter. Without it fullname resolves to "<release>-adapter-service", so a release named network-adapter produced a Service called network-adapter-adapter-service and the experience adapter's route to network-adapter:9201 resolved to nothing. That only worked before because the chart itself was named network-adapter. ci/otel-ingress-values.yaml now renders the experience role, so CI covers the role branches that ci/lint-values.yaml (network) does not reach. BREAKING CHANGE: chart renamed network-adapter -> adapter-service; role is required with no default; discovery.url replaced by routing.rules; config placeholders renamed __NETWORK_* -> __ADAPTER_*; routing file is now routing-<role>.yaml.
Member
Code reviewFound 1 issue:
helmcharts/charts/adapter-service/values.yaml Lines 277 to 296 in f4fcf23 helmcharts/charts/oan-common/templates/_helpers.tpl Lines 350 to 362 in f4fcf23 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status
These are draft charts and are not yet deployed in dev.
What
Establishes the chart repository: conventions, the
oan-commonlibrary chartevery service chart builds on, a
oan-templatestarter, and the first servicecharts.
Why
Each OAN service otherwise repeats the same labels, probes, security context,
service account and config-rendering boilerplate, and drifts.
oan-commonholds that once as a library chart so a new service chart is values plus
whatever is genuinely specific to it.
oan-templateis the copy-to-startscaffold so the shape stays consistent.
Changes
oan-common— library chart: shared helpers, labels, probes, securitycontext, service account, config-rendering pattern.
oan-template— starter chart for a new service.postgresql-cnpgandpostgresql-migration— CNPG cluster and Flywaymigration job.
keycloak— with sunbird-rc realm import.registryanddiscovery— the two core network services.network-adapter— Beckn network adapter. Identity is a keypair in a Secret,substituted by an init container into an
emptyDir, so it is never writtento a ConfigMap and never lands in a process environment.
scripts/lint-charts.sh+helm-lintworkflow — lints and renders everychart on PR. Each
ci/*-values.yamlis a separate render case, so chartscover both their default and toggled-on branches.
Notes
oan-commonviafile://../oan-common, so no dependencyartifact is committed.
scripts/lint-charts.shrebuilds it before linting;a local edit to
oan-commonneeds that script (orhelm dependency update)before it is picked up.
[#53], which refers toOpenAgriNet/engineering-tracker#53. Read inside this repo that numberresolves to the Discover Service ticket instead, so the later commits use
in-repo issue numbers.
Refs OpenAgriNet/engineering-tracker#53 — [OAN-HELM-1] Chart repo scaffold, conventions and common library chart
Refs #1 — [OAN-HELM-2] Helm chart for Registry Service
Refs #2 — [OAN-HELM-3] Helm chart for Adapter Service
Refs #3 — [OAN-HELM-4] Helm chart for Discover Service