From 0a59fbb6b582beccc52d10cf98ec424855e52607 Mon Sep 17 00:00:00 2001 From: Zhiying Lin Date: Thu, 20 Nov 2025 16:58:04 +0800 Subject: [PATCH 1/3] interface: [option 2] create new api to support on demand resourceSnapshot creation Signed-off-by: Zhiying Lin --- .../v1beta1/clusterresourceplacement_types.go | 7 ++ .../clusterresourcesnapshotpolicy_types.go | 117 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go diff --git a/apis/placement/v1beta1/clusterresourceplacement_types.go b/apis/placement/v1beta1/clusterresourceplacement_types.go index 132ee90fd..3aea1e1a2 100644 --- a/apis/placement/v1beta1/clusterresourceplacement_types.go +++ b/apis/placement/v1beta1/clusterresourceplacement_types.go @@ -529,6 +529,13 @@ type RolloutStrategy struct { // +kubebuilder:validation:Enum=RollingUpdate;External Type RolloutStrategyType `json:"type,omitempty"` + // ResourceSnapshotIndex indicates the specific resource snapshot index to be rolled out to the target clusters. + // If not specified, the latest resource snapshot will be used. + // When the specified index does not exist, the rollout will fail with reason ResourceSnapshotNotFound. + // This field is only valid when RolloutStrategyType = RollingUpdate. + // +kubebuilder:validation:Optional + ResourceSnapshotIndex *string `json:"resourceSnapshotIndex,omitempty"` + // Rolling update config params. Present only if RolloutStrategyType = RollingUpdate. // +kubebuilder:validation:Optional RollingUpdate *RollingUpdateConfig `json:"rollingUpdate,omitempty"` diff --git a/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go new file mode 100644 index 000000000..1dcf5bd3c --- /dev/null +++ b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go @@ -0,0 +1,117 @@ +/* +Copyright 2025 The KubeFleet Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope="Cluster",shortName=crsp,categories={fleet,fleet-placement} +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:printcolumn:JSONPath=`.spec.updateStrategy`,name="Strategy",type=string +// +kubebuilder:printcolumn:JSONPath=`.spec.targetSnapshot`,name="Target-Snapshot",type=string +// +kubebuilder:printcolumn:JSONPath=`.status.currentSnapshot`,name="Current-Snapshot",type=string +// +kubebuilder:printcolumn:JSONPath=`.metadata.creationTimestamp`,name="Age",type=date +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterResourceSnapshotPolicy controls the snapshot creation and selection strategy +// for a ClusterResourcePlacement. It allows users to decouple snapshot management +// from the CRP itself, providing more granular control over when snapshots are created. +// +// The name of this object must match the name of the corresponding ClusterResourcePlacement. +type ClusterResourceSnapshotPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired snapshot policy. + // +kubebuilder:validation:Required + Spec ResourceSnapshotPolicySpec `json:"spec"` + + // Status reports the observed state of the snapshot policy. + // +kubebuilder:validation:Optional + Status ResourceSnapshotPolicyStatus `json:"status,omitempty"` +} + +// ResourceSnapshotPolicySpec defines the desired snapshot management behavior. +type ResourceSnapshotPolicySpec struct { + // UpdateStrategy controls when new resource snapshots are created. + // +kubebuilder:validation:Required + // +kubebuilder:validation:Enum=Automatic;OnDemand + CreationStrategy SnapshotCreationStrategyType `json:"createStrategy"` + + // ResourceSnapshotIndex specifies which snapshot index to use for creation. + // Only valid when UpdateStrategy is "OnDemand". + // The requested index must be greater than the latest existing snapshot index if exists. + // +kubebuilder:validation:Optional + ResourceSnapshotIndex *uint32 `json:"resourceSnapshotIndex,omitempty"` + + // SnapshotRetentionPolicy controls how snapshots are retained. + // If not specified, inherits from CRP's RevisionHistoryLimit. + // +kubebuilder:validation:Optional + SnapshotRetentionPolicy *SnapshotRetentionPolicy `json:"snapshotRetentionPolicy,omitempty"` +} + +// SnapshotUpdateStrategyType describes when new snapshots are created. +// +enum +type SnapshotCreationStrategyType string + +const ( + // SnapshotUpdateStrategyAutomatic automatically creates new snapshots when selected + // resources change. This is the default behavior when no policy exists. + SnapshotUpdateStrategyAutomatic SnapshotCreationStrategyType = "Automatic" + + // SnapshotUpdateStrategyOnDemand creates snapshots only when explicitly requested by the user. + SnapshotUpdateStrategyOnDemand SnapshotCreationStrategyType = "OnDemand" +) + +// SnapshotRetentionPolicy controls snapshot retention behavior. +type SnapshotRetentionPolicy struct { + // The number of old ResourceSnapshot resources to retain. + // Defaults to 10. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default=10 + // +kubebuilder:validation:Optional + // RevisionHistoryLimit wins over CRP's RevisionHistoryLimit if both are set. + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` +} + +// ResourceSnapshotPolicyStatus reports the observed state. +type ResourceSnapshotPolicyStatus struct { + // LatestSnapshot is the most recently created snapshot index. + // +kubebuilder:validation:Optional + LatestSnapshot *SnapshotGroup `json:"latestSnapshot,omitempty"` + + // Conditions represents the current state of the snapshot policy. + // +kubebuilder:validation:Optional + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// SnapshotGroup contains metadata about a group of snapshots using the same index. +type SnapshotGroup struct { + // Index is the snapshot index. + // +kubebuilder:validation:Optional + Index string `json:"index,omitempty"` + + // NumberOfSnapshots is the count of snapshots in this group. + // +kubebuilder:validation:Optional + NumberOfSnapshots int32 `json:"numberOfSnapshots,omitempty"` +} From c11f4bda76495f8a18dbfb267165210fffefc5fc Mon Sep 17 00:00:00 2001 From: Zhiying Lin Date: Tue, 25 Nov 2025 15:11:24 +0800 Subject: [PATCH 2/3] add condition type Signed-off-by: Zhiying Lin --- .../v1beta1/clusterresourcesnapshotpolicy_types.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go index 1dcf5bd3c..78ff763f8 100644 --- a/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go +++ b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go @@ -105,6 +105,18 @@ type ResourceSnapshotPolicyStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` } +// ResourceSnapshotPolicyConditionType defines a specific condition of a resource snapshot policy object. +// +enum +type ResourceSnapshotPolicyConditionType string + +const ( + // ResourceSnapshotPolicyConditionTypeValid indicates whether the policy configuration is valid. + ResourceSnapshotPolicyConditionTypeValid ResourceSnapshotPolicyConditionType = "Valid" + + // ResourceSnapshotPolicyConditionTypeSnapshotReady indicates whether the target snapshot is ready. + ResourceSnapshotPolicyConditionTypeSnapshotReady ResourceSnapshotPolicyConditionType = "SnapshotReady" +) + // SnapshotGroup contains metadata about a group of snapshots using the same index. type SnapshotGroup struct { // Index is the snapshot index. From c1b7c28b15fca56f2f202dd96e9c352f21f49807 Mon Sep 17 00:00:00 2001 From: Zhiying Lin Date: Tue, 25 Nov 2025 17:31:19 +0800 Subject: [PATCH 3/3] update comment Signed-off-by: Zhiying Lin --- apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go | 1 + 1 file changed, 1 insertion(+) diff --git a/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go index 78ff763f8..63e3633a0 100644 --- a/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go +++ b/apis/placement/v1beta1/clusterresourcesnapshotpolicy_types.go @@ -111,6 +111,7 @@ type ResourceSnapshotPolicyConditionType string const ( // ResourceSnapshotPolicyConditionTypeValid indicates whether the policy configuration is valid. + // This condition will be set when the strategy type is onDemand. ResourceSnapshotPolicyConditionTypeValid ResourceSnapshotPolicyConditionType = "Valid" // ResourceSnapshotPolicyConditionTypeSnapshotReady indicates whether the target snapshot is ready.