75 Commits

Author SHA1 Message Date
lukaszraczylo 2fc7d23d40 Update go.mod and go.sum (#48) v0.9.16 2026-06-04 05:38:32 +01:00
lukaszraczylo 557c6cfc9b Update go.mod and go.sum (#47) v0.9.14 2026-06-01 05:40:57 +01:00
lukaszraczylo 3179a25e41 Update go.mod and go.sum (#46) v0.9.12 2026-05-31 05:38:15 +01:00
lukaszraczylo 711713bf76 Update go.mod and go.sum (#45) v0.9.10 2026-05-30 05:28:13 +01:00
lukaszraczylo 0e8a9fd0a0 Update go.mod and go.sum (#44) v0.9.8 2026-05-23 05:23:34 +01:00
lukaszraczylo d97132a111 Update go.mod and go.sum (#43) v0.9.6 2026-05-22 05:32:49 +01:00
lukaszraczylo 3ab86c34b6 Update go.mod and go.sum (#42) v0.9.4 2026-05-21 05:37:43 +01:00
lukaszraczylo 76237c6bf6 docs: add Telemetry section linking to oss-telemetry opt-out docs
Discloses the single anonymous adoption ping sent on startup and points
users to the upstream README section for full opt-out instructions
instead of duplicating the table here.
2026-05-21 04:06:40 +01:00
lukaszraczylo d552e45e2f feat: anonymous usage telemetry via oss-telemetry
Send a single fire-and-forget ping at startup to help track adoption
and version spread. No persistent identifiers are collected.

Adds main.Version var (defaulting to "dev") so the existing goreleaser
ldflags injection (-X main.Version={{.Version}}) now binds to a real
symbol.

Opt out via any of:
  DO_NOT_TRACK=1
  OSS_TELEMETRY_DISABLED=1
  KUBEMIRROR_DISABLE_TELEMETRY=1
2026-05-21 03:05:58 +01:00
lukaszraczylo 1836381d9d Update go.mod and go.sum (#41) v0.8.22 2026-05-20 05:33:53 +01:00
lukaszraczylo 9240167386 Update go.mod and go.sum (#40) v0.8.20 2026-05-13 05:26:51 +01:00
lukaszraczylo 5e360d80c6 Update go.mod and go.sum (#39) v0.8.18 2026-05-12 05:23:43 +01:00
lukaszraczylo e5a0846165 Update go.mod and go.sum (#38) v0.8.16 2026-05-10 05:28:40 +01:00
lukaszraczylo 64b14b84e0 Update go.mod and go.sum (#37) v0.8.14 2026-05-09 05:16:48 +01:00
lukaszraczylo 2a1575f5c9 Update go.mod and go.sum (#36) v0.8.12 2026-05-08 05:11:10 +01:00
lukaszraczylo 8feb93146b Update go.mod and go.sum (#35) v0.8.10 2026-05-06 05:22:35 +01:00
lukaszraczylo d055f11bd4 Update go.mod and go.sum (#34) v0.8.8 2026-05-05 05:11:34 +01:00
lukaszraczylo e886143429 Update go.mod and go.sum (#33) v0.8.6 2026-05-03 05:26:25 +01:00
lukaszraczylo ba0797f5af chore: remove unreachable SetupWithManager(secret-only) on SourceReconciler
All registration goes through SetupWithManagerForResourceType (eager and
lazy paths in main.go); the legacy single-resource SetupWithManager and
its corev1 import were dead code that misled readers about how the
controller wires up.
v0.8.4
2026-05-02 22:50:02 +01:00
lukaszraczylo 75f7c18f3c fix: hash drift, transformer leak guard, prod logger, ctx-aware wait
M7: extractUnstructuredContent only hashed 'spec' when present, dropping
all other top-level content fields. Resources with both spec and data
(or any non-spec content) silently drifted until the next 10m resync.
Now hashes every non-Kubernetes-managed top-level field, matching the
fields updateUnstructuredMirror copies.

M6: when a source has a transform annotation, also hash the source's
labels and annotations (filtered of kubemirror.raczylo.com/* keys to
avoid the controller's own bookkeeping churning the hash). Templates
read these via TransformContext; without this a label change wouldn't
re-render the transformed mirror.

H3: text/template.Execute is not context-aware, so applyTemplateRule's
timeout cancels the select but leaks the executor goroutine. Added a
process-wide semaphore (cap 64) so a runaway template can't spawn an
unbounded number of stuck goroutines on every reconcile.

M4: zap dev mode (DPanic-on-error, console output, stacktraces on
warning) was hardcoded on. Defaulted to production; --zap-devel flag
remains for opt-in.

M5: WaitForInitialDiscovery was anchored on context.Background() with
its own WithTimeout, so SIGTERM during startup couldn't abort the wait.
Now anchors on signalCtx.
2026-05-02 22:49:15 +01:00
lukaszraczylo cf095e93f4 fix(dynamic-manager): release mu before invoking registration
H2: scanAndRegister held d.mu (write lock) across registerController
and registerMirrorControllerOnly. Those calls enter controller-runtime's
manager state machine, which takes its own internal locks and can block
on cache sync — holding our application-level write lock across them
is a latent deadlock the moment any reentrant access happens (health
checks reading GetRegisteredCount, factories that introspect state).

Restructured into three phases: snapshot work under RLock, perform
registrations with NO lock held, then commit results under Lock.
Registration step routed through funcs to keep tests honest about
the lock state at the moment of invocation.
2026-05-02 22:45:27 +01:00
lukaszraczylo a8e48a9eb6 fix(controller): forward APIReader+CircuitBreaker through NamespaceReconciler
H4: NamespaceReconciler.reconcileMirror builds an ad-hoc SourceReconciler
to delegate mirror creation. The previous version left APIReader and
CircuitBreaker as nil, which silently disabled freshness verification
on the namespace-driven path (a label change to a target namespace
would mirror cached, possibly stale source data) and bypassed circuit
breaker accounting for those reconciles.

Construction extracted into newSourceReconciler so the forwarding is
covered by a unit test that pins both fields by identity.
2026-05-02 22:41:11 +01:00
lukaszraczylo dfe08b35d1 fix(controller): stop self-triggered reconcile loops
C2: updateLastSyncStatus wrote the sync-status annotation on every
successful reconcile. Because the source's watch predicate is the
'enabled' label (server-side filter), that Update fires a watch event
that re-enters Reconcile. With reconciled/error counts varying across
cycles, the value differs each time, so the API server bumps RV and
the loop never quiesces. Now skips the Update when the value matches
the existing annotation.

C3: NamespaceReconciler's happy-path returned RequeueAfter=3s
unconditionally. Every namespace in the cluster re-reconciled every
3 seconds forever, generating constant List calls per source kind.
Now returns ctrl.Result{}; cache-staleness windows are handled by
the manager's resync period and source freshness verification.
2026-05-02 22:39:09 +01:00
lukaszraczylo 99c0eccd53 fix: default verify-source-freshness=true; honor opt-out for glob
H1: --verify-source-freshness used to default to false, so any source
update whose annotation was still in the informer cache (5-20s lag)
would resolve the wrong target list. cleanupOrphanedMirrors then ran
against the stale list and missed orphans (manifested in e2e as
'Orphaned mirror in kubemirror-e2e-app-1 not deleted within timeout'
after target-namespaces was changed). Defaulting to true fixes the
race; the trade-off is one extra API read per stale-cache reconcile.

M2: ResolveTargetNamespaces glob branch checked filter.IsAllowed but
not the opt-out map, so a namespace labeled allow-mirrors=false would
still receive a mirror through patterns like 'app-*'. The 'all' branch
already had the guard; the glob branch now does too. Direct namespace
listings still bypass opt-out by design (explicit author intent).
2026-05-02 22:36:50 +01:00
lukaszraczylo 4277c8ac39 fix(controller): guard mirror deletion + enforce secret blacklist
C1: deleteAllMirrors used to issue a blind Delete on every namespace
matching the source name+GVK, which would destroy unrelated resources
(e.g. a 'default' SA, 'ca-bundle' ConfigMap) sharing the source name.
Now reads each candidate, verifies managed-by label and source-reference
annotation, and only deletes confirmed mirrors.

M1: BlacklistedSecretTypes was declared but never enforced. Enabling
mirroring on a service-account-token / bootstrap-token / helm release
Secret would mirror credentials cluster-wide. Now refused at Reconcile.

M3: deleteAllMirrors swallowed per-namespace errors and returned nil,
so callers removed the finalizer even on partial failure (orphans).
Errors are now joined and returned.
2026-05-02 22:35:40 +01:00
lukaszraczylo b555d84d32 ci: bump go-version constraint to >=1.26
k8s.io/api v0.36.0 requires Go 1.26.0; autoupdate has been failing
since 2026-04-23 because setup-go's cached 1.25.9 fell behind.
2026-05-02 22:03:19 +01:00
lukaszraczylo 30ffc823d9 Update go.mod and go.sum (#32) 2026-04-19 05:09:27 +01:00
lukaszraczylo c3450e2af2 Update go.mod and go.sum (#31) 2026-04-17 05:09:22 +01:00
lukaszraczylo d0857e4f4a Update go.mod and go.sum (#30) 2026-04-16 05:10:11 +01:00
lukaszraczylo 36c9e859af Update go.mod and go.sum (#29) 2026-04-15 05:07:38 +01:00
lukaszraczylo 05aacddeab Update go.mod and go.sum (#28) 2026-04-10 05:08:23 +01:00
lukaszraczylo a9838e9156 Update go.mod and go.sum (#27) 2026-04-09 05:02:31 +01:00
lukaszraczylo 317143c458 Update go.mod and go.sum (#26) 2026-03-31 05:04:13 +01:00
lukaszraczylo 42358a3743 Update go.mod and go.sum (#25) 2026-03-20 03:54:18 +00:00
lukaszraczylo f2ecc5d56a Update go.mod and go.sum (#24) 2026-03-19 03:57:48 +00:00
lukaszraczylo 30de592c0c Update go.mod and go.sum (#23) 2026-03-18 03:57:33 +00:00
lukaszraczylo ea405f44a2 Update go.mod and go.sum (#22) 2026-03-12 03:52:50 +00:00
lukaszraczylo f62bec57f5 Update go.mod and go.sum (#21) 2026-03-09 03:53:52 +00:00
lukaszraczylo c9cf81e4fd Update go.mod and go.sum (#20) 2026-03-07 03:46:46 +00:00
lukaszraczylo 7c8a12958d Update go.mod and go.sum (#19) 2026-03-06 03:52:51 +00:00
lukaszraczylo 0bac0f4645 Update go.mod and go.sum (#18) 2026-03-05 03:52:56 +00:00
lukaszraczylo afe6602ddd Update go.mod and go.sum (#17) 2026-03-03 03:53:14 +00:00
lukaszraczylo 91a1d05a92 Update go.mod and go.sum (#16) 2026-03-01 03:59:02 +00:00
lukaszraczylo 3c7f25bc16 Update go.mod and go.sum (#15) 2026-02-28 03:44:26 +00:00
lukaszraczylo 1a40783e36 Update go.mod and go.sum (#14) 2026-02-26 03:54:10 +00:00
lukaszraczylo 56809700fb Update go.mod and go.sum (#13) 2026-02-11 04:03:15 +00:00
lukaszraczylo 5db9fa8653 Update go.mod and go.sum (#12) 2026-02-10 04:04:06 +00:00
lukaszraczylo 1e4af7df0c Update go.mod and go.sum (#11) 2026-02-09 03:59:24 +00:00
lukaszraczylo 668a84b070 Update go.mod and go.sum (#10) 2026-02-07 03:51:55 +00:00
lukaszraczylo 9dea7a1022 Update go.mod and go.sum (#9) 2026-01-28 03:40:46 +00:00