Documentation
¶
Overview ¶
Package v1alpha3 contains API Schema definitions for the configbutler.ai v1alpha3 API group. +kubebuilder:object:generate=true +groupName=configbutler.ai
Index ¶
- Constants
- Variables
- type AgeEncryptionSpec
- type AgeRecipientsSpec
- type ClusterProvider
- func (p *ClusterProvider) AllowsAnySourceNamespace() bool
- func (p *ClusterProvider) AllowsNamespace(nsName string, nsLabels map[string]string) (bool, error)
- func (p *ClusterProvider) AuditRoute() string
- func (in *ClusterProvider) DeepCopy() *ClusterProvider
- func (in *ClusterProvider) DeepCopyInto(out *ClusterProvider)
- func (in *ClusterProvider) DeepCopyObject() runtime.Object
- func (p *ClusterProvider) IsInCluster() bool
- type ClusterProviderAttribution
- type ClusterProviderList
- type ClusterProviderSpec
- type ClusterProviderStatus
- type ClusterResourceRule
- type ClusterWatchRule
- type ClusterWatchRuleList
- type ClusterWatchRuleSpec
- type ClusterWatchRuleStatus
- type CommitMessageSpec
- type CommitRequest
- type CommitRequestList
- type CommitRequestSpec
- type CommitRequestStatus
- type CommitSigningSpec
- type CommitSpec
- type CommitterSpec
- type EncryptionSpec
- type GitProvider
- type GitProviderList
- type GitProviderSpec
- type GitProviderStatus
- type GitTarget
- type GitTargetCommitSpec
- type GitTargetList
- type GitTargetPlacementSpec
- type GitTargetPlacementStatus
- type GitTargetRetentionStatus
- type GitTargetSpec
- type GitTargetStatus
- type GitTargetStreamsStatus
- type KnownHostsReference
- type NamespaceMatcher
- type OperationType
- type PlacementMode
- type PruneMode
- type PrunePolicy
- type ResourceRule
- func (in *ResourceRule) DeepCopy() *ResourceRule
- func (in *ResourceRule) DeepCopyInto(out *ResourceRule)
- func (r *ResourceRule) DescribeSourceNamespace(ruleNamespace string) string
- func (r *ResourceRule) EffectiveSourceNamespace(ruleNamespace string) string
- func (r *ResourceRule) IsSourceNamespaceWildcard() bool
- func (r *ResourceRule) OverridesSourceNamespace(ruleNamespace string) bool
- type ResourceScope
- type WatchRule
- type WatchRuleList
- type WatchRuleSpec
- type WatchRuleStatus
- type WatchRuleStreamsStatus
Constants ¶
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.
const SourceNamespaceWildcard = "*"
SourceNamespaceWildcard is the literal rules[].sourceNamespace token meaning "every source namespace the GitTarget's credential can read", compiled to ONE cluster-wide list and watch.
It kept its spelling and changed its meaning: it used to resolve live through GitTarget.spec.allowedSourceNamespaces into a concrete set. That field is gone, so the token is bounded by source-cluster RBAC alone and is refused while the ClusterProvider does not set spec.allowAnySourceNamespace. See docs/design/source-scope-simplification.md, which is the definition of record.
Variables ¶
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.accessFrom), 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.accessFrom admits — deny-by-default, enforced at admission and again before any watch starts.
func (*ClusterProvider) AllowsAnySourceNamespace ¶ added in v0.43.0
func (p *ClusterProvider) AllowsAnySourceNamespace() bool
AllowsAnySourceNamespace 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) AllowsNamespace ¶ added in v0.38.0
AllowsNamespace reports whether a namespace (by name and labels) may reference this provider from a GitTarget, per spec.accessFrom. It is DENY-BY-DEFAULT: a provider with no accessFrom 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, never a silent allow.
The labels passed here are always CONTROL-cluster Namespace labels. This is now the only caller of NamespaceMatcher.Matches: the source-side twin was deleted with GitTarget.spec.allowedSourceNamespaces.
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.
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
func (in *ClusterProviderAttribution) DeepCopy() *ClusterProviderAttribution
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProviderAttribution.
func (*ClusterProviderAttribution) DeepCopyInto ¶ added in v0.39.0
func (in *ClusterProviderAttribution) DeepCopyInto(out *ClusterProviderAttribution)
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 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"`
// AccessFrom 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
AccessFrom *NamespaceMatcher `json:"accessFrom,omitempty"`
// AllowAnySourceNamespace 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.
//
// It grants no access by itself: the source credential's own RBAC remains the hard maximum, and
// a request it permits still fails 403 if the credential cannot read that namespace. 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 "*", which reaches every namespace the
// credential can read. It does not apply to ClusterWatchRule, which selects no namespaces at
// all.
// +optional
// +kubebuilder:default=false
AllowAnySourceNamespace bool `json:"allowAnySourceNamespace,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
func (in *ClusterProviderStatus) DeepCopy() *ClusterProviderStatus
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"`
}
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 gitTargetRef 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 source credential can read.
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 ¶
func (in *ClusterWatchRuleList) DeepCopy() *ClusterWatchRuleList
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWatchRuleList.
func (*ClusterWatchRuleList) DeepCopyInto ¶
func (in *ClusterWatchRuleList) DeepCopyInto(out *ClusterWatchRuleList)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*ClusterWatchRuleList) DeepCopyObject ¶
func (in *ClusterWatchRuleList) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type ClusterWatchRuleSpec ¶
type ClusterWatchRuleSpec struct {
// GitTargetRef names the GitTarget this rule feeds. A ClusterWatchRule has no namespace of its
// own, so the namespace is required here rather than defaulted.
// +required
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
// +kubebuilder:validation:XValidation:rule="has(self.namespace) && self.namespace != ”",message="spec.gitTargetRef.namespace is required: a ClusterWatchRule has no namespace to default to"
GitTargetRef meta.NamespacedObjectReference `json:"gitTargetRef"`
// Rules 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) DeepCopy ¶
func (in *ClusterWatchRuleSpec) DeepCopy() *ClusterWatchRuleSpec
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 ¶
func (in *ClusterWatchRuleStatus) DeepCopy() *ClusterWatchRuleStatus
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 spec.commit.window 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. It is set on GitTarget.spec.commit.message; the identically-shaped GitProvider.spec.commit.message is retained only to reject a manifest that still sets it there.
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 {
// GitTargetRef names the GitTarget whose open commit window to finalize.
// The GitTarget must be in the same namespace as this CommitRequest.
// +required
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
GitTargetRef meta.LocalObjectReference `json:"gitTargetRef"`
// 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.
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="commit.signing.secretRef.name must not be empty"
// Expected keys will be defined by the signing implementation.
SecretRef meta.LocalObjectReference `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"`
// Signing configures commit signing.
// +optional
Signing *CommitSigningSpec `json:"signing,omitempty"`
}
CommitSpec configures the commit identity and signing a GitProvider uses. Message formatting lives on the GitTarget (spec.commit.message), because it describes the folder rather than the connection.
func (*CommitSpec) DeepCopy ¶
func (in *CommitSpec) DeepCopy() *CommitSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommitSpec.
func (*CommitSpec) DeepCopyInto ¶
func (in *CommitSpec) DeepCopyInto(out *CommitSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type 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.
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="encryption.secretRef.name must not be empty"
// +optional
SecretRef meta.LocalObjectReference `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 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)
//
// An OMITTED secretRef means anonymous access. An empty name is refused rather than treated as
// one: a typo there would otherwise downgrade a private repository to anonymous silently, and
// the failure would surface as an authentication error against the remote rather than as a
// mistake in this object.
// +optional
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.secretRef.name must not be empty; omit secretRef entirely for anonymous access"
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// KnownHostsRef 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"`
// Commit configures the commit identity and signing behavior this connection uses. Message
// formatting moved to GitTarget.spec.commit.message.
// +optional
Commit *CommitSpec `json:"commit,omitempty"`
}
GitProviderSpec defines the desired state of GitProvider.
Only the repository URL is immutable. The URL is the destination identity that every referencing GitTarget materializes into; changing it would silently point those targets at a different repository and orphan their existing materialization (the same reason a GitTarget's destination is immutable). To repoint, delete and recreate the GitProvider. Everything else here is operational and deliberately stays mutable — notably 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) DeepCopy ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTarget.
func (*GitTarget) DeepCopyInto ¶
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*GitTarget) DeepCopyObject ¶
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (*GitTarget) EffectivePruneMode ¶ added in v0.39.0
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
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
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 GitTargetCommitSpec ¶ added in v0.43.0
type GitTargetCommitSpec struct {
// Window is the rolling silence window used to coalesce this target's events into a single
// commit per author. The timer resets on every event arrival, and the commit is made after
// this much silence. "0s" opts into per-event commits. Omitted, it is "5s".
// +optional
Window *string `json:"window,omitempty"`
// Message configures how this target's commit messages are formatted. Omitted, or with any
// individual template left empty, the built-in templates are used.
// +optional
Message *CommitMessageSpec `json:"message,omitempty"`
}
GitTargetCommitSpec configures how a GitTarget's writes become commits.
func (*GitTargetCommitSpec) DeepCopy ¶ added in v0.43.0
func (in *GitTargetCommitSpec) DeepCopy() *GitTargetCommitSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetCommitSpec.
func (*GitTargetCommitSpec) DeepCopyInto ¶ added in v0.43.0
func (in *GitTargetCommitSpec) DeepCopyInto(out *GitTargetCommitSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type GitTargetList ¶
type GitTargetList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []GitTarget `json:"items"`
}
GitTargetList contains a list of GitTarget.
func (*GitTargetList) DeepCopy ¶
func (in *GitTargetList) DeepCopy() *GitTargetList
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetList.
func (*GitTargetList) DeepCopyInto ¶
func (in *GitTargetList) DeepCopyInto(out *GitTargetList)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*GitTargetList) DeepCopyObject ¶
func (in *GitTargetList) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type GitTargetPlacementSpec ¶
type GitTargetPlacementSpec struct {
// ByType maps 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"`
// UseKustomize declares that this folder is a kustomize folder whose root the operator
// maintains. It controls one thing: what happens when NO kustomization governs the path a new
// document lands at.
//
// Omitted or false, the document is written and nothing else is touched. True, a
// kustomization.yaml is created at spec.path and the new document is registered in it as part
// of the same commit.
//
// A created root ADOPTS the folder: its resources: lists every managed document already there
// as well as the new one. Turning a folder into a kustomize folder means the folder, and a
// root naming one file would leave every other file in Git but out of every render.
//
// A created root carries NO namespace:. It holds an apiVersion, a kind and the resources: list
// and nothing else, so the namespace still comes from the documents (serializeNamespace unset
// or true) or from whatever installs the folder (serializeNamespace false).
//
// A folder that already has a kustomize render root never gains a second one, because two
// render roots is an ambiguous folder that stops accepting new documents altogether. If a
// byType or default template places a document outside the existing root, that placement is
// REFUSED rather than committed as a file no kustomization would render.
//
// It has NO bearing on a folder that already has a root. A new file is always registered with
// the nearest kustomization governing it, whatever chose its path, because a file no
// kustomization lists is a file kustomize never builds.
// +optional
UseKustomize bool `json:"useKustomize,omitempty"`
}
GitTargetPlacementSpec declares where NEW resources are written when no document for their identity exists yet in Git — one exact-type map plus a fallback default template (Option B2 of docs/layout/new-file-placement-rules.md). There is deliberately no separate "sensitive" placement block: sensitivity is a write-safety classification the controller owns (encrypt the content, keep the path identity-complete, never append or co-mingle), not a second placement namespace the user has to configure. A user routes Secrets the same way they route anything else — by naming their type in ByType. When a resource's type has no ByType entry and no Default, the new document goes beside the folder's kustomization when the whole folder is governed by exactly one supported kustomization (so the file is reachable from a render root instead of being written where kustomize would never build it), and otherwise at the built-in 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 ¶
func (in *GitTargetPlacementSpec) DeepCopy() *GitTargetPlacementSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetPlacementSpec.
func (*GitTargetPlacementSpec) DeepCopyInto ¶
func (in *GitTargetPlacementSpec) DeepCopyInto(out *GitTargetPlacementSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type GitTargetPlacementStatus ¶ added in v0.43.0
type GitTargetPlacementStatus struct {
// Mode is how this folder is written, and it is the field that predicts the surprises.
//
// `Plain` — no kustomization governs the folder. A new document is written and nothing else
// is touched; a delete removes it and nothing else is touched.
//
// `KustomizeRoot` — exactly one kustomization governs the folder and the folder is
// self-contained. A new document is also registered in that root's `resources:`; a delete
// also drops its entry; and every write is proved by re-rendering, so kustomize itself can
// refuse one.
//
// `KustomizeOverlay` — as KustomizeRoot, and the folder additionally renders a base outside
// it (ReadOnlyBases). The base is read-only input: an edit to a field the base owns is
// authored into the overlay when it is expressible there (`images:`, `replicas:`) and refused
// with WriteBoundaryRefused otherwise, and DELETING an object the overlay inherits authors a
// `$patch: delete` into the overlay rather than removing anything.
//
// Empty when the folder covers more than one render root, which is LayoutResolved=Ambiguous:
// there is no single answer, and no new document is placed until the target is pointed at one
// of them.
// +optional
// +kubebuilder:validation:Enum=Plain;KustomizeRoot;KustomizeOverlay
Mode PlacementMode `json:"mode,omitempty"`
// RenderRoot is the kustomization directory that governs new documents in this folder,
// relative to spec.path; "." is the folder itself. Empty for Plain (there is no root) and
// under LayoutResolved=Ambiguous (there is no single one).
// +optional
RenderRoot string `json:"renderRoot,omitempty"`
// ReadOnlyBases are the kustomization directories this folder renders but may never write to,
// relative to spec.path — so they lead with "../". Non-empty exactly when Mode is
// KustomizeOverlay, and it is what makes a WriteBoundaryRefused message predictable instead of
// surprising: an edit that lands on a document under one of these paths cannot be written
// where it lives.
// +optional
ReadOnlyBases []string `json:"readOnlyBases,omitempty"`
// ResolvedAtRevision is the Git revision this resolution was first observed at. It is not
// re-stamped on every scan: a resolution that has not changed is not republished, because
// doing so would write status once per commit to the branch, whichever target caused the
// commit. So it dates the RESOLUTION, not the last scan — a revision older than the branch
// head means the folder's layout has not changed since, not that nothing has looked.
//
// It is empty when the branch had no commit at the time (a folder nothing has written to yet)
// and is filled in by the first scan that finds one.
// +optional
ResolvedAtRevision string `json:"resolvedAtRevision,omitempty"`
// ResolvedAt is when this resolution was computed. Like ResolvedAtRevision it dates the
// resolution rather than the last scan, so a timestamp well in the past means the folder's
// shape has been stable, not that scanning stopped.
// +optional
ResolvedAt *metav1.Time `json:"resolvedAt,omitempty"`
}
GitTargetPlacementStatus is what the last scan resolved about a GitTarget folder's layout.
func (*GitTargetPlacementStatus) DeepCopy ¶ added in v0.43.0
func (in *GitTargetPlacementStatus) DeepCopy() *GitTargetPlacementStatus
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetPlacementStatus.
func (*GitTargetPlacementStatus) DeepCopyInto ¶ added in v0.43.0
func (in *GitTargetPlacementStatus) DeepCopyInto(out *GitTargetPlacementStatus)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type GitTargetRetentionStatus ¶ added in v0.39.0
type GitTargetRetentionStatus struct {
// Mode is the 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
func (in *GitTargetRetentionStatus) DeepCopy() *GitTargetRetentionStatus
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 {
// GitProviderRef names the GitProvider that backs this target, in this GitTarget's own
// namespace. Many GitTargets may name the same GitProvider.
// Immutable: delete and recreate the GitTarget to change its destination.
// +required
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitProviderRef.name must not be empty"
GitProviderRef meta.LocalObjectReference `json:"gitProviderRef"`
// 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"`
// SerializeNamespace declares whether a committed document carries its own
// metadata.namespace. It governs every write this target makes, not just the first one, and it
// applies to NAMESPACED resources only — a cluster-scoped document has no namespace, so the
// field is ignored for it rather than being an error.
//
// Omitted, the namespace is INFERRED per document, which is the behavior a target that says
// nothing has always had: metadata.namespace is omitted only when the kustomization governing
// the document's path sets namespace: to that resource's own namespace, and written explicitly
// in every other case. Leave it unset for a folder that is legitimately non-uniform — a tree of
// nested kustomize roots, each supplying its own namespace — because inference resolves each
// document against the root governing its own path.
//
// true always writes it: the setting for a flat folder applied directly, where nothing
// downstream supplies a namespace and a document without one is ambiguous.
//
// false never writes it, and is a claim about the whole folder: something outside this
// repository — a Flux Kustomization's targetNamespace, an Argo Application's
// destination.namespace, or a kustomization this target maintains itself — supplies the
// namespace instead. Because a namespace-less document takes its namespace from a single
// supplier, an explicit false admits exactly ONE source namespace: a second WatchRule bringing
// another namespace to this target is refused, with GitPathAccepted=False and reason
// MultipleSourceNamespaces.
// +optional
SerializeNamespace *bool `json:"serializeNamespace,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
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.clusterProviderRef.name must not be empty"
ClusterProviderRef *meta.LocalObjectReference `json:"clusterProviderRef,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"`
// Commit configures how this target's writes are batched into commits, and how those commits
// are phrased. Omitted, writes coalesce over a 5s rolling silence window and use the built-in
// message templates.
// +optional
Commit *GitTargetCommitSpec `json:"commit,omitempty"`
// Suspend stops this target from writing to Git, without deleting it. It is the knob to turn
// when something is wrong and the writes have to stop now: watches keep running, events keep
// arriving, the folder keeps being scanned and status.placement keeps being maintained, and no
// new commit is planned while it is set.
//
// It takes effect at the next planning boundary, not instantly. Work already committed
// locally when suspend is set is still pushed, so a target suspended during a push cooldown
// can publish one more commit seconds later. That is deliberate: a local commit that is never
// pushed would sit in the worker's checkout indefinitely and surface later, out of order, on
// resume. Suspend is a valve on new work, not an undo — it stops the next write, it does not
// revert the last one.
//
// While it is set, status.retention is not published at all: nothing is swept, so nothing is
// measured, and reporting zero retained documents would read as "converged" when nothing was
// counted.
//
// Omitted, it is false. Clearing it resumes writing from the current cluster state on the next
// resync; the writes suppressed while suspended are not replayed.
// +optional
Suspend bool `json:"suspend,omitempty"`
}
GitTargetSpec defines the desired state of GitTarget.
The destination fields — gitProviderRef, 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.
The gitProviderRef rule is guarded on oldSelf rather than written as a plain equality, and the guard is a one-way migration door rather than a loosening. A GitTarget stored before this field was named gitProviderRef serves NO value for it (a field outside the structural schema is not served, measured in TestRenamedRequiredField_StoredObjectCanAdoptIt), so a plain equality would reject the very apply that migrates it and force a delete-and-recreate. Because the field is REQUIRED, it can never be absent on an object created from this release on, so the door is shut for everything except the objects it exists for. +kubebuilder:validation:XValidation:rule="!has(oldSelf.gitProviderRef) || self.gitProviderRef == oldSelf.gitProviderRef",message="spec.gitProviderRef 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 gitProviderRef/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"`
// Placement is what the last scan resolved about this folder's layout: whether a kustomize
// render root governs new documents, which one, and whether the folder renders a base it may
// not write to. It is an observation, like streams and retention, and the LayoutResolved
// condition carries the verdict.
// +optional
Placement *GitTargetPlacementStatus `json:"placement,omitempty"`
}
GitTargetStatus defines the observed state of GitTarget.
func (*GitTargetStatus) DeepCopy ¶
func (in *GitTargetStatus) DeepCopy() *GitTargetStatus
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTargetStatus.
func (*GitTargetStatus) DeepCopyInto ¶
func (in *GitTargetStatus) DeepCopyInto(out *GitTargetStatus)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type 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 ¶
func (in *GitTargetStreamsStatus) DeepCopy() *GitTargetStreamsStatus
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 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 deny-by-default namespace-policy SHAPE this API uses where 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. Its one use is authorization, and the fail-open reading is the catastrophic one, so an absent field means "no policy declared" (which admits nothing here) while a declared-but-empty one also admits nothing.
One field uses it: ClusterProvider.spec.accessFrom, whose selector matches labels on Namespaces in the CONTROL cluster. It had a source-side twin, GitTarget.spec.allowedSourceNamespaces, evaluated against Namespace labels in another cluster; that twin and everything it forced (a three-valued verdict, a degradation path, source-cluster Namespace get/list/watch) were deleted. Matches therefore still takes the labels rather than fetching them, which is now merely convenient rather than load-bearing.
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) Matches ¶ added in v0.39.0
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 so the answer never depends on the labels when a name already admits. A nil matcher matches nothing.
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 PlacementMode ¶ added in v0.43.0
type PlacementMode string
PlacementMode is how a GitTarget folder is written: as plain files, as a kustomize root, or as an overlay over a base it may not write to.
const ( // PlacementModePlain is a folder no kustomization governs. PlacementModePlain PlacementMode = "Plain" // PlacementModeKustomizeRoot is a self-contained folder governed by exactly one kustomization. PlacementModeKustomizeRoot PlacementMode = "KustomizeRoot" // PlacementModeKustomizeOverlay is a folder governed by one kustomization that renders a base // outside the write scope. PlacementModeKustomizeOverlay PlacementMode = "KustomizeOverlay" )
type PruneMode ¶ added in v0.39.0
type PruneMode string
PruneMode enumerates which of the two deletion paths may remove a managed document from a GitTarget's folder.
| source DELETE event | resync mark-and-sweep Never | suppressed | suppressed OnEvent | applied | suppressed Always | applied | applied
const ( // PruneNever removes nothing: neither an explicit source DELETE nor an inferred sweep drop. // The folder becomes an archive that only ever gains and updates documents. PruneNever PruneMode = "Never" // PruneOnEvent mirrors an observed source DELETE but never infers a deletion from a desired // snapshot. It is the effective default. PruneOnEvent PruneMode = "OnEvent" // PruneAlways enables both paths: full desired-state convergence, including removing a Git // document whose resource is absent from the snapshot. PruneAlways PruneMode = "Always" )
func (PruneMode) AppliesEventDeletes ¶ added in v0.39.0
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
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
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
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 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 source credential can read.
//
// "*" is one cluster-wide list and watch rather than a set of per-namespace ones, so its bound
// is the credential's own RBAC and nothing else. Naming any namespace other than this rule's
// own, "*" included, requires the GitTarget's ClusterProvider to admit the target's namespace
// AND to set spec.allowAnySourceNamespace; while that flag is false, "*" is refused outright.
//
// 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 "*", which is not a namespace name: the caller compiles it to the cluster-wide cell (the empty namespace) rather than watching it.
It is controller logic rather than an API-server default because an apiserver default cannot refer to metadata.namespace.
func (*ResourceRule) IsSourceNamespaceWildcard ¶ added in v0.39.0
func (r *ResourceRule) IsSourceNamespaceWildcard() bool
IsSourceNamespaceWildcard reports whether this item asks for every namespace its credential can read, as one cluster-wide stream.
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, since it reaches every namespace the credential can read.
type ResourceScope ¶
type ResourceScope string
ResourceScope names a Kubernetes resource's scope. It is a purely INTERNAL matching vocabulary with no field in any CRD: the resolver uses both constants to align a rule's selector with the discovered scope of each type. A WatchRule always resolves Namespaced records, a ClusterWatchRule always Cluster ones, and which kind you write is the whole of how scope is chosen.
const ( // ResourceScopeCluster indicates cluster-scoped resources (Nodes, ClusterRoles, etc.). ResourceScopeCluster ResourceScope = "Cluster" // ResourceScopeNamespaced indicates namespaced resources (Pods, Deployments, etc.). ResourceScopeNamespaced ResourceScope = "Namespaced" )
type 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 ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRule.
func (*WatchRule) DeepCopyInto ¶
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*WatchRule) DeepCopyObject ¶
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 {
// GitTargetRef names the GitTarget this rule feeds, in this WatchRule's own namespace.
// +required
// +kubebuilder:validation:XValidation:rule="self.name != ”",message="spec.gitTargetRef.name must not be empty"
GitTargetRef meta.LocalObjectReference `json:"gitTargetRef"`
// 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 ¶
func (in *WatchRuleStreamsStatus) DeepCopy() *WatchRuleStreamsStatus
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.