v1alpha3

package
v0.55.0 Latest Latest
Warning

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

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

Documentation

Overview

Package v1alpha3 contains API Schema definitions for the configbutler.ai v1alpha3 API group. +kubebuilder:object:generate=true +groupName=configbutler.ai

Index

Constants

View Source
const (
	// ApplierClaimKindFlux is a FluxClaim, which holds a Flux Kustomization.
	ApplierClaimKindFlux = "FluxClaim"
	// ApplierClaimKindArgoCD is an ArgoCDClaim, which holds an Argo CD Application.
	ApplierClaimKindArgoCD = "ArgoCDClaim"
)

The applier claim kinds GitTarget.spec.applierClaimRef can name.

View Source
const (
	// ApplierKindKustomization is a Flux Kustomization (FluxClaim.spec.kustomizationRef).
	ApplierKindKustomization = "Kustomization"
	// ApplierKindApplication is an Argo CD Application (ArgoCDClaim.spec.applicationRef).
	ApplierKindApplication = "Application"
)

The kinds of applier an applier claim holds.

View Source
const (
	CommitRequestSchemaRevision = 1
	CommitRequestSchemaFloor    = 1
)

CommitRequestSchemaRevision and CommitRequestSchemaFloor are the revision of the CommitRequest schema this operator was built with, and the oldest revision it can serve: the last line of the kind's description.

View Source
const ArgoCDClaimFinalizer = "configbutler.ai/argocd-claim"

ArgoCDClaimFinalizer is the finalizer an ArgoCDClaim carries while it holds its Application's automated sync off: from before it first switches it off until it has handed the switch back or over. Deleting the applier claim, or the last eligible GitTarget naming it, hands the switch back as status.previousSuspendState recorded it. An applier claim that never held the switch (one whose Application an ApplicationSet generated, or whose switch another field manager applies) has none.

View Source
const ConsumerNameVariable = "{consumer.name}"

ConsumerNameVariable stands, in a branch pattern that also holds ConsumerNamespaceVariable, for the consumer's name: the name of the object asking for access. The consumer picks its own name, so the name bounds nothing on its own; beside the namespace it is a naming convention.

View Source
const ConsumerNamespaceVariable = "{consumer.namespace}"

ConsumerNamespaceVariable stands, in a grant's scope or branch pattern, for the consumer's namespace: the control-cluster namespace of the object asking for access.

View Source
const DefaultArgoCDCatchUpAfter = 0

DefaultArgoCDCatchUpAfter is an ArgoCDClaim's spec.catchUpAfter when it is omitted: off.

View Source
const DefaultFluxCatchUpAfter = time.Minute

DefaultFluxCatchUpAfter is a FluxClaim's spec.catchUpAfter when it is omitted.

View Source
const FluxClaimFinalizer = "configbutler.ai/flux-claim"

FluxClaimFinalizer is the finalizer a FluxClaim carries while it holds its Kustomization suspended: from before its first adoption write until it has handed the Kustomization back or over. Deleting the applier claim, or the last eligible GitTarget naming it, suspends the Kustomization once more, waits until nothing started before that suspend is running, and then hands it back to Flux as status.previousSuspendState recorded it: spec.suspend is released, so the Kustomization is resumed, unless it was suspended before the applier claim held it, and stays so. An applier claim that never held its Kustomization has none.

View Source
const ReceiverPathPrefix = "/git-push/"

ReceiverPathPrefix is the prefix every receiver path starts with.

View Source
const ReceiverTokenKey = "token"

ReceiverTokenKey is the Secret key holding a receiver's token, the key a Flux Receiver Secret uses.

View Source
const SourceNamespaceWildcard = "*"

SourceNamespaceWildcard is the literal rules[].sourceNamespace token meaning "every source namespace the GitTarget's credential can read", compiled to ONE cluster-wide list and watch.

It kept its spelling and changed its meaning: it used to resolve live through GitTarget.spec.allowedSourceNamespaces into a concrete set. That field is gone, so the token is bounded by source-cluster RBAC alone and is refused unless the KubeProvider's grant gives sourceNamespaces "*". See docs/design/source-scope-simplification.md, which is the definition of record.

Variables

View Source
var (
	// GroupVersion is group version used to register these objects.
	GroupVersion = schema.GroupVersion{Group: "configbutler.ai", Version: "v1alpha3"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

	// AddToScheme adds the types in this group-version to the given scheme.
	AddToScheme = SchemeBuilder.AddToScheme
)

Functions

func AuditRouteHolder added in v0.54.0

func AuditRouteHolder(route string, providers []KubeProvider) (string, bool)

AuditRouteHolder returns the namespace that holds route among providers, and false when none of them carries it. A route is held by one namespace, so a provider in another namespace cannot read facts that belong to a tenant it was never admitted to:

  1. The namespace the route names, its segment before the first dot, holds it when one of its providers carries it. This is what keeps a provider's default route (<namespace>.<name>) its own, even against an older provider elsewhere that spelled it out first.
  2. Otherwise the namespace of the oldest carrier (creationTimestamp, then UID) holds it.

A provider being deleted carries nothing, so its route is free the moment it goes.

func ClusterResourceIdentityFor added in v0.54.0

func ClusterResourceIdentityFor(group, resource string) string

ClusterResourceIdentityFor is the identity of a resource in group: resource.group, or the bare resource for the core group.

func DefaultAuditRoute added in v0.54.0

func DefaultAuditRoute(provider types.NamespacedName) string

DefaultAuditRoute is the audit route of a provider that sets none: <namespace>.<name>. A namespace name has no dots, so the first segment always names the provider's own namespace, and no provider in another namespace can resolve to it by default.

func MatchBranchPattern added in v0.54.0

func MatchBranchPattern(pattern BranchPattern, consumer types.NamespacedName, branch string) bool

MatchBranchPattern reports whether branch matches pattern for the GitBranch consumer: the pattern is matched against the whole branch name, '*' matches any sequence of characters, '/' included, and '{consumer.namespace}' and '{consumer.name}' are consumer's namespace and name. Nothing else is special.

func ReceiverPath added in v0.53.0

func ReceiverPath(token []byte, namespace, name string) string

ReceiverPath is the path a GitReceiver is served on: the prefix and the hex HMAC-SHA256 of "<namespace>/<name>", keyed by the receiver token.

Types

type AgeEncryptionSpec

type AgeEncryptionSpec struct {
	// Enabled turns on age encryption: resolving recipients, and creating a key
	// when asked. Defaults to false.
	// +optional
	// +kubebuilder:default=false
	Enabled bool `json:"enabled,omitempty"`

	// Recipients says where the age recipients come from.
	// +optional
	Recipients AgeRecipientsSpec `json:"recipients,omitempty"`
}

AgeEncryptionSpec configures age recipient resolution behavior.

func (*AgeEncryptionSpec) DeepCopy

func (in *AgeEncryptionSpec) DeepCopy() *AgeEncryptionSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgeEncryptionSpec.

func (*AgeEncryptionSpec) DeepCopyInto

func (in *AgeEncryptionSpec) DeepCopyInto(out *AgeEncryptionSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AgeRecipientsSpec

type AgeRecipientsSpec struct {
	// PublicKeys is a fixed list of age recipients ("age1...").
	// +optional
	// +kubebuilder:validation:items:MinLength=1
	PublicKeys []string `json:"publicKeys,omitempty"`

	// ExtractFromSecret adds the recipient of every *.agekey entry in
	// encryption.secretRef. Defaults to false.
	// +optional
	// +kubebuilder:default=false
	ExtractFromSecret bool `json:"extractFromSecret,omitempty"`

	// GenerateWhenMissing creates a date-named *.agekey entry in
	// encryption.secretRef when it has none. Defaults to false.
	// +optional
	// +kubebuilder:default=false
	GenerateWhenMissing bool `json:"generateWhenMissing,omitempty"`
}

AgeRecipientsSpec defines age recipient source and key generation behavior.

func (*AgeRecipientsSpec) DeepCopy

func (in *AgeRecipientsSpec) DeepCopy() *AgeRecipientsSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgeRecipientsSpec.

func (*AgeRecipientsSpec) DeepCopyInto

func (in *AgeRecipientsSpec) DeepCopyInto(out *AgeRecipientsSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApplierClaim added in v0.54.0

type ApplierClaim interface {
	metav1.Object
	runtime.Object

	// ClaimKind is the applier claim's kind (ApplierClaimKind*).
	ClaimKind() string
	// KubeProviderKey is the KubeProvider whose cluster holds the applier.
	KubeProviderKey() types.NamespacedName
	// ApplierKind is the kind of applier the applier claim holds (ApplierKind*).
	ApplierKind() string
	// Applier is the object the applier claim holds, its namespace defaulted to the applier claim's own.
	Applier() types.NamespacedName
	// SourceBinding is the repository and branch the applier applies, as the applier claim last read
	// them, and false when it has not read them.
	SourceBinding() (repositoryURL, branch string, known bool)
	// SharedSource is the source object the applier reads, which other appliers may read too, and
	// false when the applier has none it shares this way or the applier claim has not read it. Appliers
	// sharing one have one operation at a time.
	SharedSource() (source types.NamespacedName, known bool)
	// CatchUpAfter is spec.catchUpAfter, or the kind's default when it is omitted: how long
	// the applier may stay behind the branch after a push of GitOps Reverser's own. Zero never
	// converges for that reason.
	CatchUpAfter() time.Duration
	// Operation is status.operation, and SetOperation replaces it and status.repairPending.
	Operation() *ApplyOperation
	RepairPending() bool
	SetOperation(operation *ApplyOperation, repairPending bool)
	// PreviousSuspendState is status.previousSuspendState, and SetPreviousSuspendState replaces it.
	PreviousSuspendState() SuspendState
	SetPreviousSuspendState(state SuspendState)
	// StatusConditions returns the condition set, and SetObservedGeneration stamps the generation.
	StatusConditions() *[]metav1.Condition
	SetObservedGeneration(generation int64)
}

ApplierClaim is what every applier claim kind answers, so the controllers, the branch workers and the dispatcher handle a FluxClaim and an ArgoCDClaim alike. +kubebuilder:object:generate=false

func NewApplierClaim added in v0.54.0

func NewApplierClaim(kind string) ApplierClaim

NewApplierClaim returns an empty applier claim of kind, or nil for a kind this release does not know.

type ApplierClaimReference added in v0.54.0

type ApplierClaimReference struct {
	// Kind is the applier claim's kind: "FluxClaim" or "ArgoCDClaim".
	// +required
	// +kubebuilder:validation:Enum=FluxClaim;ArgoCDClaim
	Kind string `json:"kind"`

	// Name is the applier claim's name.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

ApplierClaimReference names an applier claim in the GitTarget's own namespace.

func (*ApplierClaimReference) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplierClaimReference.

func (*ApplierClaimReference) DeepCopyInto added in v0.54.0

func (in *ApplierClaimReference) DeepCopyInto(out *ApplierClaimReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApplyOperation added in v0.53.0

type ApplyOperation struct {
	// Phase is where the operation stands. Requested, Running, Settling (Flux
	// only: applied, and the Kustomization not yet suspended again) and Unresolved
	// (overdue, still followed) are in flight: the applier can still revert an
	// edit to an object it applies, and is asked for nothing else. Succeeded and
	// Failed are complete; Failed may have applied part of the commit.
	// +required
	Phase ApplyOperationPhase `json:"phase"`

	// Reason is why the apply was asked for: ForeignCommit (a commit GitOps
	// Reverser did not push), Refusal (a refused edit under spec.onRefusal:
	// "Reapply"), Repair (an earlier apply reverted a newer API edit), or CatchUp
	// (adopting objects the API created, and once at startup or when a GitTarget
	// first names the claim). With several GitTargets on the claim, it is the
	// strongest of their reasons.
	// +optional
	Reason ApplyReason `json:"reason,omitempty"`

	// Commit is the commit the applier was asked to apply. Empty when the remote
	// did not carry the branch.
	// +optional
	Commit string `json:"commit,omitempty"`

	// Token identifies the request in the applier's own status: the
	// reconcile.fluxcd.io/requestedAt value on a Flux object, or the
	// "gitops-reverser request" entry in an Argo CD operation's info.
	// +optional
	Token string `json:"token,omitempty"`

	// SuspendToken is the reconcile.fluxcd.io/requestedAt value of the suspend
	// that follows the apply. Once the Kustomization reports it handled, nothing
	// started before the suspend is still running. Flux only.
	// +optional
	SuspendToken string `json:"suspendToken,omitempty"`

	// AppliedRevision is the revision the applier reports applying when the
	// operation completes. It can differ from commit when the branch moved between
	// the check and the apply.
	// +optional
	AppliedRevision string `json:"appliedRevision,omitempty"`

	// RequestedAt is when the applier was asked.
	// +required
	RequestedAt metav1.Time `json:"requestedAt"`

	// FinishedAt is when the operation was seen to complete.
	// +optional
	FinishedAt *metav1.Time `json:"finishedAt,omitempty"`

	// Message says why a Failed operation failed, or why an Unresolved one is
	// overdue.
	// +optional
	Message string `json:"message,omitempty"`
}

ApplyOperation is an apply GitOps Reverser started on the applier claim's applier: the one in flight, or the last one, once it completed. The branch worker writes it on every transition.

func (*ApplyOperation) DeepCopy added in v0.53.0

func (in *ApplyOperation) DeepCopy() *ApplyOperation

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplyOperation.

func (*ApplyOperation) DeepCopyInto added in v0.53.0

func (in *ApplyOperation) DeepCopyInto(out *ApplyOperation)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ApplyOperationPhase added in v0.53.0

type ApplyOperationPhase string

ApplyOperationPhase is where an apply operation stands. +kubebuilder:validation:Enum=Requested;Running;Settling;Unresolved;Succeeded;Failed

const (
	// ApplyOperationRequested is an operation GitOps Reverser has asked the applier for.
	ApplyOperationRequested ApplyOperationPhase = "Requested"
	// ApplyOperationRunning is an operation the applier is seen working on.
	ApplyOperationRunning ApplyOperationPhase = "Running"
	// ApplyOperationSettling is a Flux operation that has applied, and whose Kustomization is not
	// yet seen suspended again.
	ApplyOperationSettling ApplyOperationPhase = "Settling"
	// ApplyOperationUnresolved is an operation that has not completed in the time it was given. It
	// is still followed, and no timer ends it.
	ApplyOperationUnresolved ApplyOperationPhase = "Unresolved"
	// ApplyOperationSucceeded is an operation that completed and applied.
	ApplyOperationSucceeded ApplyOperationPhase = "Succeeded"
	// ApplyOperationFailed is an operation that completed without applying the commit. It may have
	// applied part of it.
	ApplyOperationFailed ApplyOperationPhase = "Failed"
)

func (ApplyOperationPhase) Completed added in v0.53.0

func (p ApplyOperationPhase) Completed() bool

Completed reports whether the phase ends its operation.

type ApplyReason added in v0.53.0

type ApplyReason string

ApplyReason is why GitOps Reverser asked an applier to apply. +kubebuilder:validation:Enum=ForeignCommit;Refusal;Repair;CatchUp

const (
	// ApplyReasonForeignCommit is a commit GitOps Reverser did not push.
	ApplyReasonForeignCommit ApplyReason = "ForeignCommit"
	// ApplyReasonRefusal is a refused edit on a target with spec.onRefusal: Reapply.
	ApplyReasonRefusal ApplyReason = "Refusal"
	// ApplyReasonRepair puts back an API edit that an earlier apply reverted on the cluster after
	// the edit was made. Git kept the edit; the cluster runs the older value until the repair.
	ApplyReasonRepair ApplyReason = "Repair"
	// ApplyReasonCatchUp adopts what the API created in the applier's folders, so the applier owns
	// and can later prune it, and converges the applier once at startup and when a GitTarget first
	// names its applier claim.
	ApplyReasonCatchUp ApplyReason = "CatchUp"
)

type ArgoCDClaim added in v0.54.0

type ArgoCDClaim struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of ArgoCDClaim.
	// +required
	Spec ArgoCDClaimSpec `json:"spec"`

	// status defines the observed state of ArgoCDClaim.
	// +optional
	Status ArgoCDClaimStatus `json:"status,omitempty,omitzero"`
}

ArgoCDClaim lets GitOps Reverser decide when an Argo CD Application syncs. The Application's automated sync stays off, and GitOps Reverser starts each sync, always after the edits pending on the branch are published. It starts one:

  • after a commit that GitOps Reverser did not push;
  • after a refused edit, on a GitTarget with spec.onRefusal "Reapply";
  • after a sync reverted an edit made through the API;
  • after objects were created through the API in its folders;
  • once at startup, and when a GitTarget first names this ArgoCDClaim;
  • once spec.catchUpAfter passed since a push of GitOps Reverser's own;
  • after a CommitRequest with spec.catchUp "AfterPush" pushed a commit.

GitTargets name it with spec.applierClaimRef.

func (*ArgoCDClaim) Applier added in v0.54.0

func (t *ArgoCDClaim) Applier() types.NamespacedName

Applier is spec.applicationRef, its namespace defaulted to the applier claim's own.

func (*ArgoCDClaim) ApplierKind added in v0.54.0

func (t *ArgoCDClaim) ApplierKind() string

ApplierKind is Application.

func (*ArgoCDClaim) CatchUpAfter added in v0.55.0

func (t *ArgoCDClaim) CatchUpAfter() time.Duration

CatchUpAfter is spec.catchUpAfter, or DefaultArgoCDCatchUpAfter when it is omitted.

func (*ArgoCDClaim) ClaimKind added in v0.54.0

func (t *ArgoCDClaim) ClaimKind() string

ClaimKind is ArgoCDClaim.

func (*ArgoCDClaim) DeepCopy added in v0.54.0

func (in *ArgoCDClaim) DeepCopy() *ArgoCDClaim

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDClaim.

func (*ArgoCDClaim) DeepCopyInto added in v0.54.0

func (in *ArgoCDClaim) DeepCopyInto(out *ArgoCDClaim)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ArgoCDClaim) DeepCopyObject added in v0.54.0

func (in *ArgoCDClaim) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*ArgoCDClaim) KubeProviderKey added in v0.54.0

func (t *ArgoCDClaim) KubeProviderKey() types.NamespacedName

KubeProviderKey is spec.kubeProviderRef, its namespace defaulted to the applier claim's own.

func (*ArgoCDClaim) Operation added in v0.54.0

func (t *ArgoCDClaim) Operation() *ApplyOperation

Operation is status.operation.

func (*ArgoCDClaim) PreviousSuspendState added in v0.54.0

func (t *ArgoCDClaim) PreviousSuspendState() SuspendState

PreviousSuspendState is status.previousSuspendState.

func (*ArgoCDClaim) RepairPending added in v0.54.0

func (t *ArgoCDClaim) RepairPending() bool

RepairPending is status.repairPending.

func (*ArgoCDClaim) SetObservedGeneration added in v0.54.0

func (t *ArgoCDClaim) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*ArgoCDClaim) SetOperation added in v0.54.0

func (t *ArgoCDClaim) SetOperation(operation *ApplyOperation, repairPending bool)

SetOperation replaces status.operation and status.repairPending.

func (*ArgoCDClaim) SetPreviousSuspendState added in v0.54.0

func (t *ArgoCDClaim) SetPreviousSuspendState(state SuspendState)

SetPreviousSuspendState replaces status.previousSuspendState.

func (*ArgoCDClaim) SharedSource added in v0.54.0

func (t *ArgoCDClaim) SharedSource() (types.NamespacedName, bool)

SharedSource is none: every sync pins its own revision, so Applications reading one repository do not disturb each other's operations.

func (*ArgoCDClaim) SourceBinding added in v0.54.0

func (t *ArgoCDClaim) SourceBinding() (string, string, bool)

SourceBinding is status.source's repoURL, and the branch its targetRevision names ("HEAD" for an empty one, which follows no branch GitOps Reverser writes).

func (*ArgoCDClaim) StatusConditions added in v0.54.0

func (t *ArgoCDClaim) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type ArgoCDClaimList added in v0.54.0

type ArgoCDClaimList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []ArgoCDClaim `json:"items"`
}

ArgoCDClaimList contains a list of ArgoCDClaim.

func (*ArgoCDClaimList) DeepCopy added in v0.54.0

func (in *ArgoCDClaimList) DeepCopy() *ArgoCDClaimList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDClaimList.

func (*ArgoCDClaimList) DeepCopyInto added in v0.54.0

func (in *ArgoCDClaimList) DeepCopyInto(out *ArgoCDClaimList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ArgoCDClaimList) DeepCopyObject added in v0.54.0

func (in *ArgoCDClaimList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ArgoCDClaimSource added in v0.54.0

type ArgoCDClaimSource struct {
	// RepoURL is the Application's spec.source.repoURL.
	// +optional
	RepoURL string `json:"repoURL,omitempty"`

	// TargetRevision is the Application's spec.source.targetRevision, as written:
	// a branch name, or refs/heads/ and the name. Empty means Argo CD's HEAD.
	// +optional
	TargetRevision string `json:"targetRevision,omitempty"`
}

ArgoCDClaimSource is the source an Application syncs.

func (*ArgoCDClaimSource) DeepCopy added in v0.54.0

func (in *ArgoCDClaimSource) DeepCopy() *ArgoCDClaimSource

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDClaimSource.

func (*ArgoCDClaimSource) DeepCopyInto added in v0.54.0

func (in *ArgoCDClaimSource) DeepCopyInto(out *ArgoCDClaimSource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ArgoCDClaimSpec added in v0.54.0

type ArgoCDClaimSpec struct {

	// KubeProviderRef names the KubeProvider of the cluster that runs the
	// Application, such as a management cluster running Argo CD. An omitted
	// namespace means this ArgoCDClaim's namespace. The KubeProvider's
	// spec.allowedApplierClaims must admit this namespace, with the Application's
	// namespace in applierNamespaces, and its identity needs get, update and patch
	// on the Application. Immutable: delete and recreate the ArgoCDClaim to change
	// it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.kubeProviderRef.name must not be empty"
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.kubeProviderRef is immutable; delete and recreate the ArgoCDClaim to hold an Application elsewhere"
	KubeProviderRef meta.NamespacedObjectReference `json:"kubeProviderRef"`

	// ApplicationRef names the Argo CD Application that syncs the folders of the
	// GitTargets naming this ArgoCDClaim. It must have a single spec.source whose
	// targetRevision names a branch.
	//
	// The ArgoCDClaim keeps its automated sync off by applying
	// spec.syncPolicy.automated.enabled: false, switches it off again when
	// somebody switches it on, and gives the switch up when it lets go;
	// automated.prune still applies to the syncs GitOps Reverser starts. An
	// Application that an ApplicationSet generates, or whose switch another field
	// manager applies, must have automated sync off already. Each sync is pinned
	// to the commit GitOps Reverser checked, and a running operation is never
	// replaced.
	//
	// An omitted namespace means this ArgoCDClaim's namespace. Immutable: delete
	// and recreate the ArgoCDClaim to change it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.applicationRef is immutable; delete and recreate the ArgoCDClaim to hold another Application"
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.applicationRef.name must not be empty"
	ApplicationRef meta.NamespacedObjectReference `json:"applicationRef"`

	// CatchUpAfter is how long the Application stays behind the branch after
	// a push of GitOps Reverser's own before a sync of the tip is asked for,
	// as a Go duration ("5m"). Such a push changes nothing on the cluster,
	// which already holds the edit, but leaves the Application's last sync at
	// the commit before it. The interval starts when the Application is first
	// seen behind, so a burst of saves costs one sync, hooks included, and one
	// at the tip costs none. The sync can still wait for startup, a retry
	// backoff or edits being published. "0s" never asks for this reason, and
	// drops a sync it asked for that has not started. Otherwise at least "10s"
	// and at most "24h". Defaults to "0s".
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="0s"
	// +kubebuilder:validation:XValidation:rule="duration(self) == duration('0s') || (duration(self) >= duration('10s') && duration(self) <= duration('24h'))",message="spec.catchUpAfter must be 0s, or a Go duration from 10s to 24h"
	CatchUpAfter *metav1.Duration `json:"catchUpAfter,omitempty"`
}

ArgoCDClaimSpec names the Argo CD Application the applier claim holds, and the cluster it is in.

func (*ArgoCDClaimSpec) DeepCopy added in v0.54.0

func (in *ArgoCDClaimSpec) DeepCopy() *ArgoCDClaimSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDClaimSpec.

func (*ArgoCDClaimSpec) DeepCopyInto added in v0.54.0

func (in *ArgoCDClaimSpec) DeepCopyInto(out *ArgoCDClaimSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ArgoCDClaimStatus added in v0.54.0

type ArgoCDClaimStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this ArgoCDClaim's state. Ready,
	// Reconciling and Stalled follow kstatus.
	//
	// Configured is True when an eligible GitTarget names this ArgoCDClaim, and
	// the Application exists, syncs a single source, has automated sync off or a
	// switch this ArgoCDClaim may hold, may be written, and no other ArgoCDClaim
	// holds it. An eligible GitTarget is in this namespace, is admitted by its
	// KubeProviders, and writes the branch the Application syncs. Of several
	// ArgoCDClaims for one Application, the one holding it already holds it, then
	// the oldest; the others are Configured=False, reason HeldByAnotherClaim.
	//
	// InControl says whether GitOps Reverser decides when the Application
	// syncs:
	//
	// - True, reason AutomatedSyncOff: automated sync is off and GitOps
	//   Reverser starts every sync, also when another field manager owns the
	//   switch and keeps it off.
	// - False, reason Releasing or Revoking: the ArgoCDClaim is handing the
	//   Application back.
	// - False, reason NotReferenced: no GitTarget names this ArgoCDClaim.
	// - False, reason NotConfigured: another field manager owns the switch and
	//   has turned automated sync on.
	// - False, reason ArgoCDVersionNotSupported: the Application has no
	//   spec.syncPolicy.automated.enabled field (Argo CD before 3.1).
	// - Unknown, reason NotConfigured: Configured is not True, or another
	//   ArgoCDClaim holds the Application.
	//
	// A failed read of the Application keeps the previous InControl value. An
	// ArgoCDClaim no GitTarget names reads nothing and is Ready=True, reason
	// NotReferenced.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Source is the Application's spec.source, as last read. It is published while
	// an eligible GitTarget names this ArgoCDClaim, and that GitTarget must write
	// the repository it syncs, on the branch its targetRevision names.
	// +optional
	Source *ArgoCDClaimSource `json:"source,omitempty"`

	// Operation is the sync GitOps Reverser started on the Application: the one in
	// flight, or the last one. Absent until the first.
	// +optional
	Operation *ApplyOperation `json:"operation,omitempty"`

	// RepairPending is true while a Repair sync is pending: a sync ran a commit
	// older than an edit made through the API and reverted it on the cluster. Git
	// holds the edit, and the cluster runs the older value until the next sync.
	// +optional
	RepairPending bool `json:"repairPending,omitempty"`

	// PreviousSuspendState is how the Application stood before this ArgoCDClaim
	// first switched its automated sync off, and what handing it back restores:
	// NotSuspended (automated sync on) or Suspended (off). It is cleared once the
	// Application is handed back. Absent, handing it back leaves what the
	// Application's own spec says. A switch that an ApplicationSet or another
	// field manager owns keeps that owner's value either way.
	// +optional
	PreviousSuspendState SuspendState `json:"previousSuspendState,omitempty"`
}

ArgoCDClaimStatus is what the applier claim knows about its Application, and the sync it started.

func (*ArgoCDClaimStatus) DeepCopy added in v0.54.0

func (in *ArgoCDClaimStatus) DeepCopy() *ArgoCDClaimStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDClaimStatus.

func (*ArgoCDClaimStatus) DeepCopyInto added in v0.54.0

func (in *ArgoCDClaimStatus) DeepCopyInto(out *ArgoCDClaimStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type AttachPolicy added in v0.51.0

type AttachPolicy string

AttachPolicy selects the commit window a CommitRequest attaches to.

const (
	// AttachCurrentOrNext attaches to the author's window if one is open when the worker
	// registers the request, and otherwise to the next one a write opens.
	AttachCurrentOrNext AttachPolicy = "CurrentOrNext"
	// AttachNext closes the author's open window, under its own message, and attaches to the
	// next one a write opens. It separates work the worker already collected from work that
	// reaches it afterward; it cannot prove a write was made after the request.
	AttachNext AttachPolicy = "Next"
)

type BranchPattern added in v0.54.0

type BranchPattern string

BranchPattern matches a whole branch name: literal text, "*" for any characters including "/", and "{consumer.namespace}" and "{consumer.name}" as whole path segments. "{consumer.name}" needs "{consumer.namespace}" in the same pattern. +kubebuilder:validation:MinLength=1 +kubebuilder:validation:MaxLength=255 +kubebuilder:validation:Pattern=`^[^\s~^:?\[\\]*$` +kubebuilder:validation:XValidation:rule="!self.replace('{consumer.namespace}', 'x').replace('{consumer.name}', 'x').matches('[{][^{}]*[}]')",messageExpression="'branch pattern ' + self + ' references unknown variable ' + self.replace('{consumer.namespace}', 'x').replace('{consumer.name}', 'x').find('[{][^{}]*[}]') + '; the variables are {consumer.namespace} and {consumer.name}'" +kubebuilder:validation:XValidation:rule="self.replace('{consumer.namespace}', 'x').replace('{consumer.name}', 'x').matches('[{][^{}]*[}]') || !self.replace('{consumer.namespace}', 'x').replace('{consumer.name}', 'x').matches('[{}]')",messageExpression="'branch pattern ' + self + ' has an unmatched brace; the variables are {consumer.namespace} and {consumer.name}'" +kubebuilder:validation:XValidation:rule="!self.matches('[^/][{]consumer[.]name(space)?[}]') && !self.matches('[{]consumer[.]name(space)?[}][^/]')",messageExpression="'branch pattern ' + self + ': {consumer.namespace} and {consumer.name} must each be a whole path segment, at the start or after a /, and at the end or before a /'" +kubebuilder:validation:XValidation:rule="!self.contains('{consumer.name}') || self.contains('{consumer.namespace}')",messageExpression="'branch pattern ' + self + ': {consumer.name} needs {consumer.namespace} in the same pattern; the consumer picks its own name, so on its own it would let any admitted namespace claim any branch the pattern leaves open'" +kubebuilder:validation:XValidation:rule="!self.contains('..') && !self.contains('@{') && !self.startsWith('/') && !self.endsWith('/') && !self.contains('//')",messageExpression="'branch pattern ' + self + ' can match no branch name: git refuses .., @{, a leading or trailing / and //'"

type CatchUpPolicy added in v0.55.0

type CatchUpPolicy string

CatchUpPolicy is when a CommitRequest's commit is applied by the GitTarget's applier.

const (
	// CatchUpAsDefinedOnClaim leaves the apply to the applier claim's spec.catchUpAfter.
	CatchUpAsDefinedOnClaim CatchUpPolicy = "AsDefinedOnClaim"
	// CatchUpAfterPush asks the applier to apply the tip right after the commit is pushed.
	CatchUpAfterPush CatchUpPolicy = "AfterPush"
)

type ClusterResourceIdentity added in v0.54.0

type ClusterResourceIdentity string

ClusterResourceIdentity is a cluster-scoped resource type: resource.group, a bare resource for the core group, or "*" for every type. +kubebuilder:validation:MaxLength=317 +kubebuilder:validation:Pattern=`^(\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$`

type ClusterResourceRule

type ClusterResourceRule struct {
	// APIGroups are the API groups to match: "" is the core group, and "*" is
	// every group, as in ["rbac.authorization.k8s.io"] or ["*"]. Omitted, each
	// resource name is looked up across the served groups and must be served by
	// exactly one.
	// +optional
	APIGroups []string `json:"apiGroups,omitempty"`

	// APIVersions are the versions to match, or "*" for every served version.
	// Omitted, each resource's preferred version is used.
	// +optional
	APIVersions []string `json:"apiVersions,omitempty"`

	// Resources are the resource types to match, by plural name ("nodes",
	// "clusterroles"), or "*" for every type. Matching is exact and
	// case-insensitive; partial wildcards such as "cluster*" match nothing, and
	// subresources ("nodes/status") are rejected.
	// +required
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:Pattern=`^[^/]*$`
	Resources []string `json:"resources"`

	// ObjectSelector mirrors only the objects whose labels match, as a
	// standard label selector. Omitted or {} selects every object.
	//
	// An object that stops matching is handled like a deleted one: the
	// GitTarget's spec.prune.mode decides whether its document is removed.
	// With prune mode "Always", a resync also removes documents of the type
	// that the selector does not match.
	//
	// Two rules on one GitTarget that select the same type must use the same
	// selector. The older rule keeps the type, and the newer one is refused
	// with ResourcesResolved=False, reason CollectionOverlap. A selector that
	// does not parse refuses the whole rule with ResourcesResolved=False,
	// reason InvalidObjectSelector.
	// +optional
	ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty"`
}

ClusterResourceRule selects cluster-scoped resources by type, and optionally by API group, version and label.

func (*ClusterResourceRule) DeepCopy

func (in *ClusterResourceRule) DeepCopy() *ClusterResourceRule

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceRule.

func (*ClusterResourceRule) DeepCopyInto

func (in *ClusterResourceRule) DeepCopyInto(out *ClusterResourceRule)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ClusterWatchRule

type ClusterWatchRule struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of ClusterWatchRule.
	// +required
	Spec ClusterWatchRuleSpec `json:"spec"`

	// status defines the observed state of ClusterWatchRule.
	// +optional
	Status ClusterWatchRuleStatus `json:"status,omitempty"`
}

ClusterWatchRule selects cluster-scoped resources, such as Nodes, ClusterRoles and CRDs, for a GitTarget to mirror. The KubeProvider's grant admitting that GitTarget must list each type in clusterResources. Use a WatchRule for namespaced resources.

func (*ClusterWatchRule) DeepCopy

func (in *ClusterWatchRule) DeepCopy() *ClusterWatchRule

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWatchRule.

func (*ClusterWatchRule) DeepCopyInto

func (in *ClusterWatchRule) DeepCopyInto(out *ClusterWatchRule)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ClusterWatchRule) DeepCopyObject

func (in *ClusterWatchRule) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*ClusterWatchRule) SetObservedGeneration added in v0.44.0

func (r *ClusterWatchRule) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*ClusterWatchRule) StatusConditions added in v0.44.0

func (r *ClusterWatchRule) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type ClusterWatchRuleList

type ClusterWatchRuleList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []ClusterWatchRule `json:"items"`
}

ClusterWatchRuleList contains a list of ClusterWatchRule.

func (*ClusterWatchRuleList) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWatchRuleList.

func (*ClusterWatchRuleList) DeepCopyInto

func (in *ClusterWatchRuleList) DeepCopyInto(out *ClusterWatchRuleList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ClusterWatchRuleList) DeepCopyObject

func (in *ClusterWatchRuleList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type ClusterWatchRuleSpec

type ClusterWatchRuleSpec struct {
	// GitTargetRef names the GitTarget that mirrors what this ClusterWatchRule
	// selects. The namespace is required, because a ClusterWatchRule has none to
	// default to.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
	// +kubebuilder:validation:XValidation:rule="has(self.namespace) && self.namespace != ”",message="spec.gitTargetRef.namespace is required: a ClusterWatchRule has no namespace to default to"
	GitTargetRef meta.NamespacedObjectReference `json:"gitTargetRef"`

	// Rules select the cluster-scoped resources to mirror. A resource matching any
	// rule is mirrored. A rule that resolves to no cluster-scoped type mirrors
	// nothing; use a WatchRule for namespaced resources.
	// +required
	// +kubebuilder:validation:MinItems=1
	Rules []ClusterResourceRule `json:"rules"`
}

ClusterWatchRuleSpec defines the desired state of ClusterWatchRule.

func (*ClusterWatchRuleSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWatchRuleSpec.

func (*ClusterWatchRuleSpec) DeepCopyInto

func (in *ClusterWatchRuleSpec) DeepCopyInto(out *ClusterWatchRuleSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ClusterWatchRuleSpec) ObjectSelectors added in v0.50.0

func (s *ClusterWatchRuleSpec) ObjectSelectors() []*metav1.LabelSelector

ObjectSelectors returns every rule item's objectSelector, index-aligned with Rules.

type ClusterWatchRuleStatus

type ClusterWatchRuleStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this ClusterWatchRule's state.
	// Ready, Reconciling and Stalled follow kstatus; ResourcesResolved and
	// StreamsRunning say which check holds the rule back.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Streams counts the types this ClusterWatchRule resolves, by watch state.
	// +optional
	Streams *StreamsStatus `json:"streams,omitempty"`
}

ClusterWatchRuleStatus defines the observed state of ClusterWatchRule.

func (*ClusterWatchRuleStatus) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWatchRuleStatus.

func (*ClusterWatchRuleStatus) DeepCopyInto

func (in *ClusterWatchRuleStatus) DeepCopyInto(out *ClusterWatchRuleStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitMessageSpec

type CommitMessageSpec struct {
	// LiveTemplate is the Go template for the message of a commit made from
	// live edits, whatever its size. Omitted, a built-in template is used.
	//
	// The template receives:
	//
	// - Author: the username, which may be empty.
	// - GitTarget: the GitTarget's name.
	// - Count: the number of edits after coalescing, before comparing with Git.
	// - Operations: the number of edits per operation.
	// - Resources: one entry per resource in the commit.
	// - LabelValues "key": the distinct values of one label across Resources.
	// - LabelValue "key": the value of one label that every resource shares,
	//   or empty when they differ.
	//
	// Each resource has Operation, Group, Version, Resource, Kind, Namespace,
	// Name, APIVersion, ResourceVersion, Generation and Labels. Namespace is
	// "_cluster" for a cluster-scoped resource. Read one label with
	// {{.Label "key"}}; {{.Labels.key}} fails the commit for a resource without
	// that label. Kind and Labels are empty for a deletion, ResourceVersion
	// can be empty, and Generation is 0 for a kind without a spec, so guard
	// them with {{with}}.
	//
	// A CommitRequest's message replaces this template without changing the
	// author; spec.commit.message.requestTemplate can wrap that message.
	// +optional
	LiveTemplate string `json:"liveTemplate,omitempty"`

	// RequestTemplate is the Go template that frames a CommitRequest's message. It
	// is used only for a commit whose CommitRequest supplied a message, and gets
	// liveTemplate's fields plus RequestMessage, the message as written; template
	// syntax inside the message stays literal. Omitted, the message is committed
	// as written. A template that never renders RequestMessage is rejected, and
	// one that fails at commit time commits the message as written.
	// +optional
	RequestTemplate string `json:"requestTemplate,omitempty"`

	// ReconcileTemplate is the Go template for the message of a snapshot or resync
	// commit. Fields: Count, GitTarget, Group, Version, Resource, APIVersion,
	// Namespace and ResourceVersion (the list's, not one object's). The type and
	// namespace fields are empty for a snapshot of the whole folder, and
	// ResourceVersion can be empty, so guard them. A template naming Revision,
	// renamed to ResourceVersion, is rejected.
	// +optional
	ReconcileTemplate string `json:"reconcileTemplate,omitempty"`
}

CommitMessageSpec configures commit message formatting, on GitTarget.spec.commit.message.

func (*CommitMessageSpec) DeepCopy

func (in *CommitMessageSpec) DeepCopy() *CommitMessageSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitMessageSpec.

func (*CommitMessageSpec) DeepCopyInto

func (in *CommitMessageSpec) DeepCopyInto(out *CommitMessageSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitRequest

type CommitRequest struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of CommitRequest. It is immutable after
	// creation.
	// +required
	Spec CommitRequestSpec `json:"spec"`

	// status defines the observed state of CommitRequest.
	// +optional
	Status CommitRequestStatus `json:"status,omitempty,omitzero"`
}

CommitRequest asks for a save: it attaches to its author's current or next commit window on a GitTarget, closes that window on its own timers, and gives the commit its message. Create it on the cluster GitOps Reverser runs in, or on a source cluster whose KubeProvider sets spec.commitRequests. Its spec is immutable, and status.commit reports the commit once it is on the remote.

Schema revision 1, compatible from revision 1.

func (*CommitRequest) DeepCopy

func (in *CommitRequest) DeepCopy() *CommitRequest

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitRequest.

func (*CommitRequest) DeepCopyInto

func (in *CommitRequest) DeepCopyInto(out *CommitRequest)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*CommitRequest) DeepCopyObject

func (in *CommitRequest) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*CommitRequest) GitTargetKey added in v0.55.0

func (s *CommitRequest) GitTargetKey() types.NamespacedName

GitTargetKey is the GitTarget spec.gitTargetRef names: in the request's namespace unless the ref names another.

type CommitRequestList

type CommitRequestList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []CommitRequest `json:"items"`
}

CommitRequestList contains a list of CommitRequest.

func (*CommitRequestList) DeepCopy

func (in *CommitRequestList) DeepCopy() *CommitRequestList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitRequestList.

func (*CommitRequestList) DeepCopyInto

func (in *CommitRequestList) DeepCopyInto(out *CommitRequestList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*CommitRequestList) DeepCopyObject

func (in *CommitRequestList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type CommitRequestSpec

type CommitRequestSpec struct {
	// GitTargetRef names the GitTarget whose commit window this request
	// attaches to: in this namespace, or namespace names another. The
	// GitTarget's spec.allowedCommitRequests must admit this namespace, or the
	// request fails with reason "NotAllowed".
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
	GitTargetRef meta.NamespacedObjectReference `json:"gitTargetRef"`

	// Message is the commit message this request asks for. Omitted, the
	// GitTarget's spec.commit.message.liveTemplate words the commit.
	//
	// The text is never evaluated as a template. If the GitTarget sets
	// spec.commit.message.requestTemplate, that template wraps this text;
	// otherwise the text is committed as written.
	//
	// It is 1–1024 characters and must contain a non-whitespace character.
	// Newlines are allowed, for a subject and body; tabs and other control
	// characters are rejected.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	// +kubebuilder:validation:Pattern=`^[^\x00-\x09\x0B-\x1F\x7F]*$`
	// +kubebuilder:validation:XValidation:rule="self.matches(r'[^\\s\\x{0085}\\x{00A0}\\x{1680}\\x{2000}-\\x{200A}\\x{2028}\\x{2029}\\x{202F}\\x{205F}\\x{3000}]')",message="message must contain a non-whitespace character"
	Message string `json:"message,omitempty"`

	// Window says which commit window this request attaches to, how long it waits
	// for one, and the timers that close the window once it has. They replace the
	// GitTarget's timers for that window. A request never opens a window: only a
	// write does. Omitted, the request attaches to the author's current or next
	// window within 5s and closes it 2s later.
	// +optional
	// +kubebuilder:default={attach: "CurrentOrNext", attachTimeout: "5s", maxDuration: "2s"}
	Window *CommitRequestWindow `json:"window,omitempty"`

	// WhenNothingToCommit decides what happens when the request ends with nothing
	// to commit: attachTimeout ran out with no window, or the window closed
	// without changing Git. "Resolve" finishes without a commit; "CommitEmpty"
	// records spec.message in an empty commit. The Ready reason says which case
	// happened. A window that belonged to another author never gets an empty
	// commit, and a request on a GitTarget that may not be written (suspended, or
	// render fidelity not established) fails either way. Defaults to "Resolve".
	// +optional
	// +kubebuilder:validation:Enum=Resolve;CommitEmpty
	// +kubebuilder:default=Resolve
	WhenNothingToCommit NothingToCommitAction `json:"whenNothingToCommit,omitempty"`

	// CatchUp decides when the GitTarget's applier is asked to apply the branch
	// after this request pushes a commit. "AsDefinedOnClaim" leaves it to the
	// applier claim's spec.catchUpAfter. "AfterPush" asks right after the push.
	// The apply takes the latest branch tip, which may hold later commits, and
	// saves pushed close together can share one apply; the Applied condition
	// reports how it went. The cluster already holds the saved objects:
	// the apply brings the applier's own state, such as a Kustomization's
	// status.lastAppliedRevision, to the tip. Defaults to "AsDefinedOnClaim".
	// +optional
	// +kubebuilder:validation:Enum=AsDefinedOnClaim;AfterPush
	// +kubebuilder:default=AsDefinedOnClaim
	CatchUp CatchUpPolicy `json:"catchUp,omitempty"`
}

CommitRequestSpec defines the desired state of CommitRequest. The spec is immutable after creation: a CEL validation rule rejects any update that changes it, so a delayed audit event always acts on the spec the object was created with.

Immutability is field-by-field rather than `self == oldSelf`, and the reason is the one thing to remember when adding a field here: ADD IT TO THIS RULE TOO, or it becomes quietly mutable.

A whole-object comparison compares a duration as a STRING, and a duration does not round-trip as one: a request created with "1m" reads into Go as a time.Duration and serializes back as "1m0s", so every typed update — including one that only touches metadata — was rejected as a spec change. CommitRequestWindow compares its durations as durations, which compares what the fields mean instead of how they were spelled. +kubebuilder:validation:XValidation:rule="self.gitTargetRef == oldSelf.gitTargetRef && has(self.message) == has(oldSelf.message) && (!has(self.message) || self.message == oldSelf.message) && has(self.window) == has(oldSelf.window) && has(self.whenNothingToCommit) == has(oldSelf.whenNothingToCommit) && (!has(self.whenNothingToCommit) || self.whenNothingToCommit == oldSelf.whenNothingToCommit) && has(self.catchUp) == has(oldSelf.catchUp) && (!has(self.catchUp) || self.catchUp == oldSelf.catchUp)",message="CommitRequest spec is immutable after creation" +kubebuilder:validation:XValidation:rule="!has(self.whenNothingToCommit) || self.whenNothingToCommit != 'CommitEmpty' || has(self.message)",message="whenNothingToCommit: CommitEmpty requires spec.message, because a message is all an empty commit records"

func (*CommitRequestSpec) DeepCopy

func (in *CommitRequestSpec) DeepCopy() *CommitRequestSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitRequestSpec.

func (*CommitRequestSpec) DeepCopyInto

func (in *CommitRequestSpec) DeepCopyInto(out *CommitRequestSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitRequestStatus

type CommitRequestStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Author is who created this request, as the audit events of the cluster
	// it was created on name them. Empty when they name nobody, or when author
	// attribution is off: then the request saves only writes that name nobody
	// either.
	// +optional
	Author string `json:"author,omitempty"`

	// Conditions are the latest observations of this CommitRequest's state.
	// Reconciling and Stalled follow kstatus.
	//
	// Three conditions say how far the save got:
	//
	// - Ready (kstatus): Unknown while the save runs. True once the request
	//   ended without error, with a pushed commit or with nothing to save; it
	//   never waits for an apply. False when it failed: reason NotAllowed,
	//   GitTargetNotFound, SaveInProgress or FinalizeFailed.
	// - Pushed: True once the commit is on the remote.
	// - Applied: set only with spec.catchUp "AfterPush", once Ready is True.
	//
	// Applied says whether the cluster's applier caught up with the commit:
	//
	// - Unknown, reason Applying or Retrying: the apply runs, or did not
	//   complete and is asked again; the message says why.
	// - True, reason Applied: the applier applied a revision that holds the
	//   commit, named in status.appliedRevision.
	// - True, reason NothingToApply, NoApplierClaim or ApplierGone: no apply
	//   was needed. The request pushed no commit, or the GitTarget names no
	//   applier claim, or stopped naming the one asked; the cluster already
	//   holds the saved objects.
	// - False, reason CommitDropped: the branch no longer holds the commit;
	//   its history was rewritten after the push. Only this is False.
	// - Unknown, reason TimedOut: the apply did not settle within 10 minutes
	//   of Ready, so the request stopped following it. The commit stays
	//   pushed; the message says where the apply last stood.
	// - Unknown, reason Lost: GitOps Reverser restarted before it knew.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// GitTargetUID is the UID of the GitTarget whose spec.allowedCommitRequests
	// admitted this request. A GitTarget with another UID, such as one created
	// after the request under the same name, must admit it again.
	// +optional
	GitTargetUID string `json:"gitTargetUID,omitempty"`

	// Branch is the branch the commit is made on. Set once the request ends.
	// +optional
	Branch string `json:"branch,omitempty"`

	// Commit is the commit hash. Set once the commit is pushed (Pushed=True).
	// +optional
	Commit string `json:"commit,omitempty"`

	// AppliedRevision is the revision the GitTarget's applier reported applying
	// for this request, as in a Kustomization's status.lastAppliedRevision. It
	// holds the request's commit, and may be a later one. Set once Applied is
	// True with reason Applied.
	// +optional
	AppliedRevision string `json:"appliedRevision,omitempty"`
}

CommitRequestStatus defines the observed state of CommitRequest. Progress and outcome are reported entirely through conditions (kstatus-compatible), so the object carries no lifecycle phase string:

  • Ready (summary): True once the request reached a terminal outcome that is not an error — a pushed commit, or a benign no-commit (nothing to save, already present, or a foreign open window). Unknown while in progress, from the first status write, which records the author. False when it failed.
  • Reconciling / Stalled: the kstatus progress / blocked pair. Reconciling=True while finalizing; Stalled=True when the finalize failed and needs attention.
  • Pushed (domain): True once the commit is in the remote repository.
  • Applied (domain): with spec.catchUp "AfterPush", whether the applier caught up with the commit. It never affects Ready.

func (*CommitRequestStatus) DeepCopy

func (in *CommitRequestStatus) DeepCopy() *CommitRequestStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitRequestStatus.

func (*CommitRequestStatus) DeepCopyInto

func (in *CommitRequestStatus) DeepCopyInto(out *CommitRequestStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitRequestWindow added in v0.51.0

type CommitRequestWindow struct {
	// Attach selects the window. "CurrentOrNext" attaches to the author's open
	// window, or to the next one a write opens. "Next" closes the author's open
	// window under its own message first, and attaches to the next one; it
	// separates earlier writes from later ones, but cannot prove a write was made
	// after the request. Defaults to "CurrentOrNext".
	// +optional
	// +kubebuilder:validation:Enum=CurrentOrNext;Next
	// +kubebuilder:default=CurrentOrNext
	Attach AttachPolicy `json:"attach,omitempty"`

	// AttachTimeout is how long the request waits for a window, as a Go duration,
	// from when GitOps Reverser picks the request up, which is after its own
	// author was found. "0s" attaches only to a window already open. A request
	// whose wait ran out never takes a later window. At most "5m". Defaults to
	// "5s", which covers a write's wait for its audit event.
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="5s"
	// +kubebuilder:validation:XValidation:rule="duration(self) <= duration('5m')",message="spec.window.attachTimeout must not exceed 5m"
	AttachTimeout *metav1.Duration `json:"attachTimeout,omitempty"`

	// IdleTimeout closes the attached window this long after its last write, as a
	// Go duration. Omitted, only maxDuration closes it. At most "5m", and not more
	// than maxDuration.
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:validation:XValidation:rule="duration(self) <= duration('5m')",message="spec.window.idleTimeout must not exceed 5m"
	IdleTimeout *metav1.Duration `json:"idleTimeout,omitempty"`

	// MaxDuration closes the attached window this long after the request attached,
	// however many writes keep arriving, as a Go duration. "0s" commits right
	// after attaching. At most "5m". Defaults to "2s".
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="2s"
	// +kubebuilder:validation:XValidation:rule="duration(self) <= duration('5m')",message="spec.window.maxDuration must not exceed 5m"
	MaxDuration *metav1.Duration `json:"maxDuration,omitempty"`
}

CommitRequestWindow is how a CommitRequest attaches to a commit window and when that window closes. A window is only ever opened by a write; a request waits for one and never opens one.

Every duration shares the shape GitTargetCommitSpec documents: a Go duration string behind a pattern and a CEL bound. The immutability rule compares them as durations, for the reason CommitRequestSpec gives. +kubebuilder:validation:XValidation:rule="self.attach == oldSelf.attach && duration(self.attachTimeout) == duration(oldSelf.attachTimeout) && duration(self.maxDuration) == duration(oldSelf.maxDuration) && has(self.idleTimeout) == has(oldSelf.idleTimeout) && (!has(self.idleTimeout) || duration(self.idleTimeout) == duration(oldSelf.idleTimeout))",message="CommitRequest spec is immutable after creation" +kubebuilder:validation:XValidation:rule="!has(self.idleTimeout) || duration(self.idleTimeout) <= duration(self.maxDuration)",message="spec.window.idleTimeout must not exceed maxDuration" +kubebuilder:validation:XValidation:rule="self.attach != 'Next' || duration(self.attachTimeout) > duration('0s')",message="attach: Next needs a positive attachTimeout; with 0s it would close the author's window and give up in the same instant"

func (*CommitRequestWindow) DeepCopy added in v0.51.0

func (in *CommitRequestWindow) DeepCopy() *CommitRequestWindow

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitRequestWindow.

func (*CommitRequestWindow) DeepCopyInto added in v0.51.0

func (in *CommitRequestWindow) DeepCopyInto(out *CommitRequestWindow)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitRequestsPolicy added in v0.55.0

type CommitRequestsPolicy string

CommitRequestsPolicy is whether a KubeProvider's CommitRequests are served, and whether finished ones are deleted.

const (
	// CommitRequestsIgnore leaves the cluster's CommitRequests alone.
	CommitRequestsIgnore CommitRequestsPolicy = "Ignore"
	// CommitRequestsReconcile serves the cluster's CommitRequests and keeps finished ones.
	CommitRequestsReconcile CommitRequestsPolicy = "Reconcile"
	// CommitRequestsReconcileAndDeleteFinished serves them and deletes finished ones.
	CommitRequestsReconcileAndDeleteFinished CommitRequestsPolicy = "ReconcileAndDeleteFinished"
)

type CommitSigningSpec

type CommitSigningSpec struct {
	// SecretRef names the Secret, in this namespace, that holds the SSH signing
	// key.
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="commit.signing.secretRef.name must not be empty"
	SecretRef meta.LocalObjectReference `json:"secretRef"`

	// GenerateWhenMissing creates a signing key in the Secret when it holds none.
	// Defaults to false.
	// +optional
	// +kubebuilder:default=false
	GenerateWhenMissing bool `json:"generateWhenMissing,omitempty"`
}

CommitSigningSpec configures commit signing.

func (*CommitSigningSpec) DeepCopy

func (in *CommitSigningSpec) DeepCopy() *CommitSigningSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitSigningSpec.

func (*CommitSigningSpec) DeepCopyInto

func (in *CommitSigningSpec) DeepCopyInto(out *CommitSigningSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitSpec

type CommitSpec struct {
	// Committer is the identity written as each commit's committer. With signing
	// enabled, its email must be a verified address of the account that owns the
	// signing key.
	// +optional
	Committer *CommitterSpec `json:"committer,omitempty"`

	// Signing configures SSH commit signing.
	// +optional
	Signing *CommitSigningSpec `json:"signing,omitempty"`
}

CommitSpec configures the commit identity and signing a GitProvider uses. Message formatting lives on the GitTarget (spec.commit.message), because it describes the folder rather than the connection.

func (*CommitSpec) DeepCopy

func (in *CommitSpec) DeepCopy() *CommitSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitSpec.

func (*CommitSpec) DeepCopyInto

func (in *CommitSpec) DeepCopyInto(out *CommitSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitWindow added in v0.51.0

type CommitWindow struct {
	// IdleTimeout closes the window this long after its last write, as a Go
	// duration ("5s", "750ms"). "0s" makes one commit per write. At most "24h".
	// Defaults to "5s".
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="5s"
	// +kubebuilder:validation:XValidation:rule="duration(self) <= duration('24h')",message="spec.commit.window.idleTimeout must be a Go duration of at most 24h"
	IdleTimeout *metav1.Duration `json:"idleTimeout,omitempty"`

	// MaxDuration closes the window this long after it opened, however many writes
	// keep arriving, as a Go duration ("1m", "90s"). "0s" closes it right after
	// the write that opened it. At most "24h". Defaults to "1m".
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="1m"
	// +kubebuilder:validation:XValidation:rule="duration(self) <= duration('24h')",message="spec.commit.window.maxDuration must be a Go duration of at most 24h"
	MaxDuration *metav1.Duration `json:"maxDuration,omitempty"`
}

CommitWindow holds the two timers that close a GitTarget's commit windows. A change to them applies to windows that open afterward; a window already open keeps the timers it opened with. +kubebuilder:validation:XValidation:rule="!has(self.idleTimeout) || !has(self.maxDuration) || duration(self.idleTimeout) <= duration(self.maxDuration)",message="spec.commit.window.idleTimeout must not exceed maxDuration"

func (*CommitWindow) DeepCopy added in v0.51.0

func (in *CommitWindow) DeepCopy() *CommitWindow

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitWindow.

func (*CommitWindow) DeepCopyInto added in v0.51.0

func (in *CommitWindow) DeepCopyInto(out *CommitWindow)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type CommitterSpec

type CommitterSpec struct {
	// Name is the committer name. Defaults to "GitOps Reverser".
	// +optional
	// +kubebuilder:default="GitOps Reverser"
	Name string `json:"name,omitempty"`

	// Email is the committer email. Defaults to "noreply@configbutler.ai".
	// +optional
	// +kubebuilder:default="noreply@configbutler.ai"
	Email string `json:"email,omitempty"`
}

CommitterSpec configures the bot identity used as the commit committer.

func (*CommitterSpec) DeepCopy

func (in *CommitterSpec) DeepCopy() *CommitterSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitterSpec.

func (*CommitterSpec) DeepCopyInto

func (in *CommitterSpec) DeepCopyInto(out *CommitterSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type ConsumerNamespaces added in v0.54.0

type ConsumerNamespaces struct {
	// From selects which namespaces this grant allows consumers from:
	//
	// - "Same": the namespace of the object that holds the grant.
	// - "Names": the namespaces listed in names.
	// - "Selector": the namespaces whose labels match selector.
	// - "All": every namespace.
	// +required
	From GrantFrom `json:"from"`

	// Names are the namespaces allowed with from: "Names", by exact name.
	// +optional
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	Names []GrantNamespace `json:"names,omitempty"`

	// Selector matches the labels of the namespaces allowed with from:
	// "Selector". It must not be empty: to allow every namespace, use from:
	// "All".
	// +optional
	Selector *metav1.LabelSelector `json:"selector,omitempty"`
}

ConsumerNamespaces says which control-cluster namespaces a grant admits consumers from, for the act the list holding the grant names. +kubebuilder:validation:XValidation:rule="self.from != 'Names' || has(self.names)",message="from: Names needs names" +kubebuilder:validation:XValidation:rule="!has(self.names) || self.from == 'Names'",message="names goes only with from: Names" +kubebuilder:validation:XValidation:rule="self.from != 'Selector' || has(self.selector)",message="from: Selector needs a selector; to admit every namespace, use from: All" +kubebuilder:validation:XValidation:rule="!has(self.selector) || self.from == 'Selector'",message="selector goes only with from: Selector" +kubebuilder:validation:XValidation:rule="!has(self.selector) || (has(self.selector.matchLabels) && size(self.selector.matchLabels) > 0) || (has(self.selector.matchExpressions) && size(self.selector.matchExpressions) > 0)",message="selector: {} is refused; to admit every namespace, use from: All"

func (*ConsumerNamespaces) Admits added in v0.54.0

func (g *ConsumerNamespaces) Admits(holderNamespace, namespace string, nsLabels map[string]string) (bool, error)

Admits reports whether this grant, held by an object in holderNamespace, admits a referring object in namespace, by the labels that namespace carries in the control cluster. A selector that does not convert is an error, never a silent allow; an unknown from admits nothing.

func (*ConsumerNamespaces) DeepCopy added in v0.54.0

func (in *ConsumerNamespaces) DeepCopy() *ConsumerNamespaces

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsumerNamespaces.

func (*ConsumerNamespaces) DeepCopyInto added in v0.54.0

func (in *ConsumerNamespaces) DeepCopyInto(out *ConsumerNamespaces)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ConsumerNamespaces) Describe added in v0.54.0

func (g *ConsumerNamespaces) Describe(holderNamespace string) string

Describe names the namespaces this grant admits, for a refusal message.

type EncryptionSpec

type EncryptionSpec struct {
	// Provider is the encryption tool. Only "sops" is supported. Defaults to
	// "sops".
	// +kubebuilder:default=sops
	// +kubebuilder:validation:Enum=sops
	Provider string `json:"provider"`

	// SecretRef names the Secret, in this namespace, that holds the provider's
	// keys.
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="encryption.secretRef.name must not be empty"
	// +optional
	SecretRef meta.LocalObjectReference `json:"secretRef,omitempty"`

	// Age configures age recipients for SOPS.
	// +optional
	Age *AgeEncryptionSpec `json:"age,omitempty"`
}

EncryptionSpec configures Secret encryption behavior for git writes.

func (*EncryptionSpec) DeepCopy

func (in *EncryptionSpec) DeepCopy() *EncryptionSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EncryptionSpec.

func (*EncryptionSpec) DeepCopyInto

func (in *EncryptionSpec) DeepCopyInto(out *EncryptionSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type FluxClaim added in v0.54.0

type FluxClaim struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of FluxClaim.
	// +required
	Spec FluxClaimSpec `json:"spec"`

	// status defines the observed state of FluxClaim.
	// +optional
	Status FluxClaimStatus `json:"status,omitempty,omitzero"`
}

FluxClaim lets GitOps Reverser decide when a Flux Kustomization applies. The Kustomization stays suspended, and GitOps Reverser resumes it for each apply it starts, always after the edits pending on the branch are published. It starts one:

  • after a commit that GitOps Reverser did not push;
  • after a refused edit, on a GitTarget with spec.onRefusal "Reapply";
  • after an apply reverted an edit made through the API;
  • after objects were created through the API in its folders;
  • once at startup, and when a GitTarget first names this FluxClaim;
  • once spec.catchUpAfter passed since a push of GitOps Reverser's own;
  • after a CommitRequest with spec.catchUp "AfterPush" pushed a commit.

GitTargets name it with spec.applierClaimRef.

func (*FluxClaim) Applier added in v0.54.0

func (t *FluxClaim) Applier() types.NamespacedName

Applier is spec.kustomizationRef, its namespace defaulted to the applier claim's own.

func (*FluxClaim) ApplierKind added in v0.54.0

func (t *FluxClaim) ApplierKind() string

ApplierKind is Kustomization.

func (*FluxClaim) CatchUpAfter added in v0.55.0

func (t *FluxClaim) CatchUpAfter() time.Duration

CatchUpAfter is spec.catchUpAfter, or DefaultFluxCatchUpAfter when it is omitted.

func (*FluxClaim) ClaimKind added in v0.54.0

func (t *FluxClaim) ClaimKind() string

ClaimKind is FluxClaim.

func (*FluxClaim) DeepCopy added in v0.54.0

func (in *FluxClaim) DeepCopy() *FluxClaim

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluxClaim.

func (*FluxClaim) DeepCopyInto added in v0.54.0

func (in *FluxClaim) DeepCopyInto(out *FluxClaim)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*FluxClaim) DeepCopyObject added in v0.54.0

func (in *FluxClaim) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*FluxClaim) KubeProviderKey added in v0.54.0

func (t *FluxClaim) KubeProviderKey() types.NamespacedName

KubeProviderKey is spec.kubeProviderRef, its namespace defaulted to the applier claim's own.

func (*FluxClaim) Operation added in v0.54.0

func (t *FluxClaim) Operation() *ApplyOperation

Operation is status.operation.

func (*FluxClaim) PreviousSuspendState added in v0.54.0

func (t *FluxClaim) PreviousSuspendState() SuspendState

PreviousSuspendState is status.previousSuspendState.

func (*FluxClaim) RepairPending added in v0.54.0

func (t *FluxClaim) RepairPending() bool

RepairPending is status.repairPending.

func (*FluxClaim) SetObservedGeneration added in v0.54.0

func (t *FluxClaim) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*FluxClaim) SetOperation added in v0.54.0

func (t *FluxClaim) SetOperation(operation *ApplyOperation, repairPending bool)

SetOperation replaces status.operation and status.repairPending.

func (*FluxClaim) SetPreviousSuspendState added in v0.54.0

func (t *FluxClaim) SetPreviousSuspendState(state SuspendState)

SetPreviousSuspendState replaces status.previousSuspendState.

func (*FluxClaim) SharedSource added in v0.54.0

func (t *FluxClaim) SharedSource() (types.NamespacedName, bool)

SharedSource is the GitRepository in status.source.

func (*FluxClaim) SourceBinding added in v0.54.0

func (t *FluxClaim) SourceBinding() (string, string, bool)

SourceBinding is status.source's url and branch.

func (*FluxClaim) StatusConditions added in v0.54.0

func (t *FluxClaim) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type FluxClaimList added in v0.54.0

type FluxClaimList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []FluxClaim `json:"items"`
}

FluxClaimList contains a list of FluxClaim.

func (*FluxClaimList) DeepCopy added in v0.54.0

func (in *FluxClaimList) DeepCopy() *FluxClaimList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluxClaimList.

func (*FluxClaimList) DeepCopyInto added in v0.54.0

func (in *FluxClaimList) DeepCopyInto(out *FluxClaimList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*FluxClaimList) DeepCopyObject added in v0.54.0

func (in *FluxClaimList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type FluxClaimSource added in v0.54.0

type FluxClaimSource struct {
	// GitRepository is the Kustomization's spec.sourceRef, with its namespace
	// filled in.
	// +required
	GitRepository meta.NamespacedObjectReference `json:"gitRepository"`

	// URL is the GitRepository's spec.url.
	// +optional
	URL string `json:"url,omitempty"`

	// Branch is the GitRepository's spec.ref.branch.
	// +optional
	Branch string `json:"branch,omitempty"`

	// AlsoAppliedBy lists the other objects that apply this GitRepository and that
	// no FluxClaim holds: Kustomizations, and HelmReleases whose chart comes from
	// it. Each applies a new commit as soon as Flux fetches it. Information only;
	// it never affects Ready.
	// +optional
	// +listType=atomic
	AlsoAppliedBy []meta.NamespacedObjectKindReference `json:"alsoAppliedBy,omitempty"`
}

FluxClaimSource is the GitRepository a Kustomization applies.

func (*FluxClaimSource) DeepCopy added in v0.54.0

func (in *FluxClaimSource) DeepCopy() *FluxClaimSource

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluxClaimSource.

func (*FluxClaimSource) DeepCopyInto added in v0.54.0

func (in *FluxClaimSource) DeepCopyInto(out *FluxClaimSource)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type FluxClaimSpec added in v0.54.0

type FluxClaimSpec struct {

	// KubeProviderRef names the KubeProvider of the cluster that runs the
	// Kustomization, such as a management cluster running Flux. An omitted
	// namespace means this FluxClaim's namespace. The KubeProvider's
	// spec.allowedApplierClaims must admit this namespace, with the
	// Kustomization's namespace in applierNamespaces, and its identity needs get
	// and patch on the Kustomization and its GitRepository. Immutable: delete and
	// recreate the FluxClaim to change it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.kubeProviderRef.name must not be empty"
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.kubeProviderRef is immutable; delete and recreate the FluxClaim to hold a Kustomization elsewhere"
	KubeProviderRef meta.NamespacedObjectReference `json:"kubeProviderRef"`

	// KustomizationRef names the Flux Kustomization that applies the folders of
	// the GitTargets naming this FluxClaim. Its spec.sourceRef must be a
	// GitRepository that follows a branch. An omitted namespace means this
	// FluxClaim's namespace. Immutable: delete and recreate the FluxClaim to
	// change it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.kustomizationRef is immutable; delete and recreate the FluxClaim to hold another Kustomization"
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.kustomizationRef.name must not be empty"
	KustomizationRef meta.NamespacedObjectReference `json:"kustomizationRef"`

	// CatchUpAfter is how long the Kustomization stays behind the branch after
	// a push of GitOps Reverser's own before an apply of the tip is asked for,
	// as a Go duration ("1m", "90s"). Such a push changes nothing on the
	// cluster, which already holds the edit, but leaves
	// status.lastAppliedRevision and the GitRepository's artifact at the commit
	// before it. The interval starts when the Kustomization is first seen
	// behind, so a burst of saves costs one apply, and one at the tip costs
	// none. The apply can still wait for startup, a retry backoff or edits
	// being published. "0s" never asks for this reason, and drops an apply it
	// asked for that has not started. Otherwise at least "10s" and at most
	// "24h". Defaults to "1m".
	// +optional
	// +kubebuilder:validation:Type=string
	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|μs|ms|s|m|h))+$"
	// +kubebuilder:default="1m"
	// +kubebuilder:validation:XValidation:rule="duration(self) == duration('0s') || (duration(self) >= duration('10s') && duration(self) <= duration('24h'))",message="spec.catchUpAfter must be 0s, or a Go duration from 10s to 24h"
	CatchUpAfter *metav1.Duration `json:"catchUpAfter,omitempty"`
}

FluxClaimSpec names the Flux Kustomization the applier claim holds, and the cluster it is in.

func (*FluxClaimSpec) DeepCopy added in v0.54.0

func (in *FluxClaimSpec) DeepCopy() *FluxClaimSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluxClaimSpec.

func (*FluxClaimSpec) DeepCopyInto added in v0.54.0

func (in *FluxClaimSpec) DeepCopyInto(out *FluxClaimSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type FluxClaimStatus added in v0.54.0

type FluxClaimStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this FluxClaim's state. Ready,
	// Reconciling and Stalled follow kstatus.
	//
	// Configured is True when an eligible GitTarget names this FluxClaim, and the
	// Kustomization exists, applies a GitRepository that follows a branch, may be
	// patched, and no other FluxClaim holds it. An eligible GitTarget is in this
	// namespace, is admitted by its KubeProviders, and writes the branch the
	// GitRepository fetches. Of several FluxClaims for one Kustomization, the one
	// with an apply in flight holds it, then the one holding it already, then the
	// oldest; the others are Configured=False, reason HeldByAnotherClaim.
	//
	// InControl says whether GitOps Reverser decides when the Kustomization
	// applies:
	//
	// - True, reason Suspended: the Kustomization is suspended, and GitOps
	//   Reverser starts every apply.
	// - True, reason Applying: an apply GitOps Reverser started is running;
	//   the Kustomization is suspended again when it ends.
	// - False, reason Suspending: Flux has not yet handled the suspend.
	// - False, reason Releasing or Revoking: the FluxClaim is handing the
	//   Kustomization back.
	// - False, reason NotReferenced: no GitTarget names this FluxClaim.
	// - Unknown, reason NotConfigured: Configured is not True, or another
	//   FluxClaim holds the Kustomization.
	//
	// A FluxClaim no GitTarget names reads nothing and is Ready=True, reason
	// NotReferenced.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Source is the GitRepository the Kustomization applies, as last read. It is
	// published while an eligible GitTarget names this FluxClaim, and that
	// GitTarget must write the repository and branch it fetches.
	// +optional
	Source *FluxClaimSource `json:"source,omitempty"`

	// Operation is the apply GitOps Reverser started on the Kustomization: the one
	// in flight, or the last one. Absent until the first.
	// +optional
	Operation *ApplyOperation `json:"operation,omitempty"`

	// RepairPending is true while a Repair apply is pending: an apply ran a commit
	// older than an edit made through the API and reverted it on the cluster. Git
	// holds the edit, and the cluster runs the older value until the next apply.
	// +optional
	RepairPending bool `json:"repairPending,omitempty"`

	// PreviousSuspendState is how the Kustomization stood before this FluxClaim
	// first suspended it, and what handing it back restores: one that was
	// Suspended stays suspended, one that was NotSuspended is resumed. It is
	// cleared once the Kustomization is handed back. Absent, handing it back
	// resumes the Kustomization.
	// +optional
	PreviousSuspendState SuspendState `json:"previousSuspendState,omitempty"`
}

FluxClaimStatus is what the applier claim knows about its Kustomization, and the apply it started.

func (*FluxClaimStatus) DeepCopy added in v0.54.0

func (in *FluxClaimStatus) DeepCopy() *FluxClaimStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluxClaimStatus.

func (*FluxClaimStatus) DeepCopyInto added in v0.54.0

func (in *FluxClaimStatus) DeepCopyInto(out *FluxClaimStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitBranch added in v0.54.0

type GitBranch struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of GitBranch.
	// +required
	Spec GitBranchSpec `json:"spec"`

	// status defines the observed state of GitBranch.
	// +optional
	Status GitBranchStatus `json:"status,omitempty,omitzero"`
}

GitBranch is one branch of a Git repository, written with a GitProvider's credential. Every GitTarget that references it writes through it, and only one GitBranch may hold a repository branch at a time.

func (*GitBranch) AdmitsGitTarget added in v0.54.0

func (b *GitBranch) AdmitsGitTarget(namespace string, nsLabels map[string]string) (bool, error)

AdmitsGitTarget reports whether spec.allowedGitTargets admits a GitTarget in namespace, by the labels that namespace carries in the control cluster.

func (*GitBranch) DeepCopy added in v0.54.0

func (in *GitBranch) DeepCopy() *GitBranch

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranch.

func (*GitBranch) DeepCopyInto added in v0.54.0

func (in *GitBranch) DeepCopyInto(out *GitBranch)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitBranch) DeepCopyObject added in v0.54.0

func (in *GitBranch) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*GitBranch) DescribeAllowedGitTargets added in v0.54.0

func (b *GitBranch) DescribeAllowedGitTargets() string

DescribeAllowedGitTargets names the namespaces spec.allowedGitTargets admits.

func (*GitBranch) GitProviderKey added in v0.54.0

func (b *GitBranch) GitProviderKey() types.NamespacedName

GitProviderKey is the GitProvider this GitBranch writes through: spec.gitProviderRef, in this GitBranch's own namespace unless the reference names another one.

func (*GitBranch) SetObservedGeneration added in v0.54.0

func (b *GitBranch) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*GitBranch) StatusConditions added in v0.54.0

func (b *GitBranch) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type GitBranchAdmission added in v0.54.0

type GitBranchAdmission struct {
	// Admitted reports whether some grant admits the GitBranch's namespace.
	Admitted bool
	// BranchPatterns are the patterns the admitting grants give the GitBranch,
	// consumer variables expanded.
	BranchPatterns []string
	// Allowed reports whether the namespace is admitted and the branch matches one
	// of BranchPatterns.
	Allowed bool
}

GitBranchAdmission is what a GitProvider's allowedGitBranches give a GitBranch. +kubebuilder:object:generate=false

type GitBranchGitTargetGrant added in v0.54.0

type GitBranchGitTargetGrant struct {
	// ConsumerNamespaces are the namespaces whose GitTargets this grant admits.
	// from: "Same" is this GitBranch's namespace.
	// +required
	ConsumerNamespaces ConsumerNamespaces `json:"consumerNamespaces"`
}

GitBranchGitTargetGrant admits the GitTargets of some namespaces to write through a GitBranch.

func DefaultGitBranchGitTargetGrants added in v0.54.0

func DefaultGitBranchGitTargetGrants() []GitBranchGitTargetGrant

DefaultGitBranchGitTargetGrants is GitBranch.spec.allowedGitTargets when it is omitted: GitTargets in the GitBranch's own namespace.

func (*GitBranchGitTargetGrant) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchGitTargetGrant.

func (*GitBranchGitTargetGrant) DeepCopyInto added in v0.54.0

func (in *GitBranchGitTargetGrant) DeepCopyInto(out *GitBranchGitTargetGrant)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitBranchList added in v0.54.0

type GitBranchList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []GitBranch `json:"items"`
}

GitBranchList contains a list of GitBranch.

func (*GitBranchList) DeepCopy added in v0.54.0

func (in *GitBranchList) DeepCopy() *GitBranchList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchList.

func (*GitBranchList) DeepCopyInto added in v0.54.0

func (in *GitBranchList) DeepCopyInto(out *GitBranchList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitBranchList) DeepCopyObject added in v0.54.0

func (in *GitBranchList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type GitBranchParentState added in v0.54.0

type GitBranchParentState string

GitBranchParentState is what a branch that does not exist yet would be created from. +kubebuilder:validation:Enum=Found;Missing;Unborn

const (
	// GitBranchParentFound means the parent branch exists; the first commit builds on its tip.
	GitBranchParentFound GitBranchParentState = "Found"
	// GitBranchParentMissing means the parent is not on the remote either, so the branch cannot be
	// created; the GitBranch reports ParentBranchNotFound. The parent is spec.parentBranch, or, when
	// that is omitted, the default branch of a repository that is not empty but whose HEAD names no
	// branch it carries.
	GitBranchParentMissing GitBranchParentState = "Missing"
	// GitBranchParentUnborn means the repository is empty, with no refs at all (tags included), and
	// no parent is configured, so the first commit starts the branch with no history.
	GitBranchParentUnborn GitBranchParentState = "Unborn"
)

type GitBranchParentStatus added in v0.54.0

type GitBranchParentStatus struct {
	// State is what the branch would be created from: "Found" (the parent branch's
	// tip), "Missing" (the parent branch is not on the remote, so nothing is
	// written) or "Unborn" (an empty repository and no spec.parentBranch, so the
	// first commit has no history).
	// +required
	State GitBranchParentState `json:"state"`

	// Branch is the parent branch: spec.parentBranch, or the remote's default
	// branch when that is omitted. Empty when state is "Unborn", and when the
	// remote names no default branch.
	// +optional
	Branch string `json:"branch,omitempty"`

	// Commit is the commit hash the parent branch is at on the remote, which the
	// branch's first commit would build on. Set only when state is "Found".
	// +optional
	Commit string `json:"commit,omitempty"`
}

GitBranchParentStatus is the parent branch of a branch that does not exist yet.

func (*GitBranchParentStatus) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchParentStatus.

func (*GitBranchParentStatus) DeepCopyInto added in v0.54.0

func (in *GitBranchParentStatus) DeepCopyInto(out *GitBranchParentStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitBranchRemoteStatus added in v0.54.0

type GitBranchRemoteStatus struct {
	// Commit is the commit hash the branch is at on the remote. Empty means the
	// branch is not on the remote yet, which is not an error: a branch nothing has
	// written to does not exist.
	// +optional
	Commit string `json:"commit,omitempty"`

	// LastVerifiedAt is when the remote was last observed.
	// +optional
	LastVerifiedAt *metav1.Time `json:"lastVerifiedAt,omitempty"`

	// VerifiedBy is how commit was learned: "Push" means the remote accepted a
	// push from GitOps Reverser, and "Fetch" means a fetch found it. "Fetch" next
	// to a commit GitOps Reverser did not make means somebody else pushed to the
	// branch.
	// +optional
	// +kubebuilder:validation:Enum=Push;Fetch
	VerifiedBy string `json:"verifiedBy,omitempty"`

	// Parent is what the branch would be created from. Set only while the branch
	// is not on the remote.
	// +optional
	Parent *GitBranchParentStatus `json:"parent,omitempty"`
}

GitBranchRemoteStatus is the answer to "where is my branch, and when did we last prove it".

It is sampled when the GitBranch reconciles, from what its branch worker last proved about the branch, and written at most once a minute. The first observation, and a correction after the repository changed under the branch, are written at once.

func (*GitBranchRemoteStatus) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchRemoteStatus.

func (*GitBranchRemoteStatus) DeepCopyInto added in v0.54.0

func (in *GitBranchRemoteStatus) DeepCopyInto(out *GitBranchRemoteStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitBranchSpec added in v0.54.0

type GitBranchSpec struct {
	// GitProviderRef names the GitProvider whose repository and credential write
	// this branch. An omitted namespace means this GitBranch's namespace. The
	// GitProvider's spec.allowedGitBranches must admit this namespace and
	// spec.branch. Immutable: delete and recreate the GitBranch to change it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitProviderRef.name must not be empty"
	GitProviderRef meta.NamespacedObjectReference `json:"gitProviderRef"`

	// Branch is the branch on the remote that this GitBranch writes. It must match
	// a branch pattern that the GitProvider's spec.allowedGitBranches give this
	// namespace. Only one GitBranch holds a repository branch: the oldest admitted
	// one whose credential can open a push session. Any other reports Stalled,
	// reason BranchConflict. Immutable: delete and recreate the GitBranch to
	// change it.
	// +required
	// +kubebuilder:validation:MinLength=1
	Branch string `json:"branch"`

	// ParentBranch is the branch spec.branch is created from, and compared
	// against while spec.branch does not exist on the remote. Omitted, it is the
	// remote's default branch, or no history at all in an empty repository.
	//
	// When set, it must exist on the remote for spec.branch to be created;
	// otherwise this GitBranch reports Stalled=True, reason ParentBranchNotFound,
	// and writes nothing. Once spec.branch exists, the parent branch is no
	// longer followed. It is only read, so the GitProvider's
	// spec.allowedGitBranches need not allow it.
	//
	// Immutable, including adding or removing it: delete and recreate the
	// GitBranch to change it.
	// +optional
	// +kubebuilder:validation:MinLength=1
	ParentBranch string `json:"parentBranch,omitempty"`

	// AllowedGitTargets says which GitTargets may write through this GitBranch:
	//
	// - Omitted: the GitTargets in this GitBranch's namespace, as one grant
	//   with from: "Same".
	// - Empty list ([]): no GitTarget.
	// - A list of grants: the GitTargets that at least one grant allows.
	//
	// A list replaces the default: the GitTargets in this namespace keep access
	// only if at least one grant allows them.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=64
	// +kubebuilder:default={{consumerNamespaces: {from: Same}}}
	AllowedGitTargets []GitBranchGitTargetGrant `json:"allowedGitTargets"`
}

GitBranchSpec defines the desired state of GitBranch.

gitProviderRef, branch and parentBranch are immutable: together they are the repository branch this object claims, and a claim that could be repointed would move a branch worker's checkout, credential and pending writes to another branch under the GitTargets that reference it. Delete and recreate instead. allowedGitTargets is the branch owner's policy and stays mutable.

CEL cannot read metadata.namespace, so the reference is compared as written: spelling out the GitBranch's own namespace where it was omitted is refused too. +kubebuilder:validation:XValidation:rule="self.gitProviderRef == oldSelf.gitProviderRef",message="spec.gitProviderRef is immutable; delete and recreate the GitBranch to change it" +kubebuilder:validation:XValidation:rule="self.branch == oldSelf.branch",message="spec.branch is immutable; delete and recreate the GitBranch to change it" +kubebuilder:validation:XValidation:rule="has(self.parentBranch) == has(oldSelf.parentBranch) && (!has(self.parentBranch) || self.parentBranch == oldSelf.parentBranch)",message="spec.parentBranch is immutable; delete and recreate the GitBranch to change it"

func (*GitBranchSpec) DeepCopy added in v0.54.0

func (in *GitBranchSpec) DeepCopy() *GitBranchSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchSpec.

func (*GitBranchSpec) DeepCopyInto added in v0.54.0

func (in *GitBranchSpec) DeepCopyInto(out *GitBranchSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitBranchStatus added in v0.54.0

type GitBranchStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this GitBranch's state: whether it
	// holds its repository branch and can write it. Ready, Reconciling and Stalled
	// follow kstatus.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Repository is the GitProvider's repository URL, normalized to host and path
	// with no scheme, user or ".git" suffix. With spec.branch it is what only one
	// GitBranch may hold, so two GitProviders that spell one repository
	// differently still conflict.
	// +optional
	Repository string `json:"repository,omitempty"`

	// LastPushNoticeAt is when a GitReceiver last delivered a push for this
	// branch. It records that the delivery arrived; status.remote says what the
	// remote holds. Absent means no delivery has reached this branch: no
	// GitReceiver is set up or reachable, the delivery names the repository by a
	// URL other than the GitProvider's spec.url, or no GitTarget references this
	// GitBranch. It advances at most once a minute.
	// +optional
	LastPushNoticeAt *metav1.Time `json:"lastPushNoticeAt,omitempty"`

	// Remote is where this branch is on the Git remote, and when that was last
	// checked by a push or a fetch. It is updated at most once a minute. Absent
	// until the first check, and again after the GitProvider is recreated for
	// another repository.
	// +optional
	Remote *GitBranchRemoteStatus `json:"remote,omitempty"`

	// GitTargetCount is how many GitTargets, in any namespace, reference this
	// GitBranch. Each one reports its own folder's health in its own conditions.
	// +optional
	GitTargetCount int32 `json:"gitTargetCount"`
}

GitBranchStatus defines the observed state of GitBranch.

func (*GitBranchStatus) DeepCopy added in v0.54.0

func (in *GitBranchStatus) DeepCopy() *GitBranchStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitBranchStatus.

func (*GitBranchStatus) DeepCopyInto added in v0.54.0

func (in *GitBranchStatus) DeepCopyInto(out *GitBranchStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitProvider

type GitProvider struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of GitProvider.
	// +required
	Spec GitProviderSpec `json:"spec"`

	// status defines the observed state of GitProvider.
	// +optional
	Status GitProviderStatus `json:"status,omitempty,omitzero"`
}

GitProvider is a connection to one Git repository: its URL, the credential that reaches it, the committer identity and commit signing. GitBranches claim branches of the repository through it, as its spec.allowedGitBranches allow.

func (*GitProvider) AdmitsGitBranch added in v0.54.0

func (p *GitProvider) AdmitsGitBranch(
	consumer types.NamespacedName, nsLabels map[string]string, branch string,
) (GitBranchAdmission, error)

AdmitsGitBranch reports what spec.allowedGitBranches gives the GitBranch consumer, by the labels its namespace carries in the control cluster, and whether it may claim branch.

func (*GitProvider) DeepCopy

func (in *GitProvider) DeepCopy() *GitProvider

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProvider.

func (*GitProvider) DeepCopyInto

func (in *GitProvider) DeepCopyInto(out *GitProvider)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitProvider) DeepCopyObject

func (in *GitProvider) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*GitProvider) DescribeAllowedGitBranches added in v0.54.0

func (p *GitProvider) DescribeAllowedGitBranches() string

DescribeAllowedGitBranches names the namespaces spec.allowedGitBranches admits.

func (*GitProvider) SetObservedGeneration added in v0.44.0

func (p *GitProvider) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*GitProvider) StatusConditions added in v0.44.0

func (p *GitProvider) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type GitProviderGitBranchGrant added in v0.54.0

type GitProviderGitBranchGrant struct {
	// ConsumerNamespaces are the namespaces whose GitBranches this grant admits.
	// from: "Same" is this GitProvider's namespace.
	// +required
	ConsumerNamespaces ConsumerNamespaces `json:"consumerNamespaces"`

	// BranchPatterns are the branches an admitted GitBranch may claim, each
	// matched against the whole branch name. "*" matches any characters, "/"
	// included, so "*" alone is every branch and "main" is only main.
	// "{consumer.namespace}" and "{consumer.name}" are the GitBranch's namespace
	// and name, each a whole path segment: "teams/{consumer.namespace}/*".
	// "{consumer.name}" needs "{consumer.namespace}" in the same pattern, because
	// a GitBranch picks its own name. There is no escaping, "?" or character
	// class.
	// +required
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	BranchPatterns []BranchPattern `json:"branchPatterns"`
}

GitProviderGitBranchGrant admits the GitBranches of some namespaces to claim, through a GitProvider, the branches its patterns match.

func (*GitProviderGitBranchGrant) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProviderGitBranchGrant.

func (*GitProviderGitBranchGrant) DeepCopyInto added in v0.54.0

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitProviderList

type GitProviderList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []GitProvider `json:"items"`
}

GitProviderList contains a list of GitProvider.

func (*GitProviderList) DeepCopy

func (in *GitProviderList) DeepCopy() *GitProviderList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProviderList.

func (*GitProviderList) DeepCopyInto

func (in *GitProviderList) DeepCopyInto(out *GitProviderList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitProviderList) DeepCopyObject

func (in *GitProviderList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type GitProviderSpec

type GitProviderSpec struct {
	// URL is the repository's URL, over HTTPS or SSH. Immutable: delete and
	// recreate the GitProvider to change it.
	// +kubebuilder:validation:MinLength=1
	URL string `json:"url"`

	// SecretRef names the Secret, in this namespace, that holds the credentials
	// for the repository. Omitted means anonymous access.
	// +optional
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.secretRef.name must not be empty; omit secretRef entirely for anonymous access"
	SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`

	// KnownHostsRef names a ConfigMap or Secret, in this namespace, holding SSH
	// known_hosts, so several GitProviders on one host can share them. SSH only.
	//
	// Host keys come from the first of these that has any:
	//
	// 1. the known_hosts key of the credentials Secret, spec.secretRef;
	// 2. this reference;
	// 3. the installation's default.
	//
	// Without host keys, SSH fails unless the installation sets
	// --insecure-allow-missing-known-hosts.
	// +optional
	KnownHostsRef *KnownHostsReference `json:"knownHostsRef,omitempty"`

	// AllowedGitBranches says which GitBranches may claim a branch of this
	// repository through this GitProvider: a grant must admit the GitBranch's
	// namespace, and one of its branchPatterns must match the GitBranch's
	// spec.branch. Grants combine by union. Unlike the grant lists of GitBranch
	// and KubeProvider it has no default: omitted or empty, no GitBranch may claim
	// through it, including in this namespace.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=64
	AllowedGitBranches []GitProviderGitBranchGrant `json:"allowedGitBranches,omitempty"`

	// Commit sets the committer identity and commit signing. Commit messages are
	// set on the GitTarget, in spec.commit.message.
	// +optional
	Commit *CommitSpec `json:"commit,omitempty"`
}

GitProviderSpec defines the desired state of GitProvider.

Only the repository URL is immutable. The URL is the destination identity that every referencing GitTarget materializes into; changing it would silently point those targets at a different repository and orphan their existing materialization (the same reason a GitTarget's destination is immutable). To repoint, delete and recreate the GitProvider. Everything else here is operational and deliberately stays mutable — notably allowedGitBranches (widening or narrowing who may claim which branches is a normal change that must not require tearing down every GitBranch), plus auth and commit identity/signing.

+kubebuilder:validation:XValidation:rule="self.url == oldSelf.url",message="spec.url is immutable; delete and recreate the GitProvider to point at a different repository"

func (*GitProviderSpec) DeepCopy

func (in *GitProviderSpec) DeepCopy() *GitProviderSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProviderSpec.

func (*GitProviderSpec) DeepCopyInto

func (in *GitProviderSpec) DeepCopyInto(out *GitProviderSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitProviderStatus

type GitProviderStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this GitProvider's state: whether
	// the repository answers with its credential, and whether commit signing is
	// ready. Ready, Reconciling and Stalled follow kstatus.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// SigningPublicKey is the SSH public key commits are signed with, in
	// authorized_keys format. Register it as a signing key with your Git host. Set
	// only when spec.commit.signing is configured and its key is available.
	// +optional
	SigningPublicKey string `json:"signingPublicKey,omitempty"`

	// LastVerifiedAt is the time of the last successful connectivity check
	// against the repository, using this GitProvider's credentials, or
	// anonymous access when spec.secretRef is omitted. It is never cleared, and
	// a failure leaves it unchanged, so it does not show when a failure began.
	// status.conditions gives the reason the GitProvider is not ready.
	// +optional
	LastVerifiedAt *metav1.Time `json:"lastVerifiedAt,omitempty"`
}

GitProviderStatus defines the observed state of GitProvider.

func (*GitProviderStatus) DeepCopy

func (in *GitProviderStatus) DeepCopy() *GitProviderStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitProviderStatus.

func (*GitProviderStatus) DeepCopyInto

func (in *GitProviderStatus) DeepCopyInto(out *GitProviderStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitReceiver added in v0.54.0

type GitReceiver struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of GitReceiver.
	// +required
	Spec GitReceiverSpec `json:"spec"`

	// status defines the observed state of GitReceiver.
	// +optional
	Status GitReceiverStatus `json:"status,omitempty,omitzero"`
}

GitReceiver is the endpoint a Git host notifies when it receives a push. A delivery wakes every GitBranch of every GitProvider, in any namespace, whose spec.url names the delivery's repository, so pushes are picked up at once instead of at the next refresh. A GitProvider that reaches the host through another host name or port is not matched. A delivery is only a hint: the branch is then read with its own GitProvider's credential, so a delivery cannot choose a URL, a credential or a commit. GitBranch.status.lastPushNoticeAt shows deliveries arriving.

func (*GitReceiver) DeepCopy added in v0.54.0

func (in *GitReceiver) DeepCopy() *GitReceiver

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitReceiver.

func (*GitReceiver) DeepCopyInto added in v0.54.0

func (in *GitReceiver) DeepCopyInto(out *GitReceiver)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitReceiver) DeepCopyObject added in v0.54.0

func (in *GitReceiver) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*GitReceiver) Key added in v0.54.0

func (r *GitReceiver) Key() types.NamespacedName

Key is this GitReceiver's namespace and name.

func (*GitReceiver) SetObservedGeneration added in v0.54.0

func (r *GitReceiver) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*GitReceiver) StatusConditions added in v0.54.0

func (r *GitReceiver) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type GitReceiverList added in v0.54.0

type GitReceiverList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []GitReceiver `json:"items"`
}

GitReceiverList contains a list of GitReceiver.

func (*GitReceiverList) DeepCopy added in v0.54.0

func (in *GitReceiverList) DeepCopy() *GitReceiverList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitReceiverList.

func (*GitReceiverList) DeepCopyInto added in v0.54.0

func (in *GitReceiverList) DeepCopyInto(out *GitReceiverList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitReceiverList) DeepCopyObject added in v0.54.0

func (in *GitReceiverList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type GitReceiverSpec added in v0.54.0

type GitReceiverSpec struct {
	// Type is the payload and signature format the Git host sends:
	//
	// - "github": GitHub's payload, signed in X-Hub-Signature-256.
	// - "gitlab": GitLab's payload, with the secret in X-Gitlab-Token.
	// - "gitea": Gitea's payload, signed in X-Gitea-Signature.
	// - "generic-hmac": a relay of your own. It sends a JSON object with
	//   repository, branch and after fields, signed in X-Signature as
	//   sha256=<hex HMAC of the body>.
	// +required
	// +kubebuilder:validation:Enum=github;gitlab;gitea;generic-hmac
	Type ReceiverType `json:"type"`

	// SecretRef names the Secret, in this namespace, whose "token" key is the
	// webhook secret. The token also determines status.webhookPath, so rotating it
	// moves the path: register the new path with the new secret.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.secretRef.name must not be empty"
	SecretRef meta.LocalObjectReference `json:"secretRef"`
}

GitReceiverSpec defines the desired state of GitReceiver.

func (*GitReceiverSpec) DeepCopy added in v0.54.0

func (in *GitReceiverSpec) DeepCopy() *GitReceiverSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitReceiverSpec.

func (*GitReceiverSpec) DeepCopyInto added in v0.54.0

func (in *GitReceiverSpec) DeepCopyInto(out *GitReceiverSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitReceiverStatus added in v0.54.0

type GitReceiverStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this GitReceiver's state. Ready,
	// Reconciling and Stalled follow kstatus; Ready is True once the token is
	// readable and the receiver listener is on.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// WebhookPath is the path this GitReceiver is served on, under the receiver
	// listener: /git-push/ and an HMAC of its namespace and name, keyed by the
	// token. Point the Git host's push webhook at the listener's address plus this
	// path. Empty while the token is missing.
	// +optional
	WebhookPath string `json:"webhookPath,omitempty"`
}

GitReceiverStatus defines the observed state of GitReceiver.

func (*GitReceiverStatus) DeepCopy added in v0.54.0

func (in *GitReceiverStatus) DeepCopy() *GitReceiverStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitReceiverStatus.

func (*GitReceiverStatus) DeepCopyInto added in v0.54.0

func (in *GitReceiverStatus) DeepCopyInto(out *GitReceiverStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTarget

type GitTarget struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of GitTarget.
	// +required
	Spec GitTargetSpec `json:"spec"`

	// status defines the observed state of GitTarget.
	// +optional
	Status GitTargetStatus `json:"status,omitempty,omitzero"`
}

GitTarget mirrors objects from a source cluster into one folder of a Git branch. Its WatchRules and ClusterWatchRules select the objects, its KubeProvider reads them, and its GitBranch writes them.

func (*GitTarget) AdmitsCommitRequest added in v0.55.0

func (t *GitTarget) AdmitsCommitRequest(namespace string, nsLabels map[string]string) (bool, error)

AdmitsCommitRequest reports whether spec.allowedCommitRequests admits a CommitRequest in namespace of the control cluster, by the labels that namespace carries there: its consumerNamespaces grants.

func (*GitTarget) AdmitsSourceCommitRequest added in v0.55.0

func (t *GitTarget) AdmitsSourceCommitRequest(namespace string) bool

AdmitsSourceCommitRequest reports whether spec.allowedCommitRequests admits a CommitRequest in namespace of the cluster this GitTarget mirrors: its sourceNamespaces grants, "*" for any.

func (*GitTarget) DeepCopy

func (in *GitTarget) DeepCopy() *GitTarget

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTarget.

func (*GitTarget) DeepCopyInto

func (in *GitTarget) DeepCopyInto(out *GitTarget)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitTarget) DeepCopyObject

func (in *GitTarget) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*GitTarget) DescribeAllowedCommitRequests added in v0.55.0

func (t *GitTarget) DescribeAllowedCommitRequests() string

DescribeAllowedCommitRequests names the namespaces spec.allowedCommitRequests admits on the control cluster.

func (*GitTarget) EffectiveOnRefusal added in v0.49.0

func (g *GitTarget) EffectiveOnRefusal() RefusalAction

EffectiveOnRefusal returns the refusal action, resolving an omitted field to the default. The CRD default makes this redundant for objects that went through the API server, and not for a literal built in a test or by an older client. A value this release does not know, such as the retired "PushEmptyCommit" still stored on an object, is Ignore: an action nobody can name now is not consent to one.

func (*GitTarget) EffectivePruneMode added in v0.39.0

func (g *GitTarget) EffectivePruneMode() PruneMode

EffectivePruneMode is the mode this GitTarget's writes are subject to, with the omitted-field default applied. It is the only supported way to read the policy: reading spec.prune.mode directly would treat a legacy GitTarget as if it had no mode rather than OnEvent.

func (*GitTarget) GitBranchKey added in v0.54.0

func (g *GitTarget) GitBranchKey() types.NamespacedName

GitBranchKey is the GitBranch this GitTarget writes: spec.gitBranchRef, in this GitTarget's own namespace unless the reference names another one. An unset reference names nothing, and the zero key says exactly that.

func (*GitTarget) KubeProviderKey added in v0.54.0

func (g *GitTarget) KubeProviderKey() types.NamespacedName

KubeProviderKey is the KubeProvider this GitTarget mirrors through: spec.kubeProviderRef, in this GitTarget's own namespace unless the reference names another one. An unset reference names nothing, and the zero key says exactly that.

func (*GitTarget) SetObservedGeneration added in v0.44.0

func (t *GitTarget) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*GitTarget) SourceCluster added in v0.38.0

func (g *GitTarget) SourceCluster() string

SourceCluster is the identity the watch data plane keys a GitTarget's source cluster on: the referenced KubeProvider's namespace/name, so two providers with one name in two namespaces are two clusters. It keys the GVK→GVR registry and the watch context. It is NOT the attribution partition: facts are keyed by the referenced KubeProvider's AuditRoute().

func (*GitTarget) StatusConditions added in v0.44.0

func (t *GitTarget) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type GitTargetCommitRequestGrant added in v0.55.0

type GitTargetCommitRequestGrant struct {
	// ConsumerNamespaces are the namespaces, on the cluster GitOps Reverser
	// runs in, whose CommitRequests this grant admits. from: "Same" is this
	// GitTarget's namespace. It admits requests only for a GitTarget whose
	// KubeProvider sets spec.inCluster.
	// +optional
	ConsumerNamespaces *ConsumerNamespaces `json:"consumerNamespaces,omitempty"`

	// SourceNamespaces are the namespaces, on the cluster spec.kubeProviderRef
	// names, whose CommitRequests this grant admits: exact names, or "*" for
	// every namespace this GitTarget may mirror. Variables are refused. A
	// namespace the KubeProvider does not lend this GitTarget in
	// spec.allowedGitTargets is never admitted. It admits requests only for a
	// GitTarget whose KubeProvider names a kubeconfig.
	// +optional
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	SourceNamespaces []SourceNamespace `json:"sourceNamespaces,omitempty"`
}

GitTargetCommitRequestGrant admits the CommitRequests of some namespaces to save a GitTarget's commit windows: on the cluster GitOps Reverser runs in (consumerNamespaces), or on the cluster the GitTarget mirrors (sourceNamespaces). It sets exactly one of the two. +kubebuilder:validation:XValidation:rule="has(self.consumerNamespaces) != has(self.sourceNamespaces)",message="a grant in allowedCommitRequests sets exactly one of consumerNamespaces and sourceNamespaces"

func DefaultGitTargetCommitRequestGrants added in v0.55.0

func DefaultGitTargetCommitRequestGrants() []GitTargetCommitRequestGrant

DefaultGitTargetCommitRequestGrants is GitTarget.spec.allowedCommitRequests when it is omitted: CommitRequests in the GitTarget's own namespace.

func (*GitTargetCommitRequestGrant) DeepCopy added in v0.55.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetCommitRequestGrant.

func (*GitTargetCommitRequestGrant) DeepCopyInto added in v0.55.0

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetCommitSpec added in v0.43.0

type GitTargetCommitSpec struct {

	// Window sets when this GitTarget's commit windows close. A window opens on an
	// author's first write and collects that author's writes until idleTimeout
	// passes without one, or maxDuration after it opened, whichever comes first. A
	// change applies to windows opened afterward. A CommitRequest attached to a
	// window replaces both timers for that window.
	// +optional
	Window *CommitWindow `json:"window,omitempty"`

	// Message sets the commit message templates. A template left empty uses the
	// built-in one.
	// +optional
	Message *CommitMessageSpec `json:"message,omitempty"`
}

GitTargetCommitSpec configures how a GitTarget's writes become commits.

func (*GitTargetCommitSpec) DeepCopy added in v0.43.0

func (in *GitTargetCommitSpec) DeepCopy() *GitTargetCommitSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetCommitSpec.

func (*GitTargetCommitSpec) DeepCopyInto added in v0.43.0

func (in *GitTargetCommitSpec) DeepCopyInto(out *GitTargetCommitSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetList

type GitTargetList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []GitTarget `json:"items"`
}

GitTargetList contains a list of GitTarget.

func (*GitTargetList) DeepCopy

func (in *GitTargetList) DeepCopy() *GitTargetList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetList.

func (*GitTargetList) DeepCopyInto

func (in *GitTargetList) DeepCopyInto(out *GitTargetList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*GitTargetList) DeepCopyObject

func (in *GitTargetList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type GitTargetPlacementSpec

type GitTargetPlacementSpec struct {
	// ByType maps a resource type, written "{group}/{version}/{resource}"
	// ("apps/v1/deployments", or "v1/configmaps" for the core group), to the path
	// template for new resources of that type. The template of a sensitive type,
	// such as Secrets, must contain the resource's whole identity, so two of them
	// never share a file.
	// +optional
	ByType map[string]string `json:"byType,omitempty"`

	// Default is the path template for a new resource whose type has no byType
	// entry. Omitted, a new document goes next to the folder's kustomization when
	// exactly one governs the folder, and otherwise to
	// {namespace}/{group}/{resource}/{name}.yaml. That path has no version, so add
	// {version} to a template to keep two versions of one resource apart. A
	// bundling template such as "all.yaml" is valid only when every sensitive type
	// has its own byType entry.
	// +optional
	Default string `json:"default,omitempty"`

	// UseKustomize makes GitOps Reverser create a kustomization.yaml at spec.path
	// when no kustomization governs the folder yet. The first new document creates
	// it, listing every managed document already in the folder and the new one,
	// and nothing else: no namespace:. It has no effect on a folder that already
	// has a kustomization. A new file is always added to the kustomization
	// governing it, and a template that places a document outside that
	// kustomization is refused. Defaults to false.
	// +optional
	UseKustomize bool `json:"useKustomize,omitempty"`
}

GitTargetPlacementSpec declares where NEW resources are written when no document for their identity exists yet in Git — one exact-type map plus a fallback default template (Option B2 of docs/layout/new-file-placement-rules.md). There is deliberately no separate "sensitive" placement block: sensitivity is a write-safety classification the controller owns (encrypt the content, keep the path identity-complete, never append or co-mingle), not a second placement namespace the user has to configure. A user routes Secrets the same way they route anything else — by naming their type in ByType. When a resource's type has no ByType entry and no Default, the new document goes beside the folder's kustomization when the whole folder is governed by exactly one supported kustomization (so the file is reachable from a render root instead of being written where kustomize would never build it), and otherwise at the built-in versionless {namespace}/{group}/{resource}/{name}.yaml path. Nothing infers a destination from where the repository keeps other resources of the same type: a layout this operator cannot derive from one root is declared here or it takes the built-in path. Because the built-in path omits the API version, objects that differ only by version share a file; a target that watches several versions of the same group/resource and wants them separated must use a ByType/Default template that includes {version}.

func (*GitTargetPlacementSpec) DeepCopy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetPlacementSpec.

func (*GitTargetPlacementSpec) DeepCopyInto

func (in *GitTargetPlacementSpec) DeepCopyInto(out *GitTargetPlacementSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetPlacementStatus added in v0.43.0

type GitTargetPlacementStatus struct {
	// Mode is how this folder is written.
	//
	// "Plain": no kustomization governs the folder. Documents are written and
	// removed, and nothing else is touched.
	//
	// "KustomizeRoot": one kustomization governs the folder and renders nothing
	// outside it. A new document is also added to its resources:, a removed one is
	// dropped from it, and every write is checked by rendering, so kustomize can
	// refuse one.
	//
	// "KustomizeOverlay": as KustomizeRoot, and the folder also renders a base
	// outside it (readOnlyBases). An edit to a field the base sets is written into
	// the overlay where it can be (images:, replicas:) and refused with
	// WriteBoundaryRefused otherwise. Deleting an object the base supplies writes
	// a $patch: delete into the overlay.
	//
	// Empty when the folder holds more than one kustomize root
	// (LayoutResolved=Ambiguous): no new document is placed until spec.path points
	// at one of them.
	// +optional
	// +kubebuilder:validation:Enum=Plain;KustomizeRoot;KustomizeOverlay
	Mode PlacementMode `json:"mode,omitempty"`

	// RenderRoot is the kustomization directory that governs new documents,
	// relative to spec.path ("." is the folder itself). Empty for Plain, and when
	// the layout is Ambiguous.
	// +optional
	RenderRoot string `json:"renderRoot,omitempty"`

	// ReadOnlyBases are the kustomization directories this folder renders but may
	// not write, relative to spec.path, so they start with "../". Set only for
	// KustomizeOverlay. An edit to a document under one of them is refused with
	// WriteBoundaryRefused unless the overlay can express it.
	// +optional
	ReadOnlyBases []string `json:"readOnlyBases,omitempty"`

	// ResolvedAtCommit is the commit at which this layout was first seen. It does
	// not move while the layout stays the same, so a commit older than the branch
	// head means the layout has not changed since. Empty until the branch has a
	// commit.
	// +optional
	ResolvedAtCommit string `json:"resolvedAtCommit,omitempty"`

	// ResolvedAt is when this layout was first seen. Like resolvedAtCommit, it
	// does not move while the layout stays the same.
	// +optional
	ResolvedAt *metav1.Time `json:"resolvedAt,omitempty"`
}

GitTargetPlacementStatus is what the last scan resolved about a GitTarget folder's layout.

func (*GitTargetPlacementStatus) DeepCopy added in v0.43.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetPlacementStatus.

func (*GitTargetPlacementStatus) DeepCopyInto added in v0.43.0

func (in *GitTargetPlacementStatus) DeepCopyInto(out *GitTargetPlacementStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetRetentionStatus added in v0.39.0

type GitTargetRetentionStatus struct {
	// Mode is the spec.prune.mode these counts were taken under, with the default
	// applied.
	// +optional
	// +kubebuilder:validation:Enum=Never;OnEvent;Always
	Mode PruneMode `json:"mode,omitempty"`

	// RetainedDocuments is how many documents the prune policy kept that have no
	// resource on the cluster. Zero means a resync found nothing to keep. An
	// absent retention block means no resync has reported yet.
	RetainedDocuments int32 `json:"retainedDocuments"`

	// LastChangedAt is when the count or the mode last changed. A resync that
	// reports the same count leaves it alone, so it does not say when retention
	// was last measured.
	// +optional
	LastChangedAt *metav1.Time `json:"lastChangedAt,omitempty"`
}

GitTargetRetentionStatus is a bounded roll-up of what this GitTarget's prune policy kept.

func (*GitTargetRetentionStatus) DeepCopy added in v0.39.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetRetentionStatus.

func (*GitTargetRetentionStatus) DeepCopyInto added in v0.39.0

func (in *GitTargetRetentionStatus) DeepCopyInto(out *GitTargetRetentionStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetSpec

type GitTargetSpec struct {
	// GitBranchRef names the GitBranch this GitTarget writes to: the repository
	// branch and the credential that writes it. An omitted namespace means this
	// GitTarget's namespace. The GitBranch's spec.allowedGitTargets must admit
	// this namespace. Several GitTargets may share one GitBranch. Immutable:
	// delete and recreate the GitTarget to change it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitBranchRef.name must not be empty"
	GitBranchRef meta.NamespacedObjectReference `json:"gitBranchRef"`

	// Path is the folder this GitTarget writes, relative to the repository root.
	// Use "." for the root itself. A leading "/" and ".." are rejected, and a
	// trailing "/" is dropped. Immutable: delete and recreate the GitTarget to
	// change it.
	// +required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Encryption configures how Secrets are encrypted before they are written to
	// Git.
	// +optional
	Encryption *EncryptionSpec `json:"encryption,omitempty"`

	// ApplierClaimRef names the FluxClaim or ArgoCDClaim, in this namespace, that
	// holds the applier of this folder: the Flux Kustomization or Argo CD
	// Application that applies it. With it set, GitOps Reverser decides when that
	// applier runs, and runs it only after the edits it holds are published.
	// Objects another applier owns are not mirrored into the folder. The applier
	// must apply this GitTarget's repository and branch; the ApplierClaimReady
	// condition reports whether it does. Several GitTargets may name one applier
	// claim.
	// +optional
	ApplierClaimRef *ApplierClaimReference `json:"applierClaimRef,omitempty"`

	// OnRefusal decides what happens when a live edit is refused because it has no
	// valid place in the folder. A refusal makes no commit, so the edit stays on
	// the cluster until something applies Git over it.
	//
	// "Ignore" (the default) reports the refusal in conditions and events and does
	// nothing else.
	//
	// "Reapply" asks the applier in spec.applierClaimRef, which it requires, to
	// apply the branch once the pending edits are published, which reverts the
	// refused edit. It fires only for an edit to a document the folder already
	// holds, in a write that removes no document, and never for a refusal of the
	// whole folder, such as unparseable YAML. A refusal that stands is reapplied
	// once, not on every recheck.
	// +optional
	// +kubebuilder:validation:Enum=Ignore;Reapply
	// +kubebuilder:default=Ignore
	OnRefusal RefusalAction `json:"onRefusal,omitempty"`

	// Placement decides where a new resource is written: one with no document
	// in the folder yet. A resource that already has a document is updated
	// where that document is. So a change here affects only resources created
	// afterward, and labeling a resource later never moves its file.
	//
	// byType and default are path templates over the resource's identity:
	// {namespace}, {name}, {group}, {version}, {resource}, {kind} and more. They
	// may read a label: "{label:app.kubernetes.io/instance}/configmaps.yaml".
	//
	// Two variables can be absent, and each then renders a built-in value:
	//
	// - "{label:key}" renders "_unlabeled" for a resource without the label.
	// - "{namespace}" renders "_cluster" for a cluster-scoped resource.
	//
	// Append "|fallback" to either to choose that value instead:
	// "{label:team|unassigned}", "{namespace|_global}". A fallback is up to 63
	// characters of [A-Za-z0-9._-], is not "." or "..", and may be empty to
	// drop the path segment. A {namespace} fallback that names a real namespace
	// files cluster-scoped resources in that namespace's folder. A fallback on
	// any other variable is rejected.
	// +optional
	Placement *GitTargetPlacementSpec `json:"placement,omitempty"`

	// SerializeNamespace decides whether a namespaced resource's document
	// carries metadata.namespace. It applies to every write, not just the
	// first, and is ignored for cluster-scoped resources.
	//
	// - Omitted: decided per document. The namespace is left out only when the
	//   kustomization governing the document's path sets namespace: to that
	//   same namespace. This suits a folder of nested kustomize roots that each
	//   set their own namespace.
	// - true: always written. Use it for a flat folder applied as is.
	// - false: never written, for a folder whose namespace something else
	//   supplies: a Flux Kustomization's targetNamespace, an Argo CD
	//   Application's destination.namespace, or a kustomization.
	//
	// With false, the folder holds one source namespace. A WatchRule bringing a
	// second one is refused with GitPathAccepted=False, reason
	// MultipleSourceNamespaces.
	// +optional
	SerializeNamespace *bool `json:"serializeNamespace,omitempty"`

	// KubeProviderRef names the KubeProvider this GitTarget mirrors from: the
	// source cluster and the credential that reads it. An omitted namespace means
	// this GitTarget's namespace. The KubeProvider's spec.allowedGitTargets must
	// admit this namespace. Immutable: delete and recreate the GitTarget to change
	// it.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.kubeProviderRef.name must not be empty"
	// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.kubeProviderRef is immutable; delete and recreate the GitTarget to change the cluster it mirrors"
	KubeProviderRef meta.NamespacedObjectReference `json:"kubeProviderRef"`

	// Prune decides which deletions remove documents from this folder: a delete
	// observed on the source cluster, and a document a resync finds no resource
	// for. Omitted, mode is "OnEvent": observed deletes are mirrored, and a resync
	// removes nothing.
	// +optional
	Prune *PrunePolicy `json:"prune,omitempty"`

	// Commit configures how this GitTarget's writes are batched into commits and
	// how the commits are worded. Omitted, a commit window closes 5s after its
	// last write or 1m after it opened, and the built-in message templates are
	// used.
	// +optional
	Commit *GitTargetCommitSpec `json:"commit,omitempty"`

	// AllowedCommitRequests says which CommitRequests may save this GitTarget's
	// commit windows. Each grant sets one of:
	//
	// - consumerNamespaces: namespaces of the cluster GitOps Reverser runs
	//   in. They admit requests only when spec.kubeProviderRef names an
	//   inCluster KubeProvider.
	// - sourceNamespaces: namespaces of the cluster spec.kubeProviderRef
	//   names, which must set spec.commitRequests. They admit requests only
	//   when that KubeProvider names a kubeconfig.
	//
	// Omitted, the CommitRequests in this GitTarget's namespace are admitted,
	// as one grant with consumerNamespaces from: "Same". An empty list ([])
	// admits none. A list replaces the default. A request no grant admits
	// fails with reason "NotAllowed".
	//
	// An admitted request saves its creator's whole commit window on this
	// GitTarget, writes outside the request's namespace included.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=64
	// +kubebuilder:default={{consumerNamespaces: {from: Same}}}
	AllowedCommitRequests []GitTargetCommitRequestGrant `json:"allowedCommitRequests"`

	// Suspend stops this GitTarget from making new commits, without deleting
	// it. Defaults to false.
	//
	// While it is set, watches keep running and status.placement stays current,
	// but status.retention is not published.
	//
	// A commit already made locally is still pushed, so one more commit can
	// appear seconds after it is set: suspend stops the next write and does not
	// undo the last one.
	//
	// Clearing it resumes from the current cluster state at the next resync.
	// Writes skipped while suspended are not replayed.
	// +optional
	Suspend bool `json:"suspend,omitempty"`
}

GitTargetSpec defines the desired state of GitTarget.

The destination fields — gitBranchRef and path — are immutable. A GitTarget materializes the watched resources at exactly one (repository branch, folder); changing where it writes would orphan the old materialization and require migrating manifests between repositories/branches/folders. Instead of reconciling that move, the destination is fixed: to relocate a GitTarget, delete it and create a new one. This keeps the one-owner-per-folder invariant and the initial-snapshot gate simple — a successful snapshot can never be silently invalidated by a destination change.

+kubebuilder:validation:XValidation:rule="self.gitBranchRef == oldSelf.gitBranchRef",message="spec.gitBranchRef is immutable; delete and recreate the GitTarget to change its destination" +kubebuilder:validation:XValidation:rule="self.path == oldSelf.path",message="spec.path is immutable; delete and recreate the GitTarget to change its destination" +kubebuilder:validation:XValidation:rule="!has(self.onRefusal) || self.onRefusal != 'Reapply' || has(self.applierClaimRef)",message="spec.onRefusal: Reapply needs spec.applierClaimRef, the applier claim asked to reapply"

func (*GitTargetSpec) DeepCopy

func (in *GitTargetSpec) DeepCopy() *GitTargetSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetSpec.

func (*GitTargetSpec) DeepCopyInto

func (in *GitTargetSpec) DeepCopyInto(out *GitTargetSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GitTargetStatus

type GitTargetStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this GitTarget's state. Ready,
	// Reconciling and Stalled follow kstatus; the others say which check holds the
	// GitTarget back.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Streams counts the types this GitTarget watches, by watch state.
	// +optional
	Streams *StreamsStatus `json:"streams,omitempty"`

	// Retention counts the documents a resync kept because spec.prune.mode did not
	// allow removing them. A delete observed on the cluster and not mirrored under
	// "Never" is not counted, so a "Never" folder can report zero. It is
	// information only and changes no condition.
	// +optional
	Retention *GitTargetRetentionStatus `json:"retention,omitempty"`

	// Placement is this folder's layout as the last scan resolved it: whether a
	// kustomization governs new documents, which one, and which bases the folder
	// renders but may not write. The LayoutResolved condition gives the verdict.
	// +optional
	Placement *GitTargetPlacementStatus `json:"placement,omitempty"`
}

GitTargetStatus defines the observed state of GitTarget.

func (*GitTargetStatus) DeepCopy

func (in *GitTargetStatus) DeepCopy() *GitTargetStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetStatus.

func (*GitTargetStatus) DeepCopyInto

func (in *GitTargetStatus) DeepCopyInto(out *GitTargetStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type GrantFrom added in v0.54.0

type GrantFrom string

GrantFrom is where a grant admits referring objects from. +kubebuilder:validation:Enum=Same;Names;Selector;All

const (
	// GrantFromSame admits the namespace of the object that holds the grant.
	GrantFromSame GrantFrom = "Same"
	// GrantFromNames admits exactly the namespaces the grant lists in names.
	GrantFromNames GrantFrom = "Names"
	// GrantFromSelector admits the namespaces whose labels match the grant's selector.
	GrantFromSelector GrantFrom = "Selector"
	// GrantFromAll admits every namespace.
	GrantFromAll GrantFrom = "All"
)

type GrantNamespace added in v0.54.0

type GrantNamespace string

GrantNamespace is a namespace a grant admits, by exact name. A variable and "*" are refused. +kubebuilder:validation:MaxLength=63 +kubebuilder:validation:XValidation:rule="self != '{consumer.namespace}' && self != '{consumer.name}'",message="names: a variable is refused, because names are matched against the consumer's namespace and '{consumer.namespace}' would admit every consumer; use from: All to admit every namespace, or from: Same for the namespace of the object holding the grant" +kubebuilder:validation:XValidation:rule="self != '*'",message="names: '*' is refused; use from: All to admit every namespace" +kubebuilder:validation:XValidation:rule="self == '{consumer.namespace}' || self == '{consumer.name}' || self == '*' || self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="names holds namespace names (DNS labels)"

type KnownHostsReference

type KnownHostsReference struct {
	// Kind is "ConfigMap" or "Secret". Defaults to "ConfigMap".
	// +optional
	// +kubebuilder:validation:Enum=ConfigMap;Secret
	// +kubebuilder:default=ConfigMap
	Kind string `json:"kind,omitempty"`

	// Name is the name of the ConfigMap or Secret. Its "known_hosts" key is read,
	// or "ssh_known_hosts" (the key Argo CD's argocd-ssh-known-hosts-cm uses) when
	// that is absent.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

KnownHostsReference points at a namespace-local ConfigMap or Secret that holds SSH known_hosts host-trust material. The data is read from the "known_hosts" key, falling back to "ssh_known_hosts" (the key Argo CD's argocd-ssh-known-hosts-cm ConfigMap uses, for host keys copied out of it).

func (*KnownHostsReference) DeepCopy

func (in *KnownHostsReference) DeepCopy() *KnownHostsReference

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KnownHostsReference.

func (*KnownHostsReference) DeepCopyInto

func (in *KnownHostsReference) DeepCopyInto(out *KnownHostsReference)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProvider added in v0.54.0

type KubeProvider struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata.
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of KubeProvider.
	// +required
	Spec KubeProviderSpec `json:"spec"`

	// status defines the observed state of KubeProvider.
	// +optional
	Status KubeProviderStatus `json:"status,omitempty,omitzero"`
}

KubeProvider is a connection to a Kubernetes cluster and the identity used there: a kubeconfig Secret in its namespace, or the operator's own identity where the installation allows it. GitTargets mirror from it and applier claims reach their applier through it, as its spec.allowedGitTargets and spec.allowedApplierClaims allow.

func (*KubeProvider) AdmitsApplierClaim added in v0.54.0

func (p *KubeProvider) AdmitsApplierClaim(
	consumer types.NamespacedName, nsLabels map[string]string,
) (KubeProviderApplierClaimScope, error)

AdmitsApplierClaim reports what spec.allowedApplierClaims gives the applier claim consumer, by the labels its namespace carries in the control cluster.

func (*KubeProvider) AdmitsGitTarget added in v0.54.0

func (p *KubeProvider) AdmitsGitTarget(
	consumer types.NamespacedName, nsLabels map[string]string,
) (KubeProviderGitTargetScope, error)

AdmitsGitTarget reports what spec.allowedGitTargets gives the GitTarget consumer, by the labels its namespace carries in the control cluster.

func (*KubeProvider) AuditRoute added in v0.54.0

func (p *KubeProvider) AuditRoute() string

AuditRoute is the route this provider's attribution facts are keyed under: spec.attribution.auditRoute, or DefaultAuditRoute when that is empty. It is resolved through this method rather than read off the field so no caller ever handles the empty case.

func (*KubeProvider) DeepCopy added in v0.54.0

func (in *KubeProvider) DeepCopy() *KubeProvider

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProvider.

func (*KubeProvider) DeepCopyInto added in v0.54.0

func (in *KubeProvider) DeepCopyInto(out *KubeProvider)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*KubeProvider) DeepCopyObject added in v0.54.0

func (in *KubeProvider) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*KubeProvider) DeletesFinishedCommitRequests added in v0.55.0

func (p *KubeProvider) DeletesFinishedCommitRequests() bool

DeletesFinishedCommitRequests reports whether finished CommitRequests on this provider's cluster are deleted.

func (*KubeProvider) DescribeAllowedApplierClaims added in v0.54.0

func (p *KubeProvider) DescribeAllowedApplierClaims() string

DescribeAllowedApplierClaims names the namespaces spec.allowedApplierClaims admits.

func (*KubeProvider) DescribeAllowedGitTargets added in v0.54.0

func (p *KubeProvider) DescribeAllowedGitTargets() string

DescribeAllowedGitTargets names the namespaces spec.allowedGitTargets admits.

func (*KubeProvider) IsInCluster added in v0.54.0

func (p *KubeProvider) IsInCluster() bool

IsInCluster reports whether this provider asks for the operator's own identity (spec.inCluster). Whether it may have it is the installation's decision, not this object's.

func (*KubeProvider) Key added in v0.54.0

Key is this provider's namespace and name, the identity the watch data plane keys its source cluster on.

func (*KubeProvider) ServesCommitRequests added in v0.55.0

func (p *KubeProvider) ServesCommitRequests() bool

ServesCommitRequests reports whether GitOps Reverser serves the CommitRequests created on this provider's cluster, through its own watch of it: spec.commitRequests is one of the two Reconcile values, and the provider names a kubeconfig.

func (*KubeProvider) SetObservedGeneration added in v0.54.0

func (p *KubeProvider) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*KubeProvider) StatusConditions added in v0.54.0

func (p *KubeProvider) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type KubeProviderApplierClaimGrant added in v0.54.0

type KubeProviderApplierClaimGrant struct {
	// ConsumerNamespaces are the namespaces whose FluxClaims and ArgoCDClaims this
	// grant admits. from: "Same" is this KubeProvider's namespace.
	// +required
	ConsumerNamespaces ConsumerNamespaces `json:"consumerNamespaces"`

	// ApplierNamespaces are the namespaces, in this KubeProvider's cluster, where
	// the Kustomization or Application of an admitted applier claim may be: exact
	// names, "{consumer.namespace}" for the namespace named like the claim's, or
	// "*" for every namespace. The scope is the union over every grant admitting
	// the claim, checked when the claim reconciles and when a grant changes. An
	// applier outside it is refused (ApplierNamespaceNotAllowed), and a claim
	// holding it hands it back.
	// +required
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	ApplierNamespaces []ScopeNamespace `json:"applierNamespaces"`
}

KubeProviderApplierClaimGrant admits the FluxClaims and ArgoCDClaims of some namespaces to hold an applier through a KubeProvider, and bounds the namespaces that applier may be in.

func DefaultKubeProviderApplierClaimGrants added in v0.54.0

func DefaultKubeProviderApplierClaimGrants() []KubeProviderApplierClaimGrant

DefaultKubeProviderApplierClaimGrants is KubeProvider.spec.allowedApplierClaims when it is omitted: applier claims in the provider's own namespace, holding appliers in the namespace of the same name.

func (*KubeProviderApplierClaimGrant) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderApplierClaimGrant.

func (*KubeProviderApplierClaimGrant) DeepCopyInto added in v0.54.0

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderApplierClaimScope added in v0.54.0

type KubeProviderApplierClaimScope struct {
	// Admitted reports whether some grant admits the applier claim's namespace.
	Admitted bool
	// ApplierNamespaces is the union of the admitting grants' applierNamespaces,
	// consumer variables expanded. "*" is every namespace.
	ApplierNamespaces []string
}

KubeProviderApplierClaimScope is what a KubeProvider's allowedApplierClaims give an applier claim. +kubebuilder:object:generate=false

func (KubeProviderApplierClaimScope) AllowsApplierNamespace added in v0.54.0

func (s KubeProviderApplierClaimScope) AllowsApplierNamespace(namespace string) bool

AllowsApplierNamespace reports whether an applier in namespace may be held.

type KubeProviderAttribution added in v0.54.0

type KubeProviderAttribution struct {
	// AuditRoute is the route this cluster's audit events arrive on: the <route>
	// in the API server's audit webhook URL, /audit-webhook/<route>. When several
	// logical clusters share one webhook backend, it is instead the value of the
	// audit-event annotation that --author-attribution-audit-route-annotation-key
	// names. KubeProviders with the same route read the same cluster's
	// attribution facts.
	//
	// Empty means <namespace>.<name>. Set it when several KubeProviders in this
	// namespace connect to one cluster, since an API server posts under one
	// route.
	//
	// A route belongs to one namespace:
	//
	// - the namespace the route starts with (<namespace>.), when a KubeProvider
	//   there carries it;
	// - otherwise, the namespace of the oldest KubeProvider carrying it.
	//
	// KubeProviders in another namespace that carry the route report
	// Stalled=True, reason AuditRouteConflict, and are not used.
	// +optional
	// +kubebuilder:validation:MaxLength=253
	// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
	AuditRoute string `json:"auditRoute,omitempty"`
}

KubeProviderAttribution holds the per-cluster author-attribution settings. It exists as a block so later per-cluster knobs (grace, mode) have a home beside auditRoute.

func (*KubeProviderAttribution) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderAttribution.

func (*KubeProviderAttribution) DeepCopyInto added in v0.54.0

func (in *KubeProviderAttribution) DeepCopyInto(out *KubeProviderAttribution)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderClient added in v0.54.0

type KubeProviderClient struct {
	// QPS is the sustained request rate to this cluster, in queries per second.
	// Defaults to 20.
	// +optional
	// +kubebuilder:validation:Minimum=1
	QPS *int32 `json:"qps,omitempty"`

	// Burst is how many requests to this cluster may exceed qps at once. Defaults
	// to 30.
	// +optional
	// +kubebuilder:validation:Minimum=1
	Burst *int32 `json:"burst,omitempty"`
}

KubeProviderClient holds the per-cluster kube-client throttles.

func (*KubeProviderClient) DeepCopy added in v0.54.0

func (in *KubeProviderClient) DeepCopy() *KubeProviderClient

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderClient.

func (*KubeProviderClient) DeepCopyInto added in v0.54.0

func (in *KubeProviderClient) DeepCopyInto(out *KubeProviderClient)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderCommitRequestsStatus added in v0.55.0

type KubeProviderCommitRequestsStatus struct {
	// Namespaces are the namespaces whose CommitRequests are watched: the ones
	// this KubeProvider lends the GitTargets that mirror through it. "*" is
	// every namespace, in one watch.
	// +optional
	// +listType=set
	Namespaces []string `json:"namespaces,omitempty"`
}

KubeProviderCommitRequestsStatus is what a KubeProvider serves of its cluster's CommitRequests.

func (*KubeProviderCommitRequestsStatus) DeepCopy added in v0.55.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderCommitRequestsStatus.

func (*KubeProviderCommitRequestsStatus) DeepCopyInto added in v0.55.0

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderGitTargetGrant added in v0.54.0

type KubeProviderGitTargetGrant struct {
	// ConsumerNamespaces are the namespaces whose GitTargets this grant admits.
	// from: "Same" is this KubeProvider's namespace.
	// +required
	ConsumerNamespaces ConsumerNamespaces `json:"consumerNamespaces"`

	// SourceNamespaces are the source-cluster namespaces that the WatchRules of an
	// admitted GitTarget may read, in rules[].sourceNamespace: exact names,
	// "{consumer.namespace}" for the namespace named like the GitTarget's, or "*".
	// Omitted, this grant gives none.
	//
	// The scope is the union over every grant admitting the GitTarget. It permits
	// and selects nothing: a namespace is read only when a WatchRule names it. A
	// rule with sourceNamespace "*" needs "*" in a grant, and is refused, not
	// narrowed, without it. A WatchRule with any rule outside the scope is refused
	// as a whole (SourceNamespaceNotAllowed) when it reconciles or a grant
	// changes. The credential's RBAC still applies inside the scope.
	// +optional
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	SourceNamespaces []ScopeNamespace `json:"sourceNamespaces,omitempty"`

	// ClusterResources are the cluster-scoped types that the ClusterWatchRules of
	// an admitted GitTarget may mirror: resource.group
	// ("clusterroles.rbac.authorization.k8s.io"), a bare resource for the core
	// group ("nodes"), or "*" for every type, including CRDs installed later. Each
	// covers every served version. Omitted, this grant gives none.
	//
	// The scope is the union over every grant admitting the GitTarget, and mirrors
	// nothing until a ClusterWatchRule asks for a type. A rule with "*" in
	// apiGroups or resources needs "*" in a grant, and is refused, not narrowed,
	// without it. A ClusterWatchRule asking for any type outside the scope is
	// refused as a whole (ClusterResourceNotAllowed) when it reconciles.
	// +optional
	// +listType=set
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:MaxItems=64
	ClusterResources []ClusterResourceIdentity `json:"clusterResources,omitempty"`
}

KubeProviderGitTargetGrant admits the GitTargets of some namespaces to mirror through a KubeProvider, and bounds what they may read. It sets sourceNamespaces, clusterResources, or both. +kubebuilder:validation:XValidation:rule="has(self.sourceNamespaces) || has(self.clusterResources)",message="a grant in allowedGitTargets sets sourceNamespaces, clusterResources, or both; one that grants neither grants nothing"

func DefaultKubeProviderGitTargetGrants added in v0.54.0

func DefaultKubeProviderGitTargetGrants() []KubeProviderGitTargetGrant

DefaultKubeProviderGitTargetGrants is KubeProvider.spec.allowedGitTargets when it is omitted: GitTargets in the provider's own namespace, mirroring the namespace of the same name.

func (*KubeProviderGitTargetGrant) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderGitTargetGrant.

func (*KubeProviderGitTargetGrant) DeepCopyInto added in v0.54.0

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderGitTargetScope added in v0.54.0

type KubeProviderGitTargetScope struct {
	// Admitted reports whether some grant admits the GitTarget's namespace.
	Admitted bool
	// SourceNamespaces is the union of the admitting grants' sourceNamespaces,
	// consumer variables expanded. "*" is every namespace.
	SourceNamespaces []string
	// ClusterResources is the union of the admitting grants' clusterResources. "*"
	// is every cluster-scoped resource.
	ClusterResources []string
}

KubeProviderGitTargetScope is what a KubeProvider's allowedGitTargets give a GitTarget: whether it may mirror at all, and what. +kubebuilder:object:generate=false

func (KubeProviderGitTargetScope) AllowsAllClusterResources added in v0.54.0

func (s KubeProviderGitTargetScope) AllowsAllClusterResources() bool

AllowsAllClusterResources reports whether the scope holds "*" in clusterResources.

func (KubeProviderGitTargetScope) AllowsClusterResource added in v0.54.0

func (s KubeProviderGitTargetScope) AllowsClusterResource(group, resource string) bool

AllowsClusterResource reports whether a ClusterWatchRule may mirror resource in group.

func (KubeProviderGitTargetScope) AllowsSourceNamespace added in v0.54.0

func (s KubeProviderGitTargetScope) AllowsSourceNamespace(namespace string) bool

AllowsSourceNamespace reports whether a WatchRule may watch namespace; "*" asks for every namespace, which only a "*" in the scope allows.

type KubeProviderInCluster added in v0.54.0

type KubeProviderInCluster struct{}

KubeProviderInCluster selects the operator's own identity. It has no fields: the arm being set is the whole statement.

func (*KubeProviderInCluster) DeepCopy added in v0.54.0

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderInCluster.

func (*KubeProviderInCluster) DeepCopyInto added in v0.54.0

func (in *KubeProviderInCluster) DeepCopyInto(out *KubeProviderInCluster)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderList added in v0.54.0

type KubeProviderList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []KubeProvider `json:"items"`
}

KubeProviderList contains a list of KubeProvider.

func (*KubeProviderList) DeepCopy added in v0.54.0

func (in *KubeProviderList) DeepCopy() *KubeProviderList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderList.

func (*KubeProviderList) DeepCopyInto added in v0.54.0

func (in *KubeProviderList) DeepCopyInto(out *KubeProviderList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*KubeProviderList) DeepCopyObject added in v0.54.0

func (in *KubeProviderList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type KubeProviderSpec added in v0.54.0

type KubeProviderSpec struct {
	// SecretRef names the Secret, in this namespace, that holds a kubeconfig for
	// the cluster. With no key, the kubeconfig is read from "value", then
	// "value.yaml". A kubeconfig that uses exec auth, insecure-skip-tls-verify or
	// credentials named by file path is refused with Validated=False unless the
	// installation allows it. Set exactly one of secretRef and inCluster.
	// Immutable: delete and recreate the KubeProvider to change it.
	// +optional
	// +kubebuilder:validation:XValidation:rule="size(self.name) > 0",message="spec.secretRef.name must not be empty"
	SecretRef *meta.SecretKeyReference `json:"secretRef,omitempty"`

	// InCluster makes this KubeProvider use the operator's own identity in the
	// cluster it runs in. It is honored only for a KubeProvider the installation
	// lists in --in-cluster-kube-providers; any other reports Stalled=True, reason
	// InClusterNotAuthorized, and is never used. Set exactly one of secretRef and
	// inCluster. Immutable: delete and recreate the KubeProvider to change it.
	// +optional
	InCluster *KubeProviderInCluster `json:"inCluster,omitempty"`

	// AllowedGitTargets says which GitTargets may mirror through this
	// KubeProvider, and what. Each grant allows the GitTargets of some
	// namespaces, bounds which source namespaces their WatchRules may read
	// (sourceNamespaces), and lists the cluster-scoped types their
	// ClusterWatchRules may mirror (clusterResources).
	//
	// - Omitted: the GitTargets in this KubeProvider's namespace, reading only
	//   the source namespace of the same name and no cluster-scoped type.
	// - Empty list ([]): no GitTarget.
	// - A list of grants: the GitTargets that at least one grant allows, with
	//   what every grant that allows them permits.
	//
	// A list replaces the default: the GitTargets in this namespace keep access
	// only if at least one grant allows them.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=64
	// +kubebuilder:default={{consumerNamespaces: {from: Same}, sourceNamespaces: {"{consumer.namespace}"}}}
	AllowedGitTargets []KubeProviderGitTargetGrant `json:"allowedGitTargets"`

	// AllowedApplierClaims says which FluxClaims and ArgoCDClaims may hold an
	// applier through this KubeProvider, and in which namespaces that applier
	// may be (applierNamespaces). A namespace in allowedGitTargets gets no
	// applier access from that.
	//
	// - Omitted: the claims in this KubeProvider's namespace, holding appliers
	//   in the namespace of the same name.
	// - Empty list ([]): no claim.
	// - A list of grants: the claims that at least one grant allows, holding
	//   appliers in the applierNamespaces of every grant that allows them.
	//
	// A list replaces the default: the claims in this namespace keep access
	// only if at least one grant allows them.
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=64
	// +kubebuilder:default={{consumerNamespaces: {from: Same}, applierNamespaces: {"{consumer.namespace}"}}}
	AllowedApplierClaims []KubeProviderApplierClaimGrant `json:"allowedApplierClaims"`

	// Client sets the request rate limits for this cluster. Omitted, they are 20
	// QPS with a burst of 30. Refused beside inCluster.
	// +optional
	Client *KubeProviderClient `json:"client,omitempty"`

	// Attribution configures how commit authors are found from this cluster's
	// audit events.
	// +optional
	Attribution *KubeProviderAttribution `json:"attribution,omitempty"`

	// CommitRequests says whether GitOps Reverser serves the CommitRequests
	// created on this cluster, for the GitTargets that mirror through this
	// KubeProvider:
	//
	// - "Ignore": they are left alone.
	// - "Reconcile": the requests in the namespaces this KubeProvider lends
	//   its GitTargets in spec.allowedGitTargets are served, and their status
	//   is written. A finished request stays.
	// - "ReconcileAndDeleteFinished": as "Reconcile", and a finished request
	//   is annotated configbutler.ai/delete-after and deleted once that time
	//   has passed.
	//
	// Defaults to "Ignore". Only "Ignore" goes with inCluster: the
	// CommitRequests of the cluster GitOps Reverser runs in are always served.
	//
	// The credential needs get, list and watch on commitrequests, and update
	// on commitrequests/status, in the configbutler.ai group, in each lent
	// namespace; "ReconcileAndDeleteFinished" also needs patch and delete on
	// commitrequests. The CommitRequest CRD must be installed on the cluster.
	// The CommitRequestsServed condition reports how it goes.
	// +optional
	// +kubebuilder:validation:Enum=Ignore;Reconcile;ReconcileAndDeleteFinished
	// +kubebuilder:default=Ignore
	CommitRequests CommitRequestsPolicy `json:"commitRequests,omitempty"`
}

KubeProviderSpec defines the desired state of KubeProvider.

Exactly one credential arm is set, and there is no third: an omitted, malformed or refused credential must never fall through to the operator's own identity, so that identity is an arm of its own (inCluster) rather than what an absent secretRef means. +kubebuilder:validation:XValidation:rule="has(self.secretRef) != has(self.inCluster)",message="set exactly one of spec.secretRef and spec.inCluster"

The in-cluster client is the operator's own and is shared by everything that uses it, so a per-provider throttle cannot apply to it. Refused rather than ignored. +kubebuilder:validation:XValidation:rule="!has(self.inCluster) || !has(self.client)",message="spec.client is refused beside spec.inCluster: the operator's own client is not throttled per provider"

Which cluster a provider means must not silently change under the GitTargets mirroring through it, so the credential is immutable, including switching arms. A rotated kubeconfig is a change to the Secret, which stays allowed. +kubebuilder:validation:XValidation:rule="has(self.inCluster) == has(oldSelf.inCluster) && (!has(self.secretRef) || self.secretRef == oldSelf.secretRef)",message="spec.secretRef and spec.inCluster are immutable; delete and recreate the KubeProvider to point it at a different cluster"

The cluster GitOps Reverser runs in has no switch: its CommitRequests are always served, by the operator itself. +kubebuilder:validation:XValidation:rule="!has(self.inCluster) || !has(self.commitRequests) || self.commitRequests == 'Ignore'",message="spec.commitRequests must be Ignore beside spec.inCluster: the CommitRequests of the cluster GitOps Reverser runs in are always served"

func (*KubeProviderSpec) DeepCopy added in v0.54.0

func (in *KubeProviderSpec) DeepCopy() *KubeProviderSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderSpec.

func (*KubeProviderSpec) DeepCopyInto added in v0.54.0

func (in *KubeProviderSpec) DeepCopyInto(out *KubeProviderSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type KubeProviderStatus added in v0.54.0

type KubeProviderStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// AuditRoute is the route in use: spec.attribution.auditRoute, or
	// <namespace>.<name> when that is empty. The AuditFactsReceived condition
	// describes this route, and starts over when it changes.
	// +optional
	AuditRoute string `json:"auditRoute,omitempty"`

	// CommitRequests is what this KubeProvider serves of its cluster's
	// CommitRequests. Absent while spec.commitRequests is "Ignore".
	// +optional
	CommitRequests *KubeProviderCommitRequestsStatus `json:"commitRequests,omitempty"`

	// Conditions are the latest observations of this KubeProvider's state. Ready,
	// Reconciling and Stalled follow kstatus; Stalled=True with reason
	// InClusterNotAuthorized or AuditRouteConflict means the KubeProvider is not
	// used at all. Validated says whether the credential is safe and readable,
	// checked without connecting.
	//
	// AuditFactsReceived, which is not part of Ready, says whether an attribution
	// fact has ever arrived on status.auditRoute. It is True (Received) from the
	// first one on and never goes back. Until then it is Unknown, and the reason
	// says where to look: TransportUnavailable (the fact store refuses writes),
	// NoAuditDelivery (no audit events arrive at all), or RouteUnused (audit
	// events arrive, but never on this route). It is absent when author
	// attribution is off.
	//
	// CommitRequestsServed, which is not part of Ready either, says whether
	// this cluster's CommitRequests are served. It is absent while
	// spec.commitRequests is "Ignore". Each reason that is not True ends with
	// its fix:
	//
	// - True, Watching: watched in status.commitRequests.namespaces.
	// - True, NothingToWatch: no GitTarget mirroring through this KubeProvider
	//   is lent a namespace.
	// - False, CRDNotInstalled: the cluster serves no CommitRequest CRD.
	// - False, VersionNotServed: the CRD does not serve v1alpha3.
	// - False, Forbidden: the credential may not list or watch them.
	// - Unknown, Unreachable: the cluster's API could not be read.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

KubeProviderStatus defines the observed state of KubeProvider.

func (*KubeProviderStatus) DeepCopy added in v0.54.0

func (in *KubeProviderStatus) DeepCopy() *KubeProviderStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProviderStatus.

func (*KubeProviderStatus) DeepCopyInto added in v0.54.0

func (in *KubeProviderStatus) DeepCopyInto(out *KubeProviderStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type NothingToCommitAction added in v0.51.0

type NothingToCommitAction string

NothingToCommitAction is what a CommitRequest does when it ends with nothing to commit.

const (
	// NothingToCommitResolve finishes the request without a commit.
	NothingToCommitResolve NothingToCommitAction = "Resolve"
	// NothingToCommitCommitEmpty records the request's message in an empty commit.
	NothingToCommitCommitEmpty NothingToCommitAction = "CommitEmpty"
)

type PlacementMode added in v0.43.0

type PlacementMode string

PlacementMode is how a GitTarget folder is written: as plain files, as a kustomize root, or as an overlay over a base it may not write to.

const (
	// PlacementModePlain is a folder no kustomization governs.
	PlacementModePlain PlacementMode = "Plain"
	// PlacementModeKustomizeRoot is a self-contained folder governed by exactly one kustomization.
	PlacementModeKustomizeRoot PlacementMode = "KustomizeRoot"
	// PlacementModeKustomizeOverlay is a folder governed by one kustomization that renders a base
	// outside the write scope.
	PlacementModeKustomizeOverlay PlacementMode = "KustomizeOverlay"
)

type PruneMode added in v0.39.0

type PruneMode string

PruneMode enumerates which of the two deletion paths may remove a managed document from a GitTarget's folder.

              | source DELETE event | resync mark-and-sweep
Never         | suppressed          | suppressed
OnEvent       | applied             | suppressed
Always        | applied             | applied
const (
	// PruneNever removes nothing: neither an explicit source DELETE nor an inferred sweep drop.
	// The folder becomes an archive that only ever gains and updates documents.
	PruneNever PruneMode = "Never"
	// PruneOnEvent mirrors an observed source DELETE but never infers a deletion from a desired
	// snapshot. It is the effective default.
	PruneOnEvent PruneMode = "OnEvent"
	// PruneAlways enables both paths: full desired-state convergence, including removing a Git
	// document whose resource is absent from the snapshot.
	PruneAlways PruneMode = "Always"
)

func (PruneMode) AppliesEventDeletes added in v0.39.0

func (m PruneMode) AppliesEventDeletes() bool

AppliesEventDeletes reports whether an explicit source DELETE event may remove its managed document. True for OnEvent and Always. Call OrDefault first if the value may be unset.

func (PruneMode) MoreRestrictiveOf added in v0.39.0

func (m PruneMode) MoreRestrictiveOf(other PruneMode) PruneMode

MoreRestrictiveOf returns whichever of the two modes authorizes less deletion.

It exists for one situation: a write that was planned under one policy and is applied — or replayed after a rebase — under another. Taking the minimum makes the two directions behave the way an operator means them, and they are NOT symmetric:

  • LOOSENING must not escalate an already-planned write. A resync planned under `OnEvent` chose to keep its orphans against a desired snapshot that is now stale; someone declaring `Always` afterwards must not turn that stale plan into deletions. The new policy applies to the next resync, which gathers a fresh snapshot.
  • TIGHTENING must apply immediately. `Always` -> `OnEvent` is what an operator reaches for to stop deletions that have not landed yet; a policy change that queued work could outrun would not be a stop button at all.

func (PruneMode) OrDefault added in v0.39.0

func (m PruneMode) OrDefault() PruneMode

OrDefault resolves the EMPTY mode — unset, which is not a mode — to the documented default.

It exists because the empty string is the one value that must not be read literally: both predicates below answer false for it, which is `Never`'s behaviour, not `OnEvent`'s. Any value that has travelled through a struct literal, a retained pending write, or a stored object written before the schema default therefore passes through here first. An UNRECOGNIZED value is deliberately left alone — see SweepsOrphans.

func (PruneMode) SweepsOrphans added in v0.39.0

func (m PruneMode) SweepsOrphans() bool

SweepsOrphans reports whether a resync may drop a managed document that its desired snapshot did not contain — the inferred mark-and-sweep deletion. True only for Always.

An unrecognized value (an object stored under a schema that allowed more than this build does) reads as false here and as false in AppliesEventDeletes: an unknown policy retains everything, because the failure mode of guessing wrong in the other direction is deleting a tenant's manifests. The empty string is NOT such a value — it is unset, and OrDefault resolves it.

type PrunePolicy added in v0.39.0

type PrunePolicy struct {

	// Mode decides which deletions are mirrored. Defaults to "OnEvent".
	//
	// - "OnEvent": mirrors a delete observed on the source cluster; a resync
	//   removes nothing.
	// - "Never": removes nothing.
	// - "Always": as "OnEvent", and a resync also removes a document that has
	//   no resource on the cluster.
	// +optional
	// +kubebuilder:validation:Enum=Never;OnEvent;Always
	// +kubebuilder:default=OnEvent
	Mode PruneMode `json:"mode,omitempty"`
}

PrunePolicy declares which deletion paths may remove documents from a GitTarget's folder.

func (*PrunePolicy) DeepCopy added in v0.39.0

func (in *PrunePolicy) DeepCopy() *PrunePolicy

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrunePolicy.

func (*PrunePolicy) DeepCopyInto added in v0.39.0

func (in *PrunePolicy) DeepCopyInto(out *PrunePolicy)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*PrunePolicy) EffectiveMode added in v0.39.0

func (p *PrunePolicy) EffectiveMode() PruneMode

EffectiveMode resolves the declared mode to the one the controller acts on. A nil policy (the field was never written) and an empty mode (written without a mode, or stored before the schema default existed) both resolve to PruneOnEvent, so an unedited legacy GitTarget is safe.

The nil receiver is deliberate: it makes the omitted case answerable without every call site repeating a nil check, which is where a "safe unless someone forgot" default goes wrong.

type ReceiverType added in v0.53.0

type ReceiverType string

ReceiverType is the payload format a receiver accepts. The values are Flux's Receiver types.

const (
	// ReceiverTypeGitHub is a GitHub push event.
	ReceiverTypeGitHub ReceiverType = "github"
	// ReceiverTypeGitLab is a GitLab push event.
	ReceiverTypeGitLab ReceiverType = "gitlab"
	// ReceiverTypeGitea is a Gitea push event.
	ReceiverTypeGitea ReceiverType = "gitea"
	// ReceiverTypeGenericHMAC is a {"repository", "branch", "after"} body signed as Flux's
	// generic-hmac Receiver expects.
	ReceiverTypeGenericHMAC ReceiverType = "generic-hmac"
)

type RefusalAction added in v0.49.0

type RefusalAction string

RefusalAction is the action taken when a live write is refused. See GitTargetSpec.OnRefusal.

const (
	// RefusalActionIgnore records the refusal and does nothing else. It is the default.
	RefusalActionIgnore RefusalAction = "Ignore"
	// RefusalActionReapply asks the target's applier to apply the current tip, reverting the
	// refused edit.
	RefusalActionReapply RefusalAction = "Reapply"
)

type ResourceRule

type ResourceRule struct {
	// APIGroups are the API groups to match: "" is the core group, and "*" is
	// every group, as in ["", "apps"] or ["*"]. Omitted, each resource name is
	// looked up across the served groups and must be served by exactly one.
	// +optional
	APIGroups []string `json:"apiGroups,omitempty"`

	// APIVersions are the versions to match, or "*" for every served version.
	// Omitted, each resource's preferred version is used. The built-in Git path
	// has no version, so two versions of one object share a file unless the
	// GitTarget's placement template includes {version}.
	// +optional
	APIVersions []string `json:"apiVersions,omitempty"`

	// Resources are the resource types to match, by plural name ("configmaps",
	// "deployments"), or "*" for every type. Matching is exact and
	// case-insensitive; partial wildcards such as "pod*" match nothing, and
	// subresources ("pods/log") are rejected. For a custom resource whose name
	// more than one group serves, set apiGroups.
	// +required
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:Pattern=`^[^/]*$`
	Resources []string `json:"resources"`

	// ObjectSelector mirrors only the objects whose labels match, as a
	// standard label selector. Omitted or {} selects every object.
	//
	// An object that stops matching is handled like a deleted one: the
	// GitTarget's spec.prune.mode decides whether its document is removed.
	// With prune mode "Always", a resync also removes documents of the type
	// that the selector does not match.
	//
	// Two rules on one GitTarget that select the same type in overlapping
	// namespaces must use the same selector. The older rule keeps the type,
	// and the newer one is refused with ResourcesResolved=False, reason
	// CollectionOverlap. A selector that does not parse refuses the whole rule
	// with ResourcesResolved=False, reason InvalidObjectSelector.
	// +optional
	ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty"`

	// SourceNamespace is the source-cluster namespace this rule reads: omitted for
	// this WatchRule's own namespace, a name for another one, or "*" for every
	// namespace the KubeProvider's credential can read. Git placement follows each
	// object's own namespace, not this field.
	//
	// The KubeProvider's spec.allowedGitTargets must allow the namespace, through
	// the sourceNamespaces of a grant admitting the GitTarget; "*" needs "*"
	// there. One rule outside the grants refuses the whole WatchRule
	// (SourceNamespaceNotAllowed), checked when it reconciles.
	// +optional
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:Pattern=`^(\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)$`
	SourceNamespace string `json:"sourceNamespace,omitempty"`
}

ResourceRule selects namespaced resources by type, and optionally by API group, version, source namespace and label.

func (*ResourceRule) DeepCopy

func (in *ResourceRule) DeepCopy() *ResourceRule

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRule.

func (*ResourceRule) DeepCopyInto

func (in *ResourceRule) DeepCopyInto(out *ResourceRule)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*ResourceRule) DescribeSourceNamespace added in v0.39.0

func (r *ResourceRule) DescribeSourceNamespace(ruleNamespace string) string

DescribeSourceNamespace renders this item's requested source namespace for an operator-facing message. An omitted value is spelled out rather than shown as an empty string.

func (*ResourceRule) EffectiveSourceNamespace added in v0.39.0

func (r *ResourceRule) EffectiveSourceNamespace(ruleNamespace string) string

EffectiveSourceNamespace is the source-cluster namespace this ITEM names, given the namespace of the WatchRule that carries it: spec.rules[].sourceNamespace when set, and the rule's OWN namespace otherwise. For a wildcard item it returns "*", which is not a namespace name: the caller compiles it to the cluster-wide collection (the empty namespace) rather than watching it.

It is controller logic rather than an API-server default because an apiserver default cannot refer to metadata.namespace.

func (*ResourceRule) IsSourceNamespaceWildcard added in v0.39.0

func (r *ResourceRule) IsSourceNamespaceWildcard() bool

IsSourceNamespaceWildcard reports whether this item asks for every namespace its credential can read, as one cluster-wide stream.

type ResourceScope

type ResourceScope string

ResourceScope names a Kubernetes resource's scope. It is a purely INTERNAL matching vocabulary with no field in any CRD: the resolver uses both constants to align a rule's selector with the discovered scope of each type. A WatchRule always resolves Namespaced records, a ClusterWatchRule always Cluster ones, and which kind you write is the whole of how scope is chosen.

const (
	// ResourceScopeCluster indicates cluster-scoped resources (Nodes, ClusterRoles, etc.).
	ResourceScopeCluster ResourceScope = "Cluster"

	// ResourceScopeNamespaced indicates namespaced resources (Pods, Deployments, etc.).
	ResourceScopeNamespaced ResourceScope = "Namespaced"
)

type ScopeNamespace added in v0.54.0

type ScopeNamespace string

ScopeNamespace is a namespace in a grant's scope: a name, "{consumer.namespace}" for the namespace named like the consumer's, or "*" for every namespace. +kubebuilder:validation:MaxLength=63 +kubebuilder:validation:XValidation:rule="self != '{consumer.name}'",message="'{consumer.name}' is refused in a namespace scope: the consumer picks its own name, so any namespace could be reached by naming an object after it; use '{consumer.namespace}', namespace names, or '*'" +kubebuilder:validation:XValidation:rule="self == '*' || self == '{consumer.namespace}' || self == '{consumer.name}' || self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="a namespace scope holds a namespace name, '{consumer.namespace}' alone, or '*' alone"

type SourceNamespace added in v0.55.0

type SourceNamespace string

SourceNamespace is a namespace of a source cluster, by exact name, or "*" for every namespace. +kubebuilder:validation:MaxLength=63 +kubebuilder:validation:XValidation:rule="self == '*' || self.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",message="a source namespace is a namespace name, or '*' alone; variables are refused, because a source cluster's namespaces are not the control cluster's"

type StreamsStatus added in v0.50.0

type StreamsStatus struct {

	// Summary is ready/total for display, such as "3/4". Read ready and total
	// instead of parsing it.
	// +optional
	Summary string `json:"summary,omitempty"`

	// Total is how many types are watched.
	Total int32 `json:"total"`

	// Ready is how many of them are streaming events.
	Ready int32 `json:"ready"`

	// Replaying is how many of them are still receiving their initial list.
	Replaying int32 `json:"replaying"`

	// Blocked is how many of them cannot be watched right now.
	Blocked int32 `json:"blocked"`

	// PendingSample names up to five types that are not ready yet.
	// +optional
	// +kubebuilder:validation:MaxItems=5
	PendingSample []string `json:"pendingSample,omitempty"`
}

StreamsStatus is a bounded roll-up of the stream-readiness state for the types a GitTarget tracks, or a WatchRule or ClusterWatchRule resolves.

func (*StreamsStatus) DeepCopy added in v0.50.0

func (in *StreamsStatus) DeepCopy() *StreamsStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StreamsStatus.

func (*StreamsStatus) DeepCopyInto added in v0.50.0

func (in *StreamsStatus) DeepCopyInto(out *StreamsStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

type SuspendState added in v0.54.0

type SuspendState string

SuspendState is whether an applier applied on its own. An Argo CD Application with automated sync off counts as Suspended. +kubebuilder:validation:Enum=Suspended;NotSuspended

const (
	// SuspendStateSuspended is a Kustomization with spec.suspend: true, or an Application with
	// automated sync off.
	SuspendStateSuspended SuspendState = "Suspended"
	// SuspendStateNotSuspended is a Kustomization that applied on its own, or an Application with
	// automated sync on.
	SuspendStateNotSuspended SuspendState = "NotSuspended"
)

type WatchRule

type WatchRule struct {
	metav1.TypeMeta `json:",inline"`

	// metadata is a standard object metadata
	// +optional
	metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`

	// spec defines the desired state of WatchRule.
	// +required
	Spec WatchRuleSpec `json:"spec"`

	// status defines the observed state of WatchRule.
	// +optional
	Status WatchRuleStatus `json:"status,omitempty"`
}

WatchRule selects namespaced resources for a GitTarget in its namespace to mirror, by type, API group, version, source namespace and label. Each rule reads one source namespace: this WatchRule's own by default. Use a ClusterWatchRule for cluster-scoped types.

func (*WatchRule) DeepCopy

func (in *WatchRule) DeepCopy() *WatchRule

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRule.

func (*WatchRule) DeepCopyInto

func (in *WatchRule) DeepCopyInto(out *WatchRule)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*WatchRule) DeepCopyObject

func (in *WatchRule) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

func (*WatchRule) SetObservedGeneration added in v0.44.0

func (r *WatchRule) SetObservedGeneration(generation int64)

SetObservedGeneration records the generation this object's status describes.

func (*WatchRule) StatusConditions added in v0.44.0

func (r *WatchRule) StatusConditions() *[]metav1.Condition

StatusConditions returns the condition set to write through.

type WatchRuleList

type WatchRuleList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`

	Items []WatchRule `json:"items"`
}

WatchRuleList contains a list of WatchRule.

func (*WatchRuleList) DeepCopy

func (in *WatchRuleList) DeepCopy() *WatchRuleList

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRuleList.

func (*WatchRuleList) DeepCopyInto

func (in *WatchRuleList) DeepCopyInto(out *WatchRuleList)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*WatchRuleList) DeepCopyObject

func (in *WatchRuleList) DeepCopyObject() runtime.Object

DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.

type WatchRuleSpec

type WatchRuleSpec struct {
	// GitTargetRef names the GitTarget, in this namespace, that mirrors what this
	// WatchRule selects.
	// +required
	// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
	GitTargetRef meta.LocalObjectReference `json:"gitTargetRef"`

	// Rules select the resources to mirror. A resource matching any rule is
	// mirrored. Each rule names resource types, optionally narrowed by API group,
	// version, source namespace and labels. The GitTarget's spec.prune.mode
	// decides whether a removal on the cluster deletes the Git document.
	// +required
	// +kubebuilder:validation:MinItems=1
	Rules []ResourceRule `json:"rules"`
}

WatchRuleSpec defines the desired state of WatchRule.

func (*WatchRuleSpec) DeepCopy

func (in *WatchRuleSpec) DeepCopy() *WatchRuleSpec

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRuleSpec.

func (*WatchRuleSpec) DeepCopyInto

func (in *WatchRuleSpec) DeepCopyInto(out *WatchRuleSpec)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

func (*WatchRuleSpec) ObjectSelectors added in v0.50.0

func (s *WatchRuleSpec) ObjectSelectors() []*metav1.LabelSelector

ObjectSelectors returns every rule item's objectSelector, index-aligned with Rules.

type WatchRuleStatus

type WatchRuleStatus struct {
	// ObservedGeneration is the latest generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions are the latest observations of this WatchRule's state. Ready,
	// Reconciling and Stalled follow kstatus; ResourcesResolved,
	// SourceNamespaceAuthorized and StreamsRunning say which check holds the rule
	// back.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Streams counts the types this WatchRule resolves, by watch state.
	// +optional
	Streams *StreamsStatus `json:"streams,omitempty"`
}

WatchRuleStatus defines the observed state of WatchRule.

func (*WatchRuleStatus) DeepCopy

func (in *WatchRuleStatus) DeepCopy() *WatchRuleStatus

DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRuleStatus.

func (*WatchRuleStatus) DeepCopyInto

func (in *WatchRuleStatus) DeepCopyInto(out *WatchRuleStatus)

DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.

Jump to

Keyboard shortcuts

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