From 790b790eb31835f1bd7daadfff88542dcb333931 Mon Sep 17 00:00:00 2001 From: Jeff Roche Date: Wed, 9 Sep 2026 12:30:52 -0400 Subject: [PATCH] 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: |-