Add k8ssecret strategy for cross-namespace secret watching - #66
Closed
daniel-garcia wants to merge 1 commit into
Closed
Add k8ssecret strategy for cross-namespace secret watching#66daniel-garcia wants to merge 1 commit into
daniel-garcia wants to merge 1 commit into
Conversation
New separate Go module (k8ssecret/) that implements hotload.Strategy by watching Kubernetes Secrets via the K8s API. This enables cross-namespace secret watching for services that cannot mount secrets from other namespaces as volumes. DSN format: k8ssecret://pgx/<secret-name>?namespace=<ns>&dsn=<key> The module has its own go.mod to keep client-go and its transitive dependencies out of the root hotload module. Also fixes pre-existing CI failure by bumping Dockerfile.test and Dockerfile.integrationtest from golang:1.23 to golang:1.24 (ginkgo v2.28.1 requires go >= 1.24.0).
daniel-garcia
force-pushed
the
feat/k8ssecret-strategy
branch
from
March 19, 2026 21:44
830f6ed to
4b3fb92
Compare
daniel-garcia
added a commit
that referenced
this pull request
Jun 11, 2026
Port the k8ssecret strategy idea from PR #66 onto v3: a nested module (github.com/infobloxopen/hotload/k8ssecret, keeping client-go out of the core) implementing hotload.Strategy by watching a Kubernetes Secret through the API server, for deployments that need credentials from a Secret in another namespace, which Kubernetes cannot mount as a volume. DSN format matches the PR: k8ssecret://<driver>/<secret>?namespace=<ns>&dsn=<key>, with the namespace defaulting to the pod's own and the key to dsn.txt. Beyond the port, this fixes four defects in the PR #66 implementation: - The hotload core passes uri.Path, so the secret name arrives with a leading slash; the PR used it verbatim and would look up a secret named "/myapp-db" (its tests called Watch directly with bare names, masking this). Covered here by an end-to-end test through sql.Open with a minimal fake driver. - Updates could be lost in the gap between the initial Get and the watch start, and while a dropped watch waited to reconnect (only Modified events were handled, watching from "now"). Every (re)connect now re-reads the Secret, delivers missed changes, and watches from that read's resource version; Added events (recreated secrets, post-reconnect snapshots) are handled too. - Slow subscribers had the newest value dropped when their buffer was full, leaving them permanently stale; delivery now drops the oldest queued value so subscribers converge on the latest. - Watches were keyed by namespace/name only, so two DSNs reading different data keys of the same Secret shared one value; the data key is now part of the watch identity. Tests use client-go's fake clientset: initial fetch, missing secret/key, defaults, update propagation, delete/recreate, reconnect catch-up (via a watch reactor whose first watcher is killed), slow subscriber convergence, independent keys, CloseWatch/Close semantics, and the sql.Open end-to-end path. The module joins go.work, the Makefile module loop (and therefore CI), and the release ordering docs.
4 tasks
daniel-garcia
added a commit
that referenced
this pull request
Jul 5, 2026
Port the k8ssecret strategy idea from PR #66 onto v3: a nested module (github.com/infobloxopen/hotload/k8ssecret, keeping client-go out of the core) implementing hotload.Strategy by watching a Kubernetes Secret through the API server, for deployments that need credentials from a Secret in another namespace, which Kubernetes cannot mount as a volume. DSN format matches the PR: k8ssecret://<driver>/<secret>?namespace=<ns>&dsn=<key>, with the namespace defaulting to the pod's own and the key to dsn.txt. Beyond the port, this fixes four defects in the PR #66 implementation: - The hotload core passes uri.Path, so the secret name arrives with a leading slash; the PR used it verbatim and would look up a secret named "/myapp-db" (its tests called Watch directly with bare names, masking this). Covered here by an end-to-end test through sql.Open with a minimal fake driver. - Updates could be lost in the gap between the initial Get and the watch start, and while a dropped watch waited to reconnect (only Modified events were handled, watching from "now"). Every (re)connect now re-reads the Secret, delivers missed changes, and watches from that read's resource version; Added events (recreated secrets, post-reconnect snapshots) are handled too. - Slow subscribers had the newest value dropped when their buffer was full, leaving them permanently stale; delivery now drops the oldest queued value so subscribers converge on the latest. - Watches were keyed by namespace/name only, so two DSNs reading different data keys of the same Secret shared one value; the data key is now part of the watch identity. Tests use client-go's fake clientset: initial fetch, missing secret/key, defaults, update propagation, delete/recreate, reconnect catch-up (via a watch reactor whose first watcher is killed), slow subscriber convergence, independent keys, CloseWatch/Close semantics, and the sql.Open end-to-end path. The module joins go.work, the Makefile module loop (and therefore CI), and the release ordering docs.
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
k8ssecret/directory containing a separate Go module (github.com/infobloxopen/hotload/k8ssecret)hotload.Strategyby watching Kubernetes Secrets via the K8s APIgo.modkeepsclient-goand its transitive dependencies out of the root hotload moduleDSN Format
Usage
Motivation
In multi-namespace Kubernetes deployments, a platform service (e.g., a database relay daemon) needs to read database credentials from a Secret in another team's namespace. Kubernetes does not allow mounting Secrets cross-namespace, so volume-based approaches (fsnotify) don't work. This strategy watches the Secret via the K8s API instead.
Test plan
client-go/kubernetes/fake