Skip to content

Commit a47f418

Browse files
jparrillclaude
andcommitted
feat(CNTRLPLANE-2678): enforce restoreSnapshotURL immutability via CEL
Add CEL validation rule to prevent day-2 modifications of the restoreSnapshotURL field. This ensures the field can only be set at creation time, which aligns with the existing API contract and makes the OADP restoration workflow safe without changing the field semantics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
1 parent 02c222e commit a47f418

2 files changed

Lines changed: 395 additions & 0 deletions

File tree

api/hypershift/v1beta1/hostedcluster_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,11 @@ const (
19241924
var DefaultPersistentVolumeEtcdStorageSize resource.Quantity = resource.MustParse("8Gi")
19251925

19261926
// ManagedEtcdStorageSpec describes the storage configuration for etcd data.
1927+
//
1928+
// This struct-level rule complements the field-level "self == oldSelf" on restoreSnapshotURL.
1929+
// The field-level rule catches value changes but does not fire when the field is removed
1930+
// (CEL skips optional fields absent in the updated object). This rule covers that case.
1931+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.restoreSnapshotURL) || (has(self.restoreSnapshotURL) && self.restoreSnapshotURL == oldSelf.restoreSnapshotURL)", message="restoreSnapshotURL is immutable"
19271932
type ManagedEtcdStorageSpec struct {
19281933
// type is the kind of persistent storage implementation to use for etcd.
19291934
// Only PersistentVolume is supported at the moment.
@@ -1952,6 +1957,8 @@ type ManagedEtcdStorageSpec struct {
19521957
// +kubebuilder:validation:MaxItems=1
19531958
// +kubebuilder:validation:items:MaxLength=1024
19541959
// +kubebuilder:validation:XValidation:rule="self.size() <= 1", message="RestoreSnapshotURL shouldn't contain more than 1 entry"
1960+
// +kubebuilder:validation:XValidation:rule="self == oldSelf", message="restoreSnapshotURL is immutable"
1961+
// +kubebuilder:validation:XValidation:rule="self.size() == 0 || self[0].matches('^(https|s3)://.*')", message="restoreSnapshotURL must be a valid URL with scheme https or s3"
19551962
RestoreSnapshotURL []string `json:"restoreSnapshotURL,omitempty"`
19561963
}
19571964

0 commit comments

Comments
 (0)