Documentation
¶
Overview ¶
Package git provides Git repository operations and abstractions for the GitOps Reverser controller.
Index ¶
- Constants
- Variables
- func AuthFromSecretData(ctx context.Context, k8sClient client.Client, provider *v1alpha3.GitProvider, ...) ([]gitclient.Option, error)
- func ConstructSafeEmail(username string, domain string) string
- func GenerateSSHSigningKeyPair(passphrase []byte) ([]byte, []byte, error)
- func GetCommitSigner(ctx context.Context, k8sClient client.Client, provider *v1alpha3.GitProvider) (gogit.Signer, error)
- func GetCurrentBranch(r *git.Repository) (plumbing.ReferenceName, plumbing.Hash, error)
- func IsValidTargetPath(p string) bool
- func LoadSSHCommitSigner(secret *corev1.Secret) (gogit.Signer, error)
- func PinExplicitSigningPolicy(repo *git.Repository) error
- func PushAtomic(ctx context.Context, repo *git.Repository, rootHash plumbing.Hash, ...) error
- func SSHAuthorizedPublicKeyFromSecret(secret *corev1.Secret) (string, error)
- func SmartFetch(ctx context.Context, repo *git.Repository, target plumbing.ReferenceName, ...) (plumbing.ReferenceName, error)
- func ValidateCommitConfig(config CommitConfig) error
- type AttachCommitRequest
- type AttributionOutcome
- type BranchInfo
- type BranchKey
- type BranchWorker
- func (w *BranchWorker) Enqueue(event Event) bool
- func (w *BranchWorker) EnqueueAttach(req *AttachCommitRequest)
- func (w *BranchWorker) EnqueueRequest(request *WriteRequest)
- func (w *BranchWorker) EnqueueResync(request *ResyncRequest) bool
- func (w *BranchWorker) EnsurePathBootstrapped(path, targetName, targetNamespace string) error
- func (w *BranchWorker) GetBranchMetadata() (bool, string, time.Time)
- func (w *BranchWorker) LookupCommitRequestOutcome(namespace, name, uid string) (FinalizeResult, bool)
- func (w *BranchWorker) Start(parentCtx context.Context) error
- func (w *BranchWorker) Stop()
- func (w *BranchWorker) SyncAndGetMetadata(ctx context.Context) (*PullReport, error)
- type CommitConfig
- type CommitFile
- type CommitMessageConfig
- type CommitMessageData
- type CommitMessageKind
- type CommitMode
- type CommitterConfig
- type Credential
- type Encryptor
- type Event
- type FieldPatch
- type FinalizeOutcome
- type FinalizeResult
- type GroupedCommitMessageData
- type PathRefusalReporter
- type PendingWrite
- type PendingWriteKind
- type PullReport
- type ReconcileCommitMessageData
- type RenderFidelityGate
- func (g *RenderFidelityGate) AllowsWrites(target types.ResourceReference) bool
- func (g *RenderFidelityGate) Begin(target types.ResourceReference, scopes []RenderFidelityScope) RenderFidelityStatus
- func (g *RenderFidelityGate) Fail(target types.ResourceReference, divergence manifestanalyzer.RenderDivergence) RenderFidelityStatus
- func (g *RenderFidelityGate) Forget(target types.ResourceReference)
- func (g *RenderFidelityGate) RecordScopeClean(target types.ResourceReference, epoch uint64, scope RenderFidelityScope) (RenderFidelityStatus, bool)
- func (g *RenderFidelityGate) RecordScopeDivergence(target types.ResourceReference, epoch uint64, scope RenderFidelityScope, ...) (RenderFidelityStatus, bool)
- func (g *RenderFidelityGate) Status(target types.ResourceReference) RenderFidelityStatus
- type RenderFidelityScope
- type RenderFidelityState
- type RenderFidelityStatus
- type RepoInfo
- type ResolvedEncryptionConfig
- type ResolvedTargetMetadata
- type ResourceMeta
- type ResourceRef
- type ResyncRequest
- type ResyncResult
- type ResyncScope
- type ResyncStats
- type SOPSEncryptor
- type SSHHostKeyConfig
- type UserInfo
- type WorkItem
- type WorkerManager
- func (m *WorkerManager) EnsureWorker(_ context.Context, providerName, providerNamespace string, branch string) error
- func (m *WorkerManager) GetWorkerForTarget(providerName, providerNamespace string, branch string) (*BranchWorker, bool)
- func (m *WorkerManager) NeedLeaderElection() bool
- func (m *WorkerManager) ReconcileWorkers(ctx context.Context) error
- func (m *WorkerManager) RegisterTarget(ctx context.Context, targetName, targetNamespace string, ...) error
- func (m *WorkerManager) RenderFidelityGate() *RenderFidelityGate
- func (m *WorkerManager) SetClusterMapper(resolver func(clusterID string) typeset.Lookup)
- func (m *WorkerManager) SetMapper(mapper typeset.Lookup)
- func (m *WorkerManager) SetPathRefusalReporter(reporter PathRefusalReporter)
- func (m *WorkerManager) SetSSHHostKeyConfig(cfg SSHHostKeyConfig)
- func (m *WorkerManager) Start(ctx context.Context) error
- func (m *WorkerManager) UnregisterTarget(_, _ string, providerName, providerNamespace string, branch string) error
- type WriteRequest
Constants ¶
const ( // DefaultCommitWindow is the default rolling silence window used to coalesce // events into one commit per (author, gitTarget). Applied when // GitProvider.spec.push.commitWindow is unset or unparseable. DefaultCommitWindow = 5 * time.Second // PushCooldown is the minimum interval between successful pushes. The cooldown // is intentionally fixed: commit cadence is a user concern (commitWindow on // the CRD); push cadence is an implementation/politeness concern. PushCooldown = 5 * time.Second )
const ( // SigningKeyDataKey is the Secret data key for the PEM-encoded SSH private signing key. SigningKeyDataKey = "signing.key" // SigningPublicKeyDataKey is the Secret data key for the authorized_keys-format public key. SigningPublicKeyDataKey = "signing.pub" // SigningPassphraseDataKey is the Secret data key for an optional key passphrase. SigningPassphraseDataKey = "passphrase" )
const ( // UnresolvedAuthorUsername is the stable machine token for an unresolved attribution. UnresolvedAuthorUsername = "attribution-unresolved" // UnresolvedAuthorDisplayName is the human-facing git author name. UnresolvedAuthorDisplayName = "unknown (attribution unresolved)" // UnresolvedAuthorEmail is a reserved-invalid address (RFC 2606). UnresolvedAuthorEmail = "attribution-unresolved@gitops-reverser.invalid" )
const ( // DefaultCommitterName matches the default operator identity in Git history. DefaultCommitterName = "GitOps Reverser" // DefaultCommitterEmail matches the default operator email in Git history. DefaultCommitterEmail = "noreply@configbutler.ai" // DefaultEventCommitMessageTemplate reproduces the current per-event commit message shape. DefaultEventCommitMessageTemplate = "[{{.Operation}}] {{.APIVersion}}/{{.Resource}}/{{.Name}}" // DefaultReconcileCommitMessageTemplate is the default reconcile commit message shape. // It names the synced type for a per-type splice (e.g. "reconciled 6 secrets (last // resourceVersion: 1331)"), so the otherwise-indistinguishable per-type reconciles a single // GitTarget produces become self-describing — and the pinned resourceVersion shows exactly // how fresh the reconcile is, which is useful for demos and first-user trust. The plural // resource alone (no group/version) is chosen for readability; a custom template can add // {{.APIVersion}} when cross-group plural collisions matter. The {{if .Resource}} and // {{if .Revision}} guards fall back to "reconciled N resources" for a whole-target reconcile // (nil ScopeGVR) or the events-based atomic path, where the type/revision fields are empty — // so the subject never degrades to a trailing-space, identity-less "reconciled N ". DefaultReconcileCommitMessageTemplate = "reconciled {{.Count}} " + "{{if .Resource}}{{.Resource}}{{else}}resources{{end}}" + "{{if .Revision}} (last resourceVersion: {{.Revision}}){{end}}" // DefaultGroupCommitMessageTemplate is the default message shape for // finalized commit-window commits that contain multiple events. DefaultGroupCommitMessageTemplate = "{{.Author}} on {{.GitTarget}}: {{.Count}} resource(s)" )
const DefaultBranchBufferMaxBytes int64 = 8 * 1024 * 1024
DefaultBranchBufferMaxBytes is the default cap on a worker's combined event buffer + unpushed-events memory. Operators override this via --branch-buffer-max-size (8Mi by default).
const (
// EncryptionProviderSOPS is the only supported provider in this increment.
EncryptionProviderSOPS = "sops"
)
Variables ¶
var ( ErrRemoteRefNotFound = errors.New("remote ref not found") ErrRemoteRefNotFoundEmptyRepo = errors.New("remote ref not found (empty repo)") )
var ErrFinalizeQueueFull = errors.New("branch worker event queue full; item dropped")
ErrFinalizeQueueFull is reported when a work item cannot be enqueued because the worker's event queue is saturated.
Functions ¶
func AuthFromSecretData ¶
func AuthFromSecretData( ctx context.Context, k8sClient client.Client, provider *v1alpha3.GitProvider, secret *corev1.Secret, hostKeys SSHHostKeyConfig, ) ([]gitclient.Option, error)
AuthFromSecretData resolves go-git transport options from an already-fetched Git credentials Secret. It is the thin wrapper over CredentialFromSecretData; callers that need to know what kind of credential was produced should use that instead.
func ConstructSafeEmail ¶
ConstructSafeEmail takes a raw username and a domain and creates a valid git-compliant email address.
func GenerateSSHSigningKeyPair ¶
GenerateSSHSigningKeyPair creates an ed25519 SSH signing keypair.
func GetCommitSigner ¶
func GetCommitSigner( ctx context.Context, k8sClient client.Client, provider *v1alpha3.GitProvider, ) (gogit.Signer, error)
GetCommitSigner fetches commit signing material from the specified secret.
func GetCurrentBranch ¶
func GetCurrentBranch(r *git.Repository) (plumbing.ReferenceName, plumbing.Hash, error)
GetCurrentBranch gets the branch that is active.
func IsValidTargetPath ¶
IsValidTargetPath reports whether p is a path the writer can safely materialize into: the repository root (empty or "."), or a clean relative path. Paths the writer rejects as unsafe — absolute (leading "/"), Windows separators, or ".." traversal — are invalid and can own nothing. It mirrors sanitizePath, the write-path guard, so the overlap/admission check and the writer agree on what a target legitimately owns.
func LoadSSHCommitSigner ¶
LoadSSHCommitSigner loads a git-compatible SSH signer from the provided Secret.
func PinExplicitSigningPolicy ¶ added in v0.41.0
func PinExplicitSigningPolicy(repo *git.Repository) error
PinExplicitSigningPolicy records in the repository's own config that commits are not signed unless this operator signs them.
go-git v6 consults commit.gpgSign — merged across system, global and local scope — whenever CommitOptions.Signer is nil, and refuses the commit outright when the setting is true and no signer is registered ("cannot auto-sign commit"). v5 ignored the setting entirely.
Our signing policy comes from the GitProvider's signing Secret and is passed as CommitOptions.Signer, so an ambient commit.gpgSign — a developer's ~/.gitconfig, a mounted config, a future base image — must not be able to decide it for us. Writing the local value false makes the intent explicit and takes precedence over the wider scopes. Where we do sign, Signer is non-nil and this setting is never consulted.
func PushAtomic ¶
func PushAtomic( ctx context.Context, repo *git.Repository, rootHash plumbing.Hash, rootBranch plumbing.ReferenceName, auth []gitclient.Option, ) error
PushAtomic performs an atomic PushAtomic operation in a single network session. It checks if the remote branch is not touched before pushing to prevent creating diverged branches. An explcit error is returned if it failed: I don't plan to use these, we can always retry...
func SSHAuthorizedPublicKeyFromSecret ¶
SSHAuthorizedPublicKeyFromSecret derives the authorized_keys-form public key from a signing Secret.
func SmartFetch ¶
func SmartFetch( ctx context.Context, repo *git.Repository, target plumbing.ReferenceName, auth []gitclient.Option, ) (plumbing.ReferenceName, error)
SmartFetch performs a network sync and returns the best available LOCAL branch reference. It prioritizes the target branch but always fetches the default branch as a safety net.
Return values (example with target="refs/heads/feature"): - "refs/heads/feature", nil: Target found on remote, fetched, ready to checkout. - "refs/heads/main", nil: Target missing on remote, fell back to default branch. - "", nil: No valid branches found (empty repo).
func ValidateCommitConfig ¶
func ValidateCommitConfig(config CommitConfig) error
ValidateCommitConfig checks that commit templates are syntactically valid.
Types ¶
type AttachCommitRequest ¶
type AttachCommitRequest struct {
// Namespace, Name, UID identify the CommitRequest. UID may be empty (a
// Metadata-level audit policy can omit it); identity then keys on
// namespace/name only.
Namespace string
Name string
UID string
// Author is the effective user that requested the finalize, captured from
// validating admission. Only a window whose author
// matches is attached; this binds "the open window" to "the requesting
// author's open window".
Author string
// Attribution is the outcome of attributing THIS CommitRequest, from the command-authorship
// path. It is matched alongside Author rather than inferred from it, because an empty Author
// alone cannot say whether an actor was sought: it is both "attribution is off" and
// "attribution ran and named nobody". Only the NamesActor half is compared against the
// window's outcome — see matchesWindow for why the enums themselves must not be.
Attribution AttributionOutcome
// GitTargetName / GitTargetNamespace scope the finalize to one GitTarget.
GitTargetName string
GitTargetNamespace string
// Message is the verbatim commit message to attach to the window. Empty keeps
// the generated grouped-commit message.
Message string
// CloseDelaySeconds is the close-delay collect window: the worker closes the
// attached window and finalizes it at receipt + CloseDelaySeconds (the delay is
// anchored at attach receipt).
CloseDelaySeconds int32
}
AttachCommitRequest is the "bind this CommitRequest's message to the author's open window, then finalize that window after the grace" work item. It rides the same per-worker FIFO event queue as resource events, so by audit-stream ordering it is processed after every earlier write for that worker. Re-sends are idempotent: the worker keys pending requests by identity and keeps the first finalize deadline.
type AttributionOutcome ¶ added in v0.39.0
type AttributionOutcome string
AttributionOutcome records what happened when the operator tried to name the actor behind a change. It is carried EXPLICITLY rather than inferred from the author identity, because the author string is load-bearing in several places (window grouping, commit-message templates, the author_kind metric) and overloading it to also mean "attribution failed" made a silent failure indistinguishable from correct configured-author behaviour. See docs/architecture.md#author-and-committer-identity-in-git.
const ( // AttributionNotAttempted is configured-author mode: attribution is switched off, so the // committer legitimately IS the author and no actor was ever sought. // // It is deliberately the EMPTY string, so that it is also the ZERO VALUE of the type. Most // paths that build an Event never assign Attribution at all — reconcile, resync, bootstrap, // and configured-author mode's early return in the watch pipeline — and every one of them // means exactly "no actor was sought". Any other string would make the zero value a silent // fourth state equal to none of the three named outcomes, which is precisely the bug that // stopped every CommitRequest attaching in the default deployment. Nothing serializes this // value (it reaches no CRD field and no metric label; authorKind branches on the typed // value), so the empty string costs nothing. TestAttributionZeroValueIsNotAttempted pins it. AttributionNotAttempted AttributionOutcome = "" // AttributionResolved means an audit fact named the actor. AttributionResolved AttributionOutcome = "resolved" // AttributionUnresolved means attribution ran and did not arrive at an actor. // // Deliberately "unresolved", not "failed": the lookup collapses several genuinely // different situations into one miss — no fact was ever produced (correct; not every // change has an audited human actor), a cancelled wait, a Redis read error, and a // malformed value all return the same not-found. Calling that a failure would assert a // fault the operator cannot prove. AttributionUnresolved AttributionOutcome = "unresolved" )
func (AttributionOutcome) NamesActor ¶ added in v0.39.0
func (o AttributionOutcome) NamesActor() bool
NamesActor reports whether the outcome carries an actor to compare against.
This is the ONLY distinction that survives across subsystem boundaries. Whether an outcome is "not attempted" or "unresolved" is a property of how the subsystem that produced it is configured — and the mirrored-resource attribution path (--author-attribution) and the command-authorship path (--admission-webhook) are configured independently of each other (cmd/main.go:311-316). Two independently configured producers can therefore disagree about the enum while agreeing perfectly about the thing that matters: whether there is an actor. Compare the enums across that boundary and you couple the two flags; compare NamesActor and you do not. Within a single subsystem the enum itself is meaningful and IS compared directly (openWindow.canAppend), because both sides come from the same producer.
type BranchInfo ¶
type BranchInfo struct {
ShortName string // e.g., "main"
Sha string // commit hash, normally the tip of the default branch. But will be empty ("") for an unborn branch that is going to be orphaned branch (if the default branch does not exist)
Unborn bool // Is true for branches that don't have commits yet: only HEAD is configured to it
}
BranchInfo contains information about a Git branch.
type BranchKey ¶
type BranchKey struct {
// RepoNamespace is the namespace containing the GitProvider.
RepoNamespace string
// RepoName is the name of the GitProvider.
RepoName string
// Branch is the Git branch name.
Branch string
}
BranchKey uniquely identifies a (GitProvider, Branch) combination. This is the unit of worker ownership to prevent merge conflicts. Multiple GitTargets can share the same BranchKey (same provider+branch) but write to different paths within that branch.
type BranchWorker ¶
type BranchWorker struct {
// Identity (immutable after creation)
GitProviderRef string
GitProviderNamespace string
Branch string
// Dependencies
Client client.Client
Log logr.Logger
// contains filtered or unexported fields
}
BranchWorker processes events for a single (GitProvider, Branch) combination. It can serve multiple GitTargets that write to different paths in the same branch. This design ensures serialized commits per branch, preventing merge conflicts.
func NewBranchWorker ¶
func NewBranchWorker( client client.Client, log logr.Logger, providerName, providerNamespace string, branch string, writer *contentWriter, branchBufferMaxBytes int64, ) *BranchWorker
NewBranchWorker creates a worker for a (provider, branch) combination. Pass 0 (or a negative value) for branchBufferMaxBytes to use DefaultBranchBufferMaxBytes.
func (*BranchWorker) Enqueue ¶
func (w *BranchWorker) Enqueue(event Event) bool
Enqueue adds a single live event to this worker's queue. It reports whether the event entered the FIFO; a false return means the queue was full and the event was dropped, so a caller advancing a durable watch cursor past this event must not treat the drop as success (see reconcile.GitTargetEventStream.OnWatchEvent).
func (*BranchWorker) EnqueueAttach ¶
func (w *BranchWorker) EnqueueAttach(req *AttachCommitRequest)
EnqueueAttach adds a CommitRequest attach to this worker's queue. Riding the same queue as resource events is what makes it process in audit order, after every earlier write. The attach is fire-and-forget: the controller polls the outcome via LookupCommitRequestOutcome and re-sends idempotently, so a queue- full drop is recovered by the next poll rather than a synchronous reply.
func (*BranchWorker) EnqueueRequest ¶
func (w *BranchWorker) EnqueueRequest(request *WriteRequest)
EnqueueRequest adds a write request to this worker's queue.
func (*BranchWorker) EnqueueResync ¶
func (w *BranchWorker) EnqueueResync(request *ResyncRequest) bool
EnqueueResync adds a resync request to this worker's queue. Like a finalize signal it rides the same queue as resource events, so it is applied in order with live events: a resync enqueued during the snapshot window lands before the buffered live events that follow it. If the queue is full the request is dropped and its caller is notified immediately via the result channel.
It reports whether the request actually entered the FIFO. A dropped request never reached the queue, so a caller that gates downstream state on the resync's ordering (the per-type coverage watermark, signing-snapshot-tail-replay-failure-investigation.md §7.4) must not treat a drop as success — it would mark the target reconciled-through-Hc with no reconcile ever queued.
func (*BranchWorker) EnsurePathBootstrapped ¶
func (w *BranchWorker) EnsurePathBootstrapped(path, targetName, targetNamespace string) error
EnsurePathBootstrapped prepares bootstrap templates locally for a path. Existing files are preserved, and only missing template files are added. The files are staged in the local worktree but never committed or pushed here.
func (*BranchWorker) GetBranchMetadata ¶
func (w *BranchWorker) GetBranchMetadata() (bool, string, time.Time)
GetBranchMetadata returns current branch status without syncing. This is primarily used for quick status checks without triggering Git operations.
func (*BranchWorker) LookupCommitRequestOutcome ¶
func (w *BranchWorker) LookupCommitRequestOutcome(namespace, name, uid string) (FinalizeResult, bool)
LookupCommitRequestOutcome returns a resolved CommitRequest outcome, or ok=false when the request is still in flight (or already GC'd). The controller polls this after sending its AttachCommitRequest.
func (*BranchWorker) Start ¶
func (w *BranchWorker) Start(parentCtx context.Context) error
Start begins processing events.
func (*BranchWorker) SyncAndGetMetadata ¶
func (w *BranchWorker) SyncAndGetMetadata(ctx context.Context) (*PullReport, error)
SyncAndGetMetadata fetches latest metadata from remote Git repository. Uses caching to avoid redundant fetches within 30 seconds (optimization for multiple GitTargets sharing the same branch). Returns PullReport containing branch existence, HEAD SHA, and other metadata.
type CommitConfig ¶
type CommitConfig struct {
Committer CommitterConfig
Message CommitMessageConfig
}
CommitConfig is the resolved commit behavior used by the git writer.
func ResolveCommitConfig ¶
func ResolveCommitConfig(spec *v1alpha3.CommitSpec) CommitConfig
ResolveCommitConfig resolves API commit settings into runtime defaults.
type CommitFile ¶
CommitFile represents a single file to be committed.
type CommitMessageConfig ¶
type CommitMessageConfig struct {
EventTemplate string
ReconcileTemplate string
GroupTemplate string
}
CommitMessageConfig contains the resolved per-event, reconcile, and grouped templates.
type CommitMessageData ¶
type CommitMessageData struct {
Operation string
Group string
Version string
Resource string
Namespace string
Name string
APIVersion string
Username string
GitTarget string
}
CommitMessageData is the template context for per-event commit messages.
type CommitMessageKind ¶
type CommitMessageKind string
CommitMessageKind determines which message/authorship path the executor uses.
const ( CommitMessagePerEvent CommitMessageKind = "event" CommitMessageReconcile CommitMessageKind = "reconcile" CommitMessageGrouped CommitMessageKind = "group" )
type CommitMode ¶
type CommitMode string
CommitMode defines how a write request should be committed.
const ( // CommitModePerEvent streams request events through the live commit window. // With commitWindow=0 each event finalizes immediately; otherwise events // coalesce by author, target, and quiet-window boundaries. CommitModePerEvent CommitMode = "per_event" // CommitModeAtomic creates one commit for all events in the request. CommitModeAtomic CommitMode = "atomic" )
type CommitterConfig ¶
CommitterConfig defines the operator identity used as the git committer.
type Credential ¶ added in v0.41.0
type Credential struct {
SSH *sshpkg.KeyAuth
Basic *gogithttp.BasicAuth
Bearer *gogithttp.TokenAuth
}
Credential is the concrete credential a Secret yields, before it is wrapped into go-git v6's opaque transport client options. At most one field is non-nil; all nil means anonymous access to a public repository.
This type exists because v6 removed transport.AuthMethod: authentication is now supplied as functional options, which are closures and therefore cannot be inspected. Keeping the concrete value on the way past preserves the ability to assert which Secret key maps to which auth field, which is the contract CredentialFromSecretData is actually responsible for.
func CredentialFromSecretData ¶ added in v0.41.0
func CredentialFromSecretData( ctx context.Context, k8sClient client.Client, provider *v1alpha3.GitProvider, secret *corev1.Secret, hostKeys SSHHostKeyConfig, ) (Credential, error)
CredentialFromSecretData resolves a credential from an already-fetched Git credentials Secret, accepting the Kubernetes-native, Flux, and Argo CD key dialects (the credentials Secret is the one portable artifact across those ecosystems). provider supplies the namespace and the optional knownHostsRef for SSH host trust; hostKeys supplies the install-level default and the dev escape hatch. Auth precedence is: SSH key (if present) → HTTP basic (username+password) → bearer token.
func (Credential) Options ¶ added in v0.41.0
func (c Credential) Options() []gitclient.Option
Options renders the credential as go-git v6 transport client options. A zero Credential yields nil, which go-git treats as anonymous.
type Encryptor ¶
type Encryptor interface {
Encrypt(ctx context.Context, plain []byte, meta ResourceMeta) ([]byte, error)
}
Encryptor transforms plaintext bytes into encrypted bytes.
type Event ¶
type Event struct {
// Object is the sanitized Kubernetes object. Exactly one of Object or
// FieldPatch is set for a resource mutation; a control or DELETE event may
// carry neither.
Object *unstructured.Unstructured
// FieldPatch, when set, replaces Object with a bounded in-place edit of an
// existing parent manifest (subresource audit resolution). It is mutually
// exclusive with Object.
FieldPatch *FieldPatch
// Identifier contains resource identification information.
Identifier types.ResourceIdentifier
// Operation is the admission operation (CREATE, UPDATE, DELETE).
Operation string
// AuditStreamID is the FULL Redis stream position "<rv>-<seq>" this change was recorded at
// on the per-type audit stream. It is set ONLY on the audit-tail path (ReadTypeAuditChanges)
// and read by the per-(GitTarget, GVR) coverage-watermark gate in applyAuditChangesForType to
// decide whether the entry is historical for a target (id <= Hc, suppress) or live (id > Hc,
// route). The sub-sequence is load-bearing: distinct entries can share an rv (an rv-less
// DELETE/Status rides the high-water, duplicate/same-rv writes get fresh seqs), so the gate
// compares full positions, not bare rvs. Empty on the live admission path; not used by the
// writer. See docs/finished/signing-snapshot-tail-replay-failure-investigation.md §7.
AuditStreamID string
// UserInfo contains user information for commit messages.
UserInfo UserInfo
// Attribution records whether naming the actor was attempted and whether it succeeded.
// It is the authority for author rendering, the author_kind metric, and CommitRequest
// window matching — none of which may infer the outcome from UserInfo, because an empty
// or sentinel username cannot distinguish "attribution is off" from "attribution ran and
// found nothing". The zero value is AttributionNotAttempted — the constant is defined as the
// empty string precisely so that it is — which is correct for every non-live path
// (reconcile, resync, bootstrap) where no actor is ever sought, and for configured-author
// mode. attachAuthor is the only assignment to this field outside tests.
Attribution AttributionOutcome
// Path is the POSIX-like relative path prefix for this event's files.
// This comes from the GitTarget that triggered this event.
// Empty string means write to repository root.
Path string
// GitTargetName is the target owning this event.
GitTargetName string
// GitTargetNamespace is the namespace of the target owning this event.
GitTargetNamespace string
// SourceCluster is the NAME of the source cluster this object was watched on —
// (api/v1alpha3).GitTarget.SourceCluster(), the referenced ClusterProvider's name
// ("default" for the in-cluster provider). The writer resolves this document's GVK->GVR
// against that cluster's type registry, so a folder mirroring a remote is never indexed
// against the local cluster's mapping.
SourceCluster string
// BootstrapOptions controls path-scoped bootstrap file staging for this event.
BootstrapOptions pathBootstrapOptions
}
Event represents a resource change event to be processed by a branch worker. Branch comes from the worker context (not stored in event). Path comes from the GitTarget that created this event.
func (Event) IsFieldPatch ¶
IsFieldPatch reports whether the event carries a bounded field patch instead of a full object. It is the single predicate the pipeline branches on to route a patch to the in-place writer rather than the object writer.
type FieldPatch ¶
type FieldPatch struct {
// Assignments are the (path, value) pairs to set on the parent manifest. Paths
// are disjoint; each owns only its own subtree, so the patch is additive and
// leaves every unmentioned field in Git untouched.
Assignments []manifestedit.FieldAssignment
// Source is a bounded origin label for commit messages and metrics, e.g.
// "deployments/scale". Never the request URI.
//
// The parent Kind is intentionally NOT carried here. The audit objectRef gives
// only the GVR (plural resource), and the subresource body's own Kind (e.g.
// "Scale") is not the parent's. The writer resolves the parent document from the
// objectRef GVR through the same resource-identity inventory the GVR-only delete
// uses — it already has the live-catalog mapper — so the consumer never needs
// GVR->GVK resolution.
Source string
}
FieldPatch is a bounded set of field assignments to an existing parent manifest, carried in place of a full Object. It is how an author-preserving subresource mutation (e.g. deployments/scale) reaches Git: set exactly the audited field paths on the already committed parent, never reconstructing the whole object. See docs/spec/scale-subresource-audit-rehydration.md.
type FinalizeOutcome ¶
type FinalizeOutcome string
FinalizeOutcome is the terminal result of resolving a CommitRequest.
const ( // FinalizeCommitted means an open commit window was finalized into a commit. FinalizeCommitted FinalizeOutcome = "Committed" // FinalizeNoOpenWindow means no matching same-author window was collected // within the grace, so nothing was committed for the request. FinalizeNoOpenWindow FinalizeOutcome = "NoOpenWindow" // FinalizeWindowMismatch means the open window belonged to a different author // or GitTarget than the request, so it was left untouched. FinalizeWindowMismatch FinalizeOutcome = "WindowMismatch" // FinalizeAlreadyPresent means a matching window was finalized but its events // produced no diff — the change already matches the remote, so no commit was // made (loop prevention). Resolved at finalize, never waiting on a push. FinalizeAlreadyPresent FinalizeOutcome = "AlreadyPresent" )
type FinalizeResult ¶
type FinalizeResult struct {
// Outcome is set when Err is nil.
Outcome FinalizeOutcome
// SHA is the resulting commit SHA when Outcome is FinalizeCommitted.
SHA string
// Branch is the branch the worker operates on.
Branch string
// Err is set when the request could not be completed.
Err error
}
FinalizeResult carries the resolved outcome of a CommitRequest back to the controller, polled via LookupCommitRequestOutcome.
type GroupedCommitMessageData ¶
type GroupedCommitMessageData struct {
// Author is the verbatim event.UserInfo.Username for the group.
Author string
// GitTarget is the single target this commit is bound to.
GitTarget string
// Count is the number of distinct resources committed.
Count int
// Operations counts events by operation kind (CREATE/UPDATE/DELETE).
Operations map[string]int
// Resources is the per-resource list, deduplicated by file path so the
// final state is what's being committed.
Resources []ResourceRef
}
GroupedCommitMessageData is the template context for grouped commit messages. Each grouped commit covers exactly one (author, gitTarget) tuple (see docs/spec/commit-window-refactor.md).
type PathRefusalReporter ¶
type PathRefusalReporter func(target itypes.ResourceReference, refused *manifestanalyzer.AcceptanceRefusedError)
PathRefusalReporter surfaces a refused write plan to the layer that owns GitTarget status. A refusal is not a transient write fault: the acceptance gate or a write-boundary precondition aborted the flush before any byte was written, nothing was committed, and only a human editing the Git path can clear it — so it must reach the user as GitPathAccepted=False / Stalled=True rather than being logged and dropped.
The resync path already carries its refusal back on ResyncResult.Err, where the watch layer classifies it. The live-event paths have no result channel — a window is finalized on a timer, and its failure used to be logged and dropped — so they report through this hook instead. The watch Manager supplies it (WorkerManager.SetPathRefusalReporter), which is why the reason mapping lives there and not here.
type PendingWrite ¶
type PendingWrite struct {
Kind PendingWriteKind
Events []Event
CommitMessage string
CommitConfig CommitConfig
Signer gogit.Signer
GitTargetName string
GitTargetNamespace string
Targets map[pendingTargetKey]ResolvedTargetMetadata
ByteSize int64
// Desired is the complete desired resource snapshot, set only for a
// PendingWriteResync. The worker folds it over the worktree's content-derived
// store to produce the resync plan (upserts + mark-and-sweep drops).
Desired []manifestanalyzer.DesiredResource
// Scope, when set, restricts the resync's mark-and-sweep to one type's
// (group, resource) and optionally to one namespace: the M12 per-type
// reconcile/sweep. Desired then carries only that scope's objects (empty for a pure
// sweep), and no sibling type's — nor, for a namespace-scoped resync, any sibling
// namespace's — document is ever dropped. Nil is the whole-GitTarget resync.
Scope *ResyncScope
// Revision is the cluster snapshot resourceVersion the desired set is pinned to
// (the joined streaming-watch bookmark). Carried for diagnostics and logging.
Revision string
// ResyncStats, when non-nil, is populated during apply with the plan's
// create/update/delete/skip counts so a synchronous caller can report them.
ResyncStats *ResyncStats
// Committed, when non-nil, is set true during apply iff the resync produced a
// commit. A no-op resync (e.g. an empty initial snapshot) must not be retained or
// pushed: doing so would advance the push cooldown and delay the next real
// snapshot's push past its window.
Committed *bool
// CommitRequest, when set, is the CommitRequest claiming this write: it is
// resolved Committed (with CommitSHA) once this write is pushed. It rides the write through the
// push cooldown and the conflict rebase-replay, so the result follows the data.
CommitRequest *commitRequestID
// CommitSHA is the hash of the commit this write created, captured in
// executePendingWrite and refreshed when the write is re-executed on a
// rebase-replay (so it is never a stale pre-rebase hash). Zero when the write
// produced no commit (no diff).
CommitSHA plumbing.Hash
}
PendingWrite is the unit retained until a push succeeds.
func (PendingWrite) AttributionOutcome ¶ added in v0.39.0
func (p PendingWrite) AttributionOutcome() AttributionOutcome
AttributionOutcome returns the attribution outcome for commit-shaped pending writes. It mirrors AuthorUserInfo: the window is single-author, so the first event's outcome describes the whole write. Atomic and empty writes never attempt attribution.
func (PendingWrite) Author ¶
func (p PendingWrite) Author() string
Author returns the grouped commit author username for commit-shaped pending writes. It is the stable identity used for window coalescing and the grouped commit message; see AuthorUserInfo for the full signing identity.
func (PendingWrite) AuthorUserInfo ¶
func (p PendingWrite) AuthorUserInfo() UserInfo
AuthorUserInfo returns the full author identity for commit-shaped pending writes, including any OIDC display name and email. Atomic and empty writes have no per-user author and return the zero value.
func (PendingWrite) MessageKind ¶
func (p PendingWrite) MessageKind() CommitMessageKind
MessageKind is derived from the pending write's shape.
func (PendingWrite) Target ¶
func (p PendingWrite) Target() ResolvedTargetMetadata
Target returns the single resolved target metadata for this pending write.
type PendingWriteKind ¶
type PendingWriteKind string
PendingWriteKind distinguishes the durable write shapes retained until push.
const ( // PendingWriteCommit is one finalized commit-shaped live-event window. PendingWriteCommit PendingWriteKind = "grouped_window" // PendingWriteAtomic is a caller-defined atomic request, typically from // reconciliation. PendingWriteAtomic PendingWriteKind = "atomic" // PendingWriteResync is a streaming-snapshot resync (M8): it carries the COMPLETE // desired resource set for one GitTarget, and the worker materialises it with a // content-derived mark-and-sweep against the worktree (upsert every desired // resource, drop every watched managed document the snapshot did not contain). PendingWriteResync PendingWriteKind = "resync" )
type PullReport ¶
type PullReport struct {
ExistsOnRemote bool // Branch exists on remote
HEAD BranchInfo
IncomingChanges bool // SHA changed, requiring resource-level reconcile
}
PullReport provides detailed pull operation results.
func PrepareBranch ¶
func PrepareBranch( ctx context.Context, repoURL, repoPath, targetBranchName string, auth []gitclient.Option, ) (*PullReport, error)
PrepareBranch clones repository immediately when GitDestination is created, optimized for single branch usage. It tries to fetch the useful branch: either target or default.
type ReconcileCommitMessageData ¶
type ReconcileCommitMessageData struct {
Count int
GitTarget string
Group string
Version string
Resource string
APIVersion string
Revision string
// Namespace is the single source namespace a namespace-scoped reconcile covered, and
// is empty for a whole-target or all-namespaces reconcile.
Namespace string
}
ReconcileCommitMessageData is the template context for reconcile commit messages.
Group, Version, Resource, and APIVersion name the synced type, mirroring the per-event CommitMessageData fields so a reconcile template can identify its type exactly as a per-event template does. They are populated for a per-type splice (M12/R2 per-type reconcile, whose ResyncRequest carries a non-nil ScopeGVR) and left empty for a whole-target reconcile or the events-based atomic path. Revision is the cluster resourceVersion the desired set was pinned to (empty for a pure sweep or the events-based path). Any template that references these fields must render cleanly when they are absent — the default guards both with {{if}}.
type RenderFidelityGate ¶ added in v0.37.0
type RenderFidelityGate struct {
// contains filtered or unexported fields
}
RenderFidelityGate is the concurrency-safe ownership point for the RenderMatchesLive state machine. A fresh epoch closes writes until every current scope reports clean. A single divergence latches False for that epoch; a later success from another scope cannot reopen it.
func NewRenderFidelityGate ¶ added in v0.37.0
func NewRenderFidelityGate() *RenderFidelityGate
NewRenderFidelityGate creates an empty gate. Targets absent from it remain writable for backwards-compatible callers until their watch manager begins an epoch.
func (*RenderFidelityGate) AllowsWrites ¶ added in v0.37.0
func (g *RenderFidelityGate) AllowsWrites(target types.ResourceReference) bool
AllowsWrites reports whether a target may accept a normal live or atomic write. Resync work is deliberately not gated here: it is how the current epoch measures and repairs the Git tree.
func (*RenderFidelityGate) Begin ¶ added in v0.37.0
func (g *RenderFidelityGate) Begin( target types.ResourceReference, scopes []RenderFidelityScope, ) RenderFidelityStatus
Begin starts a new epoch for target and replaces the complete scope set. It returns Unknown when scopes are pending, or True for the vacuous zero-scope case.
func (*RenderFidelityGate) Fail ¶ added in v0.37.0
func (g *RenderFidelityGate) Fail( target types.ResourceReference, divergence manifestanalyzer.RenderDivergence, ) RenderFidelityStatus
Fail closes a target immediately when a steady-state write discovers a divergence. It does not invent a successful scope result, so recovery still requires a complete fresh epoch.
func (*RenderFidelityGate) Forget ¶ added in v0.37.0
func (g *RenderFidelityGate) Forget(target types.ResourceReference)
Forget removes a deleted GitTarget's state.
func (*RenderFidelityGate) RecordScopeClean ¶ added in v0.37.0
func (g *RenderFidelityGate) RecordScopeClean( target types.ResourceReference, epoch uint64, scope RenderFidelityScope, ) (RenderFidelityStatus, bool)
RecordScopeClean records a completed clean result. It ignores stale epochs and results for a scope the current watch set no longer contains, returning applied=false in either case.
func (*RenderFidelityGate) RecordScopeDivergence ¶ added in v0.37.0
func (g *RenderFidelityGate) RecordScopeDivergence( target types.ResourceReference, epoch uint64, scope RenderFidelityScope, divergence manifestanalyzer.RenderDivergence, ) (RenderFidelityStatus, bool)
RecordScopeDivergence records a render-vs-live mismatch for one completed scope. It latches the target False until Begin starts a newer epoch.
func (*RenderFidelityGate) Status ¶ added in v0.37.0
func (g *RenderFidelityGate) Status(target types.ResourceReference) RenderFidelityStatus
Status returns the current status. An unregistered target is treated as True so adding the gate does not change callers that have no target watch lifecycle.
type RenderFidelityScope ¶ added in v0.37.0
type RenderFidelityScope struct {
GVR schema.GroupVersionResource
Namespace string
}
RenderFidelityScope is one independently replayed target-watch scope. Namespace is part of the key: a namespaced GitTarget can watch the same GVR in more than one namespace.
type RenderFidelityState ¶ added in v0.37.0
type RenderFidelityState string
RenderFidelityState is the three-state result of a complete render-vs-live epoch.
const ( RenderFidelityUnknown RenderFidelityState = "Unknown" RenderFidelityTrue RenderFidelityState = "True" RenderFidelityFalse RenderFidelityState = "False" )
type RenderFidelityStatus ¶ added in v0.37.0
type RenderFidelityStatus struct {
Epoch uint64
State RenderFidelityState
Reason string
Message string
Divergence *manifestanalyzer.RenderDivergence
ScopeCount int
CleanScopes int
}
RenderFidelityStatus is the target-level reduction of all scope results in one epoch. Unknown means the current epoch has not observed every scope; callers must not write live events while it is Unknown or False.
type RepoInfo ¶
type RepoInfo struct {
DefaultBranch *BranchInfo
RemoteBranchCount int
}
RepoInfo represents high-level repository information.
type ResolvedEncryptionConfig ¶
ResolvedEncryptionConfig contains runtime encryption settings resolved from GitTarget spec.
It carries public age recipients only. The write path encrypts, it never decrypts, so no private age identity is retained, written to disk, or passed to the sops process. See docs/rbac.md.
func ResolveTargetEncryption ¶
func ResolveTargetEncryption( ctx context.Context, k8sClient client.Client, target *v1alpha3.GitTarget, ) (*ResolvedEncryptionConfig, error)
ResolveTargetEncryption resolves and validates GitTarget encryption configuration.
type ResolvedTargetMetadata ¶
type ResolvedTargetMetadata struct {
Name string
Namespace string
Path string
BootstrapOptions pathBootstrapOptions
EncryptionConfig *ResolvedEncryptionConfig
// Placement is the GitTarget's declared new-file placement policy, resolved
// from spec.placement. Nil when the GitTarget declares none, in which case new
// resources are placed beside the folder's one kustomize root, if it has exactly one,
// and otherwise at the canonical path.
Placement *manifestanalyzer.PlacementPolicy
// PruneMode is the GitTarget's EFFECTIVE spec.prune.mode — always a concrete value,
// because it is resolved through EffectivePruneMode and an omitted policy is onEvent.
// It gates both deletion paths: the resync mark-and-sweep (through the planner's
// SweepMode) and the steady-state DELETE-event writer.
//
// Retained on the pending write with the rest of the target's metadata, so a write replayed
// after a rebase is not re-planned under a LOOSER policy than the one it was planned against:
// its retention decisions were taken over a desired snapshot that is now stale, and a later
// `always` applies to the next resync, which gathers a fresh one.
//
// It is not frozen, though. tightenPendingPruneModes lowers it before a replay when the
// GitTarget's current policy is stricter, because the whole point of tightening a deletion
// policy is to stop deletions that have not landed yet.
PruneMode v1alpha3.PruneMode
// SourceCluster is the NAME of the source cluster the GitTarget mirrors from —
// (api/v1alpha3).GitTarget.SourceCluster(), the referenced ClusterProvider's name
// ("default" for the in-cluster provider). The resync mark-and-sweep resolves this subtree's
// documents' GVK->GVR against that cluster's registry, so a folder mirroring a remote is swept
// against the right cluster's mapping.
SourceCluster string
}
ResolvedTargetMetadata is the target-scoped planning data retained with a pending write so replay does not re-fetch mutable GitTarget state.
type ResourceMeta ¶
type ResourceMeta struct {
Identifier itypes.ResourceIdentifier
UID string
ResourceVersion string
Generation int64
}
ResourceMeta is passed to encryptors for context and diagnostics.
type ResourceRef ¶
type ResourceRef struct {
Group string
Version string
Resource string
Namespace string
Name string
}
ResourceRef is the lightweight resource identifier emitted to grouped commit templates via GroupedCommitMessageData.Resources.
func (ResourceRef) String ¶
func (r ResourceRef) String() string
String renders the ref as group/version/resource[/namespace]/name. The format mirrors ResourceIdentifier.String for templates that want to {{range}} over Resources and just print each entry.
type ResyncRequest ¶
type ResyncRequest struct {
Desired []manifestanalyzer.DesiredResource
Revision string
GitTargetName string
GitTargetNamespace string
// Scope, when set, makes this a per-type (M12) reconcile/sweep: the mark-and-sweep is
// restricted to the named type — and, when the scope names a namespace, to that
// namespace — while Desired carries only that scope's objects (empty = pure sweep of a
// removed type). Nil is a whole-GitTarget resync. See ResyncScope for the invariant
// binding this to Desired.
Scope *ResyncScope
// Heal marks a non-urgent drift-correcting resync (a periodic checkpoint re-anchor or a
// removed-type sweep) that the worker DEFERS while a commit window is open, instead of
// force-finalizing it. Because one worker serves N GitTargets and the commit window is a
// worker singleton, a force-finalizing heal can steal a DIFFERENT GitTarget's held
// CommitRequest window — the 8f2ad84 regression. A heal therefore waits for the worker to be
// idle (no open window), a boundary that recurs on every silence timeout and identity switch,
// so it never starves and, when it runs, has no window to steal. A first-sync backfill is NOT
// a heal: it must establish initial state promptly and is ordered before the audit tail.
Heal bool
// Result receives exactly one reply. It is buffered (cap 1) by the emitter so
// the worker never blocks delivering it.
Result chan ResyncResult
}
ResyncRequest is a synchronous resync of one GitTarget against a complete, revision-pinned desired snapshot (M8). It rides the worker queue so the single git-mutating goroutine applies it in order with live events, and replies on Result once the local commit is created. The desired set is the whole watched resource state at Revision; the worker's content-derived mark-and-sweep drops any managed document the snapshot did not contain.
type ResyncResult ¶
type ResyncResult struct {
Stats ResyncStats
Err error
}
ResyncResult is the reply to a ResyncRequest: the plan's change counts, or an error if the resync could not be applied (in which case nothing was committed).
type ResyncScope ¶ added in v0.39.0
type ResyncScope struct {
GVR schema.GroupVersionResource
Namespace string
}
ResyncScope restricts a resync's mark-and-sweep to the slice of the mirror the desired snapshot was actually gathered over. GVR names the type; Namespace, when non-empty, further restricts the sweep to that one namespace.
The invariant this type exists to hold: THE SWEEP SCOPE MUST BE EXACTLY THE SCOPE THE DESIRED SET WAS GATHERED OVER. A desired set narrower than its sweep scope deletes managed documents that were never in scope; a desired set wider than its sweep scope silently leaves documents unmanaged. Namespace lives here, next to GVR, precisely so a per-namespace replay cannot reach the sweep carrying only its type — the defect fixed in docs/design/watchrule-source-namespace/pr1-namespace-scoped-resync.md, where a replay of one namespace swept every other namespace's documents of the same type.
An empty Namespace is a genuinely cluster-wide (all-namespaces) scope for the type, which is what a ClusterWatchRule's cluster-wide stream gathers.
func (*ResyncScope) Matches ¶ added in v0.39.0
func (s *ResyncScope) Matches(ri types.ResourceIdentifier) bool
Matches reports whether a resolved resource identity falls inside this scope. A nil scope matches everything (whole-GitTarget resync). An empty Namespace matches every namespace for the type.
func (*ResyncScope) String ¶ added in v0.39.0
func (s *ResyncScope) String() string
String renders the scope for logs and for the deferred-heal key. It is nil-safe: a nil scope is the whole-GitTarget resync and renders empty.
type ResyncStats ¶
type ResyncStats struct {
Created int
Updated int
Deleted int
Skipped int
PlacementSkipped int
// Retained is how many managed documents this resync's prune policy kept that a converged
// mirror would have dropped. It is the ONE count here that does not describe something the
// resync did: a suppressed drop produces no action, no commit, and no other stat, so without
// it nothing downstream can tell a converged mirror from a deliberately retaining one. It
// rides the reply channel to the drain, which rolls it up onto GitTarget status.
Retained int
// PruneMode stamps Retained with the effective policy that produced it, so the count and the
// reason for it travel together. Reading the mode from the spec at projection time instead
// would let a target that has just been switched publish a new mode beside a count the old
// one produced.
PruneMode v1alpha3.PruneMode
}
ResyncStats summarises what a resync changed, for GitTarget status. Created, Updated, and Deleted are the materialised create / patch+replace / managed-drop counts; Skipped is documents present but not safely editable (e.g. encrypted or disallowed constructs). PlacementSkipped is new resources the writer refused to place fail-safe — placement could not be resolved safely, or the write would co-mingle sensitive and plaintext documents (placement Option B2). It is counted (not silently swallowed) and logged per-resource so a not-mirrored resource is visible in the resync summary; it is not (yet) surfaced as a dedicated GitTarget status condition.
type SOPSEncryptor ¶
type SOPSEncryptor struct {
// contains filtered or unexported fields
}
SOPSEncryptor encrypts YAML by invoking the external sops binary.
func NewSOPSEncryptor ¶
func NewSOPSEncryptor(binaryPath, configPath string) *SOPSEncryptor
NewSOPSEncryptor creates an Encryptor that shells out to sops.
func NewSOPSEncryptorWithEnv ¶
func NewSOPSEncryptorWithEnv(binaryPath, configPath, workDir string, env map[string]string) *SOPSEncryptor
NewSOPSEncryptorWithEnv creates an Encryptor that shells out to sops with additional environment variables.
func (*SOPSEncryptor) Encrypt ¶
func (e *SOPSEncryptor) Encrypt(ctx context.Context, plain []byte, meta ResourceMeta) ([]byte, error)
Encrypt streams plaintext YAML to sops over stdin and returns encrypted YAML bytes.
type SSHHostKeyConfig ¶
type SSHHostKeyConfig struct {
// ControllerNamespace is the namespace the controller runs in; it scopes the install-level
// default known-hosts ConfigMap.
ControllerNamespace string
// DefaultKnownHostsConfigMap names an optional install-level ConfigMap in ControllerNamespace
// that supplies known_hosts when neither the credentials Secret nor the GitProvider supplies
// it. Empty disables this layer.
DefaultKnownHostsConfigMap string
// AllowMissingKnownHosts permits SSH only when NO host-key source produced any known_hosts at
// all (the controller's --insecure-allow-missing-known-hosts flag). A known_hosts that is
// present but unparseable is always a hard error.
AllowMissingKnownHosts bool
}
SSHHostKeyConfig configures where SSH known_hosts (host-trust material) are sourced and the dev-only escape hatch for a host with no pinned key. It is set once at startup and threaded to every credentials read. Its zero value fails closed: no install-level default and no missing-key opt-out.
type UserInfo ¶
type UserInfo struct {
Username string
UID string
// DisplayName is the human-readable name from the OIDC "name" claim, when
// the audit event carries it. Empty means "fall back to Username".
DisplayName string
// Email is the address from the OIDC "email" claim, when the audit event
// carries it. Empty means "fall back to ConstructSafeEmail(Username)".
Email string
}
UserInfo contains relevant user information for commit messages.
func UnresolvedAuthor ¶ added in v0.39.0
func UnresolvedAuthor() UserInfo
UnresolvedAuthor is the identity written to the Git AUTHOR HEADER when attribution ran and did not resolve an actor. It exists so an unresolved attribution is visible in `git log` instead of being indistinguishable from a configured-author commit.
Scope: the git author header, and nothing else. It is DERIVED at the write path (commitOptionsFor) from the carried AttributionOutcome — it is never stamped onto an Event. The outcome is the fact; this identity is one rendering of it. So the sentinel deliberately does NOT reach window grouping, the grouped commit-message body, or user-authored {{.Username}} templates: those keep the empty author they have always had for an unnamed actor, on both this path and in configured-author mode. Pushing a magic token into message bodies would change the commit text of every existing deployment that has attribution misses, and force user templates to special-case a value they never had to handle.
Three fields, three different strings, because the header needs all three:
- Username is the stable machine token, so tooling that parses the header has something greppable that will not drift with the human-facing wording.
- DisplayName is what a human reads in `git log`, so it leads with what they care about.
- Email uses the RFC 2606 reserved .invalid TLD, so it can never collide with a real address and never routes mail.
type WorkItem ¶
type WorkItem struct {
// Request is a resource-write request.
Request *WriteRequest
// Attach is a CommitRequest attach: bind a message to the author's window and
// finalize it after the grace.
Attach *AttachCommitRequest
// Resync is a streaming-snapshot resync request (M8): a synchronous
// request/reply that materialises a GitTarget's complete desired set.
Resync *ResyncRequest
}
WorkItem is the unit of work in the BranchWorker queue. Exactly one of Request, Attach, or Resync is set.
type WorkerManager ¶
type WorkerManager struct {
Client client.Client
Log logr.Logger
// contains filtered or unexported fields
}
WorkerManager manages BranchWorkers. Creates workers per (repo, branch), shared by multiple GitDestinations. Implements controller-runtime's Runnable interface for lifecycle management.
func NewWorkerManager ¶
func NewWorkerManager( client client.Client, log logr.Logger, branchBufferMaxBytes int64, sensitiveResources types.SensitiveResourcePolicy, ) *WorkerManager
NewWorkerManager creates a new worker manager. branchBufferMaxBytes bounds each worker's combined buffer + unpushed-events memory. Pass 0 (or a negative value) to use DefaultBranchBufferMaxBytes.
func (*WorkerManager) EnsureWorker ¶
func (m *WorkerManager) EnsureWorker( _ context.Context, providerName, providerNamespace string, branch string, ) error
EnsureWorker ensures a worker exists for the given (provider, branch). Worker creation/start is protected by the manager lock.
func (*WorkerManager) GetWorkerForTarget ¶
func (m *WorkerManager) GetWorkerForTarget( providerName, providerNamespace string, branch string, ) (*BranchWorker, bool)
GetWorkerForTarget finds the worker for a target's (provider, branch). Returns the worker and true if found, nil and false otherwise. This is used by EventRouter to dispatch events to the correct worker.
func (*WorkerManager) NeedLeaderElection ¶
func (m *WorkerManager) NeedLeaderElection() bool
NeedLeaderElection ensures only the elected leader manages workers. This prevents multiple pods from managing the same workers.
func (*WorkerManager) ReconcileWorkers ¶
func (m *WorkerManager) ReconcileWorkers(ctx context.Context) error
ReconcileWorkers checks active GitTargets and cleans up orphaned workers. This ensures workers are removed when their GitTargets are deleted.
func (*WorkerManager) RegisterTarget ¶
func (m *WorkerManager) RegisterTarget( ctx context.Context, targetName, targetNamespace string, providerName, providerNamespace string, branch, path string, ) error
RegisterTarget ensures a worker exists for the target's (provider, branch) and registers the target with that worker. This is called by GitTarget controller when a target becomes Ready.
func (*WorkerManager) RenderFidelityGate ¶ added in v0.37.0
func (m *WorkerManager) RenderFidelityGate() *RenderFidelityGate
RenderFidelityGate returns the manager-wide target gate used by branch workers. The gate is safe for concurrent watch and worker access.
func (*WorkerManager) SetClusterMapper ¶ added in v0.38.0
func (m *WorkerManager) SetClusterMapper(resolver func(clusterID string) typeset.Lookup)
SetClusterMapper injects the per-source-cluster GVK->GVR resolver used by every worker's store scan when a GitTarget names a source cluster. Like SetMapper, it is called once at startup before any worker is created, so each worker created by EnsureWorker carries it.
func (*WorkerManager) SetMapper ¶
func (m *WorkerManager) SetMapper(mapper typeset.Lookup)
SetMapper injects the GVK->GVR resolver used by every worker's store scan. It is called once at startup, before any GitTarget registers a worker, so each worker created by EnsureWorker carries it.
func (*WorkerManager) SetPathRefusalReporter ¶
func (m *WorkerManager) SetPathRefusalReporter(reporter PathRefusalReporter)
SetPathRefusalReporter injects the hook every worker calls when a live write plan is refused, so the refusal reaches GitTarget status instead of being logged and dropped. Like SetMapper, it is called once at startup before any worker is created.
func (*WorkerManager) SetSSHHostKeyConfig ¶
func (m *WorkerManager) SetSSHHostKeyConfig(cfg SSHHostKeyConfig)
SetSSHHostKeyConfig injects the SSH host-key resolution config used by every worker's credential reads. Like SetMapper, it is called once at startup before any worker is created.
func (*WorkerManager) Start ¶
func (m *WorkerManager) Start(ctx context.Context) error
Start implements manager.Runnable interface. This is called by controller-runtime when the manager starts.
func (*WorkerManager) UnregisterTarget ¶
func (m *WorkerManager) UnregisterTarget( _, _ string, providerName, providerNamespace string, branch string, ) error
UnregisterTarget removes a GitTarget from its worker. Destroys the worker if it was the last target using it. This is called by GitTarget controller when a target is deleted.
type WriteRequest ¶
type WriteRequest struct {
Events []Event
CommitMessage string
CommitConfig *CommitConfig
Signer gogit.Signer
GitTargetName string
GitTargetNamespace string
BootstrapOptions pathBootstrapOptions
CommitMode CommitMode
}
WriteRequest is the unit of work queued and written by the BranchWorker.
Source Files
¶
- bootstrapped_repo_template.go
- branch_worker.go
- commit.go
- commit_executor.go
- commit_request_attach.go
- commit_request_attach_loop.go
- content_writer.go
- credentials.go
- encryption.go
- git.go
- git_atomic_push.go
- git_path_refusal.go
- git_smart_fetch.go
- helpers.go
- open_window.go
- pending_writes.go
- placement_metrics.go
- plan_flush.go
- render_fidelity_gate.go
- render_scope.go
- resync_flush.go
- signing.go
- sops_encryptor.go
- types.go
- worker_manager.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package manifestedit is an isolated proof of concept for the manifest-inventory "file-agnostic placement" feature.
|
Package manifestedit is an isolated proof of concept for the manifest-inventory "file-agnostic placement" feature. |