feat(configread): local ConfigReadService for config-server cache backend - #476
Open
steiler wants to merge 9 commits into
Open
feat(configread): local ConfigReadService for config-server cache backend#476steiler wants to merge 9 commits into
steiler wants to merge 9 commits into
Conversation
Implements ticket 07 of the config-server-cache-backend effort: a unary, localhost-bound gRPC server (pkg/sdc/configread) that serves Get-by-name/ List-by-target reads over Config joined with SensitiveConfig, backed entirely by the colocated controller's existing watch-synced informer cache (mgr.GetClient()) — no new watch, store, or trust boundary. Wired into cmd/controller/main.go as a manager.Runnable alongside the other runnables. Exports targetmanager.ParseSensitivePaths (was private) so the new server reuses the existing keyless-XPath parsing instead of duplicating it. Pins github.com/sdcio/sdc-protos to the sibling ../sdc-protos checkout via a temporary go.mod replace, mirroring data-server's existing pin, since ticket 01's config_read package isn't tagged upstream yet. Co-authored-by: Cursor <cursoragent@cursor.com>
configread.Server will need to decrypt TargetSnapshot entries in upcoming tickets; NewServer now requires a KeyRing and errors out immediately if one isn't provided, instead of letting a misconfigured server start and fail lazily on the first Get/List call. Co-authored-by: Cursor <cursoragent@cursor.com>
…sitiveConfigSpec Adds the shared mapping function Get/List will use to serve TargetSnapshot-backed last-applied config instead of live Config/SensitiveConfig, with unit tests covering the sensitive-path round trip and the decrypt/unmarshal failure modes. Co-authored-by: Cursor <cursoragent@cursor.com>
Get now serves the last-applied value from TargetSnapshot.Spec.Configs
instead of joining live Config + SensitiveConfig, closing the
live-vs-applied conflation that caused data-server's diff to silently
drop updates and deletions. Deletes the now-dead belongsToTarget guard:
looking the TargetSnapshot up by {target namespace, target name} makes
the lookup key the target's identity, so there's nothing left to
re-check.
Co-authored-by: Cursor <cursoragent@cursor.com>
…read List now serves every last-applied intent for a target straight from its TargetSnapshot.Spec.Configs instead of label-matching over live Config + joined SensitiveConfig, closing the last live-vs-applied read path in configread. A missing TargetSnapshot returns an empty list (parity with Cache.Type: local for a target that's never transacted); a decrypt/ unmarshal failure on any one entry fails the whole call with Internal rather than silently omitting it. Deletes the now-dead toConfigEntry, getSensitiveConfig, and isOrphan helpers. Co-authored-by: Cursor <cursoragent@cursor.com>
CI can't resolve `replace github.com/sdcio/sdc-protos => ../sdc-protos` since no sibling checkout exists on the runner. sdcio/sdc-protos@a8f3da0 (config-server-cache-backend) is now pushed, so pin go.mod to it via a real pseudo-version instead of the placeholder one and the local path replace. Also fix two errcheck findings on unchecked Close() calls, uncovered now that lint can actually resolve the module. Co-authored-by: Cursor <cursoragent@cursor.com>
Rebasing onto sensitive picked up the ENV-based keyring rework, which dropped keyring.NewFromSecret in favor of NewFromFile/NewFromBytes. Update the test helper accordingly; it no longer needs a fake Secret wrapper. Co-authored-by: Cursor <cursoragent@cursor.com>
steiler
force-pushed
the
config-server-cache-backend
branch
from
August 12, 2026 08:24
cd42f6b to
cf9aeed
Compare
Pre-existing errcheck failure on the sensitive branch itself (Go Checks has been red there since the ENV-keyring rework landed); fixing it here so this branch's own CI is green. Co-authored-by: Cursor <cursoragent@cursor.com>
…a-server-controller StatefulSet
The co-located controller+data-server StatefulSet template
(statefulset-data-server.yaml, used whenever LOCAL_DATASERVER=true —
e.g. integration-tests) only mounted the config-keyring Secret into
the data-server container. The controller container never got it,
so keyring.Load() in cmd/controller/main.go always saw "no keyring
mounted" there, even when the Secret exists and is correctly mounted
into the sibling container.
This silently broke any keyring-requiring reconciler in this topology
(targetconfig's SetupWithManager unconditionally calls
RequireKeyRing, and ENABLE_TARGETCONFIG=true is set here) well before
this PR — main.go now also fails fast constructing the config-read
server, surfacing it as a controller crash loop
("cannot construct config-read server: KeyRing is nil").
The standalone controller Deployment (deployment-controller.yaml)
already mounts the keyring correctly into its controller container;
this mirrors that.
Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
config_read.ConfigReadServicegRPC server (pkg/sdc/configread) exposing last-applied config reads (Get/List) backed byTargetSnapshot, threaded through the controller'sKeyRing.config-server-backedcache.Client(see paired PR below), which calls this service instead of talking to the local/dragonfly cache directly.github.com/sdcio/sdc-protosto the pushedconfig-server-cache-backendcommit (a8f3da0) instead of a local pathreplace, so CI can resolve the module.Pairs-with: sdcio/data-server#471
Pairs-with: sdcio/integration-tests#113
Test plan
go build ./...go test ./...golangci-lint run ./...(no new issues introduced by this branch)Cache.Type: config-serveryet. Follow-up needed insdcio/integration-tests.Note on integration-tests dependency
integration-tests'sdata-server-controllerStatefulSet was already hanging inContainerCreatingon everysensitive-based run since commit83d07f8("added ENV keyring and removed keyring secret") — that commit moved config-server'sconfig-keyringSecret sample intoartifacts/in/, whichkformexcludes from the generated deploy manifest, so the Secret volume the StatefulSet mounts can never be satisfied. This is pre-existing onsensitive(see #441) and unrelated to this PR's changes, but it blocksintegration-testshere too. ThePairs-with: sdcio/integration-tests#113line above pulls in a fix that provisions a CI-only placeholder Secret directly inintegration-tests' deploy flow (the correct place, sinceconfig-serverintentionally stopped shipping a default key to force real deployments to bring their own).Made with Cursor