controller

package
v0.41.0 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 41 Imported by: 0

Documentation

Overview

Package controller contains shared constants for all controllers.

Index

Constants

View Source
const (
	ClusterWatchRuleReasonValidating            = "Validating"
	ClusterWatchRuleReasonGitProviderNotFound   = "GitRepoConfigNotFound"
	ClusterWatchRuleReasonGitRepoConfigNotReady = "GitRepoConfigNotReady"
	ClusterWatchRuleReasonAccessDenied          = "AccessDenied"
	ClusterWatchRuleReasonGitTargetNotFound     = "GitTargetNotFound"
	ClusterWatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid"
	ClusterWatchRuleReasonReady                 = ReasonSucceeded
	ClusterWatchRuleReasonResourcesResolved     = "Resolved"
	ClusterWatchRuleReasonUnresolvedResources   = "UnresolvedResources"

	// ClusterWatchRuleReasonGitTargetNamespaceNotAuthorized is the terminal reason when the
	// referenced GitTarget's namespace is not admitted by that target's ClusterProvider. 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

	// ClusterWatchRuleReasonScopeNotSupported is the terminal reason for a STORED ClusterWatchRule
	// that still selects namespaced resources through the removed scope choice.
	ClusterWatchRuleReasonScopeNotSupported = watch.ClusterWatchRuleReasonScopeNotSupported
)

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
	// even for legacy own-namespace rules (reason LegacySourceNamespace) 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 covers both "the
	// answer is still being established" and "a rule with an already-resolved scope has lost the
	// ability to re-evaluate its policy and is retaining that scope" — neither of which may be
	// rendered as a permanent failure.
	ConditionTypeSourceNamespaceAuthorized = "SourceNamespaceAuthorized"
	// 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
	// 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"

	// ClusterProviderConditionValidated reports whether a ClusterProvider's inputs are safe and
	// resolvable: the in-cluster "default" provider is trivially Validated; a remote provider is
	// Validated once its kubeconfig Secret is present, keyed, and passes the exec/TLS safety
	// policy. It is asserted WITHOUT a network dial — runtime reachability/discovery health are
	// deferred until authenticated remote ingest wires them from the watch engine.
	ClusterProviderConditionValidated = "Validated"

	// ReasonValidated is the Validated=True reason.
	ReasonValidated = "Validated"
	// ReasonInCluster is the Validated=True reason for the in-cluster "default" provider.
	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
	// 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

	// 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

	// 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"
	// 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 (
	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
	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"
	GitTargetReadyReasonWorkerUnavailable       = "WorkerUnavailable"

	GitTargetStreamsRunningReasonNotReady = "NotReady"
)
View Source
const (
	// GitTargetConditionSourceClusterReachable is the RUNTIME reachability of the source
	// cluster a GitTarget mirrors from: True (reason LocalCluster) when kubeConfig is omitted,
	// 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"
	// GitTargetConditionGitProviderReady projects the referenced GitProvider's Ready onto the
	// GitTarget, so one `kubectl get gittarget` separates source-side (SourceClusterReachable)
	// from destination-side (GitProviderReady) failure.
	GitTargetConditionGitProviderReady = "GitProviderReady"

	// GitTargetReasonGitProviderNotReady is the GitProviderReady=False reason.
	GitTargetReasonGitProviderNotReady = "GitProviderNotReady"
	// GitTargetReasonGitProviderReady is the GitProviderReady=True reason.
	GitTargetReasonGitProviderReady = "GitProviderReady"

	// GitTargetConditionClusterProviderReady projects the referenced ClusterProvider'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
	// GitProviderReady (the destination). It follows the GitProviderReady 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 (GitTargetReasonClusterProviderNotFound), not a readiness axis.
	GitTargetConditionClusterProviderReady = "ClusterProviderReady"
	// GitTargetReasonClusterProviderNotReady is the ClusterProviderReady=False/Unknown reason.
	GitTargetReasonClusterProviderNotReady = "ClusterProviderNotReady"
	// GitTargetReasonClusterProviderReady is the ClusterProviderReady=True reason.
	GitTargetReasonClusterProviderReady = "ClusterProviderReady"
)
View Source
const (
	WatchRuleReasonValidating            = "Validating"
	WatchRuleReasonGitProviderNotFound   = "GitRepoConfigNotFound"
	WatchRuleReasonGitRepoConfigNotReady = "GitRepoConfigNotReady"
	WatchRuleReasonAccessDenied          = "AccessDenied"
	WatchRuleReasonGitTargetNotFound     = "GitTargetNotFound"
	WatchRuleReasonGitDestinationInvalid = "GitDestinationInvalid"
	WatchRuleReasonReady                 = ReasonSucceeded
	WatchRuleReasonResourcesResolved     = "Resolved"
	WatchRuleReasonUnresolvedResources   = "UnresolvedResources"
)

WatchRule status condition reasons.

View Source
const (
	// WatchRuleReasonLegacySourceNamespace is the True reason when every item watches the rule's
	// own namespace against a GitTarget that declares no allowedSourceNamespaces policy.
	WatchRuleReasonLegacySourceNamespace = authz.ReasonLegacySourceNamespace
	// WatchRuleReasonSourceNamespaceAllowed is the True reason when every item is admitted and at
	// least one names a namespace other than the rule's own — an authorized override or wildcard,
	// or an own-namespace item a declared policy explicitly lists.
	WatchRuleReasonSourceNamespaceAllowed = authz.ReasonSourceNamespaceAllowed
	// WatchRuleReasonNoAdmittedSourceNamespaces is the True reason when every item is admitted but
	// the resolved scope is EMPTY. Not stalled — but not silently healthy either.
	WatchRuleReasonNoAdmittedSourceNamespaces = authz.ReasonNoAdmittedSourceNamespaces
	// WatchRuleReasonSourceNamespaceNotAllowed is the TERMINAL False reason for a refusal.
	WatchRuleReasonSourceNamespaceNotAllowed = authz.ReasonSourceNamespaceNotAllowed
	// WatchRuleReasonSourceNamespacePolicyUnavailable is the reason for a selector policy that
	// cannot be evaluated as written. It is False/Stalled while ESTABLISHING and Unknown while
	// MAINTAINING an already-resolved scope — same reason, different claim about the rule.
	WatchRuleReasonSourceNamespacePolicyUnavailable = authz.ReasonSourceNamespacePolicyUnavailable
	// WatchRuleReasonCheckingSourceNamespacePolicy is the Unknown reason while the answer is still
	// being established or a retryable source-cluster error is being retried.
	WatchRuleReasonCheckingSourceNamespacePolicy = authz.ReasonCheckingSourceNamespacePolicy
)

SourceNamespaceAuthorized condition reasons, re-exported from internal/authz so the decision and the status surface can never drift apart.

View Source
const GitTargetConditionStreamsReady = GitTargetConditionStreamsRunning
View Source
const GitTargetReasonClusterProviderNotFound = authz.ReasonClusterProviderNotFound

GitTargetReasonClusterProviderNotFound is the Validated=False reason when a GitTarget's referenced ClusterProvider does not exist. This is a HARD GATE: a GitTarget may mirror a source cluster ONLY through an existing ClusterProvider, "default" included. 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 local identity.

View Source
const GitTargetReasonConflict = GitTargetReasonTargetConflict
View Source
const GitTargetReasonNamespaceNotAuthorized = authz.ReasonNamespaceNotAuthorized

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

View Source
const GitTargetReasonReady = GitTargetConditionReady

GitTargetReasonReady is a backward-compatible alias used by existing tests.

View Source
const GitTargetStreamsReadyReasonNotReady = GitTargetStreamsRunningReasonNotReady
View Source
const LegacyClusterProviderFinalizer = "configbutler.ai/clusterprovider-fact-purge"

LegacyClusterProviderFinalizer is the fact-purge finalizer this controller USED to take. It is no longer added; it is only ever REMOVED, so an object created by an older operator can still be deleted after an upgrade instead of stranding in Terminating.

DO NOT REINTRODUCE A FINALIZER HERE. It was dropped because purge-on-delete is a promise only a living operator can keep, and the two cases that matter break it. `helm uninstall` removes the manager and the ClusterProvider together, so nothing detaches the finalizer, the object strands in Terminating forever, and the next `helm install --wait` then fails on it — recovering needs a manual kubectl patch. That was hit on a live cluster and is why this shipped. An operator that is simply down blocks the delete instead, and then loses the purge anyway if the object is force-removed, so the finalizer does not even reliably deliver the guarantee it exists for.

The purge it protected is not needed either, and is now unsafe. Facts are keyed by (audit route, group/resource, uid, resourceVersion) and expire on their own, so a re-provisioned cluster produces different object UIDs and cannot join a stale fact on the exact key. And since spec.attribution.auditRoute is what partitions them, SEVERAL ClusterProviders may share one route (an API server posts audit under exactly one), so purging on a single provider's deletion would drop the facts of every other provider on that route, and of the operator's own cluster, which was never torn down. A purge would have to be re-derived against the route, not the object.

Variables

This section is empty.

Functions

This section is empty.

Types

type ClusterProviderReconciler added in v0.38.0

type ClusterProviderReconciler struct {
	client.Client

	Scheme *runtime.Scheme

	// OperatorNamespace is the namespace a remote provider's kubeConfig Secret is pinned to (the
	// operator's own namespace). A cluster-scoped provider has no namespace of its own, so the
	// credential for a cluster is always read from here — never from the source cluster.
	OperatorNamespace string

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

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

ClusterProviderReconciler reconciles a ClusterProvider object. It is the read-side peer of the GitProviderReconciler: it validates the cluster's connectivity inputs (spec.kubeConfig) without dialing, and owns the per-cluster status the watch engine and GitTargets project from. The in-cluster "default" provider has no kubeConfig and is trivially Validated.

func (*ClusterProviderReconciler) Reconcile added in v0.38.0

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

func (*ClusterProviderReconciler) SetupWithManager added in v0.38.0

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

SetupWithManager sets up the controller with the Manager.

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

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): 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)
}

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 (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: the interactive case 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 — 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
	// claim no actor immediately, with AuthorAttributed=False. The attached window
	// determines the eventual Git author.
	Finalizer    CommitRequestFinalizer
	AuthorLookup CommandAuthorLookup
}

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 (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-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 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
	// 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
	// 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
}

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 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

	// SourceScope exposes the source-scope service — the manager-owned evaluation of a GitTarget's
	// allowedSourceNamespaces against its SOURCE cluster, plus the per-rule resolved scopes.
	//
	// The gate runs in this package but the labels a selector needs live in a source cluster whose
	// connection and cache the watch manager already owns, so the reconciler asks the manager
	// instead of dialling that cluster itself on every pass. It may return nil (the data plane is
	// not wired), which degrades to exact-name policy evaluation — never to a denial.
	SourceScope() watch.SourceScopeService

	// SourceNamespaceEvents is the channel the WatchRule controller wires via source.Channel so a
	// SOURCE-cluster Namespace label change re-reconciles the rules it grants or revokes. Those
	// labels live in a cluster the controller has no client for, so the watch manager observes
	// them and pushes the affected GitTargets here.
	SourceNamespaceEvents() <-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