From 790b790eb31835f1bd7daadfff88542dcb333931 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Wed, 9 Sep 2026 12:30:52 -0400 Subject: [PATCH 01/10] OCPEDGE-2989: Add controlPlaneTopologyTransitions to Infrastructure status Adds a new feature-gated InfrastructureStatus field that reports, as controller-computed observed state, the control-plane topology transitions available from the cluster's current topology and whether each can currently be initiated (Available/Unavailable/Unknown, with a CamelCase reason and human message when blocked). Gated behind the existing MutableTopology feature gate. Regenerates deepcopy, OpenAPI, swagger docs, and CRD manifests (including the embedded ControllerConfig schema, which pulls in InfrastructureStatus). --- .../MutableTopology.yaml | 416 ++++++++++++++++++ config/v1/types_infrastructure.go | 93 ++++ ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 95 ++++ ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 95 ++++ ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 95 ++++ config/v1/zz_generated.deepcopy.go | 21 + .../MutableTopology.yaml | 95 ++++ config/v1/zz_generated.model_name.go | 5 + .../v1/zz_generated.swagger_doc_generated.go | 34 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 95 ++++ ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 95 ++++ ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 95 ++++ .../MutableTopology.yaml | 95 ++++ .../generated_openapi/zz_generated.openapi.go | 75 +++- openapi/openapi.json | 44 ++ ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 95 ++++ ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 95 ++++ ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 95 ++++ ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 95 ++++ ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 95 ++++ ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 95 ++++ 21 files changed, 2007 insertions(+), 11 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index b7cdc4876e1..bbadcdff09a 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -259,3 +259,419 @@ tests: spec: controlPlaneTopology: InvalidValue expectedError: 'spec.controlPlaneTopology: Unsupported value: "InvalidValue": supported values: "HighlyAvailable", "SingleReplica"' + - name: Should allow controlPlaneTopologyTransitions to remain omitted, representing that the controller has not yet completed its first evaluation + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + controlPlaneTopology: HighlyAvailable + status: + controlPlaneTopology: SingleReplica + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: + controlPlaneTopology: HighlyAvailable + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + - name: Should allow explicitly setting controlPlaneTopologyTransitions to an empty list, carrying the same meaning as omitting it + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: [] + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: [] + - name: Should allow controlPlaneTopologyTransitions to remain omitted when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + - name: Should allow setting controlPlaneTopologyTransitions to an Available entry with no reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Available + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Available + - name: Should allow setting controlPlaneTopologyTransitions to an Unavailable entry including reason and message + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: PreflightCheckFailed + message: "etcd does not have quorum: need 3 voting members, have 1" + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: PreflightCheckFailed + message: "etcd does not have quorum: need 3 voting members, have 1" + - name: Should allow setting controlPlaneTopologyTransitions to an Unknown entry with a reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unknown + reason: EvaluationPending + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unknown + reason: EvaluationPending + - name: Should allow setting every schema-permitted source/target pair in controlPlaneTopologyTransitions (a MaxItems boundary test spanning the full source x target enum cardinality; includes source==target pairs the controller itself would never emit, but which the schema permits) + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: SingleReplica + availability: Available + - source: SingleReplica + target: HighlyAvailable + availability: Available + - source: HighlyAvailable + target: SingleReplica + availability: Available + - source: HighlyAvailable + target: HighlyAvailable + availability: Available + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: + - source: SingleReplica + target: SingleReplica + availability: Available + - source: SingleReplica + target: HighlyAvailable + availability: Available + - source: HighlyAvailable + target: SingleReplica + availability: Available + - source: HighlyAvailable + target: HighlyAvailable + availability: Available + - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid source + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: External + target: HighlyAvailable + availability: Available + expectedStatusError: 'status.controlPlaneTopologyTransitions[0].source: Unsupported value: "External": supported values: "SingleReplica", "HighlyAvailable"' + - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid target + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: DualReplica + availability: Available + expectedStatusError: 'status.controlPlaneTopologyTransitions[0].target: Unsupported value: "DualReplica": supported values: "SingleReplica", "HighlyAvailable"' + - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid availability + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Pending + expectedStatusError: 'status.controlPlaneTopologyTransitions[0].availability: Unsupported value: "Pending": supported values: "Available", "Unavailable", "Unknown"' + - name: Should not allow an Unavailable controlPlaneTopologyTransitions entry without a reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + expectedStatusError: "reason is required when availability is not Available" + - name: Should not allow an Unknown controlPlaneTopologyTransitions entry without a reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unknown + expectedStatusError: "reason is required when availability is not Available" + - name: Should not allow a controlPlaneTopologyTransitions entry with a lowercase reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: preflightCheckFailed + expectedStatusError: "reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" + - name: Should not allow a controlPlaneTopologyTransitions entry with an empty reason + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: "" + expectedStatusError: "should be at least 1 chars long" + - name: Should not allow a controlPlaneTopologyTransitions entry with a reason exceeding max length + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: "Preflight012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + expectedStatusError: "Too long: may not be more than 128 bytes" + - name: Should not allow a controlPlaneTopologyTransitions entry with an empty message + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: PreflightCheckFailed + message: "" + expectedStatusError: "should be at least 1 chars long" + - name: Should not allow a controlPlaneTopologyTransitions entry with a message exceeding max length + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: PreflightCheckFailed + message: "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" + expectedStatusError: "Too long: may not be more than 2048 bytes" + - name: Should not allow duplicate source/target pairs in controlPlaneTopologyTransitions + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Available + - source: SingleReplica + target: HighlyAvailable + availability: Unavailable + reason: PreflightCheckFailed + expectedStatusError: "Duplicate value" diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 857f9b27929..2c049263b56 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -138,6 +138,35 @@ type InfrastructureStatus struct { // +optional InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` + // controlPlaneTopologyTransitions reports, as controller-computed observed state, + // the control-plane topology transitions that originate at the current + // status.controlPlaneTopology and whether each can currently be initiated. It is + // advisory: the cluster may change between a status read and a spec write, so the + // cluster-config-operator revalidates any requested transition; consumers such as + // the CLI must not treat Available as an admission guarantee. Transitions are + // requested via spec.controlPlaneTopology, not through this field. When omitted, + // the controller has not yet completed its first evaluation; an empty list is also + // valid and intentionally carries the same meaning as omitted, since this field does + // not currently distinguish "not yet evaluated" from "evaluated with no applicable + // transitions". source and target below only cover the topologies that support a + // transition today; when status.controlPlaneTopology is a topology outside that set, + // this field is expected to remain omitted or empty. Entries are keyed by the + // (source, target) topology pair and list order is not significant. At most 4 + // entries are permitted, matching the full cardinality of the 2-value source/target + // enum below. If source/target are ever widened to cover additional + // transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + // not expected to participate in a transition and should not be added here), + // MaxItems must be increased to match the new cardinality, up to 16 for all four + // non-External TopologyMode values. + // +openshift:enable:FeatureGate=MutableTopology + // +listType=map + // +listMapKey=source + // +listMapKey=target + // +kubebuilder:validation:MinItems=0 + // +kubebuilder:validation:MaxItems=4 + // +optional + ControlPlaneTopologyTransitions []ControlPlaneTopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` + // cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. // CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. // Valid values are "None" and "AllNodes". When omitted, the default value is "None". @@ -177,6 +206,70 @@ const ( ExternalTopologyMode TopologyMode = "External" ) +// ControlPlaneTopologyTransition describes one control-plane topology transition +// available from the cluster's current topology and whether it can currently be +// initiated. reason must be set whenever availability is Unavailable or Unknown; +// this is enforced by a validation rule on the entry as a whole. +// +kubebuilder:validation:XValidation:rule="self.availability == 'Available' || has(self.reason)",message="reason is required when availability is not Available" +type ControlPlaneTopologyTransition struct { + // source is the topology this transition starts from. It equals the current + // status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + Source TopologyMode `json:"source,omitempty"` + + // target is the topology this transition would move the control plane to. + // Valid values are SingleReplica and HighlyAvailable. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + Target TopologyMode `json:"target,omitempty"` + + // availability indicates whether this transition can currently be initiated. + // Valid values are Available, Unavailable, and Unknown. Available means the + // controller evaluated the transition and its preconditions pass. Unavailable + // means the transition is defined but cannot be initiated now; see reason and + // message. Unknown means the controller has not completed evaluation. + // +required + Availability TransitionAvailability `json:"availability,omitempty"` + + // reason is a CamelCase machine-readable explanation of the availability, e.g. + // PreflightCheckFailed or SourceTopologyMismatch. It is required when + // availability is Unavailable or Unknown and is normally omitted when Available. + // The set of reasons is diagnostic and not exhaustive. Must start with an + // uppercase letter and contain only alphanumeric characters, and must be + // between 1 and 128 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=128 + // +kubebuilder:validation:XValidation:rule=`self.matches('^[A-Z][A-Za-z0-9]*$')`,message="reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" + // +optional + Reason string `json:"reason,omitempty"` + + // message is a human-readable explanation, primarily for Unavailable + // transitions (e.g. a concise summary of the failing preconditions). It is for + // humans only and must not be parsed. It may be truncated by the controller. + // When set, it must be between 1 and 2048 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +optional + Message string `json:"message,omitempty"` +} + +// TransitionAvailability indicates whether a topology transition can currently be +// initiated. +// +kubebuilder:validation:Enum=Available;Unavailable;Unknown +type TransitionAvailability string + +const ( + // TransitionAvailable means the transition can be initiated now. + TransitionAvailable TransitionAvailability = "Available" + + // TransitionUnavailable means the transition is defined but cannot be initiated now. + TransitionUnavailable TransitionAvailability = "Unavailable" + + // TransitionUnknown means the controller has not completed evaluation. + TransitionUnknown TransitionAvailability = "Unknown" +) + // CPUPartitioningMode defines the mode for CPU partitioning type CPUPartitioningMode string diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 7a35e5fc0f7..de5da8364a6 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index bbeff9ec02e..3176dce0c49 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 0207127aa67..99cfb608a58 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 4b194b226a4..5e3fb9427bd 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -1906,6 +1906,22 @@ func (in *ConsoleStatus) DeepCopy() *ConsoleStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneTopologyTransition) DeepCopyInto(out *ControlPlaneTopologyTransition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneTopologyTransition. +func (in *ControlPlaneTopologyTransition) DeepCopy() *ControlPlaneTopologyTransition { + if in == nil { + return nil + } + out := new(ControlPlaneTopologyTransition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Custom) DeepCopyInto(out *Custom) { *out = *in @@ -3820,6 +3836,11 @@ func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { *out = new(PlatformStatus) (*in).DeepCopyInto(*out) } + if in.ControlPlaneTopologyTransitions != nil { + in, out := &in.ControlPlaneTopologyTransitions, &out.ControlPlaneTopologyTransitions + *out = make([]ControlPlaneTopologyTransition, len(*in)) + copy(*out, *in) + } return } diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index 446505413cb..c8eab4566e2 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1051,6 +1051,101 @@ spec: The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.model_name.go b/config/v1/zz_generated.model_name.go index 043c03ef5ef..53a455e4367 100644 --- a/config/v1/zz_generated.model_name.go +++ b/config/v1/zz_generated.model_name.go @@ -395,6 +395,11 @@ func (in ConsoleStatus) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.ConsoleStatus" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ControlPlaneTopologyTransition) OpenAPIModelName() string { + return "com.github.openshift.api.config.v1.ControlPlaneTopologyTransition" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in Custom) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.Custom" diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 0f4605ef380..f01c7328940 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1737,6 +1737,19 @@ func (CloudLoadBalancerIPs) SwaggerDoc() map[string]string { return map_CloudLoadBalancerIPs } +var map_ControlPlaneTopologyTransition = map[string]string{ + "": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + "source": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", + "target": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", +} + +func (ControlPlaneTopologyTransition) SwaggerDoc() map[string]string { + return map_ControlPlaneTopologyTransition +} + var map_EquinixMetalPlatformSpec = map[string]string{ "": "EquinixMetalPlatformSpec holds the desired state of the Equinix Metal infrastructure provider. This only includes fields that can be modified in the cluster.", } @@ -1881,16 +1894,17 @@ func (InfrastructureSpec) SwaggerDoc() map[string]string { } var map_InfrastructureStatus = map[string]string{ - "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", - "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", - "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", - "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", - "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", - "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", - "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", - "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", - "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", - "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", + "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", + "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", + "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", + "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", + "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", + "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", + "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", + "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", + "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", + "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", } func (InfrastructureStatus) SwaggerDoc() map[string]string { diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 273851bb919..36f04082ede 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 8e1534879d6..ed084e7c72f 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index fb3e18ca85e..52116d6266c 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 3d7117d83f3..a9306a664cb 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1346,6 +1346,101 @@ spec: The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 16f4728a9ae..d361400daaf 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -280,6 +280,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA configv1.ConsoleList{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleList(ref), configv1.ConsoleSpec{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleSpec(ref), configv1.ConsoleStatus{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleStatus(ref), + configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName(): schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref), configv1.Custom{}.OpenAPIModelName(): schema_openshift_api_config_v1_Custom(ref), configv1.CustomFeatureGates{}.OpenAPIModelName(): schema_openshift_api_config_v1_CustomFeatureGates(ref), configv1.CustomTLSProfile{}.OpenAPIModelName(): schema_openshift_api_config_v1_CustomTLSProfile(ref), @@ -12750,6 +12751,55 @@ func schema_openshift_api_config_v1_ConsoleStatus(ref common.ReferenceCallback) } } +func schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "source": { + SchemaProps: spec.SchemaProps{ + Description: "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", + Type: []string{"string"}, + Format: "", + }, + }, + "target": { + SchemaProps: spec.SchemaProps{ + Description: "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + Type: []string{"string"}, + Format: "", + }, + }, + "availability": { + SchemaProps: spec.SchemaProps{ + Description: "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + Type: []string{"string"}, + Format: "", + }, + }, + "reason": { + SchemaProps: spec.SchemaProps{ + Description: "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"source", "target", "availability"}, + }, + }, + } +} + func schema_openshift_api_config_v1_Custom(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -16401,6 +16451,29 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal Format: "", }, }, + "controlPlaneTopologyTransitions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "source", + "target", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref(configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName()), + }, + }, + }, + }, + }, "cpuPartitioning": { SchemaProps: spec.SchemaProps{ Description: "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", @@ -16413,7 +16486,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal }, }, Dependencies: []string{ - configv1.PlatformStatus{}.OpenAPIModelName()}, + configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName(), configv1.PlatformStatus{}.OpenAPIModelName()}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 99f806ce8fe..ec841aefb64 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -6436,6 +6436,37 @@ } } }, + "com.github.openshift.api.config.v1.ControlPlaneTopologyTransition": { + "description": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + "type": "object", + "required": [ + "source", + "target", + "availability" + ], + "properties": { + "availability": { + "description": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + "type": "string" + }, + "message": { + "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", + "type": "string" + }, + "reason": { + "description": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "type": "string" + }, + "source": { + "description": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", + "type": "string" + }, + "target": { + "description": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + "type": "string" + } + } + }, "com.github.openshift.api.config.v1.Custom": { "description": "Custom provides the custom configuration of gatherers", "type": "object", @@ -8576,6 +8607,19 @@ "type": "string", "default": "" }, + "controlPlaneTopologyTransitions": { + "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.ControlPlaneTopologyTransition" + }, + "x-kubernetes-list-map-keys": [ + "source", + "target" + ], + "x-kubernetes-list-type": "map" + }, "cpuPartitioning": { "description": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", "type": "string", diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 7a35e5fc0f7..de5da8364a6 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index bbeff9ec02e..3176dce0c49 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 0207127aa67..99cfb608a58 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1163,6 +1163,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 273851bb919..36f04082ede 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 8e1534879d6..ed084e7c72f 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index fb3e18ca85e..52116d6266c 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1468,6 +1468,101 @@ spec: - DualReplica - External type: string + controlPlaneTopologyTransitions: + description: |- + controlPlaneTopologyTransitions reports, as controller-computed observed state, + the control-plane topology transitions that originate at the current + status.controlPlaneTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". source and target below only cover the topologies that support a + transition today; when status.controlPlaneTopology is a topology outside that set, + this field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 4 + entries are permitted, matching the full cardinality of the 2-value source/target + enum below. If source/target are ever widened to cover additional + transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is + not expected to participate in a transition and should not be added here), + MaxItems must be increased to match the new cardinality, up to 16 for all four + non-External TopologyMode values. + items: + description: |- + ControlPlaneTopologyTransition describes one control-plane topology transition + available from the cluster's current topology and whether it can currently be + initiated. reason must be set whenever availability is Unavailable or Unknown; + this is enforced by a validation rule on the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the topology this transition starts from. It equals the current + status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + target: + description: |- + target is the topology this transition would move the control plane to. + Valid values are SingleReplica and HighlyAvailable. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 4 + minItems: 0 + type: array + x-kubernetes-list-map-keys: + - source + - target + x-kubernetes-list-type: map cpuPartitioning: default: None description: |- From a4712ec1f5e0badd3ef05c9da11c275da4f6e465 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Tue, 15 Sep 2026 10:57:20 -0400 Subject: [PATCH 02/10] OCPEDGE-2989: Address API review feedback --- config/v1/types_infrastructure.go | 6 ++++++ ...01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...astructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 8 ++++++++ .../MutableTopology.yaml | 8 ++++++++ config/v1/zz_generated.swagger_doc_generated.go | 6 +++--- ..._controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...ntrollerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...llerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 8 ++++++++ .../MutableTopology.yaml | 8 ++++++++ openapi/generated_openapi/zz_generated.openapi.go | 6 +++--- openapi/openapi.json | 6 +++--- ...01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...astructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 8 ++++++++ ..._controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...ntrollerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 8 ++++++++ ...llerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 8 ++++++++ 18 files changed, 127 insertions(+), 9 deletions(-) diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 2c049263b56..964aed611c5 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -20,6 +20,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:metadata:annotations=release.openshift.io/bootstrap-required=true // +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.spec.controlPlaneTopology) || (has(oldSelf.spec.controlPlaneTopology) && self.spec.controlPlaneTopology == oldSelf.spec.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.spec.controlPlaneTopology == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == 'SingleReplica' && self.spec.controlPlaneTopology == 'HighlyAvailable')",message="spec.controlPlaneTopology must match status.controlPlaneTopology or be set to HighlyAvailable when status.controlPlaneTopology is SingleReplica" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, t.source == self.status.controlPlaneTopology)",message="transition sources must match status.controlPlaneTopology" type Infrastructure struct { metav1.TypeMeta `json:",inline"` @@ -214,12 +215,16 @@ const ( type ControlPlaneTopologyTransition struct { // source is the topology this transition starts from. It equals the current // status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + // When set to SingleReplica, the transition originates from a single-replica topology. + // When set to HighlyAvailable, the transition originates from a highly available topology. // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable // +required Source TopologyMode `json:"source,omitempty"` // target is the topology this transition would move the control plane to. // Valid values are SingleReplica and HighlyAvailable. + // When set to SingleReplica, the transition moves to a single-replica topology. + // When set to HighlyAvailable, the transition moves to a highly available topology. // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable // +required Target TopologyMode `json:"target,omitempty"` @@ -247,6 +252,7 @@ type ControlPlaneTopologyTransition struct { // message is a human-readable explanation, primarily for Unavailable // transitions (e.g. a concise summary of the failing preconditions). It is for // humans only and must not be parsed. It may be truncated by the controller. + // When omitted, no human-readable explanation is available for the transition. // When set, it must be between 1 and 2048 characters long. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=2048 diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index de5da8364a6..b5519a66456 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 3176dce0c49..2ccae781a21 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 99cfb608a58..262bad71c44 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index c8eab4566e2..cb4bf8fe0d2 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1097,6 +1097,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1119,6 +1120,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1127,6 +1130,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2539,6 +2544,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index f01c7328940..93533032a12 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1739,11 +1739,11 @@ func (CloudLoadBalancerIPs) SwaggerDoc() map[string]string { var map_ControlPlaneTopologyTransition = map[string]string{ "": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", - "source": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", - "target": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + "source": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", + "target": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", - "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", + "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", } func (ControlPlaneTopologyTransition) SwaggerDoc() map[string]string { diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 36f04082ede..244fa1ec033 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index ed084e7c72f..84618cd44ad 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 52116d6266c..134ce681528 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index a9306a664cb..28ae808b977 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1392,6 +1392,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1414,6 +1415,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1422,6 +1425,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2848,6 +2853,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index d361400daaf..164ccb7bc34 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -12760,14 +12760,14 @@ func schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref common.Re Properties: map[string]spec.Schema{ "source": { SchemaProps: spec.SchemaProps{ - Description: "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", + Description: "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", Type: []string{"string"}, Format: "", }, }, "target": { SchemaProps: spec.SchemaProps{ - Description: "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + Description: "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", Type: []string{"string"}, Format: "", }, @@ -12788,7 +12788,7 @@ func schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref common.Re }, "message": { SchemaProps: spec.SchemaProps{ - Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", + Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", Type: []string{"string"}, Format: "", }, diff --git a/openapi/openapi.json b/openapi/openapi.json index ec841aefb64..f1cf814e865 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -6450,7 +6450,7 @@ "type": "string" }, "message": { - "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When set, it must be between 1 and 2048 characters long.", + "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", "type": "string" }, "reason": { @@ -6458,11 +6458,11 @@ "type": "string" }, "source": { - "description": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable.", + "description": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", "type": "string" }, "target": { - "description": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable.", + "description": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", "type": "string" } } diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index de5da8364a6..b5519a66456 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 3176dce0c49..2ccae781a21 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 99cfb608a58..262bad71c44 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1209,6 +1209,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1231,6 +1232,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1239,6 +1242,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -2951,6 +2956,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 36f04082ede..244fa1ec033 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index ed084e7c72f..84618cd44ad 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 52116d6266c..134ce681528 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1514,6 +1514,7 @@ spec: message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 @@ -1536,6 +1537,8 @@ spec: description: |- source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition originates from a single-replica topology. + When set to HighlyAvailable, the transition originates from a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -1544,6 +1547,8 @@ spec: description: |- target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. + When set to SingleReplica, the transition moves to a single-replica topology. + When set to HighlyAvailable, the transition moves to a highly available topology. enum: - SingleReplica - HighlyAvailable @@ -3275,6 +3280,9 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' + - message: transition sources must match status.controlPlaneTopology + rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, + t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by From 29bab829aaf9c85e3b9886c26b1f2cd1b27635c7 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Tue, 15 Sep 2026 12:19:33 -0400 Subject: [PATCH 03/10] OCPEDGE-2989: Align transition limits with validation --- .../MutableTopology.yaml | 26 ++++++++++++------- config/v1/types_infrastructure.go | 12 ++++----- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 ++++++----- .../MutableTopology.yaml | 15 ++++++----- .../v1/zz_generated.swagger_doc_generated.go | 2 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 ++++++----- .../MutableTopology.yaml | 15 ++++++----- .../generated_openapi/zz_generated.openapi.go | 2 +- openapi/openapi.json | 2 +- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 ++++++----- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 ++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 ++++++----- 19 files changed, 137 insertions(+), 117 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index bbadcdff09a..28a0bf4a5b8 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -419,7 +419,7 @@ tests: target: HighlyAvailable availability: Unknown reason: EvaluationPending - - name: Should allow setting every schema-permitted source/target pair in controlPlaneTopologyTransitions (a MaxItems boundary test spanning the full source x target enum cardinality; includes source==target pairs the controller itself would never emit, but which the schema permits) + - name: Should allow setting every schema-permitted target for the current source in controlPlaneTopologyTransitions as a MaxItems boundary test initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -439,12 +439,6 @@ tests: - source: SingleReplica target: HighlyAvailable availability: Available - - source: HighlyAvailable - target: SingleReplica - availability: Available - - source: HighlyAvailable - target: HighlyAvailable - availability: Available expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -460,12 +454,24 @@ tests: - source: SingleReplica target: HighlyAvailable availability: Available + - name: Should not allow a controlPlaneTopologyTransitions entry whose source differs from status controlPlaneTopology + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: - source: HighlyAvailable target: SingleReplica availability: Available - - source: HighlyAvailable - target: HighlyAvailable - availability: Available + expectedStatusError: "transition sources must match status.controlPlaneTopology" - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid source initial: | apiVersion: config.openshift.io/v1 diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 964aed611c5..8b55e4e81ba 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -20,7 +20,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:metadata:annotations=release.openshift.io/bootstrap-required=true // +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.spec.controlPlaneTopology) || (has(oldSelf.spec.controlPlaneTopology) && self.spec.controlPlaneTopology == oldSelf.spec.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.spec.controlPlaneTopology == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == 'SingleReplica' && self.spec.controlPlaneTopology == 'HighlyAvailable')",message="spec.controlPlaneTopology must match status.controlPlaneTopology or be set to HighlyAvailable when status.controlPlaneTopology is SingleReplica" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, t.source == self.status.controlPlaneTopology)",message="transition sources must match status.controlPlaneTopology" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) && t.source == self.status.controlPlaneTopology)",message="transition sources must match status.controlPlaneTopology" type Infrastructure struct { metav1.TypeMeta `json:",inline"` @@ -152,19 +152,19 @@ type InfrastructureStatus struct { // transitions". source and target below only cover the topologies that support a // transition today; when status.controlPlaneTopology is a topology outside that set, // this field is expected to remain omitted or empty. Entries are keyed by the - // (source, target) topology pair and list order is not significant. At most 4 - // entries are permitted, matching the full cardinality of the 2-value source/target - // enum below. If source/target are ever widened to cover additional + // (source, target) topology pair and list order is not significant. At most 2 + // entries are permitted, matching the cardinality of the target enum for the + // single current source. If target is ever widened to cover additional // transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is // not expected to participate in a transition and should not be added here), - // MaxItems must be increased to match the new cardinality, up to 16 for all four + // MaxItems must be increased to match the new cardinality, up to 4 for all four // non-External TopologyMode values. // +openshift:enable:FeatureGate=MutableTopology // +listType=map // +listMapKey=source // +listMapKey=target // +kubebuilder:validation:MinItems=0 - // +kubebuilder:validation:MaxItems=4 + // +kubebuilder:validation:MaxItems=2 // +optional ControlPlaneTopologyTransitions []ControlPlaneTopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index b5519a66456..e3a7b426d89 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 2ccae781a21..4d1911422a6 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 262bad71c44..63d1fc36227 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index cb4bf8fe0d2..2a40e708e6c 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1066,12 +1066,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1144,7 +1144,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2545,8 +2545,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 93533032a12..a503d7f5fb1 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1903,7 +1903,7 @@ var map_InfrastructureStatus = map[string]string{ "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", - "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", } diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 244fa1ec033..9a70a9bb4b7 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 84618cd44ad..6a23782e7b0 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 134ce681528..9f171d013ba 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 28ae808b977..33037e05b0c 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1361,12 +1361,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1439,7 +1439,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2854,8 +2854,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 164ccb7bc34..9d028050a2e 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -16462,7 +16462,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal }, }, SchemaProps: spec.SchemaProps{ - Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/openapi/openapi.json b/openapi/openapi.json index f1cf814e865..3d0d606d9cb 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -8608,7 +8608,7 @@ "default": "" }, "controlPlaneTopologyTransitions": { - "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 4 entries are permitted, matching the full cardinality of the 2-value source/target enum below. If source/target are ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 16 for all four non-External TopologyMode values.", + "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", "type": "array", "items": { "default": {}, diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index b5519a66456..e3a7b426d89 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 2ccae781a21..4d1911422a6 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 262bad71c44..63d1fc36227 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1178,12 +1178,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1256,7 +1256,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -2957,8 +2957,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 244fa1ec033..9a70a9bb4b7 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 84618cd44ad..6a23782e7b0 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 134ce681528..9f171d013ba 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1483,12 +1483,12 @@ spec: transitions". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 4 - entries are permitted, matching the full cardinality of the 2-value source/target - enum below. If source/target are ever widened to cover additional + (source, target) topology pair and list order is not significant. At most 2 + entries are permitted, matching the cardinality of the target enum for the + single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 16 for all four + MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values. items: description: |- @@ -1561,7 +1561,7 @@ spec: x-kubernetes-validations: - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 4 + maxItems: 2 minItems: 0 type: array x-kubernetes-list-map-keys: @@ -3281,8 +3281,9 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, - t.source == self.status.controlPlaneTopology)' + rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) + || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) + && t.source == self.status.controlPlaneTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by From 5f602669ffb77a318db7c10a5beaafd075dffa04 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Wed, 16 Sep 2026 13:22:54 -0400 Subject: [PATCH 04/10] OCPEDGE-2989: Reject self topology transitions --- .../MutableTopology.yaml | 122 +++++++++++++++++- config/v1/types_infrastructure.go | 6 +- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 7 +- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 7 +- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 7 +- .../MutableTopology.yaml | 7 +- .../v1/zz_generated.swagger_doc_generated.go | 2 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 7 +- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 7 +- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 7 +- .../MutableTopology.yaml | 7 +- .../generated_openapi/zz_generated.openapi.go | 2 +- openapi/openapi.json | 2 +- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 7 +- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 7 +- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 7 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 7 +- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 7 +- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 7 +- 19 files changed, 193 insertions(+), 39 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index 28a0bf4a5b8..f9918fcc79a 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -326,6 +326,29 @@ tests: controlPlaneTopology: HighlyAvailableArbiter infrastructureTopology: HighlyAvailable cpuPartitioning: None + - name: Should allow setting controlPlaneTopologyTransitions to an empty list when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + controlPlaneTopologyTransitions: [] + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailableArbiter + infrastructureTopology: HighlyAvailable + cpuPartitioning: None + controlPlaneTopologyTransitions: [] - name: Should allow setting controlPlaneTopologyTransitions to an Available entry with no reason initial: | apiVersion: config.openshift.io/v1 @@ -419,7 +442,7 @@ tests: target: HighlyAvailable availability: Unknown reason: EvaluationPending - - name: Should allow setting every schema-permitted target for the current source in controlPlaneTopologyTransitions as a MaxItems boundary test + - name: Should allow a valid controlPlaneTopologyTransitions entry for the current source initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -433,9 +456,6 @@ tests: status: controlPlaneTopology: SingleReplica controlPlaneTopologyTransitions: - - source: SingleReplica - target: SingleReplica - availability: Available - source: SingleReplica target: HighlyAvailable availability: Available @@ -449,11 +469,26 @@ tests: cpuPartitioning: None controlPlaneTopologyTransitions: - source: SingleReplica - target: SingleReplica + target: HighlyAvailable availability: Available + - name: Should not allow a self-transition in controlPlaneTopologyTransitions + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: - source: SingleReplica - target: HighlyAvailable + target: SingleReplica availability: Available + expectedStatusError: "source and target must differ" - name: Should not allow a controlPlaneTopologyTransitions entry whose source differs from status controlPlaneTopology initial: | apiVersion: config.openshift.io/v1 @@ -526,6 +561,81 @@ tests: target: HighlyAvailable availability: Pending expectedStatusError: 'status.controlPlaneTopologyTransitions[0].availability: Unsupported value: "Pending": supported values: "Available", "Unavailable", "Unknown"' + - name: Should not allow a controlPlaneTopologyTransitions entry without source + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - target: HighlyAvailable + availability: Available + expectedStatusError: "Required value" + - name: Should not allow a controlPlaneTopologyTransitions entry without target + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + availability: Available + expectedStatusError: "Required value" + - name: Should not allow a controlPlaneTopologyTransitions entry without availability + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + expectedStatusError: "Required value" + - name: Should not allow more than two controlPlaneTopologyTransitions entries + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + controlPlaneTopologyTransitions: + - source: SingleReplica + target: HighlyAvailable + availability: Available + - source: HighlyAvailable + target: SingleReplica + availability: Available + - source: HighlyAvailable + target: HighlyAvailable + availability: Available + expectedStatusError: "Too many: 3: must have at most 2 items" - name: Should not allow an Unavailable controlPlaneTopologyTransitions entry without a reason initial: | apiVersion: config.openshift.io/v1 diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 8b55e4e81ba..e341de6c9cb 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -209,8 +209,10 @@ const ( // ControlPlaneTopologyTransition describes one control-plane topology transition // available from the cluster's current topology and whether it can currently be -// initiated. reason must be set whenever availability is Unavailable or Unknown; -// this is enforced by a validation rule on the entry as a whole. +// initiated. source and target must differ. reason must be set whenever +// availability is Unavailable or Unknown; both constraints are enforced by +// validation rules on the entry as a whole. +// +kubebuilder:validation:XValidation:rule="self.source != self.target",message="source and target must differ" // +kubebuilder:validation:XValidation:rule="self.availability == 'Available' || has(self.reason)",message="reason is required when availability is not Available" type ControlPlaneTopologyTransition struct { // source is the topology this transition starts from. It equals the current diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index e3a7b426d89..d2e2ccdbfa8 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 4d1911422a6..8b175c37cae 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 63d1fc36227..7e226de0152 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index 2a40e708e6c..1f58306cd39 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1077,8 +1077,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1142,6 +1143,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index a503d7f5fb1..6fc422471a7 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1738,7 +1738,7 @@ func (CloudLoadBalancerIPs) SwaggerDoc() map[string]string { } var map_ControlPlaneTopologyTransition = map[string]string{ - "": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + "": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", "source": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", "target": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 9a70a9bb4b7..add3337adf5 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6a23782e7b0..ee30bd4c872 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9f171d013ba..7319a9cc2d7 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 33037e05b0c..bc79224a2f2 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1372,8 +1372,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1437,6 +1438,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 9d028050a2e..700fe19b95d 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -12755,7 +12755,7 @@ func schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref common.Re return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + Description: "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "source": { diff --git a/openapi/openapi.json b/openapi/openapi.json index 3d0d606d9cb..bbc517024e6 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -6437,7 +6437,7 @@ } }, "com.github.openshift.api.config.v1.ControlPlaneTopologyTransition": { - "description": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. reason must be set whenever availability is Unavailable or Unknown; this is enforced by a validation rule on the entry as a whole.", + "description": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", "type": "object", "required": [ "source", diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index e3a7b426d89..d2e2ccdbfa8 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 4d1911422a6..8b175c37cae 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 63d1fc36227..7e226de0152 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1189,8 +1189,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1254,6 +1255,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 9a70a9bb4b7..add3337adf5 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6a23782e7b0..ee30bd4c872 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9f171d013ba..7319a9cc2d7 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1494,8 +1494,9 @@ spec: description: |- ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be - initiated. reason must be set whenever availability is Unavailable or Unknown; - this is enforced by a validation rule on the entry as a whole. + initiated. source and target must differ. reason must be set whenever + availability is Unavailable or Unknown; both constraints are enforced by + validation rules on the entry as a whole. properties: availability: description: |- @@ -1559,6 +1560,8 @@ spec: - target type: object x-kubernetes-validations: + - message: source and target must differ + rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) maxItems: 2 From 3c0d796f853190a102cddf20cf4ce1f9392c39a4 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Thu, 17 Sep 2026 10:58:10 -0400 Subject: [PATCH 05/10] OCPEDGE-2989: Generalize topology transition type --- config/v1/types_infrastructure.go | 19 ++-- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 15 +-- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 +-- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 +-- config/v1/zz_generated.deepcopy.go | 34 +++--- .../MutableTopology.yaml | 15 +-- config/v1/zz_generated.model_name.go | 10 +- .../v1/zz_generated.swagger_doc_generated.go | 26 ++--- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 15 +-- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 +-- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 +-- .../MutableTopology.yaml | 15 +-- .../generated_openapi/zz_generated.openapi.go | 104 +++++++++--------- openapi/openapi.json | 64 +++++------ ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 15 +-- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 +-- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 +-- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 15 +-- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 15 +-- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 15 +-- 20 files changed, 241 insertions(+), 226 deletions(-) diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index e341de6c9cb..a0965307c3e 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -166,7 +166,7 @@ type InfrastructureStatus struct { // +kubebuilder:validation:MinItems=0 // +kubebuilder:validation:MaxItems=2 // +optional - ControlPlaneTopologyTransitions []ControlPlaneTopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` + ControlPlaneTopologyTransitions []TopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` // cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. // CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. @@ -207,23 +207,24 @@ const ( ExternalTopologyMode TopologyMode = "External" ) -// ControlPlaneTopologyTransition describes one control-plane topology transition -// available from the cluster's current topology and whether it can currently be -// initiated. source and target must differ. reason must be set whenever -// availability is Unavailable or Unknown; both constraints are enforced by -// validation rules on the entry as a whole. +// TopologyTransition describes one topology transition available from the +// cluster's current topology and whether it can currently be initiated. source +// and target must differ. reason must be set whenever availability is +// Unavailable or Unknown; both constraints are enforced by validation rules on +// the entry as a whole. // +kubebuilder:validation:XValidation:rule="self.source != self.target",message="source and target must differ" // +kubebuilder:validation:XValidation:rule="self.availability == 'Available' || has(self.reason)",message="reason is required when availability is not Available" -type ControlPlaneTopologyTransition struct { +type TopologyTransition struct { // source is the topology this transition starts from. It equals the current - // status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + // topology in the corresponding status field. Valid values are SingleReplica + // and HighlyAvailable. // When set to SingleReplica, the transition originates from a single-replica topology. // When set to HighlyAvailable, the transition originates from a highly available topology. // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable // +required Source TopologyMode `json:"source,omitempty"` - // target is the topology this transition would move the control plane to. + // target is the topology this transition would move to. // Valid values are SingleReplica and HighlyAvailable. // When set to SingleReplica, the transition moves to a single-replica topology. // When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index d2e2ccdbfa8..2a48318bc61 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 8b175c37cae..1941e81f6a7 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 7e226de0152..9d39778dcaa 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 5e3fb9427bd..d26507062c3 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -1906,22 +1906,6 @@ func (in *ConsoleStatus) DeepCopy() *ConsoleStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneTopologyTransition) DeepCopyInto(out *ControlPlaneTopologyTransition) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneTopologyTransition. -func (in *ControlPlaneTopologyTransition) DeepCopy() *ControlPlaneTopologyTransition { - if in == nil { - return nil - } - out := new(ControlPlaneTopologyTransition) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Custom) DeepCopyInto(out *Custom) { *out = *in @@ -3838,7 +3822,7 @@ func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { } if in.ControlPlaneTopologyTransitions != nil { in, out := &in.ControlPlaneTopologyTransitions, &out.ControlPlaneTopologyTransitions - *out = make([]ControlPlaneTopologyTransition, len(*in)) + *out = make([]TopologyTransition, len(*in)) copy(*out, *in) } return @@ -6869,6 +6853,22 @@ func (in *TokenUserValidationRule) DeepCopy() *TokenUserValidationRule { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyTransition) DeepCopyInto(out *TopologyTransition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyTransition. +func (in *TopologyTransition) DeepCopy() *TopologyTransition { + if in == nil { + return nil + } + out := new(TopologyTransition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Update) DeepCopyInto(out *Update) { *out = *in diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index 1f58306cd39..c0995ca5c6d 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1075,11 +1075,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1120,7 +1120,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1129,7 +1130,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/config/v1/zz_generated.model_name.go b/config/v1/zz_generated.model_name.go index 53a455e4367..84610fb4449 100644 --- a/config/v1/zz_generated.model_name.go +++ b/config/v1/zz_generated.model_name.go @@ -395,11 +395,6 @@ func (in ConsoleStatus) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.ConsoleStatus" } -// OpenAPIModelName returns the OpenAPI model name for this type. -func (in ControlPlaneTopologyTransition) OpenAPIModelName() string { - return "com.github.openshift.api.config.v1.ControlPlaneTopologyTransition" -} - // OpenAPIModelName returns the OpenAPI model name for this type. func (in Custom) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.Custom" @@ -1460,6 +1455,11 @@ func (in TokenUserValidationRule) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.TokenUserValidationRule" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TopologyTransition) OpenAPIModelName() string { + return "com.github.openshift.api.config.v1.TopologyTransition" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in Update) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.Update" diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 6fc422471a7..46a6307e40c 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1737,19 +1737,6 @@ func (CloudLoadBalancerIPs) SwaggerDoc() map[string]string { return map_CloudLoadBalancerIPs } -var map_ControlPlaneTopologyTransition = map[string]string{ - "": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - "source": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", - "target": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", - "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", - "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", - "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", -} - -func (ControlPlaneTopologyTransition) SwaggerDoc() map[string]string { - return map_ControlPlaneTopologyTransition -} - var map_EquinixMetalPlatformSpec = map[string]string{ "": "EquinixMetalPlatformSpec holds the desired state of the Equinix Metal infrastructure provider. This only includes fields that can be modified in the cluster.", } @@ -2153,6 +2140,19 @@ func (PowerVSServiceEndpoint) SwaggerDoc() map[string]string { return map_PowerVSServiceEndpoint } +var map_TopologyTransition = map[string]string{ + "": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", + "source": "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", + "target": "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", + "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", +} + +func (TopologyTransition) SwaggerDoc() map[string]string { + return map_TopologyTransition +} + var map_VSphereFailureDomainHostGroup = map[string]string{ "": "VSphereFailureDomainHostGroup holds the vmGroup and the hostGroup names in vCenter corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also contains the vmHostRule which is an affinity vm-host rule in vCenter.", "vmGroup": "vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. vmGroup is limited to 80 characters. This field is required when the VSphereFailureDomain ZoneType is HostGroup", diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index add3337adf5..5dee6112b26 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index ee30bd4c872..36b2ec493e9 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 7319a9cc2d7..14d2b5f04b7 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index bc79224a2f2..deabfd37e6e 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1370,11 +1370,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1415,7 +1415,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1424,7 +1425,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 700fe19b95d..136d741db33 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -280,7 +280,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA configv1.ConsoleList{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleList(ref), configv1.ConsoleSpec{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleSpec(ref), configv1.ConsoleStatus{}.OpenAPIModelName(): schema_openshift_api_config_v1_ConsoleStatus(ref), - configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName(): schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref), configv1.Custom{}.OpenAPIModelName(): schema_openshift_api_config_v1_Custom(ref), configv1.CustomFeatureGates{}.OpenAPIModelName(): schema_openshift_api_config_v1_CustomFeatureGates(ref), configv1.CustomTLSProfile{}.OpenAPIModelName(): schema_openshift_api_config_v1_CustomTLSProfile(ref), @@ -493,6 +492,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA configv1.TokenIssuer{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenIssuer(ref), configv1.TokenRequiredClaim{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenRequiredClaim(ref), configv1.TokenUserValidationRule{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenUserValidationRule(ref), + configv1.TopologyTransition{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyTransition(ref), configv1.Update{}.OpenAPIModelName(): schema_openshift_api_config_v1_Update(ref), configv1.UpdateHistory{}.OpenAPIModelName(): schema_openshift_api_config_v1_UpdateHistory(ref), configv1.UsernameClaimMapping{}.OpenAPIModelName(): schema_openshift_api_config_v1_UsernameClaimMapping(ref), @@ -12751,55 +12751,6 @@ func schema_openshift_api_config_v1_ConsoleStatus(ref common.ReferenceCallback) } } -func schema_openshift_api_config_v1_ControlPlaneTopologyTransition(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "source": { - SchemaProps: spec.SchemaProps{ - Description: "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", - Type: []string{"string"}, - Format: "", - }, - }, - "target": { - SchemaProps: spec.SchemaProps{ - Description: "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", - Type: []string{"string"}, - Format: "", - }, - }, - "availability": { - SchemaProps: spec.SchemaProps{ - Description: "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", - Type: []string{"string"}, - Format: "", - }, - }, - "reason": { - SchemaProps: spec.SchemaProps{ - Description: "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", - Type: []string{"string"}, - Format: "", - }, - }, - "message": { - SchemaProps: spec.SchemaProps{ - Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"source", "target", "availability"}, - }, - }, - } -} - func schema_openshift_api_config_v1_Custom(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -16468,7 +16419,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref(configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName()), + Ref: ref(configv1.TopologyTransition{}.OpenAPIModelName()), }, }, }, @@ -16486,7 +16437,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal }, }, Dependencies: []string{ - configv1.ControlPlaneTopologyTransition{}.OpenAPIModelName(), configv1.PlatformStatus{}.OpenAPIModelName()}, + configv1.PlatformStatus{}.OpenAPIModelName(), configv1.TopologyTransition{}.OpenAPIModelName()}, } } @@ -22291,6 +22242,55 @@ func schema_openshift_api_config_v1_TokenUserValidationRule(ref common.Reference } } +func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "source": { + SchemaProps: spec.SchemaProps{ + Description: "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", + Type: []string{"string"}, + Format: "", + }, + }, + "target": { + SchemaProps: spec.SchemaProps{ + Description: "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", + Type: []string{"string"}, + Format: "", + }, + }, + "availability": { + SchemaProps: spec.SchemaProps{ + Description: "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + Type: []string{"string"}, + Format: "", + }, + }, + "reason": { + SchemaProps: spec.SchemaProps{ + Description: "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"source", "target", "availability"}, + }, + }, + } +} + func schema_openshift_api_config_v1_Update(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/openapi/openapi.json b/openapi/openapi.json index bbc517024e6..5f0540d60d9 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -6436,37 +6436,6 @@ } } }, - "com.github.openshift.api.config.v1.ControlPlaneTopologyTransition": { - "description": "ControlPlaneTopologyTransition describes one control-plane topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - "type": "object", - "required": [ - "source", - "target", - "availability" - ], - "properties": { - "availability": { - "description": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", - "type": "string" - }, - "message": { - "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", - "type": "string" - }, - "reason": { - "description": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", - "type": "string" - }, - "source": { - "description": "source is the topology this transition starts from. It equals the current status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", - "type": "string" - }, - "target": { - "description": "target is the topology this transition would move the control plane to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", - "type": "string" - } - } - }, "com.github.openshift.api.config.v1.Custom": { "description": "Custom provides the custom configuration of gatherers", "type": "object", @@ -8612,7 +8581,7 @@ "type": "array", "items": { "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1.ControlPlaneTopologyTransition" + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" }, "x-kubernetes-list-map-keys": [ "source", @@ -12053,6 +12022,37 @@ } } }, + "com.github.openshift.api.config.v1.TopologyTransition": { + "description": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", + "type": "object", + "required": [ + "source", + "target", + "availability" + ], + "properties": { + "availability": { + "description": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + "type": "string" + }, + "message": { + "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", + "type": "string" + }, + "reason": { + "description": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "type": "string" + }, + "source": { + "description": "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", + "type": "string" + }, + "target": { + "description": "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", + "type": "string" + } + } + }, "com.github.openshift.api.config.v1.Update": { "description": "Update represents an administrator update request.", "type": "object", diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index d2e2ccdbfa8..2a48318bc61 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 8b175c37cae..1941e81f6a7 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 7e226de0152..9d39778dcaa 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1187,11 +1187,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1232,7 +1232,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1241,7 +1242,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index add3337adf5..5dee6112b26 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index ee30bd4c872..36b2ec493e9 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 7319a9cc2d7..14d2b5f04b7 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1492,11 +1492,11 @@ spec: non-External TopologyMode values. items: description: |- - ControlPlaneTopologyTransition describes one control-plane topology transition - available from the cluster's current topology and whether it can currently be - initiated. source and target must differ. reason must be set whenever - availability is Unavailable or Unknown; both constraints are enforced by - validation rules on the entry as a whole. + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. properties: availability: description: |- @@ -1537,7 +1537,8 @@ spec: source: description: |- source is the topology this transition starts from. It equals the current - status.controlPlaneTopology. Valid values are SingleReplica and HighlyAvailable. + topology in the corresponding status field. Valid values are SingleReplica + and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology. enum: @@ -1546,7 +1547,7 @@ spec: type: string target: description: |- - target is the topology this transition would move the control plane to. + target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology. From 8e99b2a2fe6849a0783f6ee851e64e78ce1ad11c Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Thu, 17 Sep 2026 12:00:13 -0400 Subject: [PATCH 06/10] OCPEDGE-2989: Restrict supported topology transitions --- .../MutableTopology.yaml | 42 ++++++++----------- config/v1/types_infrastructure.go | 18 ++++---- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 21 +++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 21 +++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 21 +++++----- .../MutableTopology.yaml | 21 +++++----- .../v1/zz_generated.swagger_doc_generated.go | 2 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 22 +++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 22 +++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 22 +++++----- .../MutableTopology.yaml | 22 +++++----- .../generated_openapi/zz_generated.openapi.go | 2 +- openapi/openapi.json | 2 +- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 21 +++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 21 +++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 21 +++++----- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 22 +++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 22 +++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 22 +++++----- 19 files changed, 175 insertions(+), 192 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index f9918fcc79a..0f46ef14098 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -507,6 +507,24 @@ tests: target: SingleReplica availability: Available expectedStatusError: "transition sources must match status.controlPlaneTopology" + - name: Should not allow a reverse controlPlaneTopologyTransitions entry + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailable + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: HighlyAvailable + controlPlaneTopologyTransitions: + - source: HighlyAvailable + target: SingleReplica + availability: Available + expectedStatusError: "only SingleReplica to HighlyAvailable control-plane topology transitions are supported" - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid source initial: | apiVersion: config.openshift.io/v1 @@ -612,30 +630,6 @@ tests: - source: SingleReplica target: HighlyAvailable expectedStatusError: "Required value" - - name: Should not allow more than two controlPlaneTopologyTransitions entries - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable - availability: Available - - source: HighlyAvailable - target: SingleReplica - availability: Available - - source: HighlyAvailable - target: HighlyAvailable - availability: Available - expectedStatusError: "Too many: 3: must have at most 2 items" - name: Should not allow an Unavailable controlPlaneTopologyTransitions entry without a reason initial: | apiVersion: config.openshift.io/v1 diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index a0965307c3e..0253c0e74ef 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -149,22 +149,18 @@ type InfrastructureStatus struct { // the controller has not yet completed its first evaluation; an empty list is also // valid and intentionally carries the same meaning as omitted, since this field does // not currently distinguish "not yet evaluated" from "evaluated with no applicable - // transitions". source and target below only cover the topologies that support a - // transition today; when status.controlPlaneTopology is a topology outside that set, - // this field is expected to remain omitted or empty. Entries are keyed by the - // (source, target) topology pair and list order is not significant. At most 2 - // entries are permitted, matching the cardinality of the target enum for the - // single current source. If target is ever widened to cover additional - // transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - // not expected to participate in a transition and should not be added here), - // MaxItems must be increased to match the new cardinality, up to 4 for all four - // non-External TopologyMode values. + // transitions". The only supported transition is from SingleReplica to + // HighlyAvailable. When status.controlPlaneTopology has any other value, this + // field is expected to remain omitted or empty. Entries are keyed by the + // (source, target) topology pair and list order is not significant. At most 1 + // entry is permitted because only one transition direction is currently supported. // +openshift:enable:FeatureGate=MutableTopology // +listType=map // +listMapKey=source // +listMapKey=target // +kubebuilder:validation:MinItems=0 - // +kubebuilder:validation:MaxItems=2 + // +kubebuilder:validation:MaxItems=1 + // +kubebuilder:validation:XValidation:rule="self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable')",message="only SingleReplica to HighlyAvailable control-plane topology transitions are supported" // +optional ControlPlaneTopologyTransitions []TopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 2a48318bc61..20e316fc576 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 1941e81f6a7..ae9b73430d0 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9d39778dcaa..11dd81fcd81 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index c0995ca5c6d..7ba132900f9 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1063,16 +1063,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1148,13 +1143,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 46a6307e40c..1c9c61273e1 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1890,7 +1890,7 @@ var map_InfrastructureStatus = map[string]string{ "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", - "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", + "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", } diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 5dee6112b26..02c6d0d6653 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 36b2ec493e9..6dd43d22334 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 14d2b5f04b7..654389a8baa 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index deabfd37e6e..4f9c1459d40 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1358,16 +1358,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1443,13 +1438,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 136d741db33..fc7f7b2d417 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -16413,7 +16413,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal }, }, SchemaProps: spec.SchemaProps{ - Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", + Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ diff --git a/openapi/openapi.json b/openapi/openapi.json index 5f0540d60d9..8a1d242e0c6 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -8577,7 +8577,7 @@ "default": "" }, "controlPlaneTopologyTransitions": { - "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". source and target below only cover the topologies that support a transition today; when status.controlPlaneTopology is a topology outside that set, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 2 entries are permitted, matching the cardinality of the target enum for the single current source. If target is ever widened to cover additional transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is not expected to participate in a transition and should not be added here), MaxItems must be increased to match the new cardinality, up to 4 for all four non-External TopologyMode values.", + "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", "type": "array", "items": { "default": {}, diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 2a48318bc61..20e316fc576 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 1941e81f6a7..ae9b73430d0 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9d39778dcaa..11dd81fcd81 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1175,16 +1175,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1260,13 +1255,17 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane topology + transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 5dee6112b26..02c6d0d6653 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 36b2ec493e9..6dd43d22334 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 14d2b5f04b7..654389a8baa 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1480,16 +1480,11 @@ spec: the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". source and target below only cover the topologies that support a - transition today; when status.controlPlaneTopology is a topology outside that set, - this field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 2 - entries are permitted, matching the cardinality of the target enum for the - single current source. If target is ever widened to cover additional - transition-eligible topologies (HighlyAvailableArbiter, DualReplica; External is - not expected to participate in a transition and should not be added here), - MaxItems must be increased to match the new cardinality, up to 4 for all four - non-External TopologyMode values. + transitions". The only supported transition is from SingleReplica to + HighlyAvailable. When status.controlPlaneTopology has any other value, this + field is expected to remain omitted or empty. Entries are keyed by the + (source, target) topology pair and list order is not significant. At most 1 + entry is permitted because only one transition direction is currently supported. items: description: |- TopologyTransition describes one topology transition available from the @@ -1565,13 +1560,18 @@ spec: rule: self.source != self.target - message: reason is required when availability is not Available rule: self.availability == 'Available' || has(self.reason) - maxItems: 2 + maxItems: 1 minItems: 0 type: array x-kubernetes-list-map-keys: - source - target x-kubernetes-list-type: map + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable control-plane + topology transitions are supported + rule: self.all(t, t.source == 'SingleReplica' && t.target + == 'HighlyAvailable') cpuPartitioning: default: None description: |- From c94f2ba75cf2b81a7d971182ccdfb210db640956 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Tue, 22 Sep 2026 13:34:12 -0400 Subject: [PATCH 07/10] OCPEDGE-2989: Model topology transitions as states Represent transition source and target as control-plane and infrastructure topology pairs. Update validation, tests, and generated schemas for the new status shape. --- .../MutableTopology.yaml | 370 ++++++++++++------ config/v1/types_infrastructure.go | 70 ++-- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 257 +++++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 257 +++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 257 +++++++----- config/v1/zz_generated.deepcopy.go | 22 +- .../MutableTopology.yaml | 257 +++++++----- config/v1/zz_generated.model_name.go | 5 + .../v1/zz_generated.swagger_doc_generated.go | 36 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 260 +++++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 260 +++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 260 +++++++----- .../MutableTopology.yaml | 260 +++++++----- .../generated_openapi/zz_generated.openapi.go | 53 ++- openapi/openapi.json | 50 ++- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 257 +++++++----- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 257 +++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 257 +++++++----- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 260 +++++++----- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 260 +++++++----- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 260 +++++++----- 21 files changed, 2533 insertions(+), 1692 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index 0f46ef14098..7fa70ea0f8a 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -259,7 +259,7 @@ tests: spec: controlPlaneTopology: InvalidValue expectedError: 'spec.controlPlaneTopology: Unsupported value: "InvalidValue": supported values: "HighlyAvailable", "SingleReplica"' - - name: Should allow controlPlaneTopologyTransitions to remain omitted, representing that the controller has not yet completed its first evaluation + - name: Should allow topologyTransitions to remain omitted, representing that the controller has not yet completed its first evaluation initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -282,7 +282,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: HighlyAvailable cpuPartitioning: None - - name: Should allow explicitly setting controlPlaneTopologyTransitions to an empty list, carrying the same meaning as omitting it + - name: Should allow explicitly setting topologyTransitions to an empty list, carrying the same meaning as omitting it initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -295,7 +295,7 @@ tests: spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: [] + topologyTransitions: [] expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -304,8 +304,8 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: HighlyAvailable cpuPartitioning: None - controlPlaneTopologyTransitions: [] - - name: Should allow controlPlaneTopologyTransitions to remain omitted when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) + topologyTransitions: [] + - name: Should allow topologyTransitions to remain omitted when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -326,7 +326,7 @@ tests: controlPlaneTopology: HighlyAvailableArbiter infrastructureTopology: HighlyAvailable cpuPartitioning: None - - name: Should allow setting controlPlaneTopologyTransitions to an empty list when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) + - name: Should allow setting topologyTransitions to an empty list when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -339,7 +339,7 @@ tests: spec: {} status: controlPlaneTopology: HighlyAvailableArbiter - controlPlaneTopologyTransitions: [] + topologyTransitions: [] expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -348,23 +348,29 @@ tests: controlPlaneTopology: HighlyAvailableArbiter infrastructureTopology: HighlyAvailable cpuPartitioning: None - controlPlaneTopologyTransitions: [] - - name: Should allow setting controlPlaneTopologyTransitions to an Available entry with no reason + topologyTransitions: [] + - name: Should allow setting topologyTransitions to an Available entry with no reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available expected: | apiVersion: config.openshift.io/v1 @@ -372,28 +378,38 @@ tests: spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: HighlyAvailable + infrastructureTopology: SingleReplica cpuPartitioning: None - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available - - name: Should allow setting controlPlaneTopologyTransitions to an Unavailable entry including reason and message + - name: Should allow setting topologyTransitions to an Unavailable entry including reason and message initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: PreflightCheckFailed message: "etcd does not have quorum: need 3 voting members, have 1" @@ -403,30 +419,40 @@ tests: spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: HighlyAvailable + infrastructureTopology: SingleReplica cpuPartitioning: None - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: PreflightCheckFailed message: "etcd does not have quorum: need 3 voting members, have 1" - - name: Should allow setting controlPlaneTopologyTransitions to an Unknown entry with a reason + - name: Should allow setting topologyTransitions to an Unknown entry with a reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unknown reason: EvaluationPending expected: | @@ -435,29 +461,39 @@ tests: spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: HighlyAvailable + infrastructureTopology: SingleReplica cpuPartitioning: None - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unknown reason: EvaluationPending - - name: Should allow a valid controlPlaneTopologyTransitions entry for the current source + - name: Should allow a valid topologyTransitions entry for the current source initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available expected: | apiVersion: config.openshift.io/v1 @@ -465,323 +501,429 @@ tests: spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: HighlyAvailable + infrastructureTopology: SingleReplica cpuPartitioning: None - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available - - name: Should not allow a self-transition in controlPlaneTopologyTransitions + - name: Should not allow a self-transition in topologyTransitions initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: SingleReplica + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica availability: Available expectedStatusError: "source and target must differ" - - name: Should not allow a controlPlaneTopologyTransitions entry whose source differs from status controlPlaneTopology + - name: Should not allow a topologyTransitions entry whose source differs from the current status topology initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: HighlyAvailable - target: SingleReplica + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + target: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica availability: Available - expectedStatusError: "transition sources must match status.controlPlaneTopology" - - name: Should not allow a reverse controlPlaneTopologyTransitions entry + expectedStatusError: "transition sources must match the current status topology" + - name: Should not allow a reverse topologyTransitions entry initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: HighlyAvailable - controlPlaneTopologyTransitions: - - source: HighlyAvailable - target: SingleReplica + infrastructureTopology: HighlyAvailable + topologyTransitions: + - source: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + target: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica availability: Available - expectedStatusError: "only SingleReplica to HighlyAvailable control-plane topology transitions are supported" - - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid source + expectedStatusError: "only SingleReplica to HighlyAvailable topology transitions are supported" + - name: Should not allow a topologyTransitions entry with an invalid source controlPlaneTopology initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: External - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: External + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available - expectedStatusError: 'status.controlPlaneTopologyTransitions[0].source: Unsupported value: "External": supported values: "SingleReplica", "HighlyAvailable"' - - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid target + expectedStatusError: 'status.topologyTransitions[0].source.controlPlaneTopology: Unsupported value: "External": supported values: "SingleReplica", "HighlyAvailable"' + - name: Should not allow a topologyTransitions entry with an invalid target infrastructureTopology initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: DualReplica + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: DualReplica availability: Available - expectedStatusError: 'status.controlPlaneTopologyTransitions[0].target: Unsupported value: "DualReplica": supported values: "SingleReplica", "HighlyAvailable"' - - name: Should not allow a controlPlaneTopologyTransitions entry with an invalid availability + expectedStatusError: 'status.topologyTransitions[0].target.infrastructureTopology: Unsupported value: "DualReplica": supported values: "SingleReplica", "HighlyAvailable"' + - name: Should not allow a topologyTransitions entry with an invalid availability initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Pending - expectedStatusError: 'status.controlPlaneTopologyTransitions[0].availability: Unsupported value: "Pending": supported values: "Available", "Unavailable", "Unknown"' - - name: Should not allow a controlPlaneTopologyTransitions entry without source + expectedStatusError: 'status.topologyTransitions[0].availability: Unsupported value: "Pending": supported values: "Available", "Unavailable", "Unknown"' + - name: Should not allow a topologyTransitions entry without source initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available expectedStatusError: "Required value" - - name: Should not allow a controlPlaneTopologyTransitions entry without target + - name: Should not allow a topologyTransitions entry without target initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica availability: Available expectedStatusError: "Required value" - - name: Should not allow a controlPlaneTopologyTransitions entry without availability + - name: Should not allow a topologyTransitions entry without availability initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable expectedStatusError: "Required value" - - name: Should not allow an Unavailable controlPlaneTopologyTransitions entry without a reason + - name: Should not allow an Unavailable topologyTransitions entry without a reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable expectedStatusError: "reason is required when availability is not Available" - - name: Should not allow an Unknown controlPlaneTopologyTransitions entry without a reason + - name: Should not allow an Unknown topologyTransitions entry without a reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unknown expectedStatusError: "reason is required when availability is not Available" - - name: Should not allow a controlPlaneTopologyTransitions entry with a lowercase reason + - name: Should not allow a topologyTransitions entry with a lowercase reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: preflightCheckFailed expectedStatusError: "reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" - - name: Should not allow a controlPlaneTopologyTransitions entry with an empty reason + - name: Should not allow a topologyTransitions entry with an empty reason initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: "" expectedStatusError: "should be at least 1 chars long" - - name: Should not allow a controlPlaneTopologyTransitions entry with a reason exceeding max length + - name: Should not allow a topologyTransitions entry with a reason exceeding max length initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: "Preflight012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" expectedStatusError: "Too long: may not be more than 128 bytes" - - name: Should not allow a controlPlaneTopologyTransitions entry with an empty message + - name: Should not allow a topologyTransitions entry with an empty message initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: PreflightCheckFailed message: "" expectedStatusError: "should be at least 1 chars long" - - name: Should not allow a controlPlaneTopologyTransitions entry with a message exceeding max length + - name: Should not allow a topologyTransitions entry with a message exceeding max length initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: PreflightCheckFailed message: "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" expectedStatusError: "Too long: may not be more than 2048 bytes" - - name: Should not allow duplicate source/target pairs in controlPlaneTopologyTransitions + - name: Should not allow more than one topologyTransitions entry initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - controlPlaneTopologyTransitions: - - source: SingleReplica - target: HighlyAvailable + infrastructureTopology: SingleReplica + topologyTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Available - - source: SingleReplica - target: HighlyAvailable + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable availability: Unavailable reason: PreflightCheckFailed - expectedStatusError: "Duplicate value" + expectedStatusError: "Too many: 2: must have at most 1 items" diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 0253c0e74ef..be2dc95c5ec 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -20,7 +20,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:metadata:annotations=release.openshift.io/bootstrap-required=true // +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.spec.controlPlaneTopology) || (has(oldSelf.spec.controlPlaneTopology) && self.spec.controlPlaneTopology == oldSelf.spec.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.spec.controlPlaneTopology == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == 'SingleReplica' && self.spec.controlPlaneTopology == 'HighlyAvailable')",message="spec.controlPlaneTopology must match status.controlPlaneTopology or be set to HighlyAvailable when status.controlPlaneTopology is SingleReplica" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) && t.source == self.status.controlPlaneTopology)",message="transition sources must match status.controlPlaneTopology" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)",message="transition sources must match the current status topology" type Infrastructure struct { metav1.TypeMeta `json:",inline"` @@ -139,9 +139,9 @@ type InfrastructureStatus struct { // +optional InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` - // controlPlaneTopologyTransitions reports, as controller-computed observed state, - // the control-plane topology transitions that originate at the current - // status.controlPlaneTopology and whether each can currently be initiated. It is + // topologyTransitions reports, as controller-computed observed state, the + // topology transitions that originate at the current status.controlPlaneTopology + // and status.infrastructureTopology and whether each can currently be initiated. It is // advisory: the cluster may change between a status read and a spec write, so the // cluster-config-operator revalidates any requested transition; consumers such as // the CLI must not treat Available as an admission guarantee. Transitions are @@ -149,20 +149,18 @@ type InfrastructureStatus struct { // the controller has not yet completed its first evaluation; an empty list is also // valid and intentionally carries the same meaning as omitted, since this field does // not currently distinguish "not yet evaluated" from "evaluated with no applicable - // transitions". The only supported transition is from SingleReplica to - // HighlyAvailable. When status.controlPlaneTopology has any other value, this - // field is expected to remain omitted or empty. Entries are keyed by the - // (source, target) topology pair and list order is not significant. At most 1 - // entry is permitted because only one transition direction is currently supported. + // transitions". The only supported transition is from a state where both topology + // values are SingleReplica to a state where both are HighlyAvailable. When the + // current topology does not match the supported source state, this field is expected + // to remain omitted or empty. At most 1 entry is permitted because only one + // transition direction is currently supported. // +openshift:enable:FeatureGate=MutableTopology - // +listType=map - // +listMapKey=source - // +listMapKey=target + // +listType=atomic // +kubebuilder:validation:MinItems=0 // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:rule="self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable')",message="only SingleReplica to HighlyAvailable control-plane topology transitions are supported" + // +kubebuilder:validation:XValidation:rule="self.all(t, t.source.controlPlaneTopology == 'SingleReplica' && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable')",message="only SingleReplica to HighlyAvailable topology transitions are supported" // +optional - ControlPlaneTopologyTransitions []TopologyTransition `json:"controlPlaneTopologyTransitions,omitempty"` + TopologyTransitions []TopologyTransition `json:"topologyTransitions,omitempty"` // cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. // CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. @@ -208,25 +206,19 @@ const ( // and target must differ. reason must be set whenever availability is // Unavailable or Unknown; both constraints are enforced by validation rules on // the entry as a whole. -// +kubebuilder:validation:XValidation:rule="self.source != self.target",message="source and target must differ" +// +kubebuilder:validation:XValidation:rule="self.source.controlPlaneTopology != self.target.controlPlaneTopology || self.source.infrastructureTopology != self.target.infrastructureTopology",message="source and target must differ" // +kubebuilder:validation:XValidation:rule="self.availability == 'Available' || has(self.reason)",message="reason is required when availability is not Available" type TopologyTransition struct { - // source is the topology this transition starts from. It equals the current - // topology in the corresponding status field. Valid values are SingleReplica - // and HighlyAvailable. - // When set to SingleReplica, the transition originates from a single-replica topology. - // When set to HighlyAvailable, the transition originates from a highly available topology. - // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // source is the control-plane and infrastructure topology this transition starts + // from. It must equal the current topology in the corresponding status fields. + // source is required. // +required - Source TopologyMode `json:"source,omitempty"` + Source TopologyState `json:"source,omitempty,omitzero"` - // target is the topology this transition would move to. - // Valid values are SingleReplica and HighlyAvailable. - // When set to SingleReplica, the transition moves to a single-replica topology. - // When set to HighlyAvailable, the transition moves to a highly available topology. - // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // target is the control-plane and infrastructure topology this transition would + // move to. target is required. // +required - Target TopologyMode `json:"target,omitempty"` + Target TopologyState `json:"target,omitempty,omitzero"` // availability indicates whether this transition can currently be initiated. // Valid values are Available, Unavailable, and Unknown. Available means the @@ -259,6 +251,28 @@ type TopologyTransition struct { Message string `json:"message,omitempty"` } +// TopologyState describes the control-plane and infrastructure topology at one +// end of a topology transition. +type TopologyState struct { + // controlPlaneTopology is the topology of the control-plane nodes. Valid values + // are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + // avoid spending resources for high availability. When set to HighlyAvailable, + // operators configure high availability as much as possible. + // controlPlaneTopology is required. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + ControlPlaneTopology TopologyMode `json:"controlPlaneTopology,omitempty"` + + // infrastructureTopology is the topology of infrastructure services. Valid + // values are SingleReplica and HighlyAvailable. When set to SingleReplica, + // operators avoid spending resources for high availability. When set to + // HighlyAvailable, operators configure high availability as much as possible. + // infrastructureTopology is required. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` +} + // TransitionAvailability indicates whether a topology transition can currently be // initiated. // +kubebuilder:validation:Enum=Available;Unavailable;Unknown diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 20e316fc576..f41b69ad507 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index ae9b73430d0..613f7f454a9 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 11dd81fcd81..1a5eb3d345a 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index d26507062c3..2203eda4de0 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -3820,8 +3820,8 @@ func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { *out = new(PlatformStatus) (*in).DeepCopyInto(*out) } - if in.ControlPlaneTopologyTransitions != nil { - in, out := &in.ControlPlaneTopologyTransitions, &out.ControlPlaneTopologyTransitions + if in.TopologyTransitions != nil { + in, out := &in.TopologyTransitions, &out.TopologyTransitions *out = make([]TopologyTransition, len(*in)) copy(*out, *in) } @@ -6853,9 +6853,27 @@ func (in *TokenUserValidationRule) DeepCopy() *TokenUserValidationRule { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyState) DeepCopyInto(out *TopologyState) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyState. +func (in *TopologyState) DeepCopy() *TopologyState { + if in == nil { + return nil + } + out := new(TopologyState) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TopologyTransition) DeepCopyInto(out *TopologyTransition) { *out = *in + out.Source = in.Source + out.Target = in.Target return } diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index 7ba132900f9..57e7163d5ff 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -1051,109 +1051,6 @@ spec: The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2534,6 +2431,151 @@ spec: type: string type: object type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2547,10 +2589,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.model_name.go b/config/v1/zz_generated.model_name.go index 84610fb4449..c6b56b5d979 100644 --- a/config/v1/zz_generated.model_name.go +++ b/config/v1/zz_generated.model_name.go @@ -1455,6 +1455,11 @@ func (in TokenUserValidationRule) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.TokenUserValidationRule" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TopologyState) OpenAPIModelName() string { + return "com.github.openshift.api.config.v1.TopologyState" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in TopologyTransition) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.TopologyTransition" diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 1c9c61273e1..e6518058672 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1881,17 +1881,17 @@ func (InfrastructureSpec) SwaggerDoc() map[string]string { } var map_InfrastructureStatus = map[string]string{ - "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", - "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", - "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", - "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", - "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", - "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", - "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", - "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", - "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", - "controlPlaneTopologyTransitions": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", - "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", + "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", + "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", + "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", + "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", + "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", + "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", + "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", + "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", + "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", + "topologyTransitions": "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", + "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", } func (InfrastructureStatus) SwaggerDoc() map[string]string { @@ -2140,10 +2140,20 @@ func (PowerVSServiceEndpoint) SwaggerDoc() map[string]string { return map_PowerVSServiceEndpoint } +var map_TopologyState = map[string]string{ + "": "TopologyState describes the control-plane and infrastructure topology at one end of a topology transition.", + "controlPlaneTopology": "controlPlaneTopology is the topology of the control-plane nodes. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. controlPlaneTopology is required.", + "infrastructureTopology": "infrastructureTopology is the topology of infrastructure services. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. infrastructureTopology is required.", +} + +func (TopologyState) SwaggerDoc() map[string]string { + return map_TopologyState +} + var map_TopologyTransition = map[string]string{ "": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - "source": "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", - "target": "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", + "source": "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", + "target": "target is the control-plane and infrastructure topology this transition would move to. target is required.", "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 02c6d0d6653..ca6dcfac72e 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6dd43d22334..6e915369b5a 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 654389a8baa..f0a2a4d7ef4 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 4f9c1459d40..5912521617a 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -1346,110 +1346,6 @@ spec: The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum. type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2842,6 +2738,152 @@ spec: type: string type: object type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2857,10 +2899,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index fc7f7b2d417..63802a2baf6 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -492,6 +492,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA configv1.TokenIssuer{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenIssuer(ref), configv1.TokenRequiredClaim{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenRequiredClaim(ref), configv1.TokenUserValidationRule{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenUserValidationRule(ref), + configv1.TopologyState{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyState(ref), configv1.TopologyTransition{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyTransition(ref), configv1.Update{}.OpenAPIModelName(): schema_openshift_api_config_v1_Update(ref), configv1.UpdateHistory{}.OpenAPIModelName(): schema_openshift_api_config_v1_UpdateHistory(ref), @@ -16402,18 +16403,14 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal Format: "", }, }, - "controlPlaneTopologyTransitions": { + "topologyTransitions": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ - "x-kubernetes-list-map-keys": []interface{}{ - "source", - "target", - }, - "x-kubernetes-list-type": "map", + "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Description: "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", + Description: "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -22242,27 +22239,55 @@ func schema_openshift_api_config_v1_TokenUserValidationRule(ref common.Reference } } -func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_openshift_api_config_v1_TopologyState(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", + Description: "TopologyState describes the control-plane and infrastructure topology at one end of a topology transition.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "source": { + "controlPlaneTopology": { SchemaProps: spec.SchemaProps{ - Description: "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", + Description: "controlPlaneTopology is the topology of the control-plane nodes. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. controlPlaneTopology is required.", Type: []string{"string"}, Format: "", }, }, - "target": { + "infrastructureTopology": { SchemaProps: spec.SchemaProps{ - Description: "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", + Description: "infrastructureTopology is the topology of infrastructure services. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. infrastructureTopology is required.", Type: []string{"string"}, Format: "", }, }, + }, + Required: []string{"controlPlaneTopology", "infrastructureTopology"}, + }, + }, + } +} + +func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "source": { + SchemaProps: spec.SchemaProps{ + Description: "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", + Default: map[string]interface{}{}, + Ref: ref(configv1.TopologyState{}.OpenAPIModelName()), + }, + }, + "target": { + SchemaProps: spec.SchemaProps{ + Description: "target is the control-plane and infrastructure topology this transition would move to. target is required.", + Default: map[string]interface{}{}, + Ref: ref(configv1.TopologyState{}.OpenAPIModelName()), + }, + }, "availability": { SchemaProps: spec.SchemaProps{ Description: "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", @@ -22288,6 +22313,8 @@ func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallb Required: []string{"source", "target", "availability"}, }, }, + Dependencies: []string{ + configv1.TopologyState{}.OpenAPIModelName()}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 8a1d242e0c6..1e88d1a6406 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -8576,19 +8576,6 @@ "type": "string", "default": "" }, - "controlPlaneTopologyTransitions": { - "description": "controlPlaneTopologyTransitions reports, as controller-computed observed state, the control-plane topology transitions that originate at the current status.controlPlaneTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from SingleReplica to HighlyAvailable. When status.controlPlaneTopology has any other value, this field is expected to remain omitted or empty. Entries are keyed by the (source, target) topology pair and list order is not significant. At most 1 entry is permitted because only one transition direction is currently supported.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" - }, - "x-kubernetes-list-map-keys": [ - "source", - "target" - ], - "x-kubernetes-list-type": "map" - }, "cpuPartitioning": { "description": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", "type": "string", @@ -8615,6 +8602,15 @@ "platformStatus": { "description": "platformStatus holds status information specific to the underlying infrastructure provider.", "$ref": "#/definitions/com.github.openshift.api.config.v1.PlatformStatus" + }, + "topologyTransitions": { + "description": "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" + }, + "x-kubernetes-list-type": "atomic" } } }, @@ -12022,6 +12018,24 @@ } } }, + "com.github.openshift.api.config.v1.TopologyState": { + "description": "TopologyState describes the control-plane and infrastructure topology at one end of a topology transition.", + "type": "object", + "required": [ + "controlPlaneTopology", + "infrastructureTopology" + ], + "properties": { + "controlPlaneTopology": { + "description": "controlPlaneTopology is the topology of the control-plane nodes. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. controlPlaneTopology is required.", + "type": "string" + }, + "infrastructureTopology": { + "description": "infrastructureTopology is the topology of infrastructure services. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. infrastructureTopology is required.", + "type": "string" + } + } + }, "com.github.openshift.api.config.v1.TopologyTransition": { "description": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", "type": "object", @@ -12044,12 +12058,14 @@ "type": "string" }, "source": { - "description": "source is the topology this transition starts from. It equals the current topology in the corresponding status field. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition originates from a single-replica topology. When set to HighlyAvailable, the transition originates from a highly available topology.", - "type": "string" + "description": "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyState" }, "target": { - "description": "target is the topology this transition would move to. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, the transition moves to a single-replica topology. When set to HighlyAvailable, the transition moves to a highly available topology.", - "type": "string" + "description": "target is the control-plane and infrastructure topology this transition would move to. target is required.", + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyState" } } }, diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index 20e316fc576..f41b69ad507 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index ae9b73430d0..613f7f454a9 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 11dd81fcd81..1a5eb3d345a 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1163,109 +1163,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane topology - transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -2946,6 +2843,151 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology transitions + are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology + == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -2959,10 +3001,11 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology && + t.source.infrastructureTopology == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 02c6d0d6653..ca6dcfac72e 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6dd43d22334..6e915369b5a 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 654389a8baa..f0a2a4d7ef4 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -1468,110 +1468,6 @@ spec: - DualReplica - External type: string - controlPlaneTopologyTransitions: - description: |- - controlPlaneTopologyTransitions reports, as controller-computed observed state, - the control-plane topology transitions that originate at the current - status.controlPlaneTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from SingleReplica to - HighlyAvailable. When status.controlPlaneTopology has any other value, this - field is expected to remain omitted or empty. Entries are keyed by the - (source, target) topology pair and list order is not significant. At most 1 - entry is permitted because only one transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the topology this transition starts from. It equals the current - topology in the corresponding status field. Valid values are SingleReplica - and HighlyAvailable. - When set to SingleReplica, the transition originates from a single-replica topology. - When set to HighlyAvailable, the transition originates from a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - target: - description: |- - target is the topology this transition would move to. - Valid values are SingleReplica and HighlyAvailable. - When set to SingleReplica, the transition moves to a single-replica topology. - When set to HighlyAvailable, the transition moves to a highly available topology. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source != self.target - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-map-keys: - - source - - target - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable control-plane - topology transitions are supported - rule: self.all(t, t.source == 'SingleReplica' && t.target - == 'HighlyAvailable') cpuPartitioning: default: None description: |- @@ -3269,6 +3165,152 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object + topologyTransitions: + description: |- + topologyTransitions reports, as controller-computed observed state, the + topology transitions that originate at the current status.controlPlaneTopology + and status.infrastructureTopology and whether each can currently be initiated. It is + advisory: the cluster may change between a status read and a spec write, so the + cluster-config-operator revalidates any requested transition; consumers such as + the CLI must not treat Available as an admission guarantee. Transitions are + requested via spec.controlPlaneTopology, not through this field. When omitted, + the controller has not yet completed its first evaluation; an empty list is also + valid and intentionally carries the same meaning as omitted, since this field does + not currently distinguish "not yet evaluated" from "evaluated with no applicable + transitions". The only supported transition is from a state where both topology + values are SingleReplica to a state where both are HighlyAvailable. When the + current topology does not match the supported source state, this field is expected + to remain omitted or empty. At most 1 entry is permitted because only one + transition direction is currently supported. + items: + description: |- + TopologyTransition describes one topology transition available from the + cluster's current topology and whether it can currently be initiated. source + and target must differ. reason must be set whenever availability is + Unavailable or Unknown; both constraints are enforced by validation rules on + the entry as a whole. + properties: + availability: + description: |- + availability indicates whether this transition can currently be initiated. + Valid values are Available, Unavailable, and Unknown. Available means the + controller evaluated the transition and its preconditions pass. Unavailable + means the transition is defined but cannot be initiated now; see reason and + message. Unknown means the controller has not completed evaluation. + enum: + - Available + - Unavailable + - Unknown + type: string + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed or SourceTopologyMismatch. It is required when + availability is Unavailable or Unknown and is normally omitted when Available. + The set of reasons is diagnostic and not exhaustive. Must start with an + uppercase letter and contain only alphanumeric characters, and must be + between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - availability + - source + - target + type: object + x-kubernetes-validations: + - message: source and target must differ + rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology + || self.source.infrastructureTopology != self.target.infrastructureTopology + - message: reason is required when availability is not Available + rule: self.availability == 'Available' || has(self.reason) + maxItems: 1 + minItems: 0 + type: array + x-kubernetes-list-type: atomic + x-kubernetes-validations: + - message: only SingleReplica to HighlyAvailable topology + transitions are supported + rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' + && t.source.infrastructureTopology == 'SingleReplica' + && t.target.controlPlaneTopology == 'HighlyAvailable' + && t.target.infrastructureTopology == 'HighlyAvailable') type: object required: - spec @@ -3284,10 +3326,12 @@ spec: == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - - message: transition sources must match status.controlPlaneTopology - rule: '!has(self.status) || !has(self.status.controlPlaneTopologyTransitions) - || self.status.controlPlaneTopologyTransitions.all(t, has(self.status.controlPlaneTopology) - && t.source == self.status.controlPlaneTopology)' + - message: transition sources must match the current status topology + rule: '!has(self.status) || !has(self.status.topologyTransitions) + || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by From b7b076b3b5b8d316a821150de27e882109061274 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Thu, 24 Sep 2026 12:56:47 -0400 Subject: [PATCH 08/10] OCPEDGE-2989: Expose topology transition status Co-authored-by: Jon Cope Co-authored-by: OpenAI --- .golangci.yaml | 15 + .../AAA_ungated.yaml | 23 + .../MutableTopology.yaml | 632 +++--------------- config/v1/types_infrastructure.go | 91 +-- config/v1/types_infrastructure_transitions.go | 136 ++++ ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 337 ++++++---- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 337 ++++++---- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 337 ++++++---- config/v1/zz_generated.deepcopy.go | 65 +- .../MutableTopology.yaml | 337 ++++++---- config/v1/zz_generated.model_name.go | 10 + .../v1/zz_generated.swagger_doc_generated.go | 69 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 342 ++++++---- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 342 ++++++---- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 342 ++++++---- .../MutableTopology.yaml | 342 ++++++---- .../generated_openapi/zz_generated.openapi.go | 142 +++- openapi/openapi.json | 85 ++- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 337 ++++++---- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 337 ++++++---- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 337 ++++++---- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 342 ++++++---- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 342 ++++++---- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 342 ++++++---- 24 files changed, 3451 insertions(+), 2570 deletions(-) create mode 100644 config/v1/types_infrastructure_transitions.go diff --git a/.golangci.yaml b/.golangci.yaml index 1b8472410f5..38763aa2c38 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -121,6 +121,21 @@ linters: # to enforce specific condition types are always present. path: etcd/v1/types_pacemakercluster.go text: "conditions: Conditions field in (PacemakerClusterStatus|PacemakerClusterNodeStatus|PacemakerClusterFencingAgentStatus|PacemakerClusterResourceStatus) is missing the following markers: optional" + - linters: + - kubeapilinter + # Empty lists are meaningful: no available transitions, or no completed evaluation condition yet. + path: config/v1/types_infrastructure_transitions.go + text: 'minlength: field TopologyTransitionStatus\.(AvailableTransitions|Conditions) must have a minimum items' + - linters: + - kubeapilinter + # Keep the pointer so nil means no topology transition has started; omitempty omits nil. + path: config/v1/types_infrastructure_transitions.go + text: 'optionalfields: field TopologyTransitionStatus\.CurrentTransition' + - linters: + - kubeapilinter + # Keep an evaluated empty list serialized as [] rather than omitting this required field. + path: config/v1/types_infrastructure_transitions.go + text: 'requiredfields: field TopologyTransitionStatus\.AvailableTransitions should have the omitempty tag' - linters: - kubeapilinter path: features|payload-command/ diff --git a/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml b/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml index b692386b498..70c99560e9f 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml @@ -635,6 +635,29 @@ tests: type: UserManaged type: BareMetal expectedStatusError: 'status.platformStatus.baremetal.loadBalancer.type: Invalid value: "string": type is immutable once set' + - name: Should prune topologyTransitionStatus when MutableTopology is disabled + initial: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + updated: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + topologyTransitionStatus: + availableTransitions: [] + expected: | + apiVersion: config.openshift.io/v1 + kind: Infrastructure + spec: {} + status: + controlPlaneTopology: SingleReplica + infrastructureTopology: HighlyAvailable + cpuPartitioning: None - name: Should not allow changing the immutable OpenStack load balancer type field initial: | apiVersion: config.openshift.io/v1 diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index 7fa70ea0f8a..a8f5052a6ef 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -259,7 +259,7 @@ tests: spec: controlPlaneTopology: InvalidValue expectedError: 'spec.controlPlaneTopology: Unsupported value: "InvalidValue": supported values: "HighlyAvailable", "SingleReplica"' - - name: Should allow topologyTransitions to remain omitted, representing that the controller has not yet completed its first evaluation + - name: Should allow updating Infrastructure status without topologyTransitionStatus initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -267,212 +267,58 @@ tests: status: controlPlaneTopology: SingleReplica updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: - controlPlaneTopology: HighlyAvailable - status: - controlPlaneTopology: SingleReplica - expected: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: - controlPlaneTopology: HighlyAvailable - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: HighlyAvailable - cpuPartitioning: None - - name: Should allow explicitly setting topologyTransitions to an empty list, carrying the same meaning as omitting it - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - topologyTransitions: [] - expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica infrastructureTopology: HighlyAvailable - cpuPartitioning: None - topologyTransitions: [] - - name: Should allow topologyTransitions to remain omitted when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - expected: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - infrastructureTopology: HighlyAvailable - cpuPartitioning: None - - name: Should allow setting topologyTransitions to an empty list when status.controlPlaneTopology is outside the source/target enum (e.g. HighlyAvailableArbiter) - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - topologyTransitions: [] - expected: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailableArbiter - infrastructureTopology: HighlyAvailable - cpuPartitioning: None - topologyTransitions: [] - - name: Should allow setting topologyTransitions to an Available entry with no reason - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - expected: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - cpuPartitioning: None - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - - name: Should allow setting topologyTransitions to an Unavailable entry including reason and message - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: PreflightCheckFailed - message: "etcd does not have quorum: need 3 voting members, have 1" expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica + infrastructureTopology: HighlyAvailable cpuPartitioning: None - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: PreflightCheckFailed - message: "etcd does not have quorum: need 3 voting members, have 1" - - name: Should allow setting topologyTransitions to an Unknown entry with a reason + - name: Should allow an empty availableTransitions list after successful evaluation initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unknown - reason: EvaluationPending + topologyTransitionStatus: + availableTransitions: [] + conditions: + - type: TopologyTransitionsEvaluated + status: "True" + lastTransitionTime: "2025-01-01T00:00:00Z" + reason: EvaluationComplete + message: No transitions are available expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica + infrastructureTopology: HighlyAvailable cpuPartitioning: None - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unknown - reason: EvaluationPending - - name: Should allow a valid topologyTransitions entry for the current source + topologyTransitionStatus: + availableTransitions: [] + conditions: + - type: TopologyTransitionsEvaluated + status: "True" + lastTransitionTime: "2025-01-01T00:00:00Z" + reason: EvaluationComplete + message: No transitions are available + - name: Should allow reporting current transition progress initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -487,14 +333,20 @@ tests: status: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available + topologyTransitionStatus: + availableTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + reason: PreflightCheckFailed + currentTransition: + status: Partial + reason: TransitionInProgress + message: Applying topology changes + startedTime: "2025-01-01T00:00:00Z" expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -503,15 +355,21 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica cpuPartitioning: None - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - - name: Should not allow a self-transition in topologyTransitions + topologyTransitionStatus: + availableTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + reason: PreflightCheckFailed + currentTransition: + status: Partial + reason: TransitionInProgress + message: Applying topology changes + startedTime: "2025-01-01T00:00:00Z" + - name: Should reject a topology transition reason that is not CamelCase initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -526,16 +384,17 @@ tests: status: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - availability: Available - expectedStatusError: "source and target must differ" - - name: Should not allow a topologyTransitions entry whose source differs from the current status topology + topologyTransitionStatus: + availableTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + reason: preflightCheckFailed + expectedStatusError: "reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" + - name: Should reject an available transition whose source does not match status topology initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -550,112 +409,16 @@ tests: status: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - target: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - availability: Available + topologyTransitionStatus: + availableTransitions: + - source: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + target: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica expectedStatusError: "transition sources must match the current status topology" - - name: Should not allow a reverse topologyTransitions entry - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - topologyTransitions: - - source: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - target: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - availability: Available - expectedStatusError: "only SingleReplica to HighlyAvailable topology transitions are supported" - - name: Should not allow a topologyTransitions entry with an invalid source controlPlaneTopology - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: External - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - expectedStatusError: 'status.topologyTransitions[0].source.controlPlaneTopology: Unsupported value: "External": supported values: "SingleReplica", "HighlyAvailable"' - - name: Should not allow a topologyTransitions entry with an invalid target infrastructureTopology - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: DualReplica - availability: Available - expectedStatusError: 'status.topologyTransitions[0].target.infrastructureTopology: Unsupported value: "DualReplica": supported values: "SingleReplica", "HighlyAvailable"' - - name: Should not allow a topologyTransitions entry with an invalid availability - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Pending - expectedStatusError: 'status.topologyTransitions[0].availability: Unsupported value: "Pending": supported values: "Available", "Unavailable", "Unknown"' - - name: Should not allow a topologyTransitions entry without source + - name: Should enforce the supported maximum available transition count initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -670,260 +433,53 @@ tests: status: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica - topologyTransitions: - - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - expectedStatusError: "Required value" - - name: Should not allow a topologyTransitions entry without target + topologyTransitionStatus: + availableTransitions: + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + - source: + controlPlaneTopology: SingleReplica + infrastructureTopology: SingleReplica + target: + controlPlaneTopology: HighlyAvailable + infrastructureTopology: HighlyAvailable + expectedStatusError: "Too many: 2: must have at most 1 items" + - name: Should require availableTransitions when topologyTransitionStatus is set initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - availability: Available + topologyTransitionStatus: + conditions: [] expectedStatusError: "Required value" - - name: Should not allow a topologyTransitions entry without availability + - name: Should require status on currentTransition initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica updated: | apiVersion: config.openshift.io/v1 kind: Infrastructure spec: {} status: controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable + topologyTransitionStatus: + availableTransitions: [] + currentTransition: + reason: TransitionInProgress + message: Applying topology changes expectedStatusError: "Required value" - - name: Should not allow an Unavailable topologyTransitions entry without a reason - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - expectedStatusError: "reason is required when availability is not Available" - - name: Should not allow an Unknown topologyTransitions entry without a reason - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unknown - expectedStatusError: "reason is required when availability is not Available" - - name: Should not allow a topologyTransitions entry with a lowercase reason - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: preflightCheckFailed - expectedStatusError: "reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" - - name: Should not allow a topologyTransitions entry with an empty reason - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: "" - expectedStatusError: "should be at least 1 chars long" - - name: Should not allow a topologyTransitions entry with a reason exceeding max length - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: "Preflight012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" - expectedStatusError: "Too long: may not be more than 128 bytes" - - name: Should not allow a topologyTransitions entry with an empty message - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: PreflightCheckFailed - message: "" - expectedStatusError: "should be at least 1 chars long" - - name: Should not allow a topologyTransitions entry with a message exceeding max length - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: PreflightCheckFailed - message: "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" - expectedStatusError: "Too long: may not be more than 2048 bytes" - - name: Should not allow more than one topologyTransitions entry - initial: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - updated: | - apiVersion: config.openshift.io/v1 - kind: Infrastructure - spec: {} - status: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - topologyTransitions: - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Available - - source: - controlPlaneTopology: SingleReplica - infrastructureTopology: SingleReplica - target: - controlPlaneTopology: HighlyAvailable - infrastructureTopology: HighlyAvailable - availability: Unavailable - reason: PreflightCheckFailed - expectedStatusError: "Too many: 2: must have at most 1 items" diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index be2dc95c5ec..770b460190b 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -20,7 +20,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:metadata:annotations=release.openshift.io/bootstrap-required=true // +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.spec.controlPlaneTopology) || (has(oldSelf.spec.controlPlaneTopology) && self.spec.controlPlaneTopology == oldSelf.spec.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.spec.controlPlaneTopology == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == 'SingleReplica' && self.spec.controlPlaneTopology == 'HighlyAvailable')",message="spec.controlPlaneTopology must match status.controlPlaneTopology or be set to HighlyAvailable when status.controlPlaneTopology is SingleReplica" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)",message="transition sources must match the current status topology" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.topologyTransitionStatus) || self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)",message="transition sources must match the current status topology" type Infrastructure struct { metav1.TypeMeta `json:",inline"` @@ -139,28 +139,11 @@ type InfrastructureStatus struct { // +optional InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` - // topologyTransitions reports, as controller-computed observed state, the - // topology transitions that originate at the current status.controlPlaneTopology - // and status.infrastructureTopology and whether each can currently be initiated. It is - // advisory: the cluster may change between a status read and a spec write, so the - // cluster-config-operator revalidates any requested transition; consumers such as - // the CLI must not treat Available as an admission guarantee. Transitions are - // requested via spec.controlPlaneTopology, not through this field. When omitted, - // the controller has not yet completed its first evaluation; an empty list is also - // valid and intentionally carries the same meaning as omitted, since this field does - // not currently distinguish "not yet evaluated" from "evaluated with no applicable - // transitions". The only supported transition is from a state where both topology - // values are SingleReplica to a state where both are HighlyAvailable. When the - // current topology does not match the supported source state, this field is expected - // to remain omitted or empty. At most 1 entry is permitted because only one - // transition direction is currently supported. + // topologyTransitionStatus reports available topology transitions and current progress, if any. + // It is omitted until the topology controller evaluates transitions. // +openshift:enable:FeatureGate=MutableTopology - // +listType=atomic - // +kubebuilder:validation:MinItems=0 - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:rule="self.all(t, t.source.controlPlaneTopology == 'SingleReplica' && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable')",message="only SingleReplica to HighlyAvailable topology transitions are supported" // +optional - TopologyTransitions []TopologyTransition `json:"topologyTransitions,omitempty"` + TopologyTransitionStatus *TopologyTransitionStatus `json:"topologyTransitionStatus,omitempty"` // cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. // CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. @@ -201,56 +184,6 @@ const ( ExternalTopologyMode TopologyMode = "External" ) -// TopologyTransition describes one topology transition available from the -// cluster's current topology and whether it can currently be initiated. source -// and target must differ. reason must be set whenever availability is -// Unavailable or Unknown; both constraints are enforced by validation rules on -// the entry as a whole. -// +kubebuilder:validation:XValidation:rule="self.source.controlPlaneTopology != self.target.controlPlaneTopology || self.source.infrastructureTopology != self.target.infrastructureTopology",message="source and target must differ" -// +kubebuilder:validation:XValidation:rule="self.availability == 'Available' || has(self.reason)",message="reason is required when availability is not Available" -type TopologyTransition struct { - // source is the control-plane and infrastructure topology this transition starts - // from. It must equal the current topology in the corresponding status fields. - // source is required. - // +required - Source TopologyState `json:"source,omitempty,omitzero"` - - // target is the control-plane and infrastructure topology this transition would - // move to. target is required. - // +required - Target TopologyState `json:"target,omitempty,omitzero"` - - // availability indicates whether this transition can currently be initiated. - // Valid values are Available, Unavailable, and Unknown. Available means the - // controller evaluated the transition and its preconditions pass. Unavailable - // means the transition is defined but cannot be initiated now; see reason and - // message. Unknown means the controller has not completed evaluation. - // +required - Availability TransitionAvailability `json:"availability,omitempty"` - - // reason is a CamelCase machine-readable explanation of the availability, e.g. - // PreflightCheckFailed or SourceTopologyMismatch. It is required when - // availability is Unavailable or Unknown and is normally omitted when Available. - // The set of reasons is diagnostic and not exhaustive. Must start with an - // uppercase letter and contain only alphanumeric characters, and must be - // between 1 and 128 characters long. - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=128 - // +kubebuilder:validation:XValidation:rule=`self.matches('^[A-Z][A-Za-z0-9]*$')`,message="reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" - // +optional - Reason string `json:"reason,omitempty"` - - // message is a human-readable explanation, primarily for Unavailable - // transitions (e.g. a concise summary of the failing preconditions). It is for - // humans only and must not be parsed. It may be truncated by the controller. - // When omitted, no human-readable explanation is available for the transition. - // When set, it must be between 1 and 2048 characters long. - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=2048 - // +optional - Message string `json:"message,omitempty"` -} - // TopologyState describes the control-plane and infrastructure topology at one // end of a topology transition. type TopologyState struct { @@ -273,22 +206,6 @@ type TopologyState struct { InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` } -// TransitionAvailability indicates whether a topology transition can currently be -// initiated. -// +kubebuilder:validation:Enum=Available;Unavailable;Unknown -type TransitionAvailability string - -const ( - // TransitionAvailable means the transition can be initiated now. - TransitionAvailable TransitionAvailability = "Available" - - // TransitionUnavailable means the transition is defined but cannot be initiated now. - TransitionUnavailable TransitionAvailability = "Unavailable" - - // TransitionUnknown means the controller has not completed evaluation. - TransitionUnknown TransitionAvailability = "Unknown" -) - // CPUPartitioningMode defines the mode for CPU partitioning type CPUPartitioningMode string diff --git a/config/v1/types_infrastructure_transitions.go b/config/v1/types_infrastructure_transitions.go new file mode 100644 index 00000000000..bceefdca6aa --- /dev/null +++ b/config/v1/types_infrastructure_transitions.go @@ -0,0 +1,136 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type TopologyTransitionStatus struct { + // conditions reports whether available transitions have been evaluated. + // TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + // succeeds (even if no transitions are available), and False when evaluation fails. + // An absent condition means evaluation has not completed. + // At most one condition is present. + // +kubebuilder:validation:MaxItems=1 + // +optional + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` + + // availableTransitions represents the transitions that are currently valid for this cluster. + // An empty list means that no transitions are currently available. + // At most one transition is supported currently (SNO to HA Compact) + // +kubebuilder:validation:MaxItems=1 + // +required + // +listType=atomic + AvailableTransitions []TopologyTransition `json:"availableTransitions"` + + // currentTransition is omitted until a topology transition starts. + // +optional + CurrentTransition *TopologyTransitionProgress `json:"currentTransition,omitempty"` +} + +const ( + // TopologyTransitionsEvaluatedConditionType indicates whether available transitions have been evaluated. + TopologyTransitionsEvaluatedConditionType = "TopologyTransitionsEvaluated" +) + +// TopologyTransitionProgress describes a topology transition that has started. +type TopologyTransitionProgress struct { + // status indicates the current state of a triggered transition. + // It must be between 1 and 128 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=128 + // +required + Status TransitionState `json:"status,omitempty"` + + // reason indicates why the Status is in the current state. + // It must be between 1 and 128 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=128 + // +required + Reason TransitionStateReason `json:"reason,omitempty"` + + // message is human-readable information about the reason for the current status. + // It must be between 1 and 2048 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +required + Message string `json:"message,omitempty"` + + // startedTime is the time at which the transition was started. When omitted, the start time is not available. + // +optional + StartedTime *metav1.Time `json:"startedTime,omitempty"` + + // completionTime is when the transition was fully applied. It is omitted while a transition is being applied. + // +optional + CompletionTime *metav1.Time `json:"completionTime,omitempty"` +} + +// TransitionState tracks the last observed state of a requested transition. +type TransitionState string + +const ( + // CompletedTransition indicates an transition was successfully + // completed on the cluster. + CompletedTransition TransitionState = "Completed" + // PartialTransition indicates a transition was never completely applied + // or is currently being applied. + PartialTransition TransitionState = "Partial" + // FailedTransition indicates a transition failed to be applied. + FailedTransition TransitionState = "Failed" +) + +// TransitionStateReason indicates why the transition is in a given state. +type TransitionStateReason string + +const ( + // UnsupportedTransition indicates that the requested + // transition is not supported. + UnsupportedTransition TransitionStateReason = "UnsupportedTransition" + + // PreflightCheckFailed indicates that a preflight + // check for the requested transition failed. + PreflightCheckFailed TransitionStateReason = "PreflightCheckFailed" + + // Initiated indicates that a transition is + // currently in progress. + InProgress TransitionStateReason = "TransitionInProgress" + + // Complete indicates that a transition has + // completed successfully. + Complete TransitionStateReason = "TransitionComplete" +) + +type TopologyTransition struct { + // source is the control-plane and infrastructure topology this transition starts + // from. It must equal the current topology in the corresponding status fields. + // source is required. + // +required + Source TopologyState `json:"source,omitempty,omitzero"` + + // target is the control-plane and infrastructure topology this transition would + // move to. target is required. + // +required + Target TopologyState `json:"target,omitempty,omitzero"` + + // reason is a CamelCase machine-readable explanation of the availability, e.g. + // PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + // When omitted, no machine-readable explanation is available. + // Must start with an uppercase letter and contain only alphanumeric characters, + // and must be between 1 and 128 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=128 + // +kubebuilder:validation:XValidation:rule=`self.matches('^[A-Z][A-Za-z0-9]*$')`,message="reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" + // +optional + Reason string `json:"reason,omitempty"` + + // message is a human-readable explanation, primarily for Unavailable + // transitions (e.g. a concise summary of the failing preconditions). It is for + // humans only and must not be parsed. It may be truncated by the controller. + // When omitted, no human-readable explanation is available for the transition. + // When set, it must be between 1 and 2048 characters long. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +optional + Message string `json:"message,omitempty"` +} diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index f41b69ad507..f791bbafd67 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 613f7f454a9..92270c0373f 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 1a5eb3d345a..e14398b514b 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index 2203eda4de0..cc4b6f213e2 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -3820,10 +3820,10 @@ func (in *InfrastructureStatus) DeepCopyInto(out *InfrastructureStatus) { *out = new(PlatformStatus) (*in).DeepCopyInto(*out) } - if in.TopologyTransitions != nil { - in, out := &in.TopologyTransitions, &out.TopologyTransitions - *out = make([]TopologyTransition, len(*in)) - copy(*out, *in) + if in.TopologyTransitionStatus != nil { + in, out := &in.TopologyTransitionStatus, &out.TopologyTransitionStatus + *out = new(TopologyTransitionStatus) + (*in).DeepCopyInto(*out) } return } @@ -6887,6 +6887,63 @@ func (in *TopologyTransition) DeepCopy() *TopologyTransition { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyTransitionProgress) DeepCopyInto(out *TopologyTransitionProgress) { + *out = *in + if in.StartedTime != nil { + in, out := &in.StartedTime, &out.StartedTime + *out = (*in).DeepCopy() + } + if in.CompletionTime != nil { + in, out := &in.CompletionTime, &out.CompletionTime + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyTransitionProgress. +func (in *TopologyTransitionProgress) DeepCopy() *TopologyTransitionProgress { + if in == nil { + return nil + } + out := new(TopologyTransitionProgress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TopologyTransitionStatus) DeepCopyInto(out *TopologyTransitionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AvailableTransitions != nil { + in, out := &in.AvailableTransitions, &out.AvailableTransitions + *out = make([]TopologyTransition, len(*in)) + copy(*out, *in) + } + if in.CurrentTransition != nil { + in, out := &in.CurrentTransition, &out.CurrentTransition + *out = new(TopologyTransitionProgress) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyTransitionStatus. +func (in *TopologyTransitionStatus) DeepCopy() *TopologyTransitionStatus { + if in == nil { + return nil + } + out := new(TopologyTransitionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Update) DeepCopyInto(out *Update) { *out = *in diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index 57e7163d5ff..aacfafa6e64 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -2431,151 +2431,221 @@ spec: type: string type: object type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 type: string - infrastructureTopology: + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -2590,10 +2660,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/config/v1/zz_generated.model_name.go b/config/v1/zz_generated.model_name.go index c6b56b5d979..c6def4019e6 100644 --- a/config/v1/zz_generated.model_name.go +++ b/config/v1/zz_generated.model_name.go @@ -1465,6 +1465,16 @@ func (in TopologyTransition) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.TopologyTransition" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TopologyTransitionProgress) OpenAPIModelName() string { + return "com.github.openshift.api.config.v1.TopologyTransitionProgress" +} + +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in TopologyTransitionStatus) OpenAPIModelName() string { + return "com.github.openshift.api.config.v1.TopologyTransitionStatus" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in Update) OpenAPIModelName() string { return "com.github.openshift.api.config.v1.Update" diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index e6518058672..3ce5062ee49 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -1881,17 +1881,17 @@ func (InfrastructureSpec) SwaggerDoc() map[string]string { } var map_InfrastructureStatus = map[string]string{ - "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", - "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", - "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", - "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", - "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", - "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", - "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", - "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", - "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", - "topologyTransitions": "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", - "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", + "": "InfrastructureStatus describes the infrastructure the cluster is leveraging.", + "infrastructureName": "infrastructureName uniquely identifies a cluster with a human friendly name. Once set it should not be changed. Must be of max length 27 and must have only alphanumeric or hyphen characters.", + "platform": "platform is the underlying infrastructure provider for the cluster.\n\nDeprecated: Use platformStatus.type instead.", + "platformStatus": "platformStatus holds status information specific to the underlying infrastructure provider.", + "etcdDiscoveryDomain": "etcdDiscoveryDomain is the domain used to fetch the SRV records for discovering etcd servers and clients. For more info: https://github.com/etcd-io/etcd/blob/329be66e8b3f9e2e6af83c123ff89297e49ebd15/Documentation/op-guide/clustering.md#dns-discovery deprecated: as of 4.7, this field is no longer set or honored. It will be removed in a future release.", + "apiServerURL": "apiServerURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerURL can be used by components like the web console to tell users where to find the Kubernetes API.", + "apiServerInternalURI": "apiServerInternalURL is a valid URI with scheme 'https', address and optionally a port (defaulting to 443). apiServerInternalURL can be used by components like kubelets, to contact the Kubernetes API server using the infrastructure provider rather than Kubernetes networking.", + "controlPlaneTopology": "controlPlaneTopology expresses the expectations for operands that normally run on control nodes. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation The 'External' mode indicates that the control plane is hosted externally to the cluster and that its components are not visible within the cluster. The 'HighlyAvailableArbiter' mode indicates that the control plane will consist of 2 control-plane nodes that run conventional services and 1 smaller sized arbiter node that runs a bare minimum of services to maintain quorum.", + "infrastructureTopology": "infrastructureTopology expresses the expectations for infrastructure services that do not run on control plane nodes, usually indicated by a node selector for a `role` value other than `master`. The default is 'HighlyAvailable', which represents the behavior operators have in a \"normal\" cluster. The 'SingleReplica' mode will be used in single-node deployments and the operators should not configure the operand for highly-available operation NOTE: External topology mode is not applicable for this field.", + "topologyTransitionStatus": "topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions.", + "cpuPartitioning": "cpuPartitioning expresses if CPU partitioning is a currently enabled feature in the cluster. CPU Partitioning means that this cluster can support partitioning workloads to specific CPU Sets. Valid values are \"None\" and \"AllNodes\". When omitted, the default value is \"None\". The default value of \"None\" indicates that no nodes will be setup with CPU partitioning. The \"AllNodes\" value indicates that all nodes have been setup with CPU partitioning, and can then be further configured via the PerformanceProfile API.", } func (InfrastructureStatus) SwaggerDoc() map[string]string { @@ -2150,19 +2150,6 @@ func (TopologyState) SwaggerDoc() map[string]string { return map_TopologyState } -var map_TopologyTransition = map[string]string{ - "": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - "source": "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", - "target": "target is the control-plane and infrastructure topology this transition would move to. target is required.", - "availability": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", - "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", - "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", -} - -func (TopologyTransition) SwaggerDoc() map[string]string { - return map_TopologyTransition -} - var map_VSphereFailureDomainHostGroup = map[string]string{ "": "VSphereFailureDomainHostGroup holds the vmGroup and the hostGroup names in vCenter corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also contains the vmHostRule which is an affinity vm-host rule in vCenter.", "vmGroup": "vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. vmGroup is limited to 80 characters. This field is required when the VSphereFailureDomain ZoneType is HostGroup", @@ -2294,6 +2281,40 @@ func (VSpherePlatformVCenterSpec) SwaggerDoc() map[string]string { return map_VSpherePlatformVCenterSpec } +var map_TopologyTransition = map[string]string{ + "source": "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", + "target": "target is the control-plane and infrastructure topology this transition would move to. target is required.", + "reason": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. When omitted, no machine-readable explanation is available. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "message": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", +} + +func (TopologyTransition) SwaggerDoc() map[string]string { + return map_TopologyTransition +} + +var map_TopologyTransitionProgress = map[string]string{ + "": "TopologyTransitionProgress describes a topology transition that has started.", + "status": "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", + "reason": "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", + "message": "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", + "startedTime": "startedTime is the time at which the transition was started. When omitted, the start time is not available.", + "completionTime": "completionTime is when the transition was fully applied. It is omitted while a transition is being applied.", +} + +func (TopologyTransitionProgress) SwaggerDoc() map[string]string { + return map_TopologyTransitionProgress +} + +var map_TopologyTransitionStatus = map[string]string{ + "conditions": "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + "availableTransitions": "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", + "currentTransition": "currentTransition is omitted until a topology transition starts.", +} + +func (TopologyTransitionStatus) SwaggerDoc() map[string]string { + return map_TopologyTransitionStatus +} + var map_AWSIngressSpec = map[string]string{ "": "AWSIngressSpec holds the desired state of the Ingress for Amazon Web Services infrastructure provider. This only includes fields that can be modified in the cluster.", "type": "type allows user to set a load balancer type. When this field is set the default ingresscontroller will get created using the specified LBType. If this field is not set then the default ingress controller of LBType Classic will be created. Valid values are:\n\n* \"Classic\": A Classic Load Balancer that makes routing decisions at either\n the transport layer (TCP/SSL) or the application layer (HTTP/HTTPS). See\n the following for additional details:\n\n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#clb\n\n* \"NLB\": A Network Load Balancer that makes routing decisions at the\n transport layer (TCP/SSL). See the following for additional details:\n\n https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html#nlb", diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index ca6dcfac72e..4a4601cd457 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6e915369b5a..3d93d3a240a 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index f0a2a4d7ef4..9dcca22ac42 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 5912521617a..63a14da834b 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -2738,152 +2738,224 @@ spec: type: string type: object type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -2900,11 +2972,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 63802a2baf6..ffa6de44122 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -494,6 +494,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA configv1.TokenUserValidationRule{}.OpenAPIModelName(): schema_openshift_api_config_v1_TokenUserValidationRule(ref), configv1.TopologyState{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyState(ref), configv1.TopologyTransition{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyTransition(ref), + configv1.TopologyTransitionProgress{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyTransitionProgress(ref), + configv1.TopologyTransitionStatus{}.OpenAPIModelName(): schema_openshift_api_config_v1_TopologyTransitionStatus(ref), configv1.Update{}.OpenAPIModelName(): schema_openshift_api_config_v1_Update(ref), configv1.UpdateHistory{}.OpenAPIModelName(): schema_openshift_api_config_v1_UpdateHistory(ref), configv1.UsernameClaimMapping{}.OpenAPIModelName(): schema_openshift_api_config_v1_UsernameClaimMapping(ref), @@ -16403,23 +16405,10 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal Format: "", }, }, - "topologyTransitions": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, + "topologyTransitionStatus": { SchemaProps: spec.SchemaProps{ - Description: "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref(configv1.TopologyTransition{}.OpenAPIModelName()), - }, - }, - }, + Description: "topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions.", + Ref: ref(configv1.TopologyTransitionStatus{}.OpenAPIModelName()), }, }, "cpuPartitioning": { @@ -16434,7 +16423,7 @@ func schema_openshift_api_config_v1_InfrastructureStatus(ref common.ReferenceCal }, }, Dependencies: []string{ - configv1.PlatformStatus{}.OpenAPIModelName(), configv1.TopologyTransition{}.OpenAPIModelName()}, + configv1.PlatformStatus{}.OpenAPIModelName(), configv1.TopologyTransitionStatus{}.OpenAPIModelName()}, } } @@ -22271,8 +22260,7 @@ func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallb return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", - Type: []string{"object"}, + Type: []string{"object"}, Properties: map[string]spec.Schema{ "source": { SchemaProps: spec.SchemaProps{ @@ -22288,33 +22276,137 @@ func schema_openshift_api_config_v1_TopologyTransition(ref common.ReferenceCallb Ref: ref(configv1.TopologyState{}.OpenAPIModelName()), }, }, - "availability": { + "reason": { + SchemaProps: spec.SchemaProps{ + Description: "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. When omitted, no machine-readable explanation is available. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { SchemaProps: spec.SchemaProps{ - Description: "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", + Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"source", "target"}, + }, + }, + Dependencies: []string{ + configv1.TopologyState{}.OpenAPIModelName()}, + } +} + +func schema_openshift_api_config_v1_TopologyTransitionProgress(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TopologyTransitionProgress describes a topology transition that has started.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "status": { + SchemaProps: spec.SchemaProps{ + Description: "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", Type: []string{"string"}, Format: "", }, }, "reason": { SchemaProps: spec.SchemaProps{ - Description: "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + Description: "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", Type: []string{"string"}, Format: "", }, }, "message": { SchemaProps: spec.SchemaProps{ - Description: "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", + Description: "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", Type: []string{"string"}, Format: "", }, }, + "startedTime": { + SchemaProps: spec.SchemaProps{ + Description: "startedTime is the time at which the transition was started. When omitted, the start time is not available.", + Ref: ref(metav1.Time{}.OpenAPIModelName()), + }, + }, + "completionTime": { + SchemaProps: spec.SchemaProps{ + Description: "completionTime is when the transition was fully applied. It is omitted while a transition is being applied.", + Ref: ref(metav1.Time{}.OpenAPIModelName()), + }, + }, }, - Required: []string{"source", "target", "availability"}, + Required: []string{"status", "reason", "message"}, }, }, Dependencies: []string{ - configv1.TopologyState{}.OpenAPIModelName()}, + metav1.Time{}.OpenAPIModelName()}, + } +} + +func schema_openshift_api_config_v1_TopologyTransitionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref(metav1.Condition{}.OpenAPIModelName()), + }, + }, + }, + }, + }, + "availableTransitions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref(configv1.TopologyTransition{}.OpenAPIModelName()), + }, + }, + }, + }, + }, + "currentTransition": { + SchemaProps: spec.SchemaProps{ + Description: "currentTransition is omitted until a topology transition starts.", + Ref: ref(configv1.TopologyTransitionProgress{}.OpenAPIModelName()), + }, + }, + }, + Required: []string{"availableTransitions"}, + }, + }, + Dependencies: []string{ + configv1.TopologyTransition{}.OpenAPIModelName(), configv1.TopologyTransitionProgress{}.OpenAPIModelName(), metav1.Condition{}.OpenAPIModelName()}, } } diff --git a/openapi/openapi.json b/openapi/openapi.json index 1e88d1a6406..a22cf2dc10d 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -8603,14 +8603,9 @@ "description": "platformStatus holds status information specific to the underlying infrastructure provider.", "$ref": "#/definitions/com.github.openshift.api.config.v1.PlatformStatus" }, - "topologyTransitions": { - "description": "topologyTransitions reports, as controller-computed observed state, the topology transitions that originate at the current status.controlPlaneTopology and status.infrastructureTopology and whether each can currently be initiated. It is advisory: the cluster may change between a status read and a spec write, so the cluster-config-operator revalidates any requested transition; consumers such as the CLI must not treat Available as an admission guarantee. Transitions are requested via spec.controlPlaneTopology, not through this field. When omitted, the controller has not yet completed its first evaluation; an empty list is also valid and intentionally carries the same meaning as omitted, since this field does not currently distinguish \"not yet evaluated\" from \"evaluated with no applicable transitions\". The only supported transition is from a state where both topology values are SingleReplica to a state where both are HighlyAvailable. When the current topology does not match the supported source state, this field is expected to remain omitted or empty. At most 1 entry is permitted because only one transition direction is currently supported.", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" - }, - "x-kubernetes-list-type": "atomic" + "topologyTransitionStatus": { + "description": "topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions.", + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransitionStatus" } } }, @@ -12037,24 +12032,18 @@ } }, "com.github.openshift.api.config.v1.TopologyTransition": { - "description": "TopologyTransition describes one topology transition available from the cluster's current topology and whether it can currently be initiated. source and target must differ. reason must be set whenever availability is Unavailable or Unknown; both constraints are enforced by validation rules on the entry as a whole.", "type": "object", "required": [ "source", - "target", - "availability" + "target" ], "properties": { - "availability": { - "description": "availability indicates whether this transition can currently be initiated. Valid values are Available, Unavailable, and Unknown. Available means the controller evaluated the transition and its preconditions pass. Unavailable means the transition is defined but cannot be initiated now; see reason and message. Unknown means the controller has not completed evaluation.", - "type": "string" - }, "message": { "description": "message is a human-readable explanation, primarily for Unavailable transitions (e.g. a concise summary of the failing preconditions). It is for humans only and must not be parsed. It may be truncated by the controller. When omitted, no human-readable explanation is available for the transition. When set, it must be between 1 and 2048 characters long.", "type": "string" }, "reason": { - "description": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed or SourceTopologyMismatch. It is required when availability is Unavailable or Unknown and is normally omitted when Available. The set of reasons is diagnostic and not exhaustive. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", + "description": "reason is a CamelCase machine-readable explanation of the availability, e.g. PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. When omitted, no machine-readable explanation is available. Must start with an uppercase letter and contain only alphanumeric characters, and must be between 1 and 128 characters long.", "type": "string" }, "source": { @@ -12069,6 +12058,70 @@ } } }, + "com.github.openshift.api.config.v1.TopologyTransitionProgress": { + "description": "TopologyTransitionProgress describes a topology transition that has started.", + "type": "object", + "required": [ + "status", + "reason", + "message" + ], + "properties": { + "completionTime": { + "description": "completionTime is when the transition was fully applied. It is omitted while a transition is being applied.", + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + }, + "message": { + "description": "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", + "type": "string" + }, + "reason": { + "description": "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", + "type": "string" + }, + "startedTime": { + "description": "startedTime is the time at which the transition was started. When omitted, the start time is not available.", + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + }, + "status": { + "description": "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", + "type": "string" + } + } + }, + "com.github.openshift.api.config.v1.TopologyTransitionStatus": { + "type": "object", + "required": [ + "availableTransitions" + ], + "properties": { + "availableTransitions": { + "description": "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" + }, + "x-kubernetes-list-type": "atomic" + }, + "conditions": { + "description": "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Condition" + }, + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + }, + "currentTransition": { + "description": "currentTransition is omitted until a topology transition starts.", + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransitionProgress" + } + } + }, "com.github.openshift.api.config.v1.Update": { "description": "Update represents an administrator update request.", "type": "object", diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index f41b69ad507..f791bbafd67 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 613f7f454a9..92270c0373f 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 1a5eb3d345a..e14398b514b 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -2843,151 +2843,221 @@ spec: rule: '!has(self.dnsRecordsType) || self.dnsRecordsType == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect of the + current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology transitions - are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' && t.target.controlPlaneTopology - == 'HighlyAvailable' && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology transition + starts. + properties: + completionTime: + description: completionTime is when the transition was fully + applied. It is omitted while a transition is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the transition + was started. When omitted, the start time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3002,10 +3072,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) || self.status.topologyTransitions.all(t, - has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) - && t.source.controlPlaneTopology == self.status.controlPlaneTopology && - t.source.infrastructureTopology == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || + self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology + == self.status.controlPlaneTopology && t.source.infrastructureTopology + == self.status.infrastructureTopology)' served: true storage: true subresources: diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index ca6dcfac72e..4a4601cd457 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 6e915369b5a..3d93d3a240a 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index f0a2a4d7ef4..9dcca22ac42 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -3165,152 +3165,224 @@ spec: == ''Internal'' || (has(self.loadBalancer) && self.loadBalancer.type == ''UserManaged'')' type: object - topologyTransitions: + topologyTransitionStatus: description: |- - topologyTransitions reports, as controller-computed observed state, the - topology transitions that originate at the current status.controlPlaneTopology - and status.infrastructureTopology and whether each can currently be initiated. It is - advisory: the cluster may change between a status read and a spec write, so the - cluster-config-operator revalidates any requested transition; consumers such as - the CLI must not treat Available as an admission guarantee. Transitions are - requested via spec.controlPlaneTopology, not through this field. When omitted, - the controller has not yet completed its first evaluation; an empty list is also - valid and intentionally carries the same meaning as omitted, since this field does - not currently distinguish "not yet evaluated" from "evaluated with no applicable - transitions". The only supported transition is from a state where both topology - values are SingleReplica to a state where both are HighlyAvailable. When the - current topology does not match the supported source state, this field is expected - to remain omitted or empty. At most 1 entry is permitted because only one - transition direction is currently supported. - items: - description: |- - TopologyTransition describes one topology transition available from the - cluster's current topology and whether it can currently be initiated. source - and target must differ. reason must be set whenever availability is - Unavailable or Unknown; both constraints are enforced by validation rules on - the entry as a whole. - properties: - availability: - description: |- - availability indicates whether this transition can currently be initiated. - Valid values are Available, Unavailable, and Unknown. Available means the - controller evaluated the transition and its preconditions pass. Unavailable - means the transition is defined but cannot be initiated now; see reason and - message. Unknown means the controller has not completed evaluation. - enum: - - Available - - Unavailable - - Unknown - type: string - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed or SourceTopologyMismatch. It is required when - availability is Unavailable or Unknown and is normally omitted when Available. - The set of reasons is diagnostic and not exhaustive. Must start with an - uppercase letter and contain only alphanumeric characters, and must be - between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. + topologyTransitionStatus reports available topology transitions and current progress, if any. + It is omitted until the topology controller evaluates transitions. + properties: + availableTransitions: + description: |- + availableTransitions represents the transitions that are currently valid for this cluster. + An empty list means that no transitions are currently available. + At most one transition is supported currently (SNO to HA Compact) + items: properties: - controlPlaneTopology: + message: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 type: string - infrastructureTopology: + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object required: - - controlPlaneTopology - - infrastructureTopology + - source + - target type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. + maxItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + description: |- + conditions reports whether available transitions have been evaluated. + TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation + succeeds (even if no transitions are available), and False when evaluation fails. + An absent condition means evaluation has not completed. + At most one condition is present. + items: + description: Condition contains details for one aspect + of the current state of this API Resource. properties: - controlPlaneTopology: + lastTransitionTime: description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - infrastructureTopology: + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, + False, Unknown. enum: - - SingleReplica - - HighlyAvailable + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in + foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string required: - - controlPlaneTopology - - infrastructureTopology + - lastTransitionTime + - message + - reason + - status + - type type: object - required: - - availability - - source - - target - type: object - x-kubernetes-validations: - - message: source and target must differ - rule: self.source.controlPlaneTopology != self.target.controlPlaneTopology - || self.source.infrastructureTopology != self.target.infrastructureTopology - - message: reason is required when availability is not Available - rule: self.availability == 'Available' || has(self.reason) - maxItems: 1 - minItems: 0 - type: array - x-kubernetes-list-type: atomic - x-kubernetes-validations: - - message: only SingleReplica to HighlyAvailable topology - transitions are supported - rule: self.all(t, t.source.controlPlaneTopology == 'SingleReplica' - && t.source.infrastructureTopology == 'SingleReplica' - && t.target.controlPlaneTopology == 'HighlyAvailable' - && t.target.infrastructureTopology == 'HighlyAvailable') + maxItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + currentTransition: + description: currentTransition is omitted until a topology + transition starts. + properties: + completionTime: + description: completionTime is when the transition + was fully applied. It is omitted while a transition + is being applied. + format: date-time + type: string + message: + description: |- + message is human-readable information about the reason for the current status. + It must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason indicates why the Status is in the current state. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + startedTime: + description: startedTime is the time at which the + transition was started. When omitted, the start + time is not available. + format: date-time + type: string + status: + description: |- + status indicates the current state of a triggered transition. + It must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + required: + - message + - reason + - status + type: object + required: + - availableTransitions + type: object type: object required: - spec @@ -3327,11 +3399,11 @@ spec: && self.status.controlPlaneTopology == ''SingleReplica'' && self.spec.controlPlaneTopology == ''HighlyAvailable'')' - message: transition sources must match the current status topology - rule: '!has(self.status) || !has(self.status.topologyTransitions) - || self.status.topologyTransitions.all(t, has(self.status.controlPlaneTopology) - && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology - == self.status.controlPlaneTopology && t.source.infrastructureTopology - == self.status.infrastructureTopology)' + rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) + || self.status.topologyTransitionStatus.availableTransitions.all(t, + has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) + && t.source.controlPlaneTopology == self.status.controlPlaneTopology + && t.source.infrastructureTopology == self.status.infrastructureTopology)' internalRegistryPullSecret: description: |- internalRegistryPullSecret is the pull secret for the internal registry, used by From 68dc3a611f10259c30fb437c8e26b8b4a85050bc Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Thu, 24 Sep 2026 15:40:27 -0400 Subject: [PATCH 09/10] OCPEDGE-2989: Move TopologyState to transitions file --- config/v1/types_infrastructure.go | 22 ------------------- config/v1/types_infrastructure_transitions.go | 22 +++++++++++++++++++ .../v1/zz_generated.swagger_doc_generated.go | 20 ++++++++--------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index 770b460190b..d4bbfa601e7 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -184,28 +184,6 @@ const ( ExternalTopologyMode TopologyMode = "External" ) -// TopologyState describes the control-plane and infrastructure topology at one -// end of a topology transition. -type TopologyState struct { - // controlPlaneTopology is the topology of the control-plane nodes. Valid values - // are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - // avoid spending resources for high availability. When set to HighlyAvailable, - // operators configure high availability as much as possible. - // controlPlaneTopology is required. - // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable - // +required - ControlPlaneTopology TopologyMode `json:"controlPlaneTopology,omitempty"` - - // infrastructureTopology is the topology of infrastructure services. Valid - // values are SingleReplica and HighlyAvailable. When set to SingleReplica, - // operators avoid spending resources for high availability. When set to - // HighlyAvailable, operators configure high availability as much as possible. - // infrastructureTopology is required. - // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable - // +required - InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` -} - // CPUPartitioningMode defines the mode for CPU partitioning type CPUPartitioningMode string diff --git a/config/v1/types_infrastructure_transitions.go b/config/v1/types_infrastructure_transitions.go index bceefdca6aa..e3f27588cf3 100644 --- a/config/v1/types_infrastructure_transitions.go +++ b/config/v1/types_infrastructure_transitions.go @@ -4,6 +4,28 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// TopologyState describes the control-plane and infrastructure topology at one +// end of a topology transition. +type TopologyState struct { + // controlPlaneTopology is the topology of the control-plane nodes. Valid values + // are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + // avoid spending resources for high availability. When set to HighlyAvailable, + // operators configure high availability as much as possible. + // controlPlaneTopology is required. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + ControlPlaneTopology TopologyMode `json:"controlPlaneTopology,omitempty"` + + // infrastructureTopology is the topology of infrastructure services. Valid + // values are SingleReplica and HighlyAvailable. When set to SingleReplica, + // operators avoid spending resources for high availability. When set to + // HighlyAvailable, operators configure high availability as much as possible. + // infrastructureTopology is required. + // +kubebuilder:validation:Enum=SingleReplica;HighlyAvailable + // +required + InfrastructureTopology TopologyMode `json:"infrastructureTopology,omitempty"` +} + type TopologyTransitionStatus struct { // conditions reports whether available transitions have been evaluated. // TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 3ce5062ee49..5799d00149c 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -2140,16 +2140,6 @@ func (PowerVSServiceEndpoint) SwaggerDoc() map[string]string { return map_PowerVSServiceEndpoint } -var map_TopologyState = map[string]string{ - "": "TopologyState describes the control-plane and infrastructure topology at one end of a topology transition.", - "controlPlaneTopology": "controlPlaneTopology is the topology of the control-plane nodes. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. controlPlaneTopology is required.", - "infrastructureTopology": "infrastructureTopology is the topology of infrastructure services. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. infrastructureTopology is required.", -} - -func (TopologyState) SwaggerDoc() map[string]string { - return map_TopologyState -} - var map_VSphereFailureDomainHostGroup = map[string]string{ "": "VSphereFailureDomainHostGroup holds the vmGroup and the hostGroup names in vCenter corresponds to a vm-host group of type Virtual Machine and Host respectively. Is also contains the vmHostRule which is an affinity vm-host rule in vCenter.", "vmGroup": "vmGroup is the name of the vm-host group of type virtual machine within vCenter for this failure domain. vmGroup is limited to 80 characters. This field is required when the VSphereFailureDomain ZoneType is HostGroup", @@ -2281,6 +2271,16 @@ func (VSpherePlatformVCenterSpec) SwaggerDoc() map[string]string { return map_VSpherePlatformVCenterSpec } +var map_TopologyState = map[string]string{ + "": "TopologyState describes the control-plane and infrastructure topology at one end of a topology transition.", + "controlPlaneTopology": "controlPlaneTopology is the topology of the control-plane nodes. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. controlPlaneTopology is required.", + "infrastructureTopology": "infrastructureTopology is the topology of infrastructure services. Valid values are SingleReplica and HighlyAvailable. When set to SingleReplica, operators avoid spending resources for high availability. When set to HighlyAvailable, operators configure high availability as much as possible. infrastructureTopology is required.", +} + +func (TopologyState) SwaggerDoc() map[string]string { + return map_TopologyState +} + var map_TopologyTransition = map[string]string{ "source": "source is the control-plane and infrastructure topology this transition starts from. It must equal the current topology in the corresponding status fields. source is required.", "target": "target is the control-plane and infrastructure topology this transition would move to. target is required.", From 80f90e8500e69b4593c33ca0dd7ec80ec193d718 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Fri, 25 Sep 2026 09:01:01 -0400 Subject: [PATCH 10/10] OCPEDGE-2989: Align topology transition status names --- .../AAA_ungated.yaml | 2 +- .../MutableTopology.yaml | 30 +-- config/v1/types_infrastructure.go | 2 +- config/v1/types_infrastructure_transitions.go | 41 +--- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 218 +++++++++--------- config/v1/zz_generated.deepcopy.go | 4 +- .../MutableTopology.yaml | 218 +++++++++--------- .../v1/zz_generated.swagger_doc_generated.go | 10 +- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 218 +++++++++--------- .../MutableTopology.yaml | 218 +++++++++--------- .../generated_openapi/zz_generated.openapi.go | 18 +- openapi/openapi.json | 32 +-- ...ctures-Hypershift-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...res-SelfManagedHA-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 218 +++++++++--------- ...onfigs-Hypershift-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...igs-SelfManagedHA-CustomNoUpgrade.crd.yaml | 218 +++++++++--------- ...SelfManagedHA-DevPreviewNoUpgrade.crd.yaml | 218 +++++++++--------- 22 files changed, 1585 insertions(+), 1606 deletions(-) diff --git a/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml b/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml index 70c99560e9f..66127fc55a0 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml @@ -649,7 +649,7 @@ tests: status: controlPlaneTopology: SingleReplica topologyTransitionStatus: - availableTransitions: [] + supportedTransitions: [] expected: | apiVersion: config.openshift.io/v1 kind: Infrastructure diff --git a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml index a8f5052a6ef..c283c5b07c6 100644 --- a/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/tests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -281,7 +281,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: HighlyAvailable cpuPartitioning: None - - name: Should allow an empty availableTransitions list after successful evaluation + - name: Should allow an empty supportedTransitions list after successful evaluation initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -295,7 +295,7 @@ tests: status: controlPlaneTopology: SingleReplica topologyTransitionStatus: - availableTransitions: [] + supportedTransitions: [] conditions: - type: TopologyTransitionsEvaluated status: "True" @@ -311,7 +311,7 @@ tests: infrastructureTopology: HighlyAvailable cpuPartitioning: None topologyTransitionStatus: - availableTransitions: [] + supportedTransitions: [] conditions: - type: TopologyTransitionsEvaluated status: "True" @@ -334,7 +334,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica topologyTransitionStatus: - availableTransitions: + supportedTransitions: - source: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica @@ -343,7 +343,7 @@ tests: infrastructureTopology: HighlyAvailable reason: PreflightCheckFailed currentTransition: - status: Partial + state: Partial reason: TransitionInProgress message: Applying topology changes startedTime: "2025-01-01T00:00:00Z" @@ -356,7 +356,7 @@ tests: infrastructureTopology: SingleReplica cpuPartitioning: None topologyTransitionStatus: - availableTransitions: + supportedTransitions: - source: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica @@ -365,7 +365,7 @@ tests: infrastructureTopology: HighlyAvailable reason: PreflightCheckFailed currentTransition: - status: Partial + state: Partial reason: TransitionInProgress message: Applying topology changes startedTime: "2025-01-01T00:00:00Z" @@ -385,7 +385,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica topologyTransitionStatus: - availableTransitions: + supportedTransitions: - source: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica @@ -394,7 +394,7 @@ tests: infrastructureTopology: HighlyAvailable reason: preflightCheckFailed expectedStatusError: "reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$" - - name: Should reject an available transition whose source does not match status topology + - name: Should reject a supported transition whose source does not match status topology initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -410,7 +410,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica topologyTransitionStatus: - availableTransitions: + supportedTransitions: - source: controlPlaneTopology: HighlyAvailable infrastructureTopology: HighlyAvailable @@ -418,7 +418,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica expectedStatusError: "transition sources must match the current status topology" - - name: Should enforce the supported maximum available transition count + - name: Should enforce the maximum supported transition count initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -434,7 +434,7 @@ tests: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica topologyTransitionStatus: - availableTransitions: + supportedTransitions: - source: controlPlaneTopology: SingleReplica infrastructureTopology: SingleReplica @@ -448,7 +448,7 @@ tests: controlPlaneTopology: HighlyAvailable infrastructureTopology: HighlyAvailable expectedStatusError: "Too many: 2: must have at most 1 items" - - name: Should require availableTransitions when topologyTransitionStatus is set + - name: Should require supportedTransitions when topologyTransitionStatus is set initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -464,7 +464,7 @@ tests: topologyTransitionStatus: conditions: [] expectedStatusError: "Required value" - - name: Should require status on currentTransition + - name: Should require state on currentTransition initial: | apiVersion: config.openshift.io/v1 kind: Infrastructure @@ -478,7 +478,7 @@ tests: status: controlPlaneTopology: SingleReplica topologyTransitionStatus: - availableTransitions: [] + supportedTransitions: [] currentTransition: reason: TransitionInProgress message: Applying topology changes diff --git a/config/v1/types_infrastructure.go b/config/v1/types_infrastructure.go index d4bbfa601e7..25fbed08a1b 100644 --- a/config/v1/types_infrastructure.go +++ b/config/v1/types_infrastructure.go @@ -20,7 +20,7 @@ import ( // +kubebuilder:subresource:status // +kubebuilder:metadata:annotations=release.openshift.io/bootstrap-required=true // +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.spec.controlPlaneTopology) || (has(oldSelf.spec.controlPlaneTopology) && self.spec.controlPlaneTopology == oldSelf.spec.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.spec.controlPlaneTopology == self.status.controlPlaneTopology) || (has(self.status.controlPlaneTopology) && self.status.controlPlaneTopology == 'SingleReplica' && self.spec.controlPlaneTopology == 'HighlyAvailable')",message="spec.controlPlaneTopology must match status.controlPlaneTopology or be set to HighlyAvailable when status.controlPlaneTopology is SingleReplica" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.topologyTransitionStatus) || self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)",message="transition sources must match the current status topology" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=MutableTopology,rule="!has(self.status) || !has(self.status.topologyTransitionStatus) || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)",message="transition sources must match the current status topology" type Infrastructure struct { metav1.TypeMeta `json:",inline"` diff --git a/config/v1/types_infrastructure_transitions.go b/config/v1/types_infrastructure_transitions.go index e3f27588cf3..ecdaa62f084 100644 --- a/config/v1/types_infrastructure_transitions.go +++ b/config/v1/types_infrastructure_transitions.go @@ -27,9 +27,9 @@ type TopologyState struct { } type TopologyTransitionStatus struct { - // conditions reports whether available transitions have been evaluated. + // conditions reports whether supported transitions have been evaluated. // TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - // succeeds (even if no transitions are available), and False when evaluation fails. + // succeeds (even if no transitions are supported), and False when evaluation fails. // An absent condition means evaluation has not completed. // At most one condition is present. // +kubebuilder:validation:MaxItems=1 @@ -38,13 +38,13 @@ type TopologyTransitionStatus struct { // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty"` - // availableTransitions represents the transitions that are currently valid for this cluster. - // An empty list means that no transitions are currently available. + // supportedTransitions represents the transitions that are valid for this cluster. + // An empty list means that no transitions are currently supported from the current topology. // At most one transition is supported currently (SNO to HA Compact) // +kubebuilder:validation:MaxItems=1 // +required // +listType=atomic - AvailableTransitions []TopologyTransition `json:"availableTransitions"` + SupportedTransitions []TopologyTransition `json:"supportedTransitions"` // currentTransition is omitted until a topology transition starts. // +optional @@ -58,21 +58,21 @@ const ( // TopologyTransitionProgress describes a topology transition that has started. type TopologyTransitionProgress struct { - // status indicates the current state of a triggered transition. + // state indicates the current state of a triggered transition. // It must be between 1 and 128 characters long. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=128 // +required - Status TransitionState `json:"status,omitempty"` + State TransitionState `json:"state,omitempty"` - // reason indicates why the Status is in the current state. + // reason indicates why current state is as reported. // It must be between 1 and 128 characters long. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=128 // +required - Reason TransitionStateReason `json:"reason,omitempty"` + Reason string `json:"reason,omitempty"` - // message is human-readable information about the reason for the current status. + // message is human-readable information about the reason for the current state. // It must be between 1 and 2048 characters long. // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=2048 @@ -102,27 +102,6 @@ const ( FailedTransition TransitionState = "Failed" ) -// TransitionStateReason indicates why the transition is in a given state. -type TransitionStateReason string - -const ( - // UnsupportedTransition indicates that the requested - // transition is not supported. - UnsupportedTransition TransitionStateReason = "UnsupportedTransition" - - // PreflightCheckFailed indicates that a preflight - // check for the requested transition failed. - PreflightCheckFailed TransitionStateReason = "PreflightCheckFailed" - - // Initiated indicates that a transition is - // currently in progress. - InProgress TransitionStateReason = "TransitionInProgress" - - // Complete indicates that a transition has - // completed successfully. - Complete TransitionStateReason = "TransitionComplete" -) - type TopologyTransition struct { // source is the control-plane and infrastructure topology this transition starts // from. It must equal the current topology in the corresponding status fields. diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index f791bbafd67..f5f5a7ca867 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 92270c0373f..b61b3c5b720 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index e14398b514b..c4ea73199a4 100644 --- a/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/config/v1/zz_generated.deepcopy.go b/config/v1/zz_generated.deepcopy.go index cc4b6f213e2..b62dd17e2ae 100644 --- a/config/v1/zz_generated.deepcopy.go +++ b/config/v1/zz_generated.deepcopy.go @@ -6921,8 +6921,8 @@ func (in *TopologyTransitionStatus) DeepCopyInto(out *TopologyTransitionStatus) (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.AvailableTransitions != nil { - in, out := &in.AvailableTransitions, &out.AvailableTransitions + if in.SupportedTransitions != nil { + in, out := &in.SupportedTransitions, &out.SupportedTransitions *out = make([]TopologyTransition, len(*in)) copy(*out, *in) } diff --git a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml index aacfafa6e64..676b947ea77 100644 --- a/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml +++ b/config/v1/zz_generated.featuregated-crd-manifests/infrastructures.config.openshift.io/MutableTopology.yaml @@ -2436,111 +2436,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -2614,14 +2514,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -2631,9 +2531,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -2641,10 +2541,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -2661,7 +2661,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/config/v1/zz_generated.swagger_doc_generated.go b/config/v1/zz_generated.swagger_doc_generated.go index 5799d00149c..dc81d48109b 100644 --- a/config/v1/zz_generated.swagger_doc_generated.go +++ b/config/v1/zz_generated.swagger_doc_generated.go @@ -2294,9 +2294,9 @@ func (TopologyTransition) SwaggerDoc() map[string]string { var map_TopologyTransitionProgress = map[string]string{ "": "TopologyTransitionProgress describes a topology transition that has started.", - "status": "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", - "reason": "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", - "message": "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", + "state": "state indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", + "reason": "reason indicates why current state is as reported. It must be between 1 and 128 characters long.", + "message": "message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long.", "startedTime": "startedTime is the time at which the transition was started. When omitted, the start time is not available.", "completionTime": "completionTime is when the transition was fully applied. It is omitted while a transition is being applied.", } @@ -2306,8 +2306,8 @@ func (TopologyTransitionProgress) SwaggerDoc() map[string]string { } var map_TopologyTransitionStatus = map[string]string{ - "conditions": "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", - "availableTransitions": "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", + "conditions": "conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + "supportedTransitions": "supportedTransitions represents the transitions that are valid for this cluster. An empty list means that no transitions are currently supported from the current topology. At most one transition is supported currently (SNO to HA Compact)", "currentTransition": "currentTransition is omitted until a topology transition starts.", } diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 4a4601cd457..a7e6eb44d57 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 3d93d3a240a..f5f5da3b117 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9dcca22ac42..ba183101687 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml index 63a14da834b..eff93b442eb 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/controllerconfigs.machineconfiguration.openshift.io/MutableTopology.yaml @@ -2743,111 +2743,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -2923,14 +2823,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -2941,9 +2841,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -2951,10 +2851,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -2973,7 +2973,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index ffa6de44122..ff26ba43a72 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -22306,23 +22306,23 @@ func schema_openshift_api_config_v1_TopologyTransitionProgress(ref common.Refere Description: "TopologyTransitionProgress describes a topology transition that has started.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "status": { + "state": { SchemaProps: spec.SchemaProps{ - Description: "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", + Description: "state indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", Type: []string{"string"}, Format: "", }, }, "reason": { SchemaProps: spec.SchemaProps{ - Description: "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", + Description: "reason indicates why current state is as reported. It must be between 1 and 128 characters long.", Type: []string{"string"}, Format: "", }, }, "message": { SchemaProps: spec.SchemaProps{ - Description: "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", + Description: "message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long.", Type: []string{"string"}, Format: "", }, @@ -22340,7 +22340,7 @@ func schema_openshift_api_config_v1_TopologyTransitionProgress(ref common.Refere }, }, }, - Required: []string{"status", "reason", "message"}, + Required: []string{"state", "reason", "message"}, }, }, Dependencies: []string{ @@ -22364,7 +22364,7 @@ func schema_openshift_api_config_v1_TopologyTransitionStatus(ref common.Referenc }, }, SchemaProps: spec.SchemaProps{ - Description: "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + Description: "conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -22376,14 +22376,14 @@ func schema_openshift_api_config_v1_TopologyTransitionStatus(ref common.Referenc }, }, }, - "availableTransitions": { + "supportedTransitions": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Description: "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", + Description: "supportedTransitions represents the transitions that are valid for this cluster. An empty list means that no transitions are currently supported from the current topology. At most one transition is supported currently (SNO to HA Compact)", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -22402,7 +22402,7 @@ func schema_openshift_api_config_v1_TopologyTransitionStatus(ref common.Referenc }, }, }, - Required: []string{"availableTransitions"}, + Required: []string{"supportedTransitions"}, }, }, Dependencies: []string{ diff --git a/openapi/openapi.json b/openapi/openapi.json index a22cf2dc10d..08d0b62ae86 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -12062,7 +12062,7 @@ "description": "TopologyTransitionProgress describes a topology transition that has started.", "type": "object", "required": [ - "status", + "state", "reason", "message" ], @@ -12072,19 +12072,19 @@ "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time" }, "message": { - "description": "message is human-readable information about the reason for the current status. It must be between 1 and 2048 characters long.", + "description": "message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long.", "type": "string" }, "reason": { - "description": "reason indicates why the Status is in the current state. It must be between 1 and 128 characters long.", + "description": "reason indicates why current state is as reported. It must be between 1 and 128 characters long.", "type": "string" }, "startedTime": { "description": "startedTime is the time at which the transition was started. When omitted, the start time is not available.", "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time" }, - "status": { - "description": "status indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", + "state": { + "description": "state indicates the current state of a triggered transition. It must be between 1 and 128 characters long.", "type": "string" } } @@ -12092,20 +12092,11 @@ "com.github.openshift.api.config.v1.TopologyTransitionStatus": { "type": "object", "required": [ - "availableTransitions" + "supportedTransitions" ], "properties": { - "availableTransitions": { - "description": "availableTransitions represents the transitions that are currently valid for this cluster. An empty list means that no transitions are currently available. At most one transition is supported currently (SNO to HA Compact)", - "type": "array", - "items": { - "default": {}, - "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" - }, - "x-kubernetes-list-type": "atomic" - }, "conditions": { - "description": "conditions reports whether available transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are available), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", + "description": "conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present.", "type": "array", "items": { "default": {}, @@ -12119,6 +12110,15 @@ "currentTransition": { "description": "currentTransition is omitted until a topology transition starts.", "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransitionProgress" + }, + "supportedTransitions": { + "description": "supportedTransitions represents the transitions that are valid for this cluster. An empty list means that no transitions are currently supported from the current topology. At most one transition is supported currently (SNO to HA Compact)", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/com.github.openshift.api.config.v1.TopologyTransition" + }, + "x-kubernetes-list-type": "atomic" } } }, diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml index f791bbafd67..f5f5a7ca867 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-Hypershift-CustomNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml index 92270c0373f..b61b3c5b720 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index e14398b514b..c4ea73199a4 100644 --- a/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_10_config-operator_01_infrastructures-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -2848,111 +2848,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3026,14 +2926,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3043,9 +2943,9 @@ spec: was started. When omitted, the start time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3053,10 +2953,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3073,7 +3073,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) || - self.status.topologyTransitionStatus.availableTransitions.all(t, has(self.status.controlPlaneTopology) + self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml index 4a4601cd457..a7e6eb44d57 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-Hypershift-CustomNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml index 3d93d3a240a..f5f5da3b117 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-CustomNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)' diff --git a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml index 9dcca22ac42..ba183101687 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_controllerconfigs-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml @@ -3170,111 +3170,11 @@ spec: topologyTransitionStatus reports available topology transitions and current progress, if any. It is omitted until the topology controller evaluates transitions. properties: - availableTransitions: - description: |- - availableTransitions represents the transitions that are currently valid for this cluster. - An empty list means that no transitions are currently available. - At most one transition is supported currently (SNO to HA Compact) - items: - properties: - message: - description: |- - message is a human-readable explanation, primarily for Unavailable - transitions (e.g. a concise summary of the failing preconditions). It is for - humans only and must not be parsed. It may be truncated by the controller. - When omitted, no human-readable explanation is available for the transition. - When set, it must be between 1 and 2048 characters long. - maxLength: 2048 - minLength: 1 - type: string - reason: - description: |- - reason is a CamelCase machine-readable explanation of the availability, e.g. - PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. - When omitted, no machine-readable explanation is available. - Must start with an uppercase letter and contain only alphanumeric characters, - and must be between 1 and 128 characters long. - maxLength: 128 - minLength: 1 - type: string - x-kubernetes-validations: - - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ - rule: self.matches('^[A-Z][A-Za-z0-9]*$') - source: - description: |- - source is the control-plane and infrastructure topology this transition starts - from. It must equal the current topology in the corresponding status fields. - source is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - target: - description: |- - target is the control-plane and infrastructure topology this transition would - move to. target is required. - properties: - controlPlaneTopology: - description: |- - controlPlaneTopology is the topology of the control-plane nodes. Valid values - are SingleReplica and HighlyAvailable. When set to SingleReplica, operators - avoid spending resources for high availability. When set to HighlyAvailable, - operators configure high availability as much as possible. - controlPlaneTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - infrastructureTopology: - description: |- - infrastructureTopology is the topology of infrastructure services. Valid - values are SingleReplica and HighlyAvailable. When set to SingleReplica, - operators avoid spending resources for high availability. When set to - HighlyAvailable, operators configure high availability as much as possible. - infrastructureTopology is required. - enum: - - SingleReplica - - HighlyAvailable - type: string - required: - - controlPlaneTopology - - infrastructureTopology - type: object - required: - - source - - target - type: object - maxItems: 1 - type: array - x-kubernetes-list-type: atomic conditions: description: |- - conditions reports whether available transitions have been evaluated. + conditions reports whether supported transitions have been evaluated. TopologyTransitionsEvaluated is Unknown before evaluation, True when evaluation - succeeds (even if no transitions are available), and False when evaluation fails. + succeeds (even if no transitions are supported), and False when evaluation fails. An absent condition means evaluation has not completed. At most one condition is present. items: @@ -3350,14 +3250,14 @@ spec: type: string message: description: |- - message is human-readable information about the reason for the current status. + message is human-readable information about the reason for the current state. It must be between 1 and 2048 characters long. maxLength: 2048 minLength: 1 type: string reason: description: |- - reason indicates why the Status is in the current state. + reason indicates why current state is as reported. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3368,9 +3268,9 @@ spec: time is not available. format: date-time type: string - status: + state: description: |- - status indicates the current state of a triggered transition. + state indicates the current state of a triggered transition. It must be between 1 and 128 characters long. maxLength: 128 minLength: 1 @@ -3378,10 +3278,110 @@ spec: required: - message - reason - - status + - state type: object + supportedTransitions: + description: |- + supportedTransitions represents the transitions that are valid for this cluster. + An empty list means that no transitions are currently supported from the current topology. + At most one transition is supported currently (SNO to HA Compact) + items: + properties: + message: + description: |- + message is a human-readable explanation, primarily for Unavailable + transitions (e.g. a concise summary of the failing preconditions). It is for + humans only and must not be parsed. It may be truncated by the controller. + When omitted, no human-readable explanation is available for the transition. + When set, it must be between 1 and 2048 characters long. + maxLength: 2048 + minLength: 1 + type: string + reason: + description: |- + reason is a CamelCase machine-readable explanation of the availability, e.g. + PreflightCheckFailed. The set of reasons is diagnostic and not exhaustive. + When omitted, no machine-readable explanation is available. + Must start with an uppercase letter and contain only alphanumeric characters, + and must be between 1 and 128 characters long. + maxLength: 128 + minLength: 1 + type: string + x-kubernetes-validations: + - message: reason must be CamelCase, matching ^[A-Z][A-Za-z0-9]*$ + rule: self.matches('^[A-Z][A-Za-z0-9]*$') + source: + description: |- + source is the control-plane and infrastructure topology this transition starts + from. It must equal the current topology in the corresponding status fields. + source is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + target: + description: |- + target is the control-plane and infrastructure topology this transition would + move to. target is required. + properties: + controlPlaneTopology: + description: |- + controlPlaneTopology is the topology of the control-plane nodes. Valid values + are SingleReplica and HighlyAvailable. When set to SingleReplica, operators + avoid spending resources for high availability. When set to HighlyAvailable, + operators configure high availability as much as possible. + controlPlaneTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + infrastructureTopology: + description: |- + infrastructureTopology is the topology of infrastructure services. Valid + values are SingleReplica and HighlyAvailable. When set to SingleReplica, + operators avoid spending resources for high availability. When set to + HighlyAvailable, operators configure high availability as much as possible. + infrastructureTopology is required. + enum: + - SingleReplica + - HighlyAvailable + type: string + required: + - controlPlaneTopology + - infrastructureTopology + type: object + required: + - source + - target + type: object + maxItems: 1 + type: array + x-kubernetes-list-type: atomic required: - - availableTransitions + - supportedTransitions type: object type: object required: @@ -3400,7 +3400,7 @@ spec: == ''HighlyAvailable'')' - message: transition sources must match the current status topology rule: '!has(self.status) || !has(self.status.topologyTransitionStatus) - || self.status.topologyTransitionStatus.availableTransitions.all(t, + || self.status.topologyTransitionStatus.supportedTransitions.all(t, has(self.status.controlPlaneTopology) && has(self.status.infrastructureTopology) && t.source.controlPlaneTopology == self.status.controlPlaneTopology && t.source.infrastructureTopology == self.status.infrastructureTopology)'