v1alpha3

package
v0.41.0 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 9 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 DefaultClusterProviderName = "default"

DefaultClusterProviderName is the conventionally opinionated ClusterProvider name that an omitted GitTarget.spec.clusterProviderRef points at. That defaulting is its ONLY special behavior: it is an ordinary user-created object that may omit kubeConfig (the operator's own in-cluster config) or set it to mirror a remote cluster, its audit route defaults to its name like every other provider's, and it is never created by the operator.

View Source
const SourceNamespaceWildcard = "*"

SourceNamespaceWildcard is the literal rules[].sourceNamespace token meaning "every source namespace this rule's GitTarget admits" — resolved live through GitTarget.spec.allowedSourceNamespaces, never "every namespace that exists".

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

This section is empty.

Types

type AgeEncryptionSpec

type AgeEncryptionSpec struct {
	// Enabled toggles age-based recipient resolution and bootstrap behavior.
	// +optional
	// +kubebuilder:default=false
	Enabled bool `json:"enabled,omitempty"`

	// Recipients defines how recipients are resolved.
	// +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 static list of age recipients (age1...).
	// +optional
	// +kubebuilder:validation:items:MinLength=1
	PublicKeys []string `json:"publicKeys,omitempty"`

	// ExtractFromSecret derives recipients from all *.agekey entries in encryption.secretRef.
	// +optional
	// +kubebuilder:default=false
	ExtractFromSecret bool `json:"extractFromSecret,omitempty"`

	// GenerateWhenMissing creates a date-named *.agekey entry in encryption.secretRef when no *.agekey exists.
	// +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 ClusterProvider added in v0.38.0

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

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

	// spec defines the desired state of ClusterProvider.
	// +required
	Spec ClusterProviderSpec `json:"spec"`

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

ClusterProvider is the cluster-scoped, read-side peer of GitProvider: it names a SOURCE cluster a GitTarget mirrors FROM, and owns that cluster's connectivity credential (spec.kubeConfig), namespace-access authorization (spec.allowedNamespaces), and per-cluster status. Its NAME is the cluster's identity for the watch data plane, and the DEFAULT for its audit route: attribution facts are partitioned by spec.attribution.auditRoute, which falls back to this name. Several providers may name one cluster by declaring one route, which is what an API server with a single audit webhook backend requires. No name is special: "default" is merely what an omitted GitTarget.spec.clusterProviderRef points at, and it may just as well name a remote cluster, since in-cluster-ness follows from spec.kubeConfig (omitted = in-cluster) rather than from the name.

It is cluster-scoped and requires platform-admin permissions to create. A GitTarget may reference it only from a namespace spec.allowedNamespaces admits — deny-by-default, enforced at admission and again before any watch starts.

func (*ClusterProvider) AllowsNamespace added in v0.38.0

func (p *ClusterProvider) AllowsNamespace(nsName string, nsLabels map[string]string) (bool, error)

AllowsNamespace reports whether a namespace (by name and labels) may reference this provider from a GitTarget, per spec.allowedNamespaces. It is DENY-BY-DEFAULT: a provider with no allowedNamespaces policy (neither names nor selector) admits no namespace. Names and selector are ORed. Enforced on every reconcile and NOWHERE else: checkSourceAuthorization in internal/controller/gittarget_source_cluster.go is the only non-test caller, and it returns before DeclareForGitTarget, so an unauthorized target starts no watch and writes no Git. Reconcile-time is deliberate rather than incidental — it re-evaluates continuously, so it also covers a policy tightened after the GitTarget was created, which an admission webhook could not see. There is no admission webhook for this (docs/spec/where-validation-lives.md). A malformed selector is a configuration error surfaced to the caller (not a silent allow). A malformed selector is a configuration error surfaced to the caller (not a silent allow).

It is one of two thin wrappers over NamespaceMatcher.Matches — the other being GitTarget.AllowsSourceNamespace — so the control-cluster and source-cluster policies can never drift in their deny-by-default, names-OR-selector semantics. The labels passed here are always CONTROL-cluster Namespace labels.

func (*ClusterProvider) AllowsSourceNamespaceOverride added in v0.39.0

func (p *ClusterProvider) AllowsSourceNamespaceOverride() bool

AllowsSourceNamespaceOverride reports whether this provider delegates source-namespace selection to the GitTargets it admits. See the field's documentation: false (the default) means a WatchRule mirroring through this provider may watch only its own namespace.

func (*ClusterProvider) AuditRoute added in v0.39.0

func (p *ClusterProvider) AuditRoute() string

AuditRoute is the identity this provider's attribution facts are keyed under: the route its cluster's audit events arrive on, defaulting to the provider's own name. It is resolved through this method rather than read off the field so no caller ever handles the empty case, the same shape as (api/v1alpha3).GitTarget.SourceCluster().

The default is what makes this change invisible to an existing install: one ClusterProvider per cluster already partitions its facts by name, so an unset field resolves exactly what it always resolved. Deliberately NOT conditional on locality: defaulting an in-cluster provider to the literal "default" would make that name reserved for the local cluster again, a rule this project enforced with CEL and then reversed before shipping (docs/finished/multi-cluster-author-attribution.md).

func (*ClusterProvider) DeepCopy added in v0.38.0

func (in *ClusterProvider) DeepCopy() *ClusterProvider

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

func (*ClusterProvider) DeepCopyInto added in v0.38.0

func (in *ClusterProvider) DeepCopyInto(out *ClusterProvider)

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

func (*ClusterProvider) DeepCopyObject added in v0.38.0

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

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

func (*ClusterProvider) IsInCluster added in v0.38.0

func (p *ClusterProvider) IsInCluster() bool

IsInCluster reports whether this provider represents the operator's own (in-cluster) cluster — i.e. it has no kubeConfig. The provider name is irrelevant: any name, including "default", may either omit kubeConfig for the in-cluster client or set it for a remote cluster.

type ClusterProviderAttribution added in v0.39.0

type ClusterProviderAttribution struct {
	// AuditRoute is the route this cluster's audit events arrive on. The sender is the API server's
	// webhook backend (https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#webhook-backend),
	// and this is the <name> segment its configured URL ends in: /audit-webhook/<name>. When several
	// logical clusters share one backend it is instead the value of the audit-event annotation named
	// by --author-attribution-audit-route-annotation-key.
	//
	// It partitions the attribution facts, so two ClusterProviders carrying the same route read one
	// cluster's facts, and two carrying different routes can never cross-credit an author.
	//
	// Empty means metadata.name. Set it when several ClusterProviders name one cluster, since an API
	// server has one webhook backend and so posts under one route: every other provider for that
	// cluster must be pointed at the same route or it resolves no authors at all. Set it also when
	// the events are labelled for something other than this object, such as a kcp logical cluster.
	// +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"`
}

ClusterProviderAttribution 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 (*ClusterProviderAttribution) DeepCopy added in v0.39.0

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

func (*ClusterProviderAttribution) DeepCopyInto added in v0.39.0

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

type ClusterProviderList added in v0.38.0

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

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

ClusterProviderList contains a list of ClusterProvider.

func (*ClusterProviderList) DeepCopy added in v0.38.0

func (in *ClusterProviderList) DeepCopy() *ClusterProviderList

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

func (*ClusterProviderList) DeepCopyInto added in v0.38.0

func (in *ClusterProviderList) DeepCopyInto(out *ClusterProviderList)

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

func (*ClusterProviderList) DeepCopyObject added in v0.38.0

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

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

type ClusterProviderReference added in v0.38.0

type ClusterProviderReference struct {
	// API Group of the referent.
	// +kubebuilder:default=configbutler.ai
	// +kubebuilder:validation:Enum=configbutler.ai
	Group string `json:"group,omitempty"`

	// Kind of the referent.
	// Optional because this reference currently only supports a single kind (ClusterProvider).
	// +optional
	// +kubebuilder:validation:Enum=ClusterProvider
	// +kubebuilder:default=ClusterProvider
	Kind string `json:"kind,omitempty"`

	// Name of the referent.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

ClusterProviderReference references the cluster-scoped ClusterProvider a GitTarget sources FROM. It is the read-side peer of GitProviderReference (which names the WRITE destination): a GitTarget names one ClusterProvider by name and its author-attribution facts, kube client, and namespace authorization all follow from that single reference. Group and Kind are typed (with defaults) for consistency with the project's other typed references.

func (*ClusterProviderReference) DeepCopy added in v0.38.0

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

func (*ClusterProviderReference) DeepCopyInto added in v0.38.0

func (in *ClusterProviderReference) DeepCopyInto(out *ClusterProviderReference)

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

type ClusterProviderSpec added in v0.38.0

type ClusterProviderSpec struct {
	// KubeConfig names the SOURCE CLUSTER this provider represents and the credentials to reach it
	// (Flux's meta.KubeConfigReference, embedded verbatim). OMITTED means the operator's own
	// in-cluster cluster, for any provider name. IMMUTABLE.
	//
	// The referenced Secret is resolved from the operator's namespace, so a cluster's credential
	// never has to live on that cluster. Only secretRef is honored; configMapRef is rejected. When
	// secretRef.key is empty the resolver reads "value" then "value.yaml" (Flux's order). Unsafe
	// kubeconfigs (exec auth, insecure-skip-tls-verify) are rejected with Validated=False unless the
	// operator opts in via flags.
	// +optional
	KubeConfig *meta.KubeConfigReference `json:"kubeConfig,omitempty"`

	// AllowedNamespaces is the deny-by-default policy for which CONTROL-CLUSTER namespaces may
	// reference this provider from a GitTarget. Empty (or omitted) means no namespace may
	// reference it. Its selector matches labels on Namespaces in the control cluster — the
	// cluster the operator's own CRs live in — never on the source cluster this provider names.
	// +optional
	AllowedNamespaces *NamespaceMatcher `json:"allowedNamespaces,omitempty"`

	// AllowSourceNamespaceOverride delegates SOURCE-namespace selection to the GitTargets this
	// provider admits. While false (the default) a WatchRule mirroring through this provider may
	// watch only its OWN namespace, whatever any GitTarget policy says.
	//
	// It grants no access by itself: an admitted GitTarget must still admit the namespace in its
	// spec.allowedSourceNamespaces, and the source credential's own RBAC remains the hard maximum.
	// What it delegates is the AUTHORITY to choose, so set it only when the owners of admitted
	// GitTargets are trusted to pick a subset of what that credential may read. Every
	// cross-namespace request needs it, including a rules[].sourceNamespace of "*". It does not
	// apply to ClusterWatchRule, which selects no namespaces at all.
	// +optional
	// +kubebuilder:default=false
	AllowSourceNamespaceOverride bool `json:"allowSourceNamespaceOverride,omitempty"`

	// QPS overrides the operator's outgoing kube-client query-per-second throttle for this
	// cluster's watches and discovery. Omitted, the operator-wide --source-cluster-qps applies.
	// Ignored when kubeConfig is omitted (the in-cluster client is not per-provider).
	// +optional
	// +kubebuilder:validation:Minimum=1
	QPS *int32 `json:"qps,omitempty"`

	// Burst overrides the operator's outgoing kube-client burst for this cluster. Omitted, the
	// operator-wide --source-cluster-burst applies. Ignored when kubeConfig is omitted.
	// +optional
	// +kubebuilder:validation:Minimum=1
	Burst *int32 `json:"burst,omitempty"`

	// Attribution groups this cluster's author-attribution settings. The block is spelled
	// "attribution" rather than "authorAttribution" even though the operator flags are
	// --author-attribution-*: the prefix groups a flat flag namespace, and a block on a
	// source-cluster object already supplies that scope.
	// +optional
	Attribution *ClusterProviderAttribution `json:"attribution,omitempty"`
}

ClusterProviderSpec defines the desired state of ClusterProvider.

kubeConfig is IMMUTABLE and OPTIONAL: which physical cluster a provider name means must not silently change under the GitTargets bound to it, and an OMITTED kubeConfig means the operator's own (in-cluster) cluster. That choice is free for EVERY name, "default" included — a provider named "default" may just as well carry a kubeConfig and mirror a remote cluster. The name is an identity, not a claim about which cluster it points at.

+kubebuilder:validation:XValidation:rule="has(self.kubeConfig) == has(oldSelf.kubeConfig) && (!has(self.kubeConfig) || self.kubeConfig == oldSelf.kubeConfig)",message="spec.kubeConfig is immutable; delete and recreate the ClusterProvider to point a name at a different cluster"

configMapRef (Flux workload-identity auth) is present in meta.KubeConfigReference's schema but deferred here; reject it so the v1alpha3 contract is "secretRef only". +kubebuilder:validation:XValidation:rule="!has(self.kubeConfig) || !has(self.kubeConfig.configMapRef)",message="spec.kubeConfig.configMapRef (workload-identity auth) is not yet supported; use secretRef"

secretRef.name comes from the external meta.KubeConfigReference schema, which marks it required but permits the empty string; an empty name can never resolve a Secret, so reject it here. +kubebuilder:validation:XValidation:rule="!has(self.kubeConfig) || !has(self.kubeConfig.secretRef) || size(self.kubeConfig.secretRef.name) > 0",message="spec.kubeConfig.secretRef.name must not be empty"

func (*ClusterProviderSpec) DeepCopy added in v0.38.0

func (in *ClusterProviderSpec) DeepCopy() *ClusterProviderSpec

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

func (*ClusterProviderSpec) DeepCopyInto added in v0.38.0

func (in *ClusterProviderSpec) DeepCopyInto(out *ClusterProviderSpec)

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

type ClusterProviderStatus added in v0.38.0

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

	// Conditions report the provider's readiness: Validated (kubeconfig inputs are safe and
	// resolvable, asserted without a network dial) plus the aggregated Ready and the kstatus
	// Reconciling/Stalled pair. Runtime reachability/discovery health and a last-audit-event
	// timestamp are deferred until authenticated remote ingest wires them from the watch engine.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
}

ClusterProviderStatus defines the observed state of ClusterProvider.

func (*ClusterProviderStatus) DeepCopy added in v0.38.0

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

func (*ClusterProviderStatus) DeepCopyInto added in v0.38.0

func (in *ClusterProviderStatus) DeepCopyInto(out *ClusterProviderStatus)

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

type ClusterResourceRule

type ClusterResourceRule struct {
	// Operations to watch. If empty, watches all operations (CREATE, UPDATE, DELETE).
	// Supports: CREATE, UPDATE, DELETE, or * (wildcard for all operations).
	// Examples:
	//   - ["CREATE", "UPDATE"] watches only creation and updates
	//   - ["*"] or [] watches all operations
	// +optional
	Operations []OperationType `json:"operations,omitempty"`

	// APIGroups to match. Empty string ("") matches the core API group.
	// If omitted, GitOps Reverser resolves the resource name across all served API groups.
	// Wildcards supported: "*" matches all groups.
	// Examples:
	//   - [""] matches core API (nodes, namespaces)
	//   - ["rbac.authorization.k8s.io"] matches RBAC resources
	//   - ["*"] matches all groups
	//   - [] resolves a named resource only when it is served by one API group
	// +optional
	APIGroups []string `json:"apiGroups,omitempty"`

	// APIVersions to match. If empty, uses the preferred served version for each group/resource.
	// Wildcards supported: "*" matches all versions.
	// Examples:
	//   - ["v1"] matches only v1 version
	//   - ["*"] matches all served versions
	//   - [] matches the preferred served version
	// +optional
	APIVersions []string `json:"apiVersions,omitempty"`

	// Resources to match (plural names like "nodes", "clusterroles").
	// This field is required and determines which resource types trigger this rule.
	// Wildcard semantics follow Kubernetes admission webhook patterns:
	//   - "*" matches all resources
	//   - "nodes" matches exactly nodes
	//   - "pods" matches exactly pods (for namespaced scope)
	//
	// Note: Subresources cannot be added here. Values containing "/" (for example
	// "pods/log" or "pods/*") are rejected by the API because subresources are
	// not supported for list/watch snapshot planning. Prefix/suffix wildcards
	// like "pod*" or "*.example.com" are NOT supported. Use exact matches or the
	// "*" wildcard for broad matching.
	// +required
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:Pattern=`^[^/]*$`
	Resources []string `json:"resources"`

	// Scope is REMOVED as a choice: a ClusterWatchRule is cluster-scoped only, so "Cluster" is the
	// only accepted value and also the default, making the field omittable. To watch NAMESPACED
	// resources, use a WatchRule in the tenant namespace and set spec.rules[].sourceNamespace.
	//
	// Deprecated: ClusterWatchRule is cluster-scope-only; use WatchRule with
	// spec.rules[].sourceNamespace for namespaced resources. Removed one release from now, or at
	// v1beta1.
	// +optional
	// +kubebuilder:default=Cluster
	// +kubebuilder:validation:Enum=Cluster
	Scope ResourceScope `json:"scope,omitempty"`
}

ClusterResourceRule defines which CLUSTER-SCOPED resources to watch. It deliberately has no sourceNamespace: cluster-scoped objects have no namespace, so there is nothing to select.

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 on the source cluster its GitTarget mirrors from — Nodes, PersistentVolumes, StorageClasses, ClusterRoles, CRDs, and the like. Scope is carried by the rule KIND, so it has no per-rule scope choice and no source-namespace selection.

It is cluster-scoped and requires cluster-admin permissions. Its targetRef names a GitTarget (namespace required), whose namespace must be admitted by that target's ClusterProvider. To mirror NAMESPACED resources use a WatchRule in the tenant namespace and set spec.rules[].sourceNamespace, whose "*" reaches every namespace the GitTarget admits.

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.

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 {
	// TargetRef references the GitTarget to use.
	// Must specify namespace.
	// +required
	TargetRef NamespacedTargetReference `json:"targetRef"`

	// Rules define which CLUSTER-SCOPED resources to watch.
	// Multiple rules create a logical OR - a resource matching ANY rule is watched.
	// A rule that resolves to no cluster-scoped type simply watches nothing; use a WatchRule with
	// spec.rules[].sourceNamespace for namespaced resources.
	// +required
	// +kubebuilder:validation:MinItems=1
	Rules []ClusterResourceRule `json:"rules"`
}

ClusterWatchRuleSpec defines the desired state of ClusterWatchRule.

func (*ClusterWatchRuleSpec) DeclaresNamespacedScope added in v0.39.0

func (s *ClusterWatchRuleSpec) DeclaresNamespacedScope() bool

DeclaresNamespacedScope reports whether a STORED ClusterWatchRule still selects namespaced resources through the removed scope choice. Admission rejects the value, but an object written before this release keeps it in etcd, so the compile path must refuse it rather than let the rule resolve as if it had asked for cluster scope.

It keys on the STORED value, not on what the selector happens to resolve: `resources: ["*"]` legitimately resolves cluster-scoped records, so inferring the refusal from the resolution would be ambiguous exactly where it matters.

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.

type ClusterWatchRuleStatus

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

	// Conditions represent the latest available observations of the ClusterWatchRule's state.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Streams is the bounded stream-readiness roll-up for the types this rule resolves.
	// +optional
	Streams *WatchRuleStreamsStatus `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 {
	// EventTemplate is a Go text/template string for per-event commit messages
	// (used when commitWindow is "0s"; one event per commit).
	// Available variables: Operation, Group, Version, Resource, Namespace, Name,
	// APIVersion, Username, GitTarget.
	// +optional
	EventTemplate string `json:"eventTemplate,omitempty"`

	// ReconcileTemplate is a Go text/template string for reconcile commit messages
	// (the mark-and-sweep reconcile path; one commit per synced type).
	// Available variables: Count, GitTarget, Group, Version, Resource, APIVersion, Revision.
	// Group/Version/Resource/APIVersion name the synced type for a per-type reconcile and
	// Revision is the cluster resourceVersion the reconcile was pinned to; both are empty
	// for a whole-target reconcile or a pure sweep, so a template referencing them must
	// render cleanly when they are absent (the default guards them with {{if}}).
	// +optional
	ReconcileTemplate string `json:"reconcileTemplate,omitempty"`

	// GroupTemplate is a Go text/template string for grouped commit messages
	// (the commit-window path; one commit per (author, gitTarget) group
	// produced by the batching pipeline).
	// Available variables: Author, GitTarget, Count, Operations (map of
	// CREATE/UPDATE/DELETE counts), Resources (slice of {Group, Version,
	// Resource, Namespace, Name}).
	// +optional
	GroupTemplate string `json:"groupTemplate,omitempty"`
}

CommitMessageSpec configures commit message formatting.

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
	// +required
	Spec CommitRequestSpec `json:"spec"`

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

CommitRequest is a one-shot "save" signal: creating one finalizes the open commit window for the referenced GitTarget instead of waiting for the silence timer. The resulting commit SHA is reported back in status.

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.

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 {
	// TargetRef names the GitTarget whose open commit window to finalize.
	// The GitTarget must be in the same namespace as this CommitRequest.
	// +required
	TargetRef LocalTargetReference `json:"targetRef"`

	// Message is an optional commit message for the finalized commit. When
	// omitted, the generated grouped-commit message is used.
	//
	// When present it is limited to 1-1024 Unicode characters and used
	// verbatim as the commit message. Newlines are allowed so a subject and
	// body can be supplied; all other ASCII control characters (including tab
	// and carriage return) are rejected.
	// +optional
	// +kubebuilder:validation:MinLength=1
	// +kubebuilder:validation:MaxLength=1024
	// +kubebuilder:validation:Pattern=`^[^\x00-\x09\x0B-\x1F\x7F]*$`
	Message string `json:"message,omitempty"`

	// CloseDelaySeconds optionally delays closing the open commit window for this
	// many seconds after the CommitRequest attaches to a matching open window, acting as
	// an extra collect window: matching changes that arrive in the meantime still join
	// that window and are included in the resulting commit. Omitted or 0 closes the
	// window as soon as the CommitRequest attaches. The window can still be closed
	// earlier by another author's change or by the provider's commit window timer,
	// exactly as without a CommitRequest.
	// +optional
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:validation:Maximum=300
	CloseDelaySeconds int32 `json:"closeDelaySeconds,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.

+kubebuilder:validation:XValidation:rule="self == oldSelf",message="CommitRequest spec is immutable after creation"

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 most recent generation observed by the controller.
	// +optional
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Conditions report the request's progress and terminal outcome: the Ready
	// summary, the kstatus Reconciling/Stalled pair, and the domain conditions
	// AuthorAttributed and Pushed.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchStrategy=merge
	// +patchMergeKey=type
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Branch is the Git branch the GitTarget commits to. Populated once the
	// finalize resolves.
	// +optional
	Branch string `json:"branch,omitempty"`

	// SHA is the resulting commit SHA. Set when the commit was pushed (Pushed=True).
	// +optional
	SHA string `json:"sha,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). False while in progress or when it failed.
  • Reconciling / Stalled: the kstatus progress / blocked pair. Reconciling=True while finalizing; Stalled=True when the finalize failed and needs attention.
  • AuthorAttributed (domain): binary and settled immediately. True (AttributedFromAdmission) when the submitter captured at admission named the commit author; False (CommitterFallback) when capture ran but no admission record exists, or False (AuthorCaptureDisabled) when capture is disabled. In either False case the request claims no actor. False is not a failure and does not affect Ready; the final Git author remains the matching watch window's author.
  • Pushed (domain): True once the commit is in the remote repository.

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 CommitSigningSpec

type CommitSigningSpec struct {
	// SecretRef references the Secret containing the signing key material.
	// Expected keys will be defined by the signing implementation.
	SecretRef LocalSecretReference `json:"secretRef"`

	// GenerateWhenMissing causes the operator to generate signing key material
	// in the referenced Secret when it is missing.
	// +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 configures the operator identity written as the commit committer.
	// When signing is enabled, Email must be a verified address on the account
	// that owns the signing key.
	// +optional
	Committer *CommitterSpec `json:"committer,omitempty"`

	// Message configures commit message formatting.
	// +optional
	Message *CommitMessageSpec `json:"message,omitempty"`

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

CommitSpec configures how gitops-reverser creates commits for a GitProvider.

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 CommitterSpec

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

	// Email is the git committer email.
	// +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 EncryptionSpec

type EncryptionSpec struct {
	// Provider selects the encryption provider.
	// +kubebuilder:default=sops
	// +kubebuilder:validation:Enum=sops
	Provider string `json:"provider"`

	// SecretRef references namespace-local Secret data used by the encryption provider.
	// +optional
	SecretRef LocalSecretReference `json:"secretRef,omitempty"`

	// Age configures age-specific encryption behavior 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 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 the Schema for the gitproviders API.

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.

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 GitProviderReference

type GitProviderReference struct {
	// API Group of the referent.
	// +kubebuilder:default=configbutler.ai
	// +kubebuilder:validation:Enum=configbutler.ai
	Group string `json:"group,omitempty"`

	// Kind of the referent.
	// Optional because this reference currently only supports a single kind (GitProvider).
	// Keeping it optional allows users to omit it while still benefiting from CRD defaulting.
	// +optional
	// +kubebuilder:validation:Enum=GitProvider
	// +kubebuilder:default=GitProvider
	Kind string `json:"kind,omitempty"`

	// Name of the referent.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

GitProviderReference references the GitProvider that backs a GitTarget. Many GitTargets may reference the same GitProvider; the reference is always to a GitProvider in the GitTarget's own namespace. Group and Kind are typed (with defaults) for consistency with the project's other local references and so the schema is explicit about what it accepts — currently only configbutler.ai/GitProvider.

func (*GitProviderReference) DeepCopy

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

func (*GitProviderReference) DeepCopyInto

func (in *GitProviderReference) DeepCopyInto(out *GitProviderReference)

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

type GitProviderSpec

type GitProviderSpec struct {
	// URL of the repository (HTTP/SSH).
	// Immutable: delete and recreate the GitProvider to point at a different repository.
	// +kubebuilder:validation:MinLength=1
	URL string `json:"url"`

	// SecretRef for authentication credentials (may be nil for public repos)
	SecretRef *LocalSecretReference `json:"secretRef,omitempty"`

	// KnownHostsRef optionally points at a namespace-local ConfigMap or Secret holding SSH
	// known_hosts, so host trust can be centralized across GitProviders on the same host instead
	// of repeated in every credentials Secret. It is used only for SSH and ignored for HTTP auth.
	// Host keys are resolved in priority order: the credentials Secret's own known_hosts, then this
	// ref, then the install-level default known-hosts ConfigMap; if none yields valid keys, SSH
	// fails closed.
	// +optional
	KnownHostsRef *KnownHostsReference `json:"knownHostsRef,omitempty"`

	// AllowedBranches restricts which branches can be written to.
	// +required
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	AllowedBranches []string `json:"allowedBranches"`

	// Push controls how events are coalesced into commits before pushing.
	// +optional
	Push *PushStrategy `json:"push,omitempty"`

	// Commit configures commit identity, message formatting, and signing behavior.
	// +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 allowedBranches (widening or narrowing the writable set is a normal change that must not require tearing down every GitTarget), plus auth, push tuning, 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 report repository validation and commit configuration readiness:
	// the Ready summary plus the kstatus Reconciling/Stalled pair.
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// SigningPublicKey is the operator's SSH signing public key in authorized_keys format.
	// Register this as a signing key on your git platform.
	// Only populated when commit.signing is configured and a signing key is available.
	// +optional
	SigningPublicKey string `json:"signingPublicKey,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 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 is the Schema for the gittargets API.

func (*GitTarget) AllowsSourceNamespace added in v0.39.0

func (g *GitTarget) AllowsSourceNamespace(nsName string, nsLabels map[string]string) (bool, error)

AllowsSourceNamespace reports whether a SOURCE-cluster namespace (by name and by the labels it carries IN THE SOURCE CLUSTER) may be mirrored into this target, per spec.allowedSourceNamespaces.

It is the source-side twin of ClusterProvider.AllowsNamespace, and both are thin wrappers over NamespaceMatcher.Matches so the two policies cannot drift. It answers only the POLICY question: the delegation flag, the provider's own admission of this target's namespace, and the three-valued "can the labels be read at all" question are the caller's (see internal/authz). An undeclared policy admits nothing here — callers apply the legacy rule themselves.

func (*GitTarget) DeclaresSourceNamespacePolicy added in v0.39.0

func (g *GitTarget) DeclaresSourceNamespacePolicy() bool

DeclaresSourceNamespacePolicy reports whether this target declares spec.allowedSourceNamespaces at all. A declared policy is EXHAUSTIVE — it bounds every WatchRule item writing here, with no self-namespace exception — while an absent one leaves a WatchRule its own namespace. Callers must branch on this rather than on emptiness: a declared-but-empty policy admits nothing.

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) 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) IsLocalSource added in v0.38.0

func (g *GitTarget) IsLocalSource() bool

IsLocalSource reports whether this GitTarget references the "default" ClusterProvider, which the watch data plane maps to its local cluster context. It is a NAME test, not a claim about the physical cluster: a "default" provider may carry a kubeConfig. It only supplies the pre-discovery default for SourceClusterReachable, which the watch manager overwrites as soon as it is wired.

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 ClusterProvider's NAME. It defaults to "default" when clusterProviderRef is unset — so a source-cluster-unaware caller still gets a concrete, non-empty name, and there is no "" sentinel. That name is a convention, not a claim about which physical cluster it is. The name keys the GVK→GVR registry and the watch context. It is NOT the attribution partition: facts are keyed by the referenced ClusterProvider's AuditRoute(), which defaults to this name but may differ when several providers share one cluster's single audit stream.

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 an exact resource type key ("{group}/{version}/{resource}", e.g.
	// "v1/configmaps", "apps/v1/deployments", or "v1/secrets"; core resources omit
	// the group) to the path template used for a new resource of that type. A path
	// selected for a sensitive resource (Secrets, plus any operator-configured
	// sensitive type) must be identity-complete so it cannot collide two distinct
	// sensitive resources onto one file.
	// +optional
	ByType map[string]string `json:"byType,omitempty"`

	// Default is the path template used for a new resource whose type has no ByType
	// entry. Omitted, it falls through to the folder's one supported kustomization
	// root, if it has exactly one, and then to the built-in canonical path.
	// A bundling default (one that is not identity-complete,
	// such as "all.yaml") is only valid when a sensitive resource can never reach it
	// — give every sensitive type an explicit identity-complete ByType entry.
	// +optional
	Default string `json:"default,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/spec/gittarget-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 canonical, versionless {namespaceOrCluster}/{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 is canonical. Because the canonical 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 GitTargetRetentionStatus added in v0.39.0

type GitTargetRetentionStatus struct {
	// Mode is the EFFECTIVE spec.prune.mode this roll-up was produced under. It is reported here
	// rather than left to be read from the spec because a GitTarget that predates spec.prune has
	// no stored value at all, so the spec alone cannot explain why documents are being kept.
	// +optional
	Mode PruneMode `json:"mode,omitempty"`

	// RetainedDocuments is how many managed documents the policy kept that a converged mirror
	// would not hold. Zero means a resync ran and found nothing to retain — the mirror is
	// converged. An ABSENT retention block means something different: no resync has reported yet.
	RetainedDocuments int32 `json:"retainedDocuments"`

	// ObservedTime is when this roll-up was last computed. A retention that begins just after a
	// reconcile is not visible until the next one, so read this before treating a zero as live.
	// +optional
	ObservedTime *metav1.Time `json:"observedTime,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 {
	// ProviderRef references the GitProvider that backs this target.
	// Immutable: delete and recreate the GitTarget to change its destination.
	// +required
	ProviderRef GitProviderReference `json:"providerRef"`

	// Branch to use for this target.
	// Must be one of the allowed branches in the provider.
	// Immutable: delete and recreate the GitTarget to change its destination.
	// +required
	// +kubebuilder:validation:MinLength=1
	Branch string `json:"branch"`

	// Path within the repository to write resources to, relative to the repository
	// root. Required and must be non-empty — there is no default, so a GitTarget can
	// never silently write to the repository root. To deliberately target the
	// repository root, set it to "." (the ArgoCD/Flux convention); an empty string is
	// rejected because it is too easy to leave blank by accident to be a deliberate
	// root choice. Any leading slash (absolute path) and ".." are rejected, and a
	// trailing slash is normalized away.
	// Immutable: delete and recreate the GitTarget to change its destination.
	// +required
	// +kubebuilder:validation:MinLength=1
	Path string `json:"path"`

	// Encryption defines encryption settings for Secret resource writes.
	// +optional
	Encryption *EncryptionSpec `json:"encryption,omitempty"`

	// Placement declares where NEW resources are written. It has no effect on a
	// resource that already has a document in Git — that document is always
	// updated in place at its existing location, wherever that is. Mutable: a
	// change only affects resources created after the change.
	// +optional
	Placement *GitTargetPlacementSpec `json:"placement,omitempty"`

	// ClusterProviderRef names the SOURCE cluster this GitTarget mirrors FROM, by referencing a
	// cluster-scoped ClusterProvider by name. That ClusterProvider owns the cluster's connectivity
	// credential, namespace-access authorization, and author-attribution mode. The default provider
	// name is "default" and must exist; it may be in-cluster or remote.
	// Immutable: a folder's source cluster is part of what the folder means; delete and recreate.
	// +kubebuilder:default={name: "default"}
	// +optional
	ClusterProviderRef *ClusterProviderReference `json:"clusterProviderRef,omitempty"`

	// AllowedSourceNamespaces bounds which SOURCE-cluster namespaces may be mirrored INTO this
	// target. It belongs to the DESTINATION, not to any requesting rule: once declared it is
	// exhaustive for every WatchRule that writes here, with no exception for a rule's own namespace.
	//
	// Omitted and empty differ. Omitted declares no policy, and a WatchRule keeps its own namespace;
	// a declared-but-empty policy admits nothing; `selector: {}` admits every source namespace.
	// Selector labels are read in the SOURCE cluster, so evaluating one needs Namespace
	// get/list/watch for that cluster's credential, while exact names need no such access. This is
	// also what a rules[].sourceNamespace of "*" resolves through. Naming any namespace other than
	// the WatchRule's own — including "*" — additionally requires the ClusterProvider to set
	// spec.allowSourceNamespaceOverride. It does NOT bound ClusterWatchRule, whose cluster-scoped
	// objects have no namespace. Full resolution table: docs/configuration.md.
	// +optional
	AllowedSourceNamespaces *NamespaceMatcher `json:"allowedSourceNamespaces,omitempty"`

	// Prune controls which deletion paths may remove documents from this target's folder: an
	// explicit source DELETE event, and the resync mark-and-sweep that infers a deletion from a
	// desired snapshot. Omitted, it is `mode: OnEvent` — observed deletes are mirrored, inferred
	// ones are not — for a stored GitTarget as well as a new one.
	// +optional
	Prune *PrunePolicy `json:"prune,omitempty"`
}

GitTargetSpec defines the desired state of GitTarget.

The destination fields — providerRef, branch, and path — are immutable. A GitTarget materializes the watched resources at exactly one (provider, 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.providerRef == oldSelf.providerRef",message="spec.providerRef is immutable; delete and recreate the GitTarget to change its destination" +kubebuilder:validation:XValidation:rule="self.branch == oldSelf.branch",message="spec.branch 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"

spec.clusterProviderRef names the SOURCE cluster a GitTarget mirrors FROM (see its field doc). It is immutable — a folder's source cluster is part of what the folder means, like providerRef/branch/path above — and defaults to a ClusterProvider named "default", so it is always populated (never nil) and always jumpable. +kubebuilder:validation:XValidation:rule="self.clusterProviderRef == oldSelf.clusterProviderRef",message="spec.clusterProviderRef is immutable; delete and recreate the GitTarget to change the cluster it mirrors"

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 represent the latest available observations of an object's state
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// LastPushTime is the timestamp of the last successful push.
	// +optional
	LastPushTime *metav1.Time `json:"lastPushTime,omitempty"`

	// Streams is the bounded data-plane roll-up over this GitTarget's tracked types.
	// Counts, never a per-type list, so it stays bounded however many types are watched.
	// +optional
	Streams *GitTargetStreamsStatus `json:"streams,omitempty"`

	// Retention reports documents a resync kept because this target's spec.prune.mode suppressed
	// the mark-and-sweep. It covers the INFERRED deletion path only: under `never`, a suppressed
	// source DELETE is not counted here, so a `never` target can report zero while still declining
	// to mirror deletes. It is informational either way — retention is the configured behavior,
	// never a fault, and no condition changes state because of it.
	// +optional
	Retention *GitTargetRetentionStatus `json:"retention,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 GitTargetStreamsStatus

type GitTargetStreamsStatus struct {
	// Summary is the display-only ready/total ratio, e.g. "3/4".
	//
	// It restates Ready and Total, which the API conventions would normally rule out. It exists
	// solely to feed the Streams printer column: a column can read one JSONPath, not format two.
	// Do not compute anything from it — read ready and total.
	// +optional
	Summary string `json:"summary,omitempty"`

	// Total is how many types this target tracks.
	Total int32 `json:"total"`

	// Ready is how many tracked types are Streaming.
	Ready int32 `json:"ready"`

	// Replaying is how many tracked types are still replaying their initial events.
	Replaying int32 `json:"replaying"`

	// Blocked is how many tracked types cannot currently be watched.
	Blocked int32 `json:"blocked"`
}

GitTargetStreamsStatus is a bounded roll-up of the stream readiness state for the types this GitTarget tracks.

func (*GitTargetStreamsStatus) DeepCopy

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

func (*GitTargetStreamsStatus) DeepCopyInto

func (in *GitTargetStreamsStatus) DeepCopyInto(out *GitTargetStreamsStatus)

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

type KnownHostsReference

type KnownHostsReference struct {
	// Kind of the referent: ConfigMap (default) or Secret.
	// +optional
	// +kubebuilder:validation:Enum=ConfigMap;Secret
	// +kubebuilder:default=ConfigMap
	Kind string `json:"kind,omitempty"`

	// Name of the ConfigMap or Secret.
	// +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 LocalSecretReference

type LocalSecretReference struct {
	// Group of the referent.
	// +kubebuilder:default=""
	// +optional
	Group string `json:"group,omitempty"`

	// Kind of the referent.
	// +kubebuilder:validation:Enum=Secret
	// +kubebuilder:default=Secret
	// +optional
	Kind string `json:"kind,omitempty"`

	// Name of the Secret.
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

LocalSecretReference is a typed reference to a Secret in the same namespace.

func (*LocalSecretReference) DeepCopy

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

func (*LocalSecretReference) DeepCopyInto

func (in *LocalSecretReference) DeepCopyInto(out *LocalSecretReference)

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

type LocalTargetReference

type LocalTargetReference struct {
	// API Group of the referent.
	// +kubebuilder:default=configbutler.ai
	// +kubebuilder:validation:Enum=configbutler.ai
	Group string `json:"group,omitempty"`

	// Kind of the referent.
	// Optional because this reference currently only supports a single kind (GitTarget).
	// Keeping it optional allows users to omit it while still benefiting from CRD defaulting.
	// +optional
	// +kubebuilder:validation:Enum=GitTarget
	// +kubebuilder:default=GitTarget
	Kind string `json:"kind,omitempty"`

	// Name of the referent.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`
}

func (*LocalTargetReference) DeepCopy

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

func (*LocalTargetReference) DeepCopyInto

func (in *LocalTargetReference) DeepCopyInto(out *LocalTargetReference)

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

type NamespaceMatcher added in v0.39.0

type NamespaceMatcher struct {

	// Names is an explicit allow-list of namespace names. Entries are namespace names (DNS-1123
	// labels), never patterns — `*` is rejected. To admit every namespace, declare `selector: {}`.
	// +optional
	// +listType=set
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:MaxLength=63
	// +kubebuilder:validation:items:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
	Names []string `json:"names,omitempty"`

	// Selector is a label selector matched against Namespace labels; a namespace whose labels
	// match is admitted. ORed with Names.
	// +optional
	Selector *metav1.LabelSelector `json:"selector,omitempty"`
}

NamespaceMatcher is the one deny-by-default namespace-policy SHAPE this API uses wherever a field bounds "which namespaces". It carries an explicit name allow-list and a label selector, ORed: a namespace is admitted if it is listed OR its labels match.

It is deny-by-default and the empty matcher is NOT "unrestricted": a matcher with neither names nor selector admits NOTHING. Every use of this shape is authorization, and the fail-open reading is the catastrophic one — so an absent field means "no policy declared" (which each call site interprets in its own legacy terms) while a declared-but-empty one means "admit nothing".

Two fields use it, and they mean namespaces in DIFFERENT clusters — which is exactly why the shape is shared but the fields are not:

  • ClusterProvider.spec.allowedNamespaces — control-cluster namespaces that may create a GitTarget using the provider. Selector labels come from the CONTROL cluster.
  • GitTarget.spec.allowedSourceNamespaces — source-cluster namespaces that may be mirrored into this target, by any rule kind. Selector labels come from the SOURCE cluster.

Because the two clusters differ, the LABEL half cannot be evaluated by one shared helper: only the caller knows which cluster's Namespace labels to read. Matches therefore takes the labels rather than fetching them, and MatchesName exists so an exact-name policy stays answerable when the labels cannot be read at all (see the source-scope service's degradation path).

func (*NamespaceMatcher) Declared added in v0.39.0

func (m *NamespaceMatcher) Declared() bool

Declared reports whether a policy exists at all. A nil matcher is "no policy declared"; a non-nil one is a declared policy even when it is empty (and an empty declared policy admits nothing). The distinction is load-bearing: an absent field keeps a caller's legacy scope, while a declared one is exhaustive.

func (*NamespaceMatcher) DeepCopy added in v0.39.0

func (in *NamespaceMatcher) DeepCopy() *NamespaceMatcher

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

func (*NamespaceMatcher) DeepCopyInto added in v0.39.0

func (in *NamespaceMatcher) DeepCopyInto(out *NamespaceMatcher)

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

func (*NamespaceMatcher) HasSelector added in v0.39.0

func (m *NamespaceMatcher) HasSelector() bool

HasSelector reports whether the matcher declares a label selector, i.e. whether evaluating it requires reading the Namespace's labels in that field's own cluster.

func (*NamespaceMatcher) Matches added in v0.39.0

func (m *NamespaceMatcher) Matches(nsName string, nsLabels map[string]string) (bool, error)

Matches reports whether a namespace (by name and by the labels it carries IN THE CLUSTER THIS FIELD DESCRIBES) is admitted. Names are checked before the selector, so the answer never depends on the labels when a name already admits. A malformed selector is returned as an error rather than a silent allow or a silent deny — it is a configuration mistake the operator must see. A nil matcher admits nothing.

func (*NamespaceMatcher) MatchesName added in v0.39.0

func (m *NamespaceMatcher) MatchesName(nsName string) bool

MatchesName reports whether nsName is in the matcher's explicit Names allow-list.

It is separate from Matches on purpose: the name half needs NO Namespace read, so a policy that admits by name keeps working against a cluster whose Namespace list/watch is Forbidden. Callers that can fail to read labels must consult this FIRST and only then fall through to the selector. A nil matcher matches nothing.

func (*NamespaceMatcher) SelectorAdmits added in v0.39.0

func (m *NamespaceMatcher) SelectorAdmits(nsLabels map[string]string) (bool, error)

SelectorAdmits reports whether the matcher's SELECTOR half alone — ignoring Names — admits a namespace carrying these labels. It exists for ENUMERATION: expanding a wildcard means asking this of every namespace in a snapshot, which Matches cannot do because its name check would short-circuit per candidate.

A nil matcher or a nil selector admits nothing; a present-but-EMPTY selector admits everything. That asymmetry is not incidental — LabelSelectorAsSelector returns labels.Nothing() for nil and labels.Everything() for an empty selector, which is exactly the absent-versus-declared distinction this type is built around, and `selector: {}` is the deliberate "every namespace" declaration.

func (*NamespaceMatcher) ValidateNames added in v0.39.0

func (m *NamespaceMatcher) ValidateNames() error

ValidateNames reports the first entry in Names that could never be a namespace name, or nil when every entry could be one.

The schema rejects these at admission, so this is the DEFENSIVE half: an object stored before that validation shipped keeps its value in etcd, where the only two options are to refuse it loudly or to honour the entries that happen to be valid. The second is silent narrowing — a policy that mirrors less than its author asked for, with nothing in status saying so — which is why callers must treat a non-nil error as "this policy cannot be evaluated as written" rather than as a smaller policy.

type NamespacedTargetReference

type NamespacedTargetReference struct {
	// API Group of the referent.
	// +kubebuilder:validation:Enum=configbutler.ai
	// +kubebuilder:default=configbutler.ai
	Group string `json:"group,omitempty"`

	// Kind of the referent.
	// Optional because this reference currently only supports a single kind (GitTarget).
	// Keeping it optional allows users to omit it while still benefiting from CRD defaulting.
	// +optional
	// +kubebuilder:validation:Enum=GitTarget
	// +kubebuilder:default=GitTarget
	Kind string `json:"kind,omitempty"`

	// Name of the referent.
	// +required
	// +kubebuilder:validation:MinLength=1
	Name string `json:"name"`

	// Required because ClusterWatchRule has no namespace.
	// +required
	// +kubebuilder:validation:MinLength=1
	Namespace string `json:"namespace"`
}

func (*NamespacedTargetReference) DeepCopy

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

func (*NamespacedTargetReference) DeepCopyInto

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

type OperationType

type OperationType string

OperationType specifies the type of operation that triggers a watch event. +kubebuilder:validation:Enum=CREATE;UPDATE;DELETE;*

const (
	// OperationCreate matches resource creation events.
	OperationCreate OperationType = "CREATE"
	// OperationUpdate matches resource update events.
	OperationUpdate OperationType = "UPDATE"
	// OperationDelete matches resource deletion events.
	OperationDelete OperationType = "DELETE"
	// OperationAll matches all operation types.
	OperationAll OperationType = "*"
)

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 selects which deletion paths are enabled. `Never` removes nothing; `OnEvent` mirrors an
	// observed source DELETE but never infers a deletion from a resync snapshot; `Always` enables
	// both, restoring full desired-state convergence. Omitted, it is `OnEvent`.
	// +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 PushStrategy

type PushStrategy struct {
	// CommitWindow is the rolling silence window used to coalesce events into
	// a single commit per (author, gitTarget). The timer resets on every event
	// arrival and a flush is triggered after this many seconds of silence.
	// Setting "0s" opts into per-event commits in the steady-state.
	// Defaults to "5s".
	// +optional
	CommitWindow *string `json:"commitWindow,omitempty"`
}

PushStrategy defines how events are coalesced into commits before pushing.

func (*PushStrategy) DeepCopy

func (in *PushStrategy) DeepCopy() *PushStrategy

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

func (*PushStrategy) DeepCopyInto

func (in *PushStrategy) DeepCopyInto(out *PushStrategy)

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

type ResourceRule

type ResourceRule struct {
	// Operations to watch. If empty, watches all operations (CREATE, UPDATE, DELETE).
	// Supports: CREATE, UPDATE, DELETE, or * (wildcard for all operations).
	// Examples:
	//   - ["CREATE", "UPDATE"] watches only creation and updates, ignoring deletions
	//   - ["*"] or [] watches all operations
	// +optional
	Operations []OperationType `json:"operations,omitempty"`

	// APIGroups to match. Empty string ("") matches the core API group.
	// If omitted, GitOps Reverser resolves the resource name across all served API groups.
	// Wildcards supported: "*" matches all groups.
	// Examples:
	//   - [""] matches core API (pods, services, configmaps)
	//   - ["apps"] matches apps API group (deployments, statefulsets)
	//   - ["", "apps"] matches both core and apps groups
	//   - ["*"] matches all groups
	//   - [] resolves a named resource only when it is served by one API group
	// +optional
	APIGroups []string `json:"apiGroups,omitempty"`

	// APIVersions to match. If empty, uses the preferred served version for each group/resource.
	// Wildcards supported: "*" matches all versions.
	// Examples:
	//   - ["v1"] matches only v1 version
	//   - ["v1", "v1beta1"] matches both versions
	//   - ["*"] matches all served versions
	//   - [] matches the preferred served version
	//
	// Multi-version note: the built-in cold-start Git path is versionless, so two
	// objects that differ only by API version resolve to the same file. To watch
	// several versions of a group/resource and keep them in separate files, give the
	// GitTarget a placement template that includes {version} (see GitTargetPlacementSpec).
	// +optional
	APIVersions []string `json:"apiVersions,omitempty"`

	// Resources to match (plural names like "pods", "configmaps").
	// This field is required and determines which resource types trigger this rule.
	// Wildcard semantics follow Kubernetes admission webhook patterns:
	//   - "*" matches all resources
	//   - "pods" matches exactly pods (case-insensitive)
	//
	// For custom resources, use the exact plural resource name and set apiGroups
	// when more than one served API group exposes that name.
	//
	// Note: Subresources cannot be added here. Values containing "/" (for example
	// "pods/log" or "pods/*") are rejected by the API because subresources are
	// not supported for list/watch snapshot planning. Prefix/suffix wildcards
	// like "pod*" or "*.example.com" are NOT supported. Use exact matches or the
	// "*" wildcard for broad matching.
	// +required
	// +kubebuilder:validation:MinItems=1
	// +kubebuilder:validation:items:MinLength=1
	// +kubebuilder:validation:items:Pattern=`^[^/]*$`
	Resources []string `json:"resources"`

	// SourceNamespace is the namespace this item watches IN THE SOURCE CLUSTER its GitTarget
	// mirrors from: omitted for this WatchRule's own namespace, an exact name for one other, or
	// "*" for every namespace the GitTarget's spec.allowedSourceNamespaces currently admits.
	//
	// "*" never means "every namespace that exists" — it expands to exactly what that policy
	// admits, so a target declaring no policy denies it. Naming any namespace other than this
	// rule's own, "*" included, additionally requires the GitTarget's ClusterProvider to admit the
	// target's namespace AND to set spec.allowSourceNamespaceOverride. Once the GitTarget declares
	// a policy it is exhaustive, so even an omitted sourceNamespace is checked against it.
	//
	// This changes only which namespace is WATCHED, never where objects are written: Git placement
	// follows each mirrored object's own namespace.
	// +optional
	// +kubebuilder:validation:MaxLength=63
	// +kubebuilder:validation:Pattern=`^(\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)$`
	SourceNamespace string `json:"sourceNamespace,omitempty"`
}

ResourceRule defines a set of namespaced resources to watch. Omitted API groups and versions are resolved from the served Kubernetes API surface. All fields except Resources are optional.

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 "*" — the caller must expand that through the GitTarget's policy rather than treat it as a namespace name.

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 to follow its GitTarget's admitted set.

func (*ResourceRule) OverridesSourceNamespace added in v0.39.0

func (r *ResourceRule) OverridesSourceNamespace(ruleNamespace string) bool

OverridesSourceNamespace reports whether this item asks for a source namespace OTHER than the WatchRule's own — the case that needs the ClusterProvider's delegation flag. A sourceNamespace that merely restates the rule's own namespace is not an override and stays the legacy case; "*" always is one, even against a policy that happens to list only that namespace, because a later policy edit would otherwise widen the watch with no platform-admin opt-in.

type ResourceScope

type ResourceScope string

ResourceScope names a Kubernetes resource's scope. It is an INTERNAL matching vocabulary: 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). The only field that still exposes it — ClusterResourceRule.scope — is narrowed to Cluster alone, so "Namespaced" is no longer a public choice anywhere in the API.

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

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

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 on the source cluster its GitTarget mirrors from, with filtering by operation, API group, version, and source namespace. Scope is carried by the rule KIND: a WatchRule never selects cluster-scoped types — use a ClusterWatchRule for those.

Each spec.rules[] item watches its own source namespace: this WatchRule's OWN namespace when omitted, an explicit name, or "*" for every namespace the GitTarget admits. Anything other than its own namespace passes the gate described on rules[].sourceNamespace. RBAC controls who may create or modify WatchRules per namespace.

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.

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 {
	// TargetRef references the GitTarget to use.
	// Must be in the same namespace.
	// +required
	TargetRef LocalTargetReference `json:"targetRef"`

	// Rules define which resources to watch, and in which source namespaces.
	// Multiple rules create a logical OR - a resource matching ANY rule is watched.
	// Each rule can specify operations, API groups, versions, resource types, and a source namespace.
	// +required
	// +kubebuilder:validation:MinItems=1
	Rules []ResourceRule `json:"rules"`
}

WatchRuleSpec defines the desired state of WatchRule. WatchRule selects NAMESPACED resources on its GitTarget's source cluster. Each rules[] item carries its own source namespace: omitted for this WatchRule's own namespace, an explicit name, or "*" for every namespace the GitTarget admits.

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.

type WatchRuleStatus

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

	// Conditions represent the latest available observations of an object's state
	// +optional
	// +listType=map
	// +listMapKey=type
	// +patchMergeKey=type
	// +patchStrategy=merge
	Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

	// Streams is the bounded stream-readiness roll-up for the types this rule resolves.
	// +optional
	Streams *WatchRuleStreamsStatus `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.

type WatchRuleStreamsStatus

type WatchRuleStreamsStatus struct {
	// Summary is the display-only ready/total ratio.
	// +optional
	Summary string `json:"summary,omitempty"`

	// Total is how many types this rule resolves.
	Total int32 `json:"total"`

	// Ready is how many resolved types are Streaming.
	Ready int32 `json:"ready"`

	// Replaying is how many resolved types are still replaying their initial events.
	Replaying int32 `json:"replaying"`

	// Blocked is how many resolved types cannot currently be watched.
	Blocked int32 `json:"blocked"`

	// PendingSample is a bounded sample of types not yet ready.
	// +optional
	// +kubebuilder:validation:MaxItems=5
	PendingSample []string `json:"pendingSample,omitempty"`
}

WatchRuleStreamsStatus is a bounded roll-up of the stream-readiness state for the types a WatchRule or ClusterWatchRule resolves.

func (*WatchRuleStreamsStatus) DeepCopy

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

func (*WatchRuleStreamsStatus) DeepCopyInto

func (in *WatchRuleStreamsStatus) DeepCopyInto(out *WatchRuleStreamsStatus)

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