Documentation
¶
Overview ¶
Package controller contains shared constants for all controllers.
Index ¶
Constants ¶
const ( ClusterWatchRuleReasonValidating = "Validating" ClusterWatchRuleReasonGitProviderNotFound = "GitRepoConfigNotFound" ClusterWatchRuleReasonGitRepoConfigNotReady = "GitRepoConfigNotReady" ClusterWatchRuleReasonAccessDenied = "AccessDenied" ClusterWatchRuleReasonGitTargetNotFound = "GitTargetNotFound" ClusterWatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid" ClusterWatchRuleReasonReady = "Ready" ClusterWatchRuleReasonResourcesResolved = "Resolved" ClusterWatchRuleReasonUnresolvedResources = "UnresolvedResources" )
ClusterWatchRule status condition reasons.
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" // ConditionTypeStreamsReady is a source-compatibility alias for StreamsRunning. ConditionTypeStreamsReady = ConditionTypeStreamsRunning // 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 // no admission record exists — the webhook is not configured — and the commit is // authored by the configured committer. False is not a failure and does not affect // Ready (docs/spec/commitrequest-admission-authorship.md §5). ConditionTypeAuthorAttributed = "AuthorAttributed" // ConditionTypePushed indicates whether a CommitRequest's commit reached the // remote repository. ConditionTypePushed = "Pushed" // 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 // 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 // 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 // ReasonChecking indicates that the controller is checking the resource status. ReasonChecking = "Checking" // ReasonReconciling indicates that reconciliation is still making progress. ReasonReconciling = "Reconciling" // ReasonStalled indicates that reconciliation is blocked until a human fixes the object or dependency. ReasonStalled = "Stalled" // ReasonProgressing indicates that a stream or control-plane gate is still converging. ReasonProgressing = "Progressing" // 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" )
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 )
const ( GitTargetReasonOK = "OK" GitTargetReasonProviderNotFound = "ProviderNotFound" GitTargetReasonBranchNotAllowed = "BranchNotAllowed" GitTargetReasonTargetConflict = "TargetConflict" GitTargetReasonNotChecked = "NotChecked" GitTargetReasonBlocked = "Blocked" GitTargetReasonNotStarted = "NotStarted" GitTargetReasonNotRequired = "NotRequired" GitTargetReasonMissingSecret = "MissingSecret" GitTargetReasonInvalidConfig = "InvalidConfig" GitTargetReasonSecretCreateDisabled = "SecretCreateDisabled" GitTargetReasonGitPathAccepted = "GitPathAccepted" 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" GitTargetReasonRenderMatchesLive = "RenderMatchesLive" GitTargetReasonRenderDoesNotMatchLive = "RenderDoesNotMatchLive" GitTargetReasonRenderRechecking = "Rechecking" GitTargetReadyReasonValidationFailed = "ValidationFailed" GitTargetReadyReasonEncryptionNotConfigured = "EncryptionNotConfigured" GitTargetStreamsRunningReasonNotReady = "NotReady" )
const ( WatchRuleReasonValidating = "Validating" WatchRuleReasonGitProviderNotFound = "GitRepoConfigNotFound" WatchRuleReasonGitRepoConfigNotReady = "GitRepoConfigNotReady" WatchRuleReasonAccessDenied = "AccessDenied" WatchRuleReasonGitTargetNotFound = "GitTargetNotFound" WatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid" WatchRuleReasonReady = "Ready" WatchRuleReasonResourcesResolved = "Resolved" WatchRuleReasonUnresolvedResources = "UnresolvedResources" )
WatchRule status condition reasons.
const GitTargetConditionStreamsReady = GitTargetConditionStreamsRunning
const GitTargetReasonConflict = GitTargetReasonTargetConflict
const GitTargetReasonReady = GitTargetConditionReady
GitTargetReasonReady is a backward-compatible alias used by existing tests.
const GitTargetStreamsReadyReasonNotReady = GitTargetStreamsRunningReasonNotReady
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ClusterWatchRuleReconciler ¶
type ClusterWatchRuleReconciler struct {
client.Client
Scheme *runtime.Scheme
RuleStore *rulestore.RuleStore
WatchManager WatchManagerInterface
}
ClusterWatchRuleReconciler reconciles a ClusterWatchRule object.
func (*ClusterWatchRuleReconciler) Reconcile ¶
func (r *ClusterWatchRuleReconciler) 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 (*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 §2): a miss is immediate and final — the webhook is not configured (or a best-effort write missed) — and the controller finalizes as the committer with no wait.
type CommitRequestFinalizer ¶
type CommitRequestFinalizer interface {
ServiceCommitRequest(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 §6.4.3): ServiceCommitRequest registers the attach idempotently on the GitTarget's branch worker (bind the message to the author's open window, finalize after the grace) and returns the request's current outcome — resolved=false means keep polling. watch.EventRouter satisfies it without adaptation.
There is no watermark barrier (§6.3): UC1 is covered by the human gap between the edit and the save, UC2 by the collect-grace. The grace is anchored at attribution — the worker stamps finalizeAt = receipt + closeDelaySeconds (§6.4.4) — so the controller no longer 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
// finalize as the configured committer — immediately, with AuthorAttributed=False.
Finalizer CommitRequestFinalizer
AuthorLookup CommandAuthorLookup
}
CommitRequestReconciler drives a CommitRequest through its state machine (docs/spec/commitrequest-design.md §6.4 and docs/spec/commitrequest-admission-authorship.md §5):
- ATTRIBUTE — a single synchronous read of the submitter captured at admission (present-or-never, §2). A hit names that submitter as the author (AuthorAttributed=True); a miss falls back to the configured committer 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.
- ATTACH + POLL — the instant the author is settled, send the attach to the GitTarget's worker (bind the message to the author's open window, finalize after the grace) and poll the outcome. The grace is anchored at attribution by the worker (finalizeAt = receipt + closeDelaySeconds), so there is no controller-side delay. A window belonging to someone else (or no window) resolves NoOpenWindow; the foreign window stays open.
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-multi-finalize-design.md).
Restart recovery is best-effort by design (commitrequest-design.md §6.6): 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 GitProviderReconciler ¶
type GitProviderReconciler struct {
client.Client
Scheme *runtime.Scheme
// 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
// 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 GitTargetReconciler ¶
type GitTargetReconciler struct {
client.Client
Scheme *runtime.Scheme
WorkerManager *git.WorkerManager
EventRouter *watch.EventRouter
}
GitTargetReconciler reconciles a GitTarget object.
func (*GitTargetReconciler) Reconcile ¶
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 WatchManagerInterface ¶
type WatchManagerInterface interface {
ReconcileForRuleChange(ctx context.Context) error
ResolveWatchRuleResources(ctx context.Context, rule configv1alpha3.WatchRule) (bool, string)
ResolveClusterWatchRuleResources(ctx context.Context, rule configv1alpha3.ClusterWatchRule) (bool, string)
StreamSummaryForGitTarget(gitDest types.ResourceReference) watch.StreamSummary
StreamSummaryForWatchRule(rule configv1alpha3.WatchRule) watch.StreamSummary
StreamSummaryForClusterWatchRule(rule configv1alpha3.ClusterWatchRule) watch.StreamSummary
}
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
}
WatchRuleReconciler reconciles a WatchRule object.
func (*WatchRuleReconciler) Reconcile ¶
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.
Source Files
¶
- clusterwatchrule_controller.go
- commitrequest_controller.go
- commitrequest_finalize.go
- condition_helper.go
- constants.go
- dependency_watches.go
- gitprovider_controller.go
- gitprovider_signing.go
- gittarget_controller.go
- gittarget_dependency_status.go
- gittarget_path_overlap.go
- gittarget_placement_validation.go
- stream_status.go
- watchrule_controller.go