Help us shape the future of Go! Take the 2026 Go Developer Survey

controller

package
v0.54.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 48 Imported by: 0

Documentation

Overview

Package controller contains shared constants for all controllers.

Index

Constants

View Source
const (
	// ReasonSuspended is InControl=True: the Kustomization is suspended, the last suspend handled, and
	// nothing applies.
	ReasonSuspended = "Suspended"
	// ReasonApplying is InControl=True while an operation of a branch worker is in flight and followed:
	// the Kustomization is resumed for it, and suspended again when it ends.
	ReasonApplying = "Applying"
	// ReasonSuspending is InControl=False while the token of the suspend is not handled yet.
	ReasonSuspending = "Suspending"
	// ReasonNotConfigured is InControl=Unknown on an applier claim that is not Configured: nothing is held, or
	// the Kustomization is left suspended as the applier claim last held it (the message says which).
	ReasonNotConfigured = "NotConfigured"
	// ReasonReleasing is InControl=False on an applier claim that held its Kustomization and is handing
	// it back: it is being deleted, or no eligible GitTarget references it any more. InControl=False with
	// applier.ReasonNotReferenced is an applier claim with nothing to hold.
	ReasonReleasing = "Releasing"
	// ReasonRevoking is InControl=False on an applier claim that held its applier and is handing it back
	// because its KubeProvider's spec.allowedApplierClaims no longer admit it. The hand-back finishes
	// even if a grant admits the applier claim again meanwhile, which then adopts its applier anew.
	ReasonRevoking = "Revoking"
	// EventReasonAdopted is a Kustomization suspended, or an Application's automated sync switched
	// off, for the first time.
	EventReasonAdopted = "Adopted"
	// EventReasonClaimedResourceReconciled is a held applier found changed by somebody else, and put
	// back as the applier claim holds it: a Kustomization resumed (`flux resume`) and suspended again, or an
	// Application's automated sync switched on and off again.
	EventReasonClaimedResourceReconciled = "ClaimedResourceReconciled"
	// EventReasonReleased is an applier handed back to Flux or Argo CD, or left held for the applier claim
	// next in line, when its applier claim was deleted or no eligible GitTarget references it any more.
	EventReasonReleased = "Released"
	// EventReasonReleaseFailed is a retiring applier claim that could not hand its applier back.
	EventReasonReleaseFailed = "ReleaseFailed"
)

InControl reasons, and the Events of the hold lifecycle on an applier claim.

View Source
const (
	ClusterWatchRuleReasonValidating            = "Validating"
	ClusterWatchRuleReasonAccessDenied          = "AccessDenied"
	ClusterWatchRuleReasonGitTargetNotFound     = "GitTargetNotFound"
	ClusterWatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid"
	ClusterWatchRuleReasonReady                 = ReasonSucceeded
	// ClusterWatchRuleReasonCatalogNotReady is ResourcesResolved=False: the source cluster's discovery
	// catalog is not ready, so no selector can be resolved yet. A selector that matches nothing
	// the cluster serves is not this: it resolves True, watching zero types.
	ClusterWatchRuleReasonCatalogNotReady = "CatalogNotReady"

	// ClusterWatchRuleReasonGitTargetNamespaceNotAuthorized is the terminal reason when the
	// referenced GitTarget's namespace is not admitted by that target's KubeProvider. It is
	// re-exported from internal/watch, where the shared compile path both bootstrap and this
	// reconciler call decides it, so the two can never drift.
	ClusterWatchRuleReasonGitTargetNamespaceNotAuthorized = watch.ClusterWatchRuleReasonGitTargetNamespaceNotAuthorized
)

ClusterWatchRule status condition reasons.

View Source
const (
	// ConditionTypeReady indicates whether the resource is ready.
	ConditionTypeReady = "Ready"
	// ConditionTypeResourcesResolved indicates whether rule resources resolved to concrete GVRs.
	ConditionTypeResourcesResolved = "ResourcesResolved"
	// ConditionTypeReconciling is the kstatus progress condition. It is abnormal-true.
	ConditionTypeReconciling = "Reconciling"
	// ConditionTypeStalled is the kstatus blocked condition. It is abnormal-true.
	ConditionTypeStalled = "Stalled"
	// ConditionTypeStreamsRunning indicates whether watched type streams are routing live events.
	ConditionTypeStreamsRunning = "StreamsRunning"
	// ConditionTypeGitPathAccepted indicates whether the GitTarget path is safe to materialize.
	ConditionTypeGitPathAccepted = "GitPathAccepted"
	// ConditionTypeRenderMatchesLive indicates whether every current render scope agrees with live.
	ConditionTypeRenderMatchesLive = "RenderMatchesLive"
	// ConditionTypeGitTargetReady indicates whether the referenced GitTarget is ready for writes.
	ConditionTypeGitTargetReady = "GitTargetReady"
	// ConditionTypeSourceNamespaceAuthorized reports whether a rule's EFFECTIVE source namespace
	// is authorized for the observed generation. It is positive and state-style, and it is set for
	// every rule, its own namespace included, so the effective authorization is always visible and
	// automation has ONE condition to inspect.
	//
	// It is deliberately distinct from GitTargetReady, which stays the health of the referenced
	// GitTarget and must never be reused for source authorization. Its three values are not
	// interchangeable: False is a refusal (terminal, Stalled=True), while Unknown means the answer is
	// still being established (the rule is blocked by validation), which must not be rendered as a
	// permanent failure.
	ConditionTypeSourceNamespaceAuthorized = "SourceNamespaceAuthorized"
	// ConditionTypeAuthorAttributed indicates whether a CommitRequest's commit author
	// was named from the submitter captured at admission. It is binary and immediately
	// settled (no Unknown, no timeout): True (AttributedFromAdmission) when the
	// validate-operator-types webhook recorded the submitter, False (CommitterFallback) when
	// capture ran but found no record, or False (AuthorCaptureDisabled) when capture is off.
	// False is not a failure and does not affect Ready: the
	// request claims no actor and can attach only to an unnamed watch window
	// (docs/architecture.md#commitrequest-finalize).
	ConditionTypeAuthorAttributed = "AuthorAttributed"
	// ConditionTypePushed indicates whether a CommitRequest's commit reached the
	// remote repository.
	ConditionTypePushed = "Pushed"

	// KubeProviderConditionValidated reports whether a KubeProvider's credential is safe and
	// resolvable: an inCluster provider is Validated while the installation lists it in
	// --in-cluster-kube-providers; a secretRef provider once its kubeconfig Secret is present,
	// keyed, and passes the exec/TLS/file-reference safety policy. It is asserted WITHOUT a network
	// dial — runtime reachability is the GitTarget's SourceClusterReachable.
	KubeProviderConditionValidated = "Validated"

	// KubeProviderConditionAuditFactsReceived reports whether an attribution fact has ever been
	// published on this provider's audit route (spec.attribution.auditRoute, defaulting to
	// <namespace>.<name>). It is Unknown from creation until the first fact, with the reason naming
	// which silence it is (see the three below), and True (ReasonFactsReceived) from then on. It
	// NEVER regresses: the persisted status is the latch, so a restart — or the memory transport,
	// whose in-process state is lost with the process — keeps it True. Later silence is a quiet cluster, not a fault, which is why there is
	// no False state, no grace window and no timer.
	//
	// It is deliberately NOT part of Ready: a provider reading a route nobody posts under mirrors
	// perfectly and loses only the commit AUTHOR, so reporting it through Ready would tell every
	// kstatus reader the object is broken. It is absent entirely when the operator runs with
	// --author-attribution=false, where no fact was ever expected.
	KubeProviderConditionAuditFactsReceived = "AuditFactsReceived"

	// ReasonTransportUnavailable is the AuditFactsReceived=Unknown reason when the last append to
	// the fact transport failed. Nothing can be concluded about any route's configuration while
	// this holds. The fix is the operator's transport, not the reader's audit webhook.
	ReasonTransportUnavailable = "TransportUnavailable"
	// ReasonNoAuditDelivery is the AuditFactsReceived=Unknown reason when no audit request has ever
	// reached this operator, on any route. Nothing is posting to it, so the fix is the API server's
	// audit webhook configuration and its connectivity, never this provider's route.
	ReasonNoAuditDelivery = "NoAuditDelivery"
	// ReasonRouteUnused is the AuditFactsReceived=Unknown reason when audit requests ARE arriving
	// and nothing has ever landed on this provider's route. That is the one case where the route
	// itself is the thing to look at.
	//
	// It deliberately does not claim the facts went to some OTHER route, which would be the sharper
	// message: requests can also arrive and produce no fact anywhere, when the audit policy's level
	// or verbs leave nothing attributable. This reason stays true for both.
	ReasonRouteUnused = "RouteUnused"
	// ReasonFactsReceived is the AuditFactsReceived=True reason: a fact has arrived on the route,
	// and that answer is latched.
	ReasonFactsReceived = "Received"

	// ReasonInCluster is the Validated=True reason for an inCluster provider the installation
	// allows. A secretRef provider that validates reports the shared ReasonSucceeded instead.
	ReasonInCluster = "InCluster"
	// ReasonKubeConfigInvalid is the Validated=False reason for a malformed or unsafe kubeconfig
	// whose specific cause is carried in the message.
	ReasonKubeConfigInvalid = "KubeConfigInvalid"

	// MsgSnapshotCompleted is returned as the condition message when the initial
	// cluster snapshot has been successfully committed to Git.
	MsgSnapshotCompleted = "Initial snapshot reconciliation completed"

	// RequeueSteadyInterval is the unified control-plane periodic reconcile fallback.
	// The control plane no longer watches Secrets (docs/rbac.md),
	// so out-of-band credential and age-key changes are picked up on this steady cadence
	// instead of via a Secret informer. It replaces the former split of a 2-minute
	// transient-retry, a 5-minute auth/secret, and a 10-minute revalidation interval with
	// a single 5-minute fallback for the GitProvider, GitTarget, WatchRule, and
	// ClusterWatchRule reconcilers. The fast stream-settle loop below is separate.
	RequeueSteadyInterval = 5 * time.Minute
	// RemotePublicationInterval is the FLOOR on how often one GitTarget writes status.remote: at
	// most one such write per target per interval, whatever the branch's commit rate.
	//
	// It is a floor and not a deadline. What a target publishes is what it holds when it
	// reconciles, so the lag is its own cadence; this only stops a target reconciling in a tight
	// loop from writing the stanza every time. The one place it also acts as a delay is a
	// reconcile that has just ASKED the remote where the branch is, which comes back after this
	// long to publish the answer rather than leaving it undelivered for a tick.
	//
	// One minute: short enough that a target being asked questions answers promptly, long enough
	// that ten folders sharing a busy branch cost ten status writes a minute, not ten per commit.
	RemotePublicationInterval = 1 * time.Minute
	// DefaultGitRefreshInterval is how often an IDLE branch's remote state is re-proved. A target
	// that is publishing renews its observation on every push and never waits for this.
	DefaultGitRefreshInterval = 10 * time.Minute
	// DefaultCommitRequestTTL is how long a CommitRequest is kept once it finishes. Each save leaves
	// one object behind, so without an expiry they accumulate in etcd for as long as the namespace
	// lives. Two days leaves a weekend's worth of saves to inspect.
	DefaultCommitRequestTTL = 48 * time.Hour
	// RequeueStreamSettleInterval is the requeue interval while a Ready GitTarget still
	// has streams pending replay completion. Stream status is computed during reconcile, so
	// this keeps status.streams fresh while watches converge.
	RequeueStreamSettleInterval = 10 * time.Second
	// RequeueCollectionOverlapInterval is how often a rule refused for a CollectionOverlap
	// re-checks the conflict. It is a fallback: the stream-state event of the sibling rule that
	// cleared it usually arrives first, but that event is best-effort.
	RequeueCollectionOverlapInterval = 30 * time.Second
	// RequeueReceiverTokenInterval is how often a GitReceiver whose token Secret or "token" key is
	// missing looks again. Secrets are not watched, so nothing else tells it the token arrived, and
	// until it does no delivery can reach the receiver: Flux or Argo CD applying a GitReceiver and
	// its Secret in one pass, in either order, must not leave the path unpublished for a steady
	// interval.
	RequeueReceiverTokenInterval = 30 * time.Second
	// RequeueWriteLostInterval is how soon a reconcile whose status write lost the optimistic-lock
	// race comes back. It is short because there is nothing to wait FOR: the write was rejected
	// against a resourceVersion this reconcile had already read, so the only thing that has to
	// happen before the retry can succeed is the informer cache catching up with a write that is
	// already durable — milliseconds, not a settle window.
	//
	// It used to borrow RequeueStreamSettleInterval, which put the recovery ten seconds out and
	// made every lost write a ten-second window of published-but-stale status. Two unrelated
	// cadences shared one constant; only the coincidence that both were "soon" hid it.
	RequeueWriteLostInterval = 100 * time.Millisecond

	// RetryInitialDuration is the initial duration for exponential backoff retry.
	RetryInitialDuration = 100 * time.Millisecond
	// RetryBackoffFactor is the multiplicative factor for exponential backoff.
	RetryBackoffFactor = 2.0
	// RetryBackoffJitter is the jitter factor for retry backoff.
	RetryBackoffJitter = 0.1
	// RetryMaxSteps is the maximum number of retry attempts.
	RetryMaxSteps = 5

	// ReasonSucceeded is the reason on a healthy, fully reconciled object. It replaces the former
	// "OK"/"Ready" spellings, which restated the condition type instead of answering "why".
	ReasonSucceeded = fluxmeta.SucceededReason
	// ReasonProgressing indicates that a stream or control-plane gate is still converging.
	ReasonProgressing = fluxmeta.ProgressingReason

	// ReasonFailed indicates that reconciliation is blocked until a human fixes the object or
	// dependency. fluxmeta has no Stalled reason, and a reason restating the Stalled type would
	// answer nothing, so this is the upstream Failed.
	ReasonFailed = fluxmeta.FailedReason
	// ReasonSecretNotFound indicates that the referenced secret was not found.
	ReasonSecretNotFound = "SecretNotFound"
	// ReasonSecretMalformed indicates that the referenced secret is invalid.
	ReasonSecretMalformed = "SecretMalformed"
	// ReasonConnectionFailed indicates that the connection to the provider failed.
	ReasonConnectionFailed = "ConnectionFailed"
	// ReasonCommitConfigInvalid indicates the commit configuration is invalid.
	ReasonCommitConfigInvalid = "CommitConfigInvalid"
	// ReasonEncryptionConfigInvalid indicates encryption configuration is invalid.
	ReasonEncryptionConfigInvalid = "EncryptionConfigInvalid"
)
View Source
const (
	// GitBranchReasonGitProviderNotFound is the stall for a GitBranch whose GitProvider does not
	// exist.
	GitBranchReasonGitProviderNotFound = "GitProviderNotFound"
	// GitBranchReasonGitProviderNotReady is the progress reason while the GitProvider is not Ready.
	GitBranchReasonGitProviderNotReady = "GitProviderNotReady"
	// GitBranchReasonBranchNotAllowed is the stall for a branch outside the patterns the
	// GitProvider's spec.allowedGitBranches give this GitBranch's namespace.
	GitBranchReasonBranchNotAllowed = authz.ReasonBranchNotAllowed
	// GitBranchReasonNamespaceNotAuthorized is the stall for a GitBranch whose namespace no grant in
	// the GitProvider's spec.allowedGitBranches admits.
	GitBranchReasonNamespaceNotAuthorized = authz.ReasonNamespaceNotAuthorized
	// GitBranchReasonPushSessionFailed is the progress reason while the credential cannot open a
	// push (receive-pack) session on the remote. A GitBranch that holds its branch keeps it.
	GitBranchReasonPushSessionFailed = "PushSessionFailed"
	// GitBranchReasonBranchConflict is the stall for a GitBranch whose repository branch another,
	// older GitBranch holds.
	GitBranchReasonBranchConflict = "BranchConflict"
	// GitBranchReasonParentBranchNotFound is the stall for a branch that cannot be created: the
	// remote carries neither it nor the parent it would be created from.
	GitBranchReasonParentBranchNotFound = "ParentBranchNotFound"
	// GitBranchReasonRecoveringParentBranch is progress while the parent branch has been found again
	// but the branch worker has not yet published the writes it kept while the parent was missing.
	GitBranchReasonRecoveringParentBranch = "RecoveringParentBranch"
)
View Source
const (
	GitTargetConditionReady                = ConditionTypeReady
	GitTargetConditionReconciling          = ConditionTypeReconciling
	GitTargetConditionStalled              = ConditionTypeStalled
	GitTargetConditionValidated            = "Validated"
	GitTargetConditionEncryptionConfigured = "EncryptionConfigured"
	GitTargetConditionGitPathAccepted      = ConditionTypeGitPathAccepted
	GitTargetConditionRenderMatchesLive    = ConditionTypeRenderMatchesLive
	// GitTargetConditionStreamsRunning is the source data-plane axis: True when every tracked type's
	// watch has crossed its replay watermark or resumed from a durable cursor.
	GitTargetConditionStreamsRunning = ConditionTypeStreamsRunning
)
View Source
const (
	// GitTargetReasonOK is the healthy reason. It is the shared Succeeded vocabulary rather than
	// a per-kind spelling; the name is kept for call-site stability.
	GitTargetReasonOK = ReasonSucceeded
	// GitTargetReasonGitBranchNotFound is the Validated=False reason for a GitTarget whose
	// spec.gitBranchRef names no GitBranch, or is not set.
	GitTargetReasonGitBranchNotFound    = "GitBranchNotFound"
	GitTargetReasonTargetConflict       = "TargetConflict"
	GitTargetReasonNotChecked           = "NotChecked"
	GitTargetReasonBlocked              = "Blocked"
	GitTargetReasonNotStarted           = "NotStarted"
	GitTargetReasonNotRequired          = "NotRequired"
	GitTargetReasonMissingSecret        = "MissingSecret"
	GitTargetReasonInvalidConfig        = "InvalidConfig"
	GitTargetReasonSecretCreateDisabled = "SecretCreateDisabled"
	GitTargetReasonUnsupportedContent   = "UnsupportedContent"
	// GitTargetReasonIgnoreShadowsManagedPath is the terminal reason for the one
	// unrecoverable .gittargetignore footgun (docs/spec/gitpath-foreign-content-stringency.md
	// §4.3): an ignore pattern matches a path the operator writes, which would blind it to its
	// own file. The writer's write-plan precondition refuses the flush before any byte is
	// written and the GitTarget is failed with this reason. The string must stay in sync with
	// the watch package's gitPathRefusalReason.
	GitTargetReasonIgnoreShadowsManagedPath = "IgnoreShadowsManagedPath"
	// GitTargetReasonWriteBoundaryRefused is the reason for a write the operator refused
	// because it had nowhere safe to land, rather than because the folder holds content the
	// operator cannot manage
	// (docs/design/support-boundary/gittarget-granularity-and-cross-environment-edits.md §1): a
	// planned write escaping spec.path (L1), or an in-place edit of a source file more than
	// one kustomize render root reaches (L2, write-fan-in > 1). Nothing was committed. The
	// string must stay in sync with the watch package's gitPathRefusalReason.
	GitTargetReasonWriteBoundaryRefused = "WriteBoundaryRefused"
	// GitTargetReasonMultipleSourceNamespaces is the terminal reason for a target that declared
	// its folder namespace-free (spec.serializeNamespace: false) and that more than one source
	// namespace reaches. Two namespaces produce documents whose identities are equal once the
	// namespace is stripped, so each write flips one document between two live objects; the writer
	// refuses the flush before any byte is written. The remedy is a GitTarget or WatchRule edit.
	// The string must stay in sync with manifestanalyzer.GitPathRefusalReason.
	GitTargetReasonMultipleSourceNamespaces = "MultipleSourceNamespaces"
	// GitTargetReasonUnrenderedPlacement is the terminal reason for a placement under
	// spec.placement.useKustomize that no kustomization would render: the folder already has a
	// render root and the resolved path is outside it. Nothing is written, because a document in
	// Git that nothing applies looks mirrored and is not. The remedy is the target's own template
	// or path. The string must stay in sync with manifestanalyzer.GitPathRefusalReason.
	GitTargetReasonUnrenderedPlacement    = "UnrenderedPlacement"
	GitTargetReasonRenderDoesNotMatchLive = "RenderDoesNotMatchLive"
	GitTargetReasonRenderRechecking       = "Rechecking"

	GitTargetReadyReasonValidationFailed        = "ValidationFailed"
	GitTargetReadyReasonEncryptionNotConfigured = "EncryptionNotConfigured"
	GitTargetReadyReasonWorkerUnavailable       = "WorkerUnavailable"
	// GitTargetReasonWatchPlanFailing is Ready=False/Reconciling=True while the watch-plane
	// owner's pass for this GitTarget keeps failing and being retried on its backoff ladder. It
	// is deliberately a PROGRESSING reason rather than a stall: a pass fails on a source cluster
	// that is unreachable or a catalog that is not observable yet, both of which recover on their
	// own. What it buys is that such a target does not read as idle.
	GitTargetReasonWatchPlanFailing = "WatchPlanFailing"

	GitTargetStreamsRunningReasonNotReady = "NotReady"

	// GitTargetReasonSuspended is Ready=True on a target whose spec.suspend stops it writing. It
	// is True on purpose: suppressing writes on request is a configured outcome, not ill health.
	GitTargetReasonSuspended = fluxmeta.SuspendedReason
)
View Source
const (
	// GitTargetReasonAmbiguousLayout is a GitTarget path covering more than one kustomize render
	// root. The string must stay in sync with the watch package's gitPathRefusalReason, which
	// maps the corresponding write refusal onto GitPathAccepted.
	GitTargetReasonAmbiguousLayout = "AmbiguousLayout"
	// GitTargetReasonLayoutNotScanned is the pre-scan state: the target has not read its folder
	// yet, so nothing is known about its layout. Distinct from a folder that resolved to nothing.
	GitTargetReasonLayoutNotScanned = "NotScanned"
)
View Source
const (
	// GitTargetConditionSourceClusterReachable is the RUNTIME reachability of the source
	// cluster a GitTarget mirrors from: True (reason LocalCluster) for an inCluster provider,
	// Unknown before the data plane's first discovery, False after a real failed attempt. It is
	// distinct from Validated: a missing/malformed kubeconfig is Validated=False (an input the
	// controller reads without a network dial); an otherwise-valid kubeconfig whose API server
	// cannot be contacted is SourceClusterReachable=False.
	GitTargetConditionSourceClusterReachable = "SourceClusterReachable"
	// GitTargetConditionGitBranchReady projects the referenced GitBranch's Ready onto the GitTarget,
	// and whether it holds its repository branch, so one `kubectl get gittarget` separates
	// source-side (SourceClusterReachable) from destination-side (GitBranchReady) failure.
	GitTargetConditionGitBranchReady = "GitBranchReady"

	// GitTargetReasonGitBranchNotReady is the GitBranchReady=False reason: the GitBranch exists but
	// does not hold its branch, or reports itself not Ready.
	GitTargetReasonGitBranchNotReady = "GitBranchNotReady"

	// GitTargetConditionKubeProviderReady projects the referenced KubeProvider's Ready onto
	// the GitTarget, so one `kubectl get gittarget` shows whether the SOURCE cluster's provider is
	// healthy — distinct from SourceClusterReachable (the data plane's runtime reach) and
	// GitBranchReady (the destination). It follows the GitBranchReady contract: only an
	// EXPLICIT Ready=False downgrades the GitTarget; a provider that has not reported readiness yet
	// is Unknown and does not. A MISSING provider never reaches this projection at all — that is the
	// Validated gate's hard denial (GitTargetReasonKubeProviderNotFound), not a readiness axis.
	GitTargetConditionKubeProviderReady = "KubeProviderReady"
	// GitTargetReasonKubeProviderNotReady is the KubeProviderReady=False/Unknown reason.
	GitTargetReasonKubeProviderNotReady = "KubeProviderNotReady"
)
View Source
const (
	WatchRuleReasonValidating            = "Validating"
	WatchRuleReasonAccessDenied          = "AccessDenied"
	WatchRuleReasonGitTargetNotFound     = "GitTargetNotFound"
	WatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid"
	WatchRuleReasonReady                 = ReasonSucceeded
	// WatchRuleReasonCatalogNotReady is ResourcesResolved=False: the source cluster's discovery
	// catalog is not ready, so no selector can be resolved yet. A selector that matches nothing
	// the cluster serves is not this: it resolves True, watching zero types.
	WatchRuleReasonCatalogNotReady = "CatalogNotReady"
)

WatchRule status condition reasons.

View Source
const (
	// WatchRuleReasonSourceNamespaceAllowed is the True reason when every item watches a namespace the
	// KubeProvider's grants give the GitTarget.
	WatchRuleReasonSourceNamespaceAllowed = authz.ReasonSourceNamespaceAllowed
	// WatchRuleReasonSourceNamespaceNotAllowed is the TERMINAL False reason for a refusal.
	WatchRuleReasonSourceNamespaceNotAllowed = authz.ReasonSourceNamespaceNotAllowed
)

SourceNamespaceAuthorized condition reasons, re-exported from internal/authz so the decision and the status surface can never drift apart. The condition can never be Unknown: the gate reads only control-plane objects this reconcile already has.

View Source
const ApplierClaimConditionConfigured = "Configured"

ApplierClaimConditionConfigured reports whether an applier claim's applier is one GitOps Reverser can drive: it exists in its cluster, applies a source that follows a branch, may be written, and (an Argo CD Application) has automated sync off or a switch the applier claim may hold. The applier claim's KubeProvider must admit its namespace first, and no applier claim in line before it may name the same applier (applier.ReasonHeldByAnotherClaim).

View Source
const ApplierClaimConditionInControl = applier.ApplierClaimConditionInControl

ApplierClaimConditionInControl reports whether an applier claim decides, right now, when its applier applies. A FluxClaim is in control while its Kustomization is suspended under GitOps Reverser's field manager, with the last suspend's token handled, so nothing that started before the suspend is still running, or resumed for an apply of GitOps Reverser's own. An ArgoCDClaim is in control while its Application's automated sync is off (argocdclaim_hold.go). Holding the applier is something else: an applier claim handing its applier back still holds it, and is not in control. An applier claim is Ready only once it is in control.

View Source
const CommitRequestDeleteAfterAnnotation = "configbutler.ai/delete-after"

CommitRequestDeleteAfterAnnotation carries the RFC 3339 time after which the controller deletes a finished CommitRequest. The controller writes it once, when the request finishes, and from then on the annotation alone decides: remove it to keep the request, or edit it to move the deletion. A request that finished before this annotation existed carries none and is never deleted.

View Source
const DefaultUnfollowedGrace = time.Minute

DefaultUnfollowedGrace is how long a branch worker's operation in flight may go unfollowed before the reconciler suspends it. It covers the moments nobody follows an operation that is fine: a process that just started, whose worker has not recovered the operation yet, and an operation whose completion is not written yet.

View Source
const EventReasonOperationUnfollowed = "OperationUnfollowed"

EventReasonOperationUnfollowed is a branch worker's operation nobody followed any more, whose Kustomization the reconciler suspended and whose operation it completed.

View Source
const GitBranchFinalizer = "configbutler.ai/git-branch"

GitBranchFinalizer holds a GitBranch until its branch worker has given every pending write and CommitRequest an outcome. It never deletes the branch on the remote.

View Source
const GitBranchProviderIndex = "configbutler.ai/gitbranch-provider"

GitBranchProviderIndex indexes GitBranches by the GitProvider they claim through, its namespace resolved (namespace/name). A GitBranch may name a GitProvider in another namespace, so the GitBranches of a provider cannot be found by listing the provider's namespace.

View Source
const GitReceiverReasonListenerDisabled = "ListenerDisabled"

GitReceiverReasonListenerDisabled is the stall for a GitReceiver the operator does not serve: it runs with --receiver-bind-address=0, so nothing listens for the path it publishes.

View Source
const GitTargetConditionApplierClaimReady = "ApplierClaimReady"

GitTargetConditionApplierClaimReady reports whether spec.applierClaimRef names an applier claim that is Ready and whose applier applies this target's repository and branch. Present only while spec.applierClaimRef is set.

View Source
const GitTargetConditionLayoutResolved = "LayoutResolved"

GitTargetConditionLayoutResolved reports what the last scan resolved about the folder's shape: which kustomize render root governs new documents, or that there is none, or that there are several. It is an OBSERVATION and writes no part of the kstatus trio — a folder with no kustomization at all is a perfectly healthy folder, and most of them are.

View Source
const GitTargetReasonKubeProviderNotFound = authz.ReasonKubeProviderNotFound

GitTargetReasonKubeProviderNotFound is the Validated=False reason when a GitTarget's referenced KubeProvider does not exist. This is a HARD GATE: a GitTarget may mirror a source cluster ONLY through an existing KubeProvider. The operator never creates one, so a target whose provider was never declared is held NotReady and its data plane stopped rather than mirroring on an implicit identity.

View Source
const GitTargetReasonNamespaceNotAuthorized = authz.ReasonNamespaceNotAuthorized

GitTargetReasonNamespaceNotAuthorized is the Validated=False reason when a GitTarget's namespace is not admitted by its referenced KubeProvider's spec.allowedGitTargets, or by its GitBranch's. It runs on every reconcile, so a policy tightened AFTER a GitTarget was created stops that target's watches too.

View Source
const ReasonApplierClaimNotFound = "ApplierClaimNotFound"

ReasonApplierClaimNotFound is ApplierClaimReady=False for a GitTarget naming an applier claim that does not exist in its namespace.

View Source
const ReasonAutomatedSyncOff = "AutomatedSyncOff"

ReasonAutomatedSyncOff is InControl=True on an ArgoCDClaim whose Application has automated sync off: held off by GitOps Reverser, or kept off by the switch's owner (the message says which).

View Source
const ReasonOperationUnresolved = "OperationUnresolved"

ReasonOperationUnresolved is Ready=False on an applier claim whose operation has not completed in the time it was given. It clears when the operation completes.

View Source
const ReconcileRequestAnnotation = "reconcile.configbutler.ai/requestedAt"

ReconcileRequestAnnotation asks a GitTarget to be reconciled at once, and to re-read its Git folder rather than wait for the periodic pass. Set it to any value that changes — a timestamp is the convention — and the change is what triggers; the value itself carries no meaning.

The spelling is Flux's, deliberately: `reconcile.fluxcd.io/requestedAt` is what this ecosystem already types, and `flux reconcile` is the muscle memory a user brings. Nothing else in this repository had a reconcile-request convention to be consistent with instead.

It matters most for a folder someone else edits. The resolution only refreshes when this target scans, and a resolution that only refreshes on the periodic cadence is one you cannot iterate with: edit the folder, request a reconcile, read status.placement.

Variables

This section is empty.

Functions

func IndexGitBranchProvider added in v0.54.0

func IndexGitBranchProvider(obj client.Object) []string

IndexGitBranchProvider is the GitBranchProviderIndex value of a GitBranch.

func IndexGitBranches added in v0.54.0

func IndexGitBranches(ctx context.Context, indexer client.FieldIndexer) error

IndexGitBranches registers GitBranchProviderIndex. The GitBranch, GitTarget and applier claim controllers all find a provider's GitBranches through it, so it is registered once, before any of them is set up.

Types

type ApplierClaimReconciler added in v0.54.0

type ApplierClaimReconciler struct {
	client.Client

	// Kind is the applier claim kind this reconciler serves (v1alpha3.ApplierClaimKind*).
	Kind     string
	Recorder record.EventRecorder

	// ApplierClients resolves the dynamic client of an applier claim's cluster. Nil leaves Configured
	// Unknown (tests, and the CLI).
	ApplierClients applier.Clients
	// APIReader reads an applier claim uncached before its Kustomization is suspended, so an operation a
	// branch worker recorded a moment ago is never taken for an external resume. Nil reads through
	// Client.
	APIReader client.Reader
	// Follower says which branch-worker operations this process follows (the apply dispatcher). A
	// FluxClaim's Kustomization is left resumed for an operation in flight only while it is
	// followed, or for UnfollowedGrace (DefaultUnfollowedGrace when zero) after it was first seen
	// followed by nobody. Nil follows nothing, so only the grace applies.
	Follower        OperationFollower
	UnfollowedGrace time.Duration
	// contains filtered or unexported fields
}

ApplierClaimReconciler reconciles one applier claim kind: it checks that the applier the applier claim holds is one GitOps Reverser can drive, and publishes what it applies (status.source) for the GitTargets naming the applier claim. It also holds the applier (a Kustomization suspended, fluxclaim_hold.go; an Application's automated sync off, argocdclaim_hold.go), and hands it back once the applier claim is deleted. It never starts an apply: the branch workers decide when, and write status.operation and status.repairPending. It writes status.operation only for what no worker follows: an external resume, and an operation nobody follows any more.

func (*ApplierClaimReconciler) Reconcile added in v0.54.0

func (r *ApplierClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile publishes one applier claim's Configured and InControl conditions, its source and the readiness trio.

func (*ApplierClaimReconciler) SetupWithManager added in v0.54.0

func (r *ApplierClaimReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller for its kind with the Manager.

type AuditRouteFacts added in v0.44.0

type AuditRouteFacts interface {
	// FirstFactAt reports when the first fact was published on a route IN THIS PROCESS. A restart
	// empties it, which is why the condition latches in the persisted status instead.
	FirstFactAt(route string) (time.Time, bool)
	// FirstFactEvents carries a KubeProvider-shaped event naming the ROUTE whose first fact just
	// landed, so the providers reading it re-reconcile within seconds.
	FirstFactEvents() <-chan event.GenericEvent
	// TransportFailing and AuditDelivered are PROCESS-WIDE, not per route. They exist only to say
	// which of the three silences a provider with no facts is in; neither is ever asserted as this
	// provider's own status, because a fault shared by the whole pipeline must not become a verdict
	// repeated on every object that reads it.
	TransportFailing() bool
	AuditDelivered() bool
	// TransportName is the configured transport ("redis" or "memory"), used only to point the
	// reader at the right thing while publishes are failing. Empty yields neutral wording.
	TransportName() string
	// DeclareRoute and ForgetRoute keep the set of routes some KubeProvider carries, which bounds
	// the audit_route label on the audit census.
	DeclareRoute(provider types.NamespacedName, route string)
	ForgetRoute(provider types.NamespacedName)
}

AuditRouteFacts is the per-route "has a fact ever been published here" registry the AuditFactsReceived condition reads. internal/attribution.RouteHealth implements it; a nil reconciler field means author attribution is off, and the condition is then absent rather than Unknown — nothing was ever expected on the route.

type ClusterWatchRuleReconciler

type ClusterWatchRuleReconciler struct {
	client.Client

	Scheme       *runtime.Scheme
	RuleStore    *rulestore.RuleStore
	WatchManager WatchManagerInterface
	// Recorder emits a Kubernetes Event on every persisted Ready transition; nil disables Events.
	Recorder record.EventRecorder
}

ClusterWatchRuleReconciler reconciles a ClusterWatchRule object.

func (*ClusterWatchRuleReconciler) Reconcile

func (*ClusterWatchRuleReconciler) SetupWithManager

func (r *ClusterWatchRuleReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type CommandAuthorLookup

type CommandAuthorLookup interface {
	LookupCommandAuthor(ctx context.Context, uid types.UID) (queue.CommandAuthor, bool)
}

CommandAuthorLookup resolves the author of a CommitRequest from the submitter captured at admission by the validate-operator-types webhook, keyed by the persisted object's UID. *queue.CommandAuthorStore satisfies it without adaptation. The lookup is present-or-never (docs/spec/commitrequest-admission-authorship.md): a miss is immediate and final — the webhook is not configured (or a best-effort write missed) — and the request claims no actor with no wait.

type CommitRequestFinalizer

type CommitRequestFinalizer interface {
	ServiceCommitRequest(ctx context.Context, attach git.AttachCommitRequest) (git.FinalizeResult, bool, error)
	// WithdrawCommitRequest cancels a request the worker has not acted on and reports the worker's
	// answer: resolved with git.ErrCommitRequestWithdrawn when it is cancelled, the real outcome
	// when the worker got there first, or resolved=false with the worker's phase while it decides.
	WithdrawCommitRequest(ctx context.Context, attach git.AttachCommitRequest) (git.FinalizeResult, bool, error)
}

CommitRequestFinalizer is the EventRouter seam the reconciler drives, using the attach-then-poll protocol (docs/spec/commitrequest-design.md): ServiceCommitRequest registers the attach idempotently on the GitTarget's branch worker (attach it to the author's window with its message and timers) and returns the request's current outcome — resolved=false means keep polling. watch.EventRouter satisfies it without adaptation.

There is no watermark barrier: the interactive case is covered by the human gap between the edit and the save, UC2 by the request's attach wait. The worker anchors that wait at its own registration and runs the window's timers, so the controller never holds the finalize itself.

type CommitRequestReconciler

type CommitRequestReconciler struct {
	client.Client

	Scheme *runtime.Scheme

	// APIReader performs uncached reads so a stale cache echo of our own
	// status stamp can never re-run a finalize that already reached a
	// terminal phase. Nil falls back to the (cached) Client.
	APIReader client.Reader

	// Finalizer attaches the request to the author-bound open window and reports
	// its outcome; AuthorLookup resolves the submitter captured at admission. When
	// AuthorLookup is nil (the validate-operator-types webhook is disabled), requests
	// claim no actor immediately, with AuthorAttributed=False. The attached window
	// determines the eventual Git author.
	Finalizer    CommitRequestFinalizer
	AuthorLookup CommandAuthorLookup

	// TTL is how long a request is kept once it finishes. It is written onto the request as
	// CommitRequestDeleteAfterAnnotation at that moment; zero writes nothing, so the request stays.
	TTL time.Duration
}

CommitRequestReconciler deliberately does NOT use reconcileStatus, which every other controller here shares. The difference is not stylistic, so it is worth saying once:

  • Its For() carries no GenerationChangedPredicate, so a status write re-enqueues the object. The lost-write hazard reconcileStatus exists to close — the winning status-only update being filtered out, leaving nothing to correct the stale answer — cannot arise.
  • It reads through APIReader (uncached) precisely so a cache echo cannot re-drive work, which is the same lag that makes reconcileStatus lose its optimistic lock in the first place.
  • The policies are opposites, and reconcileStatus's is the wrong one here. It drops a losing write and asks the caller to come back and recompute; a re-run of THIS reconcile would re-finalize an already-flushed window. So writeTerminalStatus retries in place, bounded, and gives up rather than requeue. (The worker now defends the same boundary from its side: a request whose window has committed stays identifiable until the push settles it, so a re-sent attach is recognized rather than registered afresh. This policy is still the right one, but a re-run is no longer the only thing standing between a flushed window and a NoOpenWindow that never happened.)

CommitRequestReconciler drives a CommitRequest through its state machine (docs/spec/commitrequest-design.md and docs/spec/commitrequest-admission-authorship.md):

  1. ATTRIBUTE — a single synchronous read of the submitter captured at admission (present-or-never). A hit names that submitter as the author (AuthorAttributed=True); a miss claims no actor immediately (AuthorAttributed=False). There is no wait and no requeue for the author: the record is written before the object is visible, so waiting cannot help.
  2. ATTACH + POLL — the instant the author is settled, send the attach to the GitTarget's worker, which attaches the request to the author's window with its message and timers, and poll the outcome. The attach wait is anchored at the worker's registration, so there is no controller-side delay. While it polls, the controller reports the phase the worker reports. No window before the attach deadline resolves NoWindow; a window belonging to someone else stays open for its own author.

func (*CommitRequestReconciler) Reconcile

func (r *CommitRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile advances one CommitRequest through attribute → attach + poll → terminal status. With MaxConcurrentReconciles=1 concurrent CommitRequests are serialized by construction, and the worker keys attaches by request identity so re-sends across poll requeues are idempotent.

func (*CommitRequestReconciler) SetupWithManager

func (r *CommitRequestReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager. MaxConcurrentReconciles is pinned to 1 on purpose: the single worker IS the multi-CommitRequest ordering design — concurrent CommitRequests for the same GitTarget are serialized exactly as a dedicated finalize-coordinator goroutine would serialize them, without the extra moving parts (see docs/spec/commitrequest-design.md).

Restart recovery is best-effort by design: the message is durable in spec.message, so on restart any non-terminal request is re-reconciled — author-resolved from the admission cache when present and re-attached — which heals the common cases. The one knowingly-accepted gap is a request whose commit was already pushed but whose terminal status was not yet written: the in-memory outcome is gone, the re-driven attach finds the work already mirrored, and it resolves Rejected/AlreadyPresent. We do not build a durable record to close that.

type GitBranchReconciler added in v0.54.0

type GitBranchReconciler struct {
	client.Client

	Scheme        *runtime.Scheme
	WorkerManager *git.WorkerManager
	// Recorder emits a Kubernetes Event on every persisted Ready transition. It may be nil in tests.
	Recorder record.EventRecorder

	// SSHHostKeys and CredentialPolicy resolve the GitProvider's credential exactly as its branch
	// worker does, so the credential proved is the one that will push.
	SSHHostKeys      git.SSHHostKeyConfig
	CredentialPolicy git.CredentialTransportPolicy
	// contains filtered or unexported fields
}

GitBranchReconciler reconciles a GitBranch: it proves the credential, keeps the claim on the repository branch (git.BranchClaims), and publishes where the branch is on the remote.

func (*GitBranchReconciler) Reconcile added in v0.54.0

func (r *GitBranchReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile proves the GitBranch's credential, keeps its claim, and publishes its status.

func (*GitBranchReconciler) SetupWithManager added in v0.54.0

func (r *GitBranchReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type GitProviderReconciler

type GitProviderReconciler struct {
	client.Client

	Scheme *runtime.Scheme

	// Recorder emits a Kubernetes Event on every persisted Ready transition; nil disables Events.
	Recorder record.EventRecorder

	// SSHHostKeys configures SSH host-key resolution (install-level default ConfigMap and the
	// dev-only missing-key opt-out) for the connectivity check's credential read, so it matches
	// what the write path uses.
	SSHHostKeys gitpkg.SSHHostKeyConfig

	// CredentialPolicy controls explicit insecure opt-ins for Git credential transports.
	CredentialPolicy gitpkg.CredentialTransportPolicy
	// contains filtered or unexported fields
}

GitProviderReconciler reconciles a GitProvider object.

func (*GitProviderReconciler) Reconcile

func (r *GitProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

func (*GitProviderReconciler) SetupWithManager

func (r *GitProviderReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type GitReceiverReconciler added in v0.54.0

type GitReceiverReconciler struct {
	client.Client

	Scheme *runtime.Scheme

	// ListenerEnabled reports whether this operator serves the push receiver listener
	// (--receiver-bind-address). Without it a GitReceiver publishes its path and reports
	// ListenerDisabled, because no delivery can reach it.
	ListenerEnabled bool

	// Recorder emits a Kubernetes Event on every persisted Ready transition; nil disables Events.
	Recorder record.EventRecorder
}

GitReceiverReconciler reconciles a GitReceiver: it reads the token Secret, publishes the path the receiver is served on, and reports whether anything serves it.

It takes no finalizer: a delivery reads the GitReceiver and its token afresh, so nothing has to happen before one goes away.

func (*GitReceiverReconciler) Reconcile added in v0.54.0

func (r *GitReceiverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile reads a GitReceiver's token and publishes its path and readiness.

func (*GitReceiverReconciler) SetupWithManager added in v0.54.0

func (r *GitReceiverReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type GitTargetReconciler

type GitTargetReconciler struct {
	client.Client

	Scheme        *runtime.Scheme
	WorkerManager *git.WorkerManager
	EventRouter   *watch.EventRouter

	// GitRefreshInterval is how often an idle branch is asked to re-prove where its remote is,
	// and the quantizer status.remote's clock is written against. Zero or less turns the
	// refresher OFF, which buys back the property that nothing here holds a timer against the
	// Git host; status.remote still works in that mode, because pushes still renew it.
	GitRefreshInterval time.Duration
	// Recorder emits a Kubernetes Event on every persisted Ready transition. It may be nil in
	// tests, in which case no Event is recorded and nothing else changes.
	Recorder record.EventRecorder
	// contains filtered or unexported fields
}

GitTargetReconciler reconciles a GitTarget object.

func (*GitTargetReconciler) Reconcile

func (r *GitTargetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile validates GitTarget references and drives startup lifecycle gates.

func (*GitTargetReconciler) SetupWithManager

func (r *GitTargetReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type KubeProviderReconciler added in v0.54.0

type KubeProviderReconciler struct {
	client.Client

	Scheme *runtime.Scheme

	// KubeConfigSafety gates exec-auth and insecure-TLS kubeconfigs (reject-not-strip) and lists the
	// providers allowed to use spec.inCluster, matching what the watch engine's resolver enforces,
	// so Validated agrees with what a watch would use.
	KubeConfigSafety kubeconfig.SafetyPolicy

	// AuditFacts is the per-audit-route fact registry the AuditFactsReceived condition latches on.
	// Nil means the operator runs with author attribution disabled, and the condition is then
	// absent rather than Unknown.
	AuditFacts AuditRouteFacts

	// Recorder emits a Kubernetes Event on every persisted Ready transition; nil disables Events.
	Recorder record.EventRecorder
	// contains filtered or unexported fields
}

KubeProviderReconciler reconciles a KubeProvider object. It is the read-side peer of the GitProviderReconciler: it validates the cluster's credential without dialing, reports whether the provider may be used at all (the installation's inCluster consent, and its audit route), and owns the per-cluster status the watch engine and GitTargets project from.

It takes no finalizer: nothing has to happen before a KubeProvider goes away. Attribution facts are keyed by (audit route, group/resource, uid, resourceVersion) and expire on their own, and several providers may share one route, so there is nothing to purge per object.

func (*KubeProviderReconciler) Reconcile added in v0.54.0

func (r *KubeProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile validates a KubeProvider's inputs and updates its status.

func (*KubeProviderReconciler) SetupWithManager added in v0.54.0

func (r *KubeProviderReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type OperationFollower added in v0.53.0

type OperationFollower interface {
	Following(claim git.ApplierClaimRef, token string) bool
}

OperationFollower answers whether this process carries out or follows a branch worker's operation: (*applier.Dispatcher).Following, which runs beside this reconciler on the leader.

type WatchManagerInterface

type WatchManagerInterface interface {
	// TriggerRuleChange marks the GitTarget a rule names as needing a new plan pass, and returns.
	// The watch-plane owner runs the pass once that target has been quiet for its settle window.
	//
	// It replaces a ReconcileForRuleChange that did the work inline, on the controller worker
	// that observed the rule: a discovery call, a namespace list, a full re-projection, and then a
	// replan of every running GitTarget. A rule edit now replans the ONE target the rule names.
	TriggerRuleChange(gitDest types.ResourceReference)

	// TriggerAllRuleChange marks every declared GitTarget. It is the rule-DELETION path only: the
	// object is already gone, so it cannot be read for the target it named and the owner does not
	// pretend to narrow the invalidation.
	TriggerAllRuleChange()

	ResolveWatchRuleResources(ctx context.Context, rule configv1alpha3.WatchRule) (bool, string)
	ResolveClusterWatchRuleResources(ctx context.Context, rule configv1alpha3.ClusterWatchRule) (bool, string)
	// CollectionOverlapForWatchRule and CollectionOverlapForClusterWatchRule report
	// whether a compiled rule is refused because its collections overlap a different collection on
	// the same GitTarget; the older rule keeps the collection.
	CollectionOverlapForWatchRule(rule configv1alpha3.WatchRule) (bool, string)
	CollectionOverlapForClusterWatchRule(rule configv1alpha3.ClusterWatchRule) (bool, string)
	StreamSummaryForGitTarget(gitDest types.ResourceReference) watch.StreamSummary
	StreamSummaryForWatchRule(rule configv1alpha3.WatchRule) watch.StreamSummary
	StreamSummaryForClusterWatchRule(rule configv1alpha3.ClusterWatchRule) watch.StreamSummary

	// ClusterResourcesSelectedFor is what the watch planner selects for a ClusterWatchRule item in
	// the cluster a GitTarget mirrors from, so the compile checks those types against the grant.
	ClusterResourcesSelectedFor(target configv1alpha3.GitTarget) watch.ClusterResourceSelection

	// StreamStateEvents is the channel a rule controller wires via source.Channel so a stream
	// reaching (or leaving) Streaming re-reconciles the rules that project it, instead of leaving
	// them to discover it on RequeueStreamSettleInterval. A stream coming up is the last thing
	// that has to happen before a rule can honestly report StreamsRunning=True, and the data plane
	// is the only thing that knows when it did.
	//
	// Every call registers a NEW subscriber: a Go channel has one consumer, and three controllers
	// project this state. It may return nil when no data plane is wired.
	StreamStateEvents() <-chan event.GenericEvent
}

WatchManagerInterface defines the interface for watch manager reconciliation. This allows for easier testing by enabling mock implementations.

type WatchRuleReconciler

type WatchRuleReconciler struct {
	client.Client

	Scheme       *runtime.Scheme
	RuleStore    *rulestore.RuleStore
	WatchManager WatchManagerInterface
	// Recorder emits a Kubernetes Event on every persisted Ready transition; nil disables Events.
	Recorder record.EventRecorder
}

WatchRuleReconciler reconciles a WatchRule object.

func (*WatchRuleReconciler) Reconcile

func (r *WatchRuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile is part of the main kubernetes reconciliation loop which aims to move the current state of the cluster closer to the desired state.

func (*WatchRuleReconciler) SetupWithManager

func (r *WatchRuleReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL