Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

69 changes: 68 additions & 1 deletion config/v1/types_cluster_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,23 @@ type ClusterVersionStatus struct {
// availableUpdates. This list may be empty if no updates are
// recommended, if the update service is unavailable, or if an empty
// or invalid channel has been specified.
// +kubebuilder:validation:MaxItems=500
// +listType=atomic
// +optional
ConditionalUpdates []ConditionalUpdate `json:"conditionalUpdates,omitempty"`

// conditionalUpdateRisks contains the list of risks associated with conditionalUpdates.
// When performing a conditional update, all its associated risks will be compared with the set of accepted risks in the spec.desiredUpdate.acceptRisks field.
// If all risks for a conditional update are included in the spec.desiredUpdate.acceptRisks set, the conditional update can proceed, otherwise it is blocked.
// The risk names in the list must be unique.
// conditionalUpdateRisks must not contain more than 500 entries.
// +openshift:enable:FeatureGate=ClusterUpdateAcceptRisks
// +kubebuilder:validation:MaxItems=500
// +kubebuilder:validation:MinItems=1
// +listType=map
// +listMapKey=name
// +optional
ConditionalUpdateRisks []ConditionalUpdateRisk `json:"conditionalUpdateRisks,omitempty"`
}

// UpdateState is a constant representing whether an update was successfully
Expand Down Expand Up @@ -258,7 +272,7 @@ type UpdateHistory struct {
Verified bool `json:"verified"`

// acceptedRisks records risks which were accepted to initiate the update.
// For example, it may menition an Upgradeable=False or missing signature
// For example, it may mention an Upgradeable=False or missing signature
// that was overridden via desiredUpdate.force, or an update that was
// initiated despite not being in the availableUpdates set of recommended
// update targets.
Expand Down Expand Up @@ -732,6 +746,30 @@ type Update struct {
//
// +optional
Force bool `json:"force"`

// acceptRisks is an optional set of names of conditional update risks that are considered acceptable.
// A conditional update is performed only if all of its risks are acceptable.
// This list may contain entries that apply to current, previous or future updates.
// The entries therefore may not map directly to a risk in .status.conditionalUpdateRisks.
// acceptRisks must not contain more than 1000 entries.
// Entries in this list must be unique.
// +openshift:enable:FeatureGate=ClusterUpdateAcceptRisks
// +kubebuilder:validation:MaxItems=1000
// +kubebuilder:validation:MinItems=1
// +listType=map
// +listMapKey=name
// +optional
AcceptRisks []AcceptRisk `json:"acceptRisks,omitempty"`
}

// AcceptRisk represents a risk that is considered acceptable.
type AcceptRisk struct {
// name is the name of the acceptable risk.
// It must be a non-empty string and must not exceed 256 characters.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=256
// +required
Name string `json:"name,omitempty"`
}
Comment on lines +765 to 773
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Remove omitempty from required field.

The Name field is marked as +required (line 770) but has omitempty in the JSON tag (line 771). This creates an inconsistency:

  • The OpenAPI schema correctly marks name as required (see CRD line 180-181)
  • However, Go serialization will omit the field when it's an empty string
  • This violates the required constraint and breaks API contract
🔎 Fix: Remove omitempty from the json tag
 	// +required
-	Name string `json:"name,omitempty"`
+	Name string `json:"name"`
🤖 Prompt for AI Agents
In config/v1/types_cluster_version.go around lines 764 to 772, the Name field is
marked +required but its struct tag uses `json:"name,omitempty"`, causing
required fields to be omitted when empty; remove the `omitempty` from the JSON
tag (change to `json:"name"`) so the field is always serialized and consistent
with the CRD OpenAPI required constraint.


// Release represents an OpenShift release image and associated metadata.
Expand Down Expand Up @@ -787,12 +825,27 @@ type ConditionalUpdate struct {
// +required
Release Release `json:"release"`

// riskNames represents the set of the names of conditionalUpdateRisks that are relevant to this update for some clusters.
// The Applies condition of each conditionalUpdateRisks entry declares if that risk applies to this cluster.
// A conditional update is accepted only if each of its risks either does not apply to the cluster or is considered acceptable by the cluster administrator.
// The latter means that the risk names are included in value of the spec.desiredUpdate.acceptRisks field.
// Entries must be unique and must not exceed 256 characters.
// riskNames must not contain more than 500 entries.
// +openshift:enable:FeatureGate=ClusterUpdateAcceptRisks
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:items:MaxLength=256
// +kubebuilder:validation:MaxItems=500
// +listType=set
// +optional
RiskNames []string `json:"riskNames,omitempty"`

// risks represents the range of issues associated with
// updating to the target release. The cluster-version
// operator will evaluate all entries, and only recommend the
// update if there is at least one entry and all entries
// recommend the update.
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=200
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
Expand All @@ -813,6 +866,20 @@ type ConditionalUpdate struct {
// for not recommending a conditional update.
// +k8s:deepcopy-gen=true
type ConditionalUpdateRisk struct {
// conditions represents the observations of the conditional update
// risk's current status. Known types are:
// * Applies, for whether the risk applies to the current cluster.
// The condition's types in the list must be unique.
// conditions must not contain more than one entry.
// +openshift:enable:FeatureGate=ClusterUpdateAcceptRisks
// +kubebuilder:validation:XValidation:rule="self.exists_one(x, x.type == 'Applies')",message="must contain a condition of type 'Applies'"
// +kubebuilder:validation:MaxItems=8
// +kubebuilder:validation:MinItems=1
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// url contains information about this risk.
// +kubebuilder:validation:Format=uri
// +kubebuilder:validation:MinLength=1
Expand Down
Loading