From c085b808e953966b77c107fef5a4ab43d1bb481e Mon Sep 17 00:00:00 2001
From: Borja Clemente
Date: Thu, 11 Jun 2026 14:58:10 +0200
Subject: [PATCH 1/5] build(capi): migrate CAPI core types from v1beta1 to
v1beta2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bump Cluster API core imports from v1beta1 to v1beta2 across all
consumers. Provider imports (Azure, GCP, OpenStack, AWS, IBM Cloud)
remain on v1beta1 as their ControlPlaneEndpoint field still references
core v1beta1.APIEndpoint — no provider has migrated this yet.
Key type changes:
- corev1.ObjectReference → capiv1.ContractVersionedObjectReference
- Machine.Status.NodeRef: pointer → MachineNodeReference (use .IsDefined())
- Cluster.Spec.Paused: bool → *bool
- Version/FailureDomain: *string → string
- Status replica fields: int32 → *int32 (access via ptr.Deref)
- Strategy → Rollout.Strategy
- NodeDrainTimeout → Deletion.NodeDrainTimeoutSeconds
- MHC: UnhealthyConditions → Checks.UnhealthyNodeConditions,
MaxUnhealthy → Remediation.TriggerIf.UnhealthyLessThanOrEqualTo
- Conditions: capiv1.Condition → metav1.Condition
- ReadyCondition → MachinesReadyCondition (on MachineDeployment/MachineSet)
- machineConditionResult.Status: corev1.ConditionStatus → metav1.ConditionStatus
- MachineDeploymentComplete: use UpToDateReplicas + ReadyReplicas
- Constants renamed with V1Beta1 suffix (e.g. WaitingForNodeRefReason)
Control plane changes:
- Add HCP Status.Initialization.ControlPlaneInitialized
- Add patchInfrastructureInitializationProvisioned for CAPI v1beta2 contract
- Remove conversion webhook (no longer needed with single API version)
- Remove v1beta1 scheme registration (core, addons, ipam)
Signed-off-by: Borja Clemente
---
api/.golangci.yml | 4 +
api/hypershift/v1beta1/hosted_controlplane.go | 20 +++
.../v1beta1/zz_generated.deepcopy.go | 21 +++
.../AAA_ungated.yaml | 16 ++
.../ClusterUpdateAcceptRisks.yaml | 16 ++
.../ClusterVersionOperatorConfiguration.yaml | 16 ++
.../ExternalOIDC.yaml | 16 ++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 16 ++
.../ExternalOIDCWithUpstreamParity.yaml | 16 ++
.../GCPPlatform.yaml | 16 ++
.../HCPEtcdBackup.yaml | 16 ++
...perShiftOnlyDynamicResourceAllocation.yaml | 16 ++
.../ImageStreamImportMode.yaml | 16 ++
.../KMSEncryptionProvider.yaml | 16 ++
.../OpenStack.yaml | 16 ++
.../TLSAdherence.yaml | 16 ++
.../hostedcontrolplaneinitializationstatus.go | 38 ++++
.../v1beta1/hostedcontrolplanestatus.go | 45 +++--
client/applyconfiguration/utils.go | 2 +
cmd/cluster/core/dump.go | 2 +-
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 16 ++
...dcontrolplanes-Hypershift-Default.crd.yaml | 16 ++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 16 ++
.../hostedcontrolplane_controller.go | 6 +-
.../hostedcontrolplane/v2/kas/kubeconfig.go | 2 +-
.../hostedclusterconfigoperator/api/scheme.go | 2 +-
.../inplaceupgrader/inplaceupgrader.go | 4 +-
.../controllers/inplaceupgrader/setup.go | 2 +-
.../controllers/machine/machine.go | 2 +-
.../controllers/machine/setup.go | 2 +-
.../controllers/node/node.go | 2 +-
.../spotremediation/spotremediation.go | 2 +-
docs/content/reference/aggregated-docs.md | 51 ++++++
docs/content/reference/api.md | 51 ++++++
.../hostedcluster/hostedcluster_controller.go | 64 +++++--
.../hostedcluster/hostedcluster_webhook.go | 3 +-
.../internal/platform/agent/agent.go | 21 ++-
.../internal/platform/agent/agent_test.go | 1 -
.../internal/platform/aws/aws.go | 16 +-
.../internal/platform/azure/azure.go | 7 +-
.../internal/platform/gcp/gcp.go | 7 +-
.../internal/platform/ibmcloud/ibmcloud.go | 14 +-
.../platform/ibmcloud/ibmcloud_test.go | 3 +-
.../internal/platform/kubevirt/kubevirt.go | 2 +-
.../internal/platform/openstack/openstack.go | 12 +-
.../platform/openstack/openstack_test.go | 55 +++---
.../internal/platform/powervs/powervs.go | 19 +-
.../controlplaneoperator/manifests.go | 2 +-
.../controllers/nodepool/aws.go | 2 +-
.../controllers/nodepool/azure_test.go | 2 +-
.../controllers/nodepool/capi.go | 162 ++++++++++--------
.../controllers/nodepool/conditions.go | 19 +-
.../controllers/nodepool/gcp.go | 2 +-
.../controllers/nodepool/metrics/metrics.go | 2 +-
.../nodepool/nodepool_controller.go | 26 ++-
.../controllers/nodepool/powervs.go | 2 +-
.../controllers/nodepool/version.go | 6 +-
.../karpenter/karpenter_controller.go | 2 +-
support/api/capi_types.go | 5 +-
support/k8sutil/resources.go | 2 +-
support/upsert/upsert.go | 2 +-
test/e2e/util/util.go | 2 +-
test/e2e/v2/backuprestore/cleanup.go | 2 +-
.../hypershift/v1beta1/hosted_controlplane.go | 12 ++
64 files changed, 775 insertions(+), 215 deletions(-)
create mode 100644 client/applyconfiguration/hypershift/v1beta1/hostedcontrolplaneinitializationstatus.go
diff --git a/api/.golangci.yml b/api/.golangci.yml
index 6a6b91242230..5a49711b4b23 100644
--- a/api/.golangci.yml
+++ b/api/.golangci.yml
@@ -120,6 +120,10 @@ linters:
- kubeapilinter
path: hypershift/v1beta1/hosted_controlplane.go
text: 'nobools: field HostedControlPlaneStatus.Initialized should not use a bool. Use a string type with meaningful constant values as an enum.'
+ - linters:
+ - kubeapilinter
+ path: hypershift/v1beta1/hosted_controlplane.go
+ text: 'nobools: field HostedControlPlaneInitializationStatus.ControlPlaneInitialized pointer should not use a bool. Use a string type with meaningful constant values as an enum.'
- linters:
- kubeapilinter
path: hypershift/v1beta1/hosted_controlplane.go
diff --git a/api/hypershift/v1beta1/hosted_controlplane.go b/api/hypershift/v1beta1/hosted_controlplane.go
index 8486514f0a18..cfc63ec4be22 100644
--- a/api/hypershift/v1beta1/hosted_controlplane.go
+++ b/api/hypershift/v1beta1/hosted_controlplane.go
@@ -419,6 +419,26 @@ type HostedControlPlaneStatus struct {
// configuration contains the cluster configuration status of the HostedCluster
// +optional
Configuration *ConfigurationStatus `json:"configuration,omitempty"`
+
+ // initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ // This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ // https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ // +optional
+ Initialization HostedControlPlaneInitializationStatus `json:"initialization,omitzero"`
+}
+
+// HostedControlPlaneInitializationStatus provides observations of the HostedControlPlane initialization process.
+// This satisfies the CAPI v1beta2 ControlPlane provider contract:
+// https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1361-L1379
+// +kubebuilder:validation:MinProperties=1
+type HostedControlPlaneInitializationStatus struct {
+ // controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ // Once this condition is marked true, its value is never changed. See the Ready condition for an
+ // indication of the current readiness of the cluster's control plane.
+ // This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ // +optional
+ // +default=false
+ ControlPlaneInitialized *bool `json:"controlPlaneInitialized,omitempty"`
}
// APIEndpoint represents a reachable Kubernetes API endpoint.
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 454f86378499..b9e2e2546e76 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -2500,6 +2500,26 @@ func (in *HostedControlPlane) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HostedControlPlaneInitializationStatus) DeepCopyInto(out *HostedControlPlaneInitializationStatus) {
+ *out = *in
+ if in.ControlPlaneInitialized != nil {
+ in, out := &in.ControlPlaneInitialized, &out.ControlPlaneInitialized
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneInitializationStatus.
+func (in *HostedControlPlaneInitializationStatus) DeepCopy() *HostedControlPlaneInitializationStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(HostedControlPlaneInitializationStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostedControlPlaneList) DeepCopyInto(out *HostedControlPlaneList) {
*out = *in
@@ -2697,6 +2717,7 @@ func (in *HostedControlPlaneStatus) DeepCopyInto(out *HostedControlPlaneStatus)
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.Initialization.DeepCopyInto(&out.Initialization)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneStatus.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index 7faf853bd178..11869d3fd5ad 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -6746,6 +6746,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 927f2b9ffc23..6b93ee2982d7 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -6729,6 +6729,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index ad6e7742c0ec..0d299a8b05c7 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -6749,6 +6749,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index 1b9da7de5255..78b34729216c 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -7226,6 +7226,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 3cd3503473be..1a772a81e2a9 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -7366,6 +7366,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 9d7a73cb3bf0..0aa0b956f691 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -7192,6 +7192,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index 1527b355549f..e35cffdbe686 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -7175,6 +7175,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
index 36a11500968d..1cf8c9d0ea04 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -6794,6 +6794,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 5ea38844b584..9ae07cbe4cac 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -6751,6 +6751,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index 9de4ad90ead5..736ab6e3fcbf 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -6758,6 +6758,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index db3f3840a8c2..b56c1afe2f35 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -6805,6 +6805,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index c3c0b64fcf23..97c22c290562 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -7280,6 +7280,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
index e52cbe485e19..dd70f04299b8 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/TLSAdherence.yaml
@@ -6769,6 +6769,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplaneinitializationstatus.go b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplaneinitializationstatus.go
new file mode 100644
index 000000000000..3df3d3039414
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplaneinitializationstatus.go
@@ -0,0 +1,38 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// HostedControlPlaneInitializationStatusApplyConfiguration represents a declarative configuration of the HostedControlPlaneInitializationStatus type for use
+// with apply.
+type HostedControlPlaneInitializationStatusApplyConfiguration struct {
+ ControlPlaneInitialized *bool `json:"controlPlaneInitialized,omitempty"`
+}
+
+// HostedControlPlaneInitializationStatusApplyConfiguration constructs a declarative configuration of the HostedControlPlaneInitializationStatus type for use with
+// apply.
+func HostedControlPlaneInitializationStatus() *HostedControlPlaneInitializationStatusApplyConfiguration {
+ return &HostedControlPlaneInitializationStatusApplyConfiguration{}
+}
+
+// WithControlPlaneInitialized sets the ControlPlaneInitialized field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ControlPlaneInitialized field is set to the value of the last call.
+func (b *HostedControlPlaneInitializationStatusApplyConfiguration) WithControlPlaneInitialized(value bool) *HostedControlPlaneInitializationStatusApplyConfiguration {
+ b.ControlPlaneInitialized = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
index 3921f0dd7d99..090775246ba1 100644
--- a/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
+++ b/client/applyconfiguration/hypershift/v1beta1/hostedcontrolplanestatus.go
@@ -26,24 +26,25 @@ import (
// HostedControlPlaneStatusApplyConfiguration represents a declarative configuration of the HostedControlPlaneStatus type for use
// with apply.
type HostedControlPlaneStatusApplyConfiguration struct {
- Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
- Ready *bool `json:"ready,omitempty"`
- Initialized *bool `json:"initialized,omitempty"`
- ExternalManagedControlPlane *bool `json:"externalManagedControlPlane,omitempty"`
- ControlPlaneEndpoint *APIEndpointApplyConfiguration `json:"controlPlaneEndpoint,omitempty"`
- OAuthCallbackURLTemplate *string `json:"oauthCallbackURLTemplate,omitempty"`
- ControlPlaneVersion *ControlPlaneVersionStatusApplyConfiguration `json:"controlPlaneVersion,omitempty"`
- VersionStatus *ClusterVersionStatusApplyConfiguration `json:"versionStatus,omitempty"`
- Version *string `json:"version,omitempty"`
- ReleaseImage *string `json:"releaseImage,omitempty"`
- LastReleaseImageTransitionTime *metav1.Time `json:"lastReleaseImageTransitionTime,omitempty"`
- KubeConfig *KubeconfigSecretRefApplyConfiguration `json:"kubeConfig,omitempty"`
- CustomKubeconfig *KubeconfigSecretRefApplyConfiguration `json:"customKubeconfig,omitempty"`
- KubeadminPassword *corev1.LocalObjectReference `json:"kubeadminPassword,omitempty"`
- Platform *PlatformStatusApplyConfiguration `json:"platform,omitempty"`
- NodeCount *int `json:"nodeCount,omitempty"`
- AutoNode *AutoNodeStatusApplyConfiguration `json:"autoNode,omitempty"`
- Configuration *ConfigurationStatusApplyConfiguration `json:"configuration,omitempty"`
+ Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
+ Ready *bool `json:"ready,omitempty"`
+ Initialized *bool `json:"initialized,omitempty"`
+ ExternalManagedControlPlane *bool `json:"externalManagedControlPlane,omitempty"`
+ ControlPlaneEndpoint *APIEndpointApplyConfiguration `json:"controlPlaneEndpoint,omitempty"`
+ OAuthCallbackURLTemplate *string `json:"oauthCallbackURLTemplate,omitempty"`
+ ControlPlaneVersion *ControlPlaneVersionStatusApplyConfiguration `json:"controlPlaneVersion,omitempty"`
+ VersionStatus *ClusterVersionStatusApplyConfiguration `json:"versionStatus,omitempty"`
+ Version *string `json:"version,omitempty"`
+ ReleaseImage *string `json:"releaseImage,omitempty"`
+ LastReleaseImageTransitionTime *metav1.Time `json:"lastReleaseImageTransitionTime,omitempty"`
+ KubeConfig *KubeconfigSecretRefApplyConfiguration `json:"kubeConfig,omitempty"`
+ CustomKubeconfig *KubeconfigSecretRefApplyConfiguration `json:"customKubeconfig,omitempty"`
+ KubeadminPassword *corev1.LocalObjectReference `json:"kubeadminPassword,omitempty"`
+ Platform *PlatformStatusApplyConfiguration `json:"platform,omitempty"`
+ NodeCount *int `json:"nodeCount,omitempty"`
+ AutoNode *AutoNodeStatusApplyConfiguration `json:"autoNode,omitempty"`
+ Configuration *ConfigurationStatusApplyConfiguration `json:"configuration,omitempty"`
+ Initialization *HostedControlPlaneInitializationStatusApplyConfiguration `json:"initialization,omitempty"`
}
// HostedControlPlaneStatusApplyConfiguration constructs a declarative configuration of the HostedControlPlaneStatus type for use with
@@ -200,3 +201,11 @@ func (b *HostedControlPlaneStatusApplyConfiguration) WithConfiguration(value *Co
b.Configuration = value
return b
}
+
+// WithInitialization sets the Initialization field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Initialization field is set to the value of the last call.
+func (b *HostedControlPlaneStatusApplyConfiguration) WithInitialization(value *HostedControlPlaneInitializationStatusApplyConfiguration) *HostedControlPlaneStatusApplyConfiguration {
+ b.Initialization = value
+ return b
+}
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index 5464e88f8024..231d2ff71112 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -241,6 +241,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.HostedClusterStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("HostedControlPlane"):
return &hypershiftv1beta1.HostedControlPlaneApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("HostedControlPlaneInitializationStatus"):
+ return &hypershiftv1beta1.HostedControlPlaneInitializationStatusApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("HostedControlPlaneSpec"):
return &hypershiftv1beta1.HostedControlPlaneSpecApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("HostedControlPlaneStatus"):
diff --git a/cmd/cluster/core/dump.go b/cmd/cluster/core/dump.go
index 5c5536954787..d7a5e7148c52 100644
--- a/cmd/cluster/core/dump.go
+++ b/cmd/cluster/core/dump.go
@@ -56,7 +56,7 @@ import (
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
capiopenstackv1alpha1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha1"
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
karpenterv1 "sigs.k8s.io/karpenter/pkg/apis/v1"
secretsstorev1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 798d4f0664f8..d41d1d84459d 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -8743,6 +8743,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index 5fd583a45ffa..1724b36a9183 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -7403,6 +7403,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 25068f5cf7f6..7b965b426a44 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -8603,6 +8603,22 @@ spec:
is managed by an external service.
https://github.com/kubernetes-sigs/cluster-api/blob/65e5385bffd71bf4aad3cf34a537f11b217c7fab/controllers/machine_controller.go#L468
type: boolean
+ initialization:
+ description: |-
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ minProperties: 1
+ properties:
+ controlPlaneInitialized:
+ default: false
+ description: |-
+ controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ Once this condition is marked true, its value is never changed. See the Ready condition for an
+ indication of the current readiness of the cluster's control plane.
+ This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ type: boolean
+ type: object
initialized:
default: false
description: |-
diff --git a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
index 5861a1fda10d..69a848bbec04 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/hostedcontrolplane_controller.go
@@ -236,7 +236,6 @@ func (r *HostedControlPlaneReconciler) SetupWithManager(mgr ctrl.Manager, create
}
func (r *HostedControlPlaneReconciler) registerComponents(hcp *hyperv1.HostedControlPlane) {
-
r.components = append(r.components,
pkioperatorv2.NewComponent(r.CertRotationScale),
etcdv2.NewComponent(),
@@ -679,6 +678,11 @@ func (r *HostedControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
hostedControlPlane.Status.Initialized = true
+ // Set status.initialization.controlPlaneInitialized for CAPI 1.11 v1beta2 contract.
+ // CAPI reads this field from the ControlPlane provider object to determine if the
+ // control plane is initialized (ControlPlaneInitialized condition on the CAPI Cluster).
+ hostedControlPlane.Status.Initialization.ControlPlaneInitialized = ptr.To(true)
+
meta.SetStatusCondition(&hostedControlPlane.Status.Conditions, util.GenerateReconciliationActiveCondition(hostedControlPlane.Spec.PausedUntil, hostedControlPlane.Generation))
// Always update status based on the current state of the world.
if err := r.Client.Status().Patch(ctx, hostedControlPlane, client.MergeFromWithOptions(originalHostedControlPlane, client.MergeFromWithOptimisticLock{})); err != nil {
diff --git a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go
index 91baf82a8bea..c42acf71c166 100644
--- a/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go
+++ b/control-plane-operator/controllers/hostedcontrolplane/v2/kas/kubeconfig.go
@@ -18,7 +18,7 @@ import (
clientcmd "k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/control-plane-operator/hostedclusterconfigoperator/api/scheme.go b/control-plane-operator/hostedclusterconfigoperator/api/scheme.go
index e45e1efcc4a9..dd7fd922de5e 100644
--- a/control-plane-operator/hostedclusterconfigoperator/api/scheme.go
+++ b/control-plane-operator/hostedclusterconfigoperator/api/scheme.go
@@ -26,7 +26,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
snapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader.go b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader.go
index b633420098a0..1b8b7df013a2 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader.go
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -690,7 +690,7 @@ func getNodesForMachineSet(ctx context.Context, c client.Reader, hostedClusterCl
var nodes []*corev1.Node
nodeToMachine := make(map[string]*capiv1.Machine)
for i, machine := range machineSetOwnedMachines {
- if machine.Status.NodeRef != nil {
+ if machine.Status.NodeRef.IsDefined() {
node := &corev1.Node{}
if err := hostedClusterClient.Get(ctx, client.ObjectKey{Name: machine.Status.NodeRef.Name}, node); err != nil {
return nil, nil, fmt.Errorf("error getting node: %w", err)
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/setup.go b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/setup.go
index 4be8a2dd110c..7db84b423a93 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/setup.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/setup.go
@@ -8,7 +8,7 @@ import (
corev1 "k8s.io/api/core/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine.go b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine.go
index 281d87dee56a..121cc1668ff5 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine.go
@@ -18,7 +18,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/setup.go b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/setup.go
index 03a6fd056368..74bb1d0a09ad 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/setup.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/setup.go
@@ -14,7 +14,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/node/node.go b/control-plane-operator/hostedclusterconfigoperator/controllers/node/node.go
index 0b5890570824..fa127dba0b26 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/node/node.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/node/node.go
@@ -15,7 +15,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation.go b/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation.go
index fd096d21af1b..55a22c4fab43 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation.go
@@ -9,7 +9,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md
index d70c1b359e8d..f6f3e64d2acd 100644
--- a/docs/content/reference/aggregated-docs.md
+++ b/docs/content/reference/aggregated-docs.md
@@ -45315,6 +45315,41 @@ are ephemeral and may be deleted by retention policies.
+###HostedControlPlaneInitializationStatus { #hypershift.openshift.io/v1beta1.HostedControlPlaneInitializationStatus }
+
+(Appears on:
+HostedControlPlaneStatus)
+
+
+
HostedControlPlaneInitializationStatus provides observations of the HostedControlPlane initialization process.
+This satisfies the CAPI v1beta2 ControlPlane provider contract:
+https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1361-L1379
+
+
###HostedControlPlaneSpec { #hypershift.openshift.io/v1beta1.HostedControlPlaneSpec }
HostedControlPlaneSpec defines the desired state of HostedControlPlane
@@ -46101,6 +46136,22 @@ ConfigurationStatus
configuration contains the cluster configuration status of the HostedCluster
+
+
+initialization,omitzero
+
+
+HostedControlPlaneInitializationStatus
+
+
+ |
+
+(Optional)
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+This satisfies the CAPI v1beta2 ControlPlane provider contract:
+https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ |
+
###IBMCloudKMSAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSAuthSpec }
diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md
index fb4fb96c1b20..62080699471e 100644
--- a/docs/content/reference/api.md
+++ b/docs/content/reference/api.md
@@ -9630,6 +9630,41 @@ are ephemeral and may be deleted by retention policies.
+###HostedControlPlaneInitializationStatus { #hypershift.openshift.io/v1beta1.HostedControlPlaneInitializationStatus }
+
+(Appears on:
+HostedControlPlaneStatus)
+
+
+
HostedControlPlaneInitializationStatus provides observations of the HostedControlPlane initialization process.
+This satisfies the CAPI v1beta2 ControlPlane provider contract:
+https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1361-L1379
+
+
###HostedControlPlaneSpec { #hypershift.openshift.io/v1beta1.HostedControlPlaneSpec }
HostedControlPlaneSpec defines the desired state of HostedControlPlane
@@ -10416,6 +10451,22 @@ ConfigurationStatus
configuration contains the cluster configuration status of the HostedCluster
+
+
+initialization,omitzero
+
+
+HostedControlPlaneInitializationStatus
+
+
+ |
+
+(Optional)
+ initialization contains fields that track the status of the initialization of the HostedControlPlane.
+This satisfies the CAPI v1beta2 ControlPlane provider contract:
+https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
+ |
+
###IBMCloudKMSAuthSpec { #hypershift.openshift.io/v1beta1.IBMCloudKMSAuthSpec }
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index f7c2deac532f..381bfd6fc297 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -100,7 +100,7 @@ import (
"k8s.io/utils/clock"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -1866,6 +1866,17 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to reconcile capi cluster: %w", err)
}
+ // Patch InfrastructureProvisioned on the CAPI Cluster status once infrastructure
+ // is confirmed ready. This is done via a dedicated Status patch (not in
+ // reconcileCAPICluster) to keep spec and status concerns separate.
+ // Gate on HCP.InfrastructureReady to match CAPI 1.10 timing where CAPA set
+ // AWSCluster.status.ready only after infrastructure was verified, preventing
+ // premature control plane convergence that breaks e2e timing assumptions.
+ if hcp != nil && meta.IsStatusConditionTrue(hcp.Status.Conditions, string(hyperv1.InfrastructureReady)) {
+ if err := patchInfrastructureInitializationProvisioned(ctx, r.Client, capiCluster); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to patch CAPI cluster InfrastructureProvisioned: %w", err)
+ }
+ }
}
// Reconcile the monitoring dashboard if configured
@@ -2943,11 +2954,36 @@ func reconcilecontrolPlaneOperatorIngressOperatorRoleBinding(binding *rbacv1.Rol
return nil
}
+// patchInfrastructureInitializationProvisioned sets InfrastructureProvisioned=True on
+// the CAPI Cluster status via a dedicated Status patch. For externally managed infra
+// (ManagedByAnnotation="external"), CAPI skips InfrastructureCluster reconciliation so
+// it cannot determine infra readiness itself. HyperShift fulfills this part of the CAPI
+// contract here, gated on HCP.InfrastructureReady=True.
+func patchInfrastructureInitializationProvisioned(ctx context.Context, c client.Client, capiCluster *capiv1.Cluster) error {
+ if ptr.Deref(capiCluster.Status.Initialization.InfrastructureProvisioned, false) {
+ return nil
+ }
+ original := capiCluster.DeepCopy()
+ capiCluster.Status.Initialization.InfrastructureProvisioned = ptr.To(true)
+ return c.Status().Patch(ctx, capiCluster, client.MergeFrom(original))
+}
+
func reconcileCAPICluster(cluster *capiv1.Cluster, hcluster *hyperv1.HostedCluster, hcp *hyperv1.HostedControlPlane, infraCR client.Object) error {
+ // Note: InfrastructureProvisioned is NOT set here. It is managed by
+ // patchInfrastructureInitializationProvisioned which does a dedicated Status
+ // patch gated on HCP.InfrastructureReady=True. This preserves CAPI 1.10
+ // timing semantics and keeps this function focused on spec-only changes.
+ // Note: ControlPlaneInitialized is intentionally NOT set here. CAPI's cluster
+ // controller will set it naturally when HCP.Status.Initialized=True (via v1beta1
+ // contract reading status.initialized). This preserves CAPI 1.10 timing where
+ // machines were only created after the guest cluster bootstrap RBAC was set up by
+ // HCCO. Setting it unconditionally caused machines to boot before HCCO had finished
+ // configuring the guest cluster, resulting in bootstrap authentication failures.
+
// We only create this resource once and then let CAPI own it
if !cluster.CreationTimestamp.IsZero() {
// make sure cluster is not paused.
- cluster.Spec.Paused = false
+ cluster.Spec.Paused = ptr.To(false)
return nil
}
infraCRGVK, err := apiutil.GVKForObject(infraCR, api.Scheme)
@@ -2960,17 +2996,15 @@ func reconcileCAPICluster(cluster *capiv1.Cluster, hcluster *hyperv1.HostedClust
}
cluster.Spec = capiv1.ClusterSpec{
ControlPlaneEndpoint: capiv1.APIEndpoint{},
- ControlPlaneRef: &corev1.ObjectReference{
- APIVersion: "hypershift.openshift.io/v1beta1",
- Kind: "HostedControlPlane",
- Namespace: hcp.Namespace,
- Name: hcp.Name,
+ ControlPlaneRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: "hypershift.openshift.io",
+ Kind: "HostedControlPlane",
+ Name: hcp.Name,
},
- InfrastructureRef: &corev1.ObjectReference{
- APIVersion: infraCRGVK.GroupVersion().String(),
- Kind: infraCRGVK.Kind,
- Namespace: infraCR.GetNamespace(),
- Name: infraCR.GetName(),
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: infraCRGVK.Group,
+ Kind: infraCRGVK.Kind,
+ Name: infraCR.GetName(),
},
}
@@ -2992,8 +3026,8 @@ func pauseCAPICluster(ctx context.Context, c client.Client, hc *hyperv1.HostedCl
return nil
}
- if capiCluster.Spec.Paused != paused {
- capiCluster.Spec.Paused = paused
+ if ptr.Deref(capiCluster.Spec.Paused, false) != paused {
+ capiCluster.Spec.Paused = ptr.To(paused)
if err := c.Update(ctx, capiCluster); err != nil {
return fmt.Errorf("failed to update CAPI Cluster: %w", err)
}
@@ -3006,7 +3040,7 @@ func reconcileCAPIManagerClusterRole(role *rbacv1.ClusterRole) error {
{
APIGroups: []string{"apiextensions.k8s.io"},
Resources: []string{"customresourcedefinitions"},
- Verbs: []string{"get", "list", "watch"},
+ Verbs: []string{"get", "list", "patch", "watch"},
},
}
return nil
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_webhook.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_webhook.go
index 3b32c6adc86c..21a667f3ff37 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_webhook.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_webhook.go
@@ -25,8 +25,7 @@ import (
"github.com/go-logr/logr"
)
-type hostedClusterDefaulter struct {
-}
+type hostedClusterDefaulter struct{}
type nodePoolDefaulter struct {
client client.Client
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent.go b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent.go
index 6f116cd98131..f4c669f4a15f 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent.go
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -35,8 +35,8 @@ type Agent struct{}
func (p Agent) ReconcileCAPIInfraCR(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string, apiEndpoint hyperv1.APIEndpoint) (client.Object, error) {
-
+ controlPlaneNamespace string, apiEndpoint hyperv1.APIEndpoint,
+) (client.Object, error) {
// Ensure we create the agentCluster only after ignition endpoint exists
// so AgentClusterInstall is only created with the right ign to boot machines.
// https://bugzilla.redhat.com/show_bug.cgi?id=2097895
@@ -135,8 +135,8 @@ func (p Agent) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _ *hy
// TODO add a new method to Platform interface?
func (p Agent) ReconcileCredentials(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
-
+ controlPlaneNamespace string,
+) error {
roleBinding := &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Namespace: hcluster.Spec.Platform.Agent.AgentNamespace,
@@ -166,7 +166,8 @@ func (p Agent) ReconcileCredentials(ctx context.Context, c client.Client, create
func (Agent) ReconcileSecretEncryption(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
return nil
}
@@ -194,9 +195,10 @@ func reconcileAgentCluster(agentCluster *agentv1.AgentCluster, ignEndpoint, cont
caSecret := ignitionserver.IgnitionCACertSecret(controlPlaneNamespace)
agentCluster.Spec.IgnitionEndpoint = &agentv1.IgnitionEndpoint{
Url: "https://" + ignEndpoint + "/ignition",
- CaCertificateReference: &agentv1.CaCertificateReference{Name: caSecret.Name, Namespace: caSecret.Namespace}}
+ CaCertificateReference: &agentv1.CaCertificateReference{Name: caSecret.Name, Namespace: caSecret.Namespace},
+ }
- agentCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ agentCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
@@ -206,7 +208,8 @@ func reconcileAgentCluster(agentCluster *agentv1.AgentCluster, ignEndpoint, cont
func (Agent) DeleteCredentials(ctx context.Context, c client.Client,
hc *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
if _, err := k8sutil.DeleteIfNeeded(ctx, c, &rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("%s-%s", CredentialsRBACPrefix, controlPlaneNamespace), Namespace: hc.Spec.Platform.Agent.AgentNamespace}}); err != nil {
return fmt.Errorf("failed to clean up CAPI provider rolebinding: %w", err)
}
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
index cbf448d50a75..ca040656d58a 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
@@ -19,7 +19,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go b/hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go
index ac588320f15e..b4ea13ca0f69 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go
@@ -22,7 +22,8 @@ import (
"k8s.io/utils/ptr"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -119,7 +120,7 @@ func (p AWS) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, hcp *hy
featureGates = append(featureGates, "ROSA=false")
}
- defaultMode := int32(0640)
+ defaultMode := int32(0o640)
deploymentSpec := &appsv1.DeploymentSpec{
Replicas: ptr.To[int32](1),
Template: corev1.PodTemplateSpec{
@@ -211,7 +212,8 @@ func (p AWS) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, hcp *hy
Value: "true",
},
},
- Args: []string{"--namespace", "$(MY_NAMESPACE)",
+ Args: []string{
+ "--namespace", "$(MY_NAMESPACE)",
"--v=4",
"--leader-elect=true",
fmt.Sprintf("--feature-gates=%s", strings.Join(featureGates, ",")),
@@ -288,7 +290,8 @@ func buildAWSWebIdentityCredentials(roleArn, region string) (string, error) {
func (p AWS) ReconcileCredentials(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
// TODO (alberto): consider moving this reconciliation logic down to the CPO.
// this is not trivial as the CPO deployment itself needs the secret with the ControlPlaneOperatorARN
var errs []error
@@ -340,7 +343,8 @@ func (p AWS) ReconcileCredentials(ctx context.Context, c client.Client, createOr
func (AWS) ReconcileSecretEncryption(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
return nil
}
@@ -425,7 +429,7 @@ func reconcileAWSCluster(awsCluster *capiaws.AWSCluster, hcluster *hyperv1.Hoste
// Set the values for upper level controller
awsCluster.Status.Ready = true
- awsCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ awsCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/azure/azure.go b/hypershift-operator/controllers/hostedcluster/internal/platform/azure/azure.go
index 6d633c16e840..2e5e2faa1a0f 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/azure/azure.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/azure/azure.go
@@ -27,7 +27,8 @@ import (
"k8s.io/utils/ptr"
capiazure "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/blang/semver"
@@ -97,7 +98,7 @@ func (a Azure) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _ *hy
if override, ok := hcluster.Annotations[hyperv1.ClusterAPIAzureProviderImage]; ok {
image = override
}
- defaultMode := int32(0640)
+ defaultMode := int32(0o640)
deploymentSpec := &appsv1.DeploymentSpec{
Replicas: ptr.To[int32](1),
Template: corev1.PodTemplateSpec{
@@ -376,7 +377,7 @@ func reconcileAzureCluster(azureCluster *capiazure.AzureCluster, hcluster *hyper
azureCluster.Spec.NetworkSpec.NodeOutboundLB.Name = hcluster.Spec.InfraID
azureCluster.Spec.NetworkSpec.NodeOutboundLB.BackendPool.Name = hcluster.Spec.InfraID
- azureCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ azureCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go b/hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go
index 683566e2254a..66ee4e7b9278 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/gcp/gcp.go
@@ -36,7 +36,8 @@ import (
"k8s.io/utils/ptr"
capigcp "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/blang/semver"
@@ -162,7 +163,7 @@ func (p GCP) reconcileGCPCluster(gcpCluster *capigcp.GCPCluster, hcluster *hyper
}
// Set control plane endpoint (following AWS pattern)
- gcpCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ gcpCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
@@ -273,7 +274,7 @@ func (p GCP) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _ *hype
// buildVolumes creates all volumes needed for CAPG deployment including
// credentials and webhook certificates.
func (p GCP) buildVolumes(_ *hyperv1.HostedCluster) []corev1.Volume {
- defaultMode := int32(0640)
+ defaultMode := int32(0o640)
return []corev1.Volume{
{
Name: "capi-webhooks-tls",
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud.go b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud.go
index 55f4ec11ee43..12aa812b0cb0 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud.go
@@ -15,7 +15,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -24,7 +25,8 @@ type IBMCloud struct{}
func (p IBMCloud) ReconcileCAPIInfraCR(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
controlPlaneNamespace string,
- apiEndpoint hyperv1.APIEndpoint) (client.Object, error) {
+ apiEndpoint hyperv1.APIEndpoint,
+) (client.Object, error) {
// TODO: will adjust reconcile for non-upi platforms when CAPI components ready
if hcluster.Spec.Platform.IBMCloud != nil && (hcluster.Spec.Platform.IBMCloud.ProviderType == configv1.IBMCloudProviderTypeUPI ||
hcluster.Spec.Platform.IBMCloud.ProviderType == configv1.IBMCloudProviderTypeClassic || hcluster.Spec.Platform.IBMCloud.ProviderType == configv1.IBMCloudProviderTypeVPC) {
@@ -44,7 +46,7 @@ func (p IBMCloud) ReconcileCAPIInfraCR(ctx context.Context, c client.Client, cre
// Set the values for upper level controller
ibmCluster.Status.Ready = true
- ibmCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ ibmCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
@@ -62,13 +64,15 @@ func (p IBMCloud) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _
func (p IBMCloud) ReconcileCredentials(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
return nil
}
func (IBMCloud) ReconcileSecretEncryption(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
if hcluster.Spec.SecretEncryption.KMS.IBMCloud == nil {
return fmt.Errorf("ibm kms metadata nil")
}
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
index 7d841db0b5fc..542ebec5b9f5 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
@@ -13,7 +13,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt.go b/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt.go
index a536ac1df6a2..c2d0777e75fa 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt.go
@@ -18,7 +18,7 @@ import (
"k8s.io/utils/ptr"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
cdicore "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack.go b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack.go
index 523b81a6f342..d57552209570 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack.go
@@ -20,7 +20,7 @@ import (
"k8s.io/utils/ptr"
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/blang/semver"
@@ -51,7 +51,8 @@ func New(capiProviderImage string, orcImage string, payloadVersion *semver.Versi
}
func (a OpenStack) ReconcileCAPIInfraCR(ctx context.Context, client client.Client, createOrUpdate upsert.CreateOrUpdateFN, hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string, apiEndpoint hyperv1.APIEndpoint) (client.Object, error) {
+ controlPlaneNamespace string, apiEndpoint hyperv1.APIEndpoint,
+) (client.Object, error) {
openStackCluster := &capo.OpenStackCluster{
ObjectMeta: metav1.ObjectMeta{
Name: hcluster.Name,
@@ -87,7 +88,7 @@ func reconcileOpenStackClusterSpec(hcluster *hyperv1.HostedCluster, openStackClu
openStackPlatform := hcluster.Spec.Platform.OpenStack
- openStackClusterSpec.ControlPlaneEndpoint = &capiv1.APIEndpoint{
+ openStackClusterSpec.ControlPlaneEndpoint = &capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
@@ -190,7 +191,7 @@ func (a OpenStack) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _
orcImage = override
}
allowPrivilegeEscalation := false
- defaultMode := int32(0640)
+ defaultMode := int32(0o640)
deploymentSpec := appsv1.DeploymentSpec{
Replicas: ptr.To[int32](1),
Template: corev1.PodTemplateSpec{
@@ -277,7 +278,8 @@ func (a OpenStack) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _
},
},
}},
- }},
+ },
+ },
}
// Add the ORC manager container if the payload version is 4.19 or later
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
index 7196d200d50d..8c495a567b1f 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
@@ -15,7 +15,6 @@ import (
"k8s.io/utils/ptr"
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"github.com/blang/semver"
"github.com/google/go-cmp/cmp"
@@ -54,9 +53,11 @@ func TestReconcileOpenStackCluster(t *testing.T) {
AllocationPools: []hyperv1.AllocationPool{{
Start: "10.0.0.1",
End: "10.0.0.10",
- }}}},
+ }},
+ }},
NetworkMTU: ptr.To(1500),
- }},
+ },
+ },
},
},
expectedOpenStackClusterSpec: capo.OpenStackClusterSpec{
@@ -64,13 +65,15 @@ func TestReconcileOpenStackCluster(t *testing.T) {
Name: "openstack-credentials",
CloudName: "openstack",
},
- ManagedSubnets: []capo.SubnetSpec{{
- CIDR: "10.0.0.0/24",
- DNSNameservers: []string{"1.1.1.1"},
- AllocationPools: []capo.AllocationPool{{
- Start: "10.0.0.1",
- End: "10.0.0.10",
- }}},
+ ManagedSubnets: []capo.SubnetSpec{
+ {
+ CIDR: "10.0.0.0/24",
+ DNSNameservers: []string{"1.1.1.1"},
+ AllocationPools: []capo.AllocationPool{{
+ Start: "10.0.0.1",
+ End: "10.0.0.10",
+ }},
+ },
},
NetworkMTU: ptr.To(1500),
ControlPlaneEndpoint: &capiv1.APIEndpoint{
@@ -108,7 +111,10 @@ func TestReconcileOpenStackCluster(t *testing.T) {
Subnets: []hyperv1.SubnetParam{
{ID: ptr.To(subnetID)},
},
- }}}},
+ },
+ },
+ },
+ },
expectedOpenStackClusterSpec: capo.OpenStackClusterSpec{
IdentityRef: capo.OpenStackIdentityReference{
Name: "openstack-credentials",
@@ -149,7 +155,8 @@ func TestReconcileOpenStackCluster(t *testing.T) {
Filter: &hyperv1.NetworkFilter{
FilterByNeutronTags: hyperv1.FilterByNeutronTags{
Tags: []hyperv1.NeutronTag{"test"},
- }},
+ },
+ },
},
Subnets: []hyperv1.SubnetParam{
{Filter: &hyperv1.SubnetFilter{
@@ -159,7 +166,10 @@ func TestReconcileOpenStackCluster(t *testing.T) {
}},
},
Tags: []string{"hcp-id=123"},
- }}}},
+ },
+ },
+ },
+ },
expectedOpenStackClusterSpec: capo.OpenStackClusterSpec{
IdentityRef: capo.OpenStackIdentityReference{
Name: "openstack-credentials",
@@ -176,7 +186,8 @@ func TestReconcileOpenStackCluster(t *testing.T) {
Filter: &capo.NetworkFilter{
FilterByNeutronTags: capo.FilterByNeutronTags{
Tags: []capo.NeutronTag{"test"},
- }},
+ },
+ },
},
ControlPlaneEndpoint: &capiv1.APIEndpoint{
Host: "api-endpoint",
@@ -204,7 +215,8 @@ func TestReconcileOpenStackCluster(t *testing.T) {
Filter: &hyperv1.NetworkFilter{
FilterByNeutronTags: hyperv1.FilterByNeutronTags{
Tags: []hyperv1.NeutronTag{"test"},
- }},
+ },
+ },
},
Subnets: []hyperv1.SubnetParam{
{Filter: &hyperv1.SubnetFilter{
@@ -213,7 +225,10 @@ func TestReconcileOpenStackCluster(t *testing.T) {
},
}},
},
- }}}},
+ },
+ },
+ },
+ },
expectedOpenStackClusterSpec: capo.OpenStackClusterSpec{
IdentityRef: capo.OpenStackIdentityReference{
Name: "openstack-credentials",
@@ -278,7 +293,7 @@ func TestCAPIProviderDeploymentSpec(t *testing.T) {
Name: "capi-webhooks-tls",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- DefaultMode: ptr.To[int32](0640),
+ DefaultMode: ptr.To[int32](0o640),
SecretName: "capi-webhooks-tls",
},
},
@@ -287,7 +302,7 @@ func TestCAPIProviderDeploymentSpec(t *testing.T) {
Name: "svc-kubeconfig",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- DefaultMode: ptr.To[int32](0640),
+ DefaultMode: ptr.To[int32](0o640),
SecretName: "service-network-admin-kubeconfig",
},
},
@@ -386,7 +401,7 @@ func TestCAPIProviderDeploymentSpec(t *testing.T) {
Name: "capi-webhooks-tls",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- DefaultMode: ptr.To[int32](0640),
+ DefaultMode: ptr.To[int32](0o640),
SecretName: "capi-webhooks-tls",
},
},
@@ -395,7 +410,7 @@ func TestCAPIProviderDeploymentSpec(t *testing.T) {
Name: "svc-kubeconfig",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- DefaultMode: ptr.To[int32](0640),
+ DefaultMode: ptr.To[int32](0o640),
SecretName: "service-network-admin-kubeconfig",
},
},
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/powervs/powervs.go b/hypershift-operator/controllers/hostedcluster/internal/platform/powervs/powervs.go
index c0f1215b731b..0f71137ebf39 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/powervs/powervs.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/powervs/powervs.go
@@ -18,7 +18,8 @@ import (
"k8s.io/utils/ptr"
capiibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -33,14 +34,15 @@ type PowerVS struct {
}
func (p PowerVS) DeleteCredentials(ctx context.Context, c client.Client, hcluster *hyperv1.HostedCluster, controlPlaneNamespace string) error {
- //TODO(mkumatag): implement me
+ // TODO(mkumatag): implement me
return nil
}
func (p PowerVS) ReconcileCAPIInfraCR(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
controlPlaneNamespace string,
- apiEndpoint hyperv1.APIEndpoint) (client.Object, error) {
+ apiEndpoint hyperv1.APIEndpoint,
+) (client.Object, error) {
ibmCluster := &capiibmv1.IBMPowerVSCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
@@ -57,7 +59,7 @@ func (p PowerVS) ReconcileCAPIInfraCR(ctx context.Context, c client.Client, crea
// Set the values for upper level controller
ibmCluster.Status.Ready = true
- ibmCluster.Spec.ControlPlaneEndpoint = capiv1.APIEndpoint{
+ ibmCluster.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
Host: apiEndpoint.Host,
Port: apiEndpoint.Port,
}
@@ -146,7 +148,8 @@ func (p PowerVS) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _ *
},
},
Command: []string{"/bin/cluster-api-provider-ibmcloud-controller-manager"},
- Args: []string{"--namespace", "$(MY_NAMESPACE)",
+ Args: []string{
+ "--namespace", "$(MY_NAMESPACE)",
"--v=4",
"--leader-elect=true",
"--provider-id-fmt=v2",
@@ -184,7 +187,8 @@ func (p PowerVS) CAPIProviderDeploymentSpec(hcluster *hyperv1.HostedCluster, _ *
func (p PowerVS) ReconcileCredentials(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
// Reconcile the platform provider cloud controller credentials secret by resolving
// the reference from the HostedCluster and syncing the secret in the control
// plane namespace.
@@ -365,7 +369,8 @@ func (p PowerVS) ReconcileCredentials(ctx context.Context, c client.Client, crea
func (PowerVS) ReconcileSecretEncryption(ctx context.Context, c client.Client, createOrUpdate upsert.CreateOrUpdateFN,
hcluster *hyperv1.HostedCluster,
- controlPlaneNamespace string) error {
+ controlPlaneNamespace string,
+) error {
return nil
}
diff --git a/hypershift-operator/controllers/manifests/controlplaneoperator/manifests.go b/hypershift-operator/controllers/manifests/controlplaneoperator/manifests.go
index f4e618338103..bf60e6108a9f 100644
--- a/hypershift-operator/controllers/manifests/controlplaneoperator/manifests.go
+++ b/hypershift-operator/controllers/manifests/controlplaneoperator/manifests.go
@@ -8,7 +8,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
prometheusoperatorv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
)
diff --git a/hypershift-operator/controllers/nodepool/aws.go b/hypershift-operator/controllers/nodepool/aws.go
index df5223ff2a9f..b1b6db3c6f8d 100644
--- a/hypershift-operator/controllers/nodepool/aws.go
+++ b/hypershift-operator/controllers/nodepool/aws.go
@@ -13,7 +13,7 @@ import (
"k8s.io/utils/ptr"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
diff --git a/hypershift-operator/controllers/nodepool/azure_test.go b/hypershift-operator/controllers/nodepool/azure_test.go
index 471ac81a4988..33bf09b283e8 100644
--- a/hypershift-operator/controllers/nodepool/azure_test.go
+++ b/hypershift-operator/controllers/nodepool/azure_test.go
@@ -15,7 +15,7 @@ import (
"k8s.io/utils/ptr"
capiazure "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
- clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"github.com/coreos/stream-metadata-go/stream"
"github.com/coreos/stream-metadata-go/stream/rhcos"
diff --git a/hypershift-operator/controllers/nodepool/capi.go b/hypershift-operator/controllers/nodepool/capi.go
index 248c7fc468b0..9e9bf8bed4fa 100644
--- a/hypershift-operator/controllers/nodepool/capi.go
+++ b/hypershift-operator/controllers/nodepool/capi.go
@@ -29,7 +29,7 @@ import (
capigcp "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
@@ -245,9 +245,15 @@ func (c *CAPI) cleanupMachineTemplates(ctx context.Context, log logr.Logger, nod
ref := filtered[0].Spec.Template.Spec.InfrastructureRef
machineTemplates := new(unstructured.UnstructuredList)
- machineTemplates.SetAPIVersion(ref.APIVersion)
+ // v1beta2 ContractVersionedObjectReference has no APIVersion; reconstruct from scheme.
+ versions := api.Scheme.VersionsForGroupKind(schema.GroupKind{Group: ref.APIGroup, Kind: ref.Kind})
+ if len(versions) == 0 {
+ return fmt.Errorf("no versions registered for GroupKind %s/%s", ref.APIGroup, ref.Kind)
+ }
+ apiVersion := schema.GroupVersion{Group: ref.APIGroup, Version: versions[0].Version}.String()
+ machineTemplates.SetAPIVersion(apiVersion)
machineTemplates.SetKind(ref.Kind)
- if err := c.Client.List(ctx, machineTemplates, client.InNamespace(ref.Namespace)); err != nil {
+ if err := c.Client.List(ctx, machineTemplates, client.InNamespace(controlPlaneNamespace)); err != nil {
return fmt.Errorf("failed to list MachineTemplates: %w", err)
}
@@ -440,15 +446,16 @@ func (c *CAPI) reconcileMachineDeployment(ctx context.Context, log logr.Logger,
Bootstrap: capiv1.Bootstrap{
DataSecretName: machineDeployment.Spec.Template.Spec.Bootstrap.DataSecretName,
},
- InfrastructureRef: corev1.ObjectReference{
- Kind: gvk.Kind,
- APIVersion: gvk.GroupVersion().String(),
- Namespace: machineTemplateCR.GetNamespace(),
- Name: machineDeployment.Spec.Template.Spec.InfrastructureRef.Name,
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: gvk.Kind,
+ APIGroup: gvk.Group,
+ Name: machineDeployment.Spec.Template.Spec.InfrastructureRef.Name,
+ },
+ Version: machineDeployment.Spec.Template.Spec.Version,
+ Deletion: capiv1.MachineDeletionSpec{
+ NodeDrainTimeoutSeconds: durationToSeconds(nodePool.Spec.NodeDrainTimeout),
+ NodeVolumeDetachTimeoutSeconds: durationToSeconds(nodePool.Spec.NodeVolumeDetachTimeout),
},
- Version: machineDeployment.Spec.Template.Spec.Version,
- NodeDrainTimeout: nodePool.Spec.NodeDrainTimeout,
- NodeVolumeDetachTimeout: nodePool.Spec.NodeVolumeDetachTimeout,
},
}
@@ -463,10 +470,9 @@ func (c *CAPI) reconcileMachineDeployment(ctx context.Context, log logr.Logger,
return err
}
- machineDeployment.Spec.Strategy = &capiv1.MachineDeploymentStrategy{}
- machineDeployment.Spec.Strategy.Type = capiv1.MachineDeploymentStrategyType(nodePool.Spec.Management.Replace.Strategy)
+ machineDeployment.Spec.Rollout.Strategy.Type = capiv1.MachineDeploymentRolloutStrategyType(nodePool.Spec.Management.Replace.Strategy)
if nodePool.Spec.Management.Replace.RollingUpdate != nil {
- machineDeployment.Spec.Strategy.RollingUpdate = &capiv1.MachineRollingUpdateDeployment{
+ machineDeployment.Spec.Rollout.Strategy.RollingUpdate = capiv1.MachineDeploymentRolloutStrategyRollingUpdate{
MaxUnavailable: nodePool.Spec.Management.Replace.RollingUpdate.MaxUnavailable,
MaxSurge: nodePool.Spec.Management.Replace.RollingUpdate.MaxSurge,
}
@@ -499,13 +505,13 @@ func setMachineDeploymentFailureDomain(nodePool *hyperv1.NodePool, machineDeploy
// The CAPI provider for OpenStack uses the FailureDomain field to set the availability zone.
if nodePool.Spec.Platform.Type == hyperv1.OpenStackPlatform && nodePool.Spec.Platform.OpenStack != nil {
if nodePool.Spec.Platform.OpenStack.AvailabilityZone != "" {
- machineDeployment.Spec.Template.Spec.FailureDomain = ptr.To(nodePool.Spec.Platform.OpenStack.AvailabilityZone)
+ machineDeployment.Spec.Template.Spec.FailureDomain = nodePool.Spec.Platform.OpenStack.AvailabilityZone
}
}
// The CAPI provider for GCP uses the FailureDomain field to set the zone.
if nodePool.Spec.Platform.Type == hyperv1.GCPPlatform && nodePool.Spec.Platform.GCP != nil {
if nodePool.Spec.Platform.GCP.Zone != "" {
- machineDeployment.Spec.Template.Spec.FailureDomain = ptr.To(nodePool.Spec.Platform.GCP.Zone)
+ machineDeployment.Spec.Template.Spec.FailureDomain = nodePool.Spec.Platform.GCP.Zone
}
}
}
@@ -575,7 +581,7 @@ func (c *CAPI) propagateVersionAndTemplate(log logr.Logger, machineDeployment *c
"current", machineDeployment.Spec.Template.Spec.Bootstrap.DataSecretName,
"target", userDataSecret.Name)
- if targetVersion != ptr.Deref(machineDeployment.Spec.Template.Spec.Version, "") {
+ if targetVersion != machineDeployment.Spec.Template.Spec.Version {
log.Info("Starting version update: Propagating new version to the MachineDeployment",
"releaseImage", nodePool.Spec.Release.Image, "target", targetVersion)
}
@@ -584,7 +590,7 @@ func (c *CAPI) propagateVersionAndTemplate(log logr.Logger, machineDeployment *c
log.Info("Starting config update: Propagating new config to the MachineDeployment",
"current", nodePool.Annotations[nodePoolAnnotationCurrentConfig], "target", targetConfigHash)
}
- machineDeployment.Spec.Template.Spec.Version = &targetVersion
+ machineDeployment.Spec.Template.Spec.Version = targetVersion
machineDeployment.Spec.Template.Spec.Bootstrap.DataSecretName = ptr.To(userDataSecret.Name)
isUpdating = true
}
@@ -632,18 +638,21 @@ func (c *CAPI) reconcileMachineDeploymentStatus(log logr.Logger, machineDeployme
}
}
- nodePool.Status.Replicas = machineDeployment.Status.AvailableReplicas
- for _, cond := range machineDeployment.Status.Conditions {
- if cond.Type == capiv1.ReadyCondition {
+ nodePool.Status.Replicas = ptr.Deref(machineDeployment.Status.AvailableReplicas, 0)
+ for _, c := range machineDeployment.Status.Conditions {
+ // In CAPI v1beta2 "Ready" was replaced by "MachinesReady" (True when all machines are ready).
+ // https://github.com/kubernetes-sigs/cluster-api/issues/3486.
+ if c.Type == capiv1.MachinesReadyCondition {
reason := hyperv1.AsExpectedReason
- if cond.Reason != "" {
- reason = cond.Reason
+ if c.Reason != "" {
+ reason = c.Reason
}
+
SetStatusCondition(&nodePool.Status.Conditions, hyperv1.NodePoolCondition{
Type: hyperv1.NodePoolReadyConditionType,
- Status: cond.Status,
+ Status: corev1.ConditionStatus(c.Status),
ObservedGeneration: nodePool.Generation,
- Message: cond.Message,
+ Message: c.Message,
Reason: reason,
})
break
@@ -660,6 +669,16 @@ func taintsToJSON(taints []hyperv1.Taint) (string, error) {
return string(taintsInJSON), nil
}
+// durationToSeconds converts a *metav1.Duration to *int32 seconds.
+// CAPI v1beta2 uses integer seconds for timeouts instead of metav1.Duration.
+func durationToSeconds(d *metav1.Duration) *int32 {
+ if d == nil {
+ return nil
+ }
+ s := int32(d.Seconds())
+ return &s
+}
+
func (c *CAPI) reconcileMachineHealthCheck(ctx context.Context,
mhc *capiv1.MachineHealthCheck,
) error {
@@ -723,6 +742,8 @@ func (c *CAPI) reconcileMachineHealthCheck(ctx context.Context,
}
resourcesName := generateName(capiClusterName, nodePool.Spec.ClusterName, nodePool.GetName())
+ timeoutSec := int32(timeOut.Seconds())
+ startupSec := int32(nodeStartupTimeout.Seconds())
mhc.Spec = capiv1.MachineHealthCheckSpec{
ClusterName: capiClusterName,
Selector: metav1.LabelSelector{
@@ -730,25 +751,25 @@ func (c *CAPI) reconcileMachineHealthCheck(ctx context.Context,
resourcesName: resourcesName,
},
},
- UnhealthyConditions: []capiv1.UnhealthyCondition{
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionFalse,
- Timeout: metav1.Duration{
- Duration: timeOut,
+ Checks: capiv1.MachineHealthCheckChecks{
+ NodeStartupTimeoutSeconds: &startupSec,
+ UnhealthyNodeConditions: []capiv1.UnhealthyNodeCondition{
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionFalse,
+ TimeoutSeconds: &timeoutSec,
},
- },
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionUnknown,
- Timeout: metav1.Duration{
- Duration: timeOut,
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionUnknown,
+ TimeoutSeconds: &timeoutSec,
},
},
},
- MaxUnhealthy: &maxUnhealthy,
- NodeStartupTimeout: &metav1.Duration{
- Duration: nodeStartupTimeout,
+ Remediation: capiv1.MachineHealthCheckRemediation{
+ TriggerIf: capiv1.MachineHealthCheckRemediationTriggerIf{
+ UnhealthyLessThanOrEqualTo: &maxUnhealthy,
+ },
},
}
return nil
@@ -923,17 +944,18 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
// Keep current user data for later check.
DataSecretName: machineSet.Spec.Template.Spec.Bootstrap.DataSecretName,
},
- InfrastructureRef: corev1.ObjectReference{
- Kind: gvk.Kind,
- APIVersion: gvk.GroupVersion().String(),
- Namespace: machineTemplateCR.GetNamespace(),
- // Keep current version for later check.
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: gvk.Kind,
+ APIGroup: gvk.Group,
+ // Keep current template name for later check.
Name: machineSet.Spec.Template.Spec.InfrastructureRef.Name,
},
// Keep current version for later check.
- Version: machineSet.Spec.Template.Spec.Version,
- NodeDrainTimeout: nodePool.Spec.NodeDrainTimeout,
- NodeVolumeDetachTimeout: nodePool.Spec.NodeVolumeDetachTimeout,
+ Version: machineSet.Spec.Template.Spec.Version,
+ Deletion: capiv1.MachineDeletionSpec{
+ NodeDrainTimeoutSeconds: durationToSeconds(nodePool.Spec.NodeDrainTimeout),
+ NodeVolumeDetachTimeoutSeconds: durationToSeconds(nodePool.Spec.NodeVolumeDetachTimeout),
+ },
},
}
@@ -967,7 +989,7 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
"target", userDataSecret.Name)
// TODO (alberto): possibly compare with NodePool here instead so we don't rely on impl details to drive decisions.
- if targetVersion != ptr.Deref(machineSet.Spec.Template.Spec.Version, "") {
+ if targetVersion != machineSet.Spec.Template.Spec.Version {
log.Info("Starting version upgrade: Propagating new version to the MachineSet",
"releaseImage", nodePool.Spec.Release.Image, "target", targetVersion)
}
@@ -976,7 +998,7 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
log.Info("Starting config upgrade: Propagating new config to the MachineSet",
"current", nodePool.Annotations[nodePoolAnnotationCurrentConfig], "target", targetConfigHash)
}
- machineSet.Spec.Template.Spec.Version = &targetVersion
+ machineSet.Spec.Template.Spec.Version = targetVersion
machineSet.Spec.Template.Spec.Bootstrap.DataSecretName = ptr.To(userDataSecret.Name)
// Signal in-place upgrade request.
@@ -1032,11 +1054,11 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
}
// Bubble up AvailableReplicas and Ready condition from MachineSet.
- nodePool.Status.Replicas = machineSet.Status.AvailableReplicas
+ nodePool.Status.Replicas = ptr.Deref(machineSet.Status.AvailableReplicas, 0)
for _, c := range machineSet.Status.Conditions {
- // This condition should aggregate and summarize readiness from underlying MachineSets and Machines
+ // In CAPI v1beta2 "Ready" was replaced by "MachinesReady" (True when all machines are ready).
// https://github.com/kubernetes-sigs/cluster-api/issues/3486.
- if c.Type == capiv1.ReadyCondition {
+ if c.Type == capiv1.MachinesReadyCondition {
// this is so api server does not complain
// invalid value: \"\": status.conditions.reason in body should be at least 1 chars long"
reason := hyperv1.AsExpectedReason
@@ -1046,7 +1068,7 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
SetStatusCondition(&nodePool.Status.Conditions, hyperv1.NodePoolCondition{
Type: hyperv1.NodePoolReadyConditionType,
- Status: c.Status,
+ Status: corev1.ConditionStatus(c.Status),
ObservedGeneration: nodePool.Generation,
Message: c.Message,
Reason: reason,
@@ -1170,6 +1192,8 @@ func (c *CAPI) reconcileSpotMachineHealthCheck(_ context.Context, mhc *capiv1.Ma
timeOut := 8 * time.Minute
nodeStartupTimeout := 20 * time.Minute
+ timeoutSec := int32(timeOut.Seconds())
+ startupSec := int32(nodeStartupTimeout.Seconds())
mhc.Spec = capiv1.MachineHealthCheckSpec{
ClusterName: c.capiClusterName,
Selector: metav1.LabelSelector{
@@ -1177,25 +1201,25 @@ func (c *CAPI) reconcileSpotMachineHealthCheck(_ context.Context, mhc *capiv1.Ma
interruptibleInstanceLabel: "",
},
},
- UnhealthyConditions: []capiv1.UnhealthyCondition{
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionFalse,
- Timeout: metav1.Duration{
- Duration: timeOut,
+ Checks: capiv1.MachineHealthCheckChecks{
+ NodeStartupTimeoutSeconds: &startupSec,
+ UnhealthyNodeConditions: []capiv1.UnhealthyNodeCondition{
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionFalse,
+ TimeoutSeconds: &timeoutSec,
},
- },
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionUnknown,
- Timeout: metav1.Duration{
- Duration: timeOut,
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionUnknown,
+ TimeoutSeconds: &timeoutSec,
},
},
},
- MaxUnhealthy: &maxUnhealthy,
- NodeStartupTimeout: &metav1.Duration{
- Duration: nodeStartupTimeout,
+ Remediation: capiv1.MachineHealthCheckRemediation{
+ TriggerIf: capiv1.MachineHealthCheckRemediationTriggerIf{
+ UnhealthyLessThanOrEqualTo: &maxUnhealthy,
+ },
},
}
diff --git a/hypershift-operator/controllers/nodepool/conditions.go b/hypershift-operator/controllers/nodepool/conditions.go
index cff009e3590e..10ac12225bc4 100644
--- a/hypershift-operator/controllers/nodepool/conditions.go
+++ b/hypershift-operator/controllers/nodepool/conditions.go
@@ -20,7 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -100,17 +100,17 @@ func FindStatusCondition(conditions []hyperv1.NodePoolCondition, conditionType s
// machineConditionResult normalizes a CAPI Machine condition into a common struct.
type machineConditionResult struct {
- Status corev1.ConditionStatus
+ Status metav1.ConditionStatus
Reason string
Message string
}
// findMachineStatusCondition looks up a condition on a CAPI Machine from
-// Machine.Status.Conditions ([]capiv1.Condition).
+// Machine.Status.Conditions ([]metav1.Condition).
// Returns nil if the condition is not found.
func findMachineStatusCondition(machine *capiv1.Machine, conditionType string) *machineConditionResult {
for i := range machine.Status.Conditions {
- if string(machine.Status.Conditions[i].Type) == conditionType {
+ if machine.Status.Conditions[i].Type == conditionType {
return &machineConditionResult{
Status: machine.Status.Conditions[i].Status,
Reason: machine.Status.Conditions[i].Reason,
@@ -637,10 +637,10 @@ func (r *NodePoolReconciler) setAllNodesHealthyCondition(nodePool *hyperv1.NodeP
// NodeHealthy condition not yet reported; treat as not healthy.
status = corev1.ConditionFalse
numNotHealthy++
- mapReason := capiv1.WaitingForNodeRefReason
+ mapReason := capiv1.WaitingForNodeRefV1Beta1Reason
mapMessage := fmt.Sprintf("Machine %s: %s\n", machine.Name, mapReason)
messageMap[mapReason] = append(messageMap[mapReason], mapMessage)
- } else if condition.Status != corev1.ConditionTrue {
+ } else if condition.Status != metav1.ConditionTrue {
status = corev1.ConditionFalse
numNotHealthy++
mapReason := condition.Reason
@@ -700,10 +700,10 @@ func (r *NodePoolReconciler) setAllMachinesReadyCondition(nodePool *hyperv1.Node
// Ready condition not yet reported; treat as not ready.
status = corev1.ConditionFalse
numNotReady++
- mapReason := capiv1.WaitingForInfrastructureFallbackReason
+ mapReason := capiv1.WaitingForInfrastructureFallbackV1Beta1Reason
mapMessage := fmt.Sprintf("Machine %s: %s\n", machine.Name, mapReason)
messageMap[mapReason] = append(messageMap[mapReason], mapMessage)
- } else if readyCond.Status != corev1.ConditionTrue {
+ } else if readyCond.Status != metav1.ConditionTrue {
status = corev1.ConditionFalse
numNotReady++
infraReadyCond := findMachineStatusCondition(machine, string(capiv1.InfrastructureReadyCondition))
@@ -716,7 +716,7 @@ func (r *NodePoolReconciler) setAllMachinesReadyCondition(nodePool *hyperv1.Node
// status: "False"
// type: Ready
var mapReason, mapMessage string
- if infraReadyCond != nil && infraReadyCond.Status != corev1.ConditionTrue && !isSetupCounterCondMessage.MatchString(infraReadyCond.Message) {
+ if infraReadyCond != nil && infraReadyCond.Status != metav1.ConditionTrue && !isSetupCounterCondMessage.MatchString(infraReadyCond.Message) {
mapReason = infraReadyCond.Reason
mapMessage = fmt.Sprintf("Machine %s: %s: %s\n", machine.Name, infraReadyCond.Reason, infraReadyCond.Message)
} else {
@@ -780,7 +780,6 @@ func (r *NodePoolReconciler) setCIDRConflictCondition(nodePool *hyperv1.NodePool
if len(messages) > 0 {
message := ""
for _, entry := range messages {
-
if len(message) == 0 {
message = entry
} else if len(entry)+len(message) < maxMessageLength {
diff --git a/hypershift-operator/controllers/nodepool/gcp.go b/hypershift-operator/controllers/nodepool/gcp.go
index 50a107b210b4..87129f150116 100644
--- a/hypershift-operator/controllers/nodepool/gcp.go
+++ b/hypershift-operator/controllers/nodepool/gcp.go
@@ -12,7 +12,7 @@ import (
"k8s.io/utils/ptr"
capigcp "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/hypershift-operator/controllers/nodepool/metrics/metrics.go b/hypershift-operator/controllers/nodepool/metrics/metrics.go
index 0fb0e01c4a68..37759e15ea4c 100644
--- a/hypershift-operator/controllers/nodepool/metrics/metrics.go
+++ b/hypershift-operator/controllers/nodepool/metrics/metrics.go
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/clock"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/metrics"
diff --git a/hypershift-operator/controllers/nodepool/nodepool_controller.go b/hypershift-operator/controllers/nodepool/nodepool_controller.go
index fbbd74145794..f0463f70d70e 100644
--- a/hypershift-operator/controllers/nodepool/nodepool_controller.go
+++ b/hypershift-operator/controllers/nodepool/nodepool_controller.go
@@ -42,7 +42,7 @@ import (
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
capiazure "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/conversion"
"sigs.k8s.io/cluster-api/util/patch"
@@ -780,20 +780,18 @@ func defaultNodePoolGCPImage(specifiedArch string, releaseImage *releaseinfo.Rel
// MachineDeploymentComplete considers a MachineDeployment to be complete once all of its desired replicas
// are updated and available, and no old machines are running.
-//
-// In CAPI v1.11+, the controller writes status natively in v1beta2 and the v1beta1 status
-// fields come from conversion. The converted v1beta1 fields (especially UpdatedReplicas,
-// which maps from deprecated.v1beta1.updatedReplicas rather than the native upToDateReplicas)
-// can transiently disagree with the v1beta2 native fields. To guard against this, when the
-// v1beta1 fields indicate completion we cross-check against the authoritative v1beta2 status
-// stored in the conversion-data annotation.
func MachineDeploymentComplete(deployment *capiv1.MachineDeployment) bool {
- newStatus := &deployment.Status
- v1beta1Complete := newStatus.UpdatedReplicas == *(deployment.Spec.Replicas) &&
- newStatus.Replicas == *(deployment.Spec.Replicas) &&
- newStatus.AvailableReplicas == *(deployment.Spec.Replicas) &&
- newStatus.ObservedGeneration >= deployment.Generation
- if !v1beta1Complete {
+ desired := ptr.Deref(deployment.Spec.Replicas, 0)
+ s := &deployment.Status
+
+ // As long as storage version is v1beta1 conversion happens, causing flickering on this check.
+ // TODO(bclement): Remove conversion data check when storage version is v1beta2
+ conversionComplete := ptr.Deref(s.UpToDateReplicas, 0) == desired &&
+ ptr.Deref(s.Replicas, 0) == desired &&
+ ptr.Deref(s.AvailableReplicas, 0) == desired &&
+ s.ObservedGeneration >= deployment.Generation
+
+ if !conversionComplete {
return false
}
return machineDeploymentCompleteFromConversionData(deployment)
diff --git a/hypershift-operator/controllers/nodepool/powervs.go b/hypershift-operator/controllers/nodepool/powervs.go
index 7f2bf8ee9fb4..feb10ddbb87f 100644
--- a/hypershift-operator/controllers/nodepool/powervs.go
+++ b/hypershift-operator/controllers/nodepool/powervs.go
@@ -12,7 +12,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capipowervs "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/coreos/stream-metadata-go/stream"
diff --git a/hypershift-operator/controllers/nodepool/version.go b/hypershift-operator/controllers/nodepool/version.go
index d63ca3417daa..0b8ffeb0a395 100644
--- a/hypershift-operator/controllers/nodepool/version.go
+++ b/hypershift-operator/controllers/nodepool/version.go
@@ -7,9 +7,9 @@ import (
hyperv1 "github.com/openshift/hypershift/api/hypershift/v1beta1"
- corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
)
// versionKey is used as a map key for grouping machines by version.
@@ -53,7 +53,7 @@ func (r *NodePoolReconciler) nodeVersionsFromMachines(_ context.Context, machine
// Determine node health from CAPI NodeHealthy condition.
condition := findMachineStatusCondition(machine, string(capiv1.MachineNodeHealthyCondition))
- if condition != nil && condition.Status == corev1.ConditionTrue {
+ if condition != nil && condition.Status == metav1.ConditionTrue {
versionCounts[key].ready++
} else {
versionCounts[key].unready++
diff --git a/karpenter-operator/controllers/karpenter/karpenter_controller.go b/karpenter-operator/controllers/karpenter/karpenter_controller.go
index 218179a84f5b..dbc0567893fe 100644
--- a/karpenter-operator/controllers/karpenter/karpenter_controller.go
+++ b/karpenter-operator/controllers/karpenter/karpenter_controller.go
@@ -33,7 +33,7 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/cluster"
diff --git a/support/api/capi_types.go b/support/api/capi_types.go
index 3c6e71a4bba9..c6351cf7f216 100644
--- a/support/api/capi_types.go
+++ b/support/api/capi_types.go
@@ -9,5 +9,8 @@ import (
_ "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta1"
_ "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
_ "sigs.k8s.io/cluster-api/api/addons/v1beta1"
- _ "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ _ "sigs.k8s.io/cluster-api/api/addons/v1beta2"
+ _ "sigs.k8s.io/cluster-api/api/core/v1beta2"
+ _ "sigs.k8s.io/cluster-api/api/ipam/v1beta1"
+ _ "sigs.k8s.io/cluster-api/api/ipam/v1beta2"
)
diff --git a/support/k8sutil/resources.go b/support/k8sutil/resources.go
index ade91311e71f..0a0925d024d0 100644
--- a/support/k8sutil/resources.go
+++ b/support/k8sutil/resources.go
@@ -14,7 +14,7 @@ import (
capiibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
secretsstorev1 "sigs.k8s.io/secrets-store-csi-driver/apis/v1"
)
diff --git a/support/upsert/upsert.go b/support/upsert/upsert.go
index b181fd4fc730..292d9d368656 100644
--- a/support/upsert/upsert.go
+++ b/support/upsert/upsert.go
@@ -22,7 +22,7 @@ import (
capigcp "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
capiibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
diff --git a/test/e2e/util/util.go b/test/e2e/util/util.go
index 27359db6b2a6..9f81bc8804b0 100644
--- a/test/e2e/util/util.go
+++ b/test/e2e/util/util.go
@@ -73,7 +73,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
diff --git a/test/e2e/v2/backuprestore/cleanup.go b/test/e2e/v2/backuprestore/cleanup.go
index d33dd1b32795..4d62c531dd74 100644
--- a/test/e2e/v2/backuprestore/cleanup.go
+++ b/test/e2e/v2/backuprestore/cleanup.go
@@ -20,7 +20,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/discovery"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
index 8486514f0a18..a2dfc2449c90 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
@@ -419,6 +419,18 @@ type HostedControlPlaneStatus struct {
// configuration contains the cluster configuration status of the HostedCluster
// +optional
Configuration *ConfigurationStatus `json:"configuration,omitempty"`
+
+ // Initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ // +optional
+ // +kubebuilder:validation:MinProperties=1
+ Initialization HostedControlPlaneInitializationStatus `json:"initialization,omitzero"`
+}
+
+// HostedControlPlaneInitializationStatus defines the observed initialization state of the HostedControlPlane.
+type HostedControlPlaneInitializationStatus struct {
+ // ControlPlaneInitialized denotes whether the control plane has been initialized.
+ // +optional
+ ControlPlaneInitialized *bool `json:"controlPlaneInitialized,omitempty"`
}
// APIEndpoint represents a reachable Kubernetes API endpoint.
From 0dc9741e48122c265a9ddb14d039fd385177db46 Mon Sep 17 00:00:00 2001
From: Borja Clemente
Date: Thu, 11 Jun 2026 14:59:01 +0200
Subject: [PATCH 2/5] test(capi): update tests for CAPI v1beta2 type migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- ContractVersionedObjectReference (APIGroup instead of APIVersion, no Namespace)
- FailureDomain: *string nil → empty string
- Version: *string → string
- Status replica fields: int32 → *int32 via ptr.To
- Conditions: []capiv1.Condition → []metav1.Condition
- MHC: restructured Checks/Remediation fields
- MachineDeploymentComplete rewritten for v1beta2 native fields
- MachinePhaseFailed (deprecated) → MachinePhaseDeleting
- machineConditionResult expectations: corev1 → metav1 ConditionStatus
- Constants renamed with V1Beta1 suffix
- Fix bare v1beta2 import and misleading alias in e2e tests
Signed-off-by: Borja Clemente
---
.../controllers/globalps/globalps_test.go | 10 +-
.../inplaceupgrader/inplaceupgrader_test.go | 16 +-
.../controllers/machine/machine_test.go | 12 +-
.../controllers/node/node_test.go | 2 +-
.../spotremediation/spotremediation_test.go | 2 +-
.../hostedcluster_controller_test.go | 94 ++--
.../internal/platform/agent/agent_test.go | 3 +-
.../platform/ibmcloud/ibmcloud_test.go | 2 +-
.../platform/kubevirt/kubevirt_test.go | 2 +-
.../platform/openstack/openstack_test.go | 7 +-
.../controllers/nodepool/aws_test.go | 6 +-
.../controllers/nodepool/azure_test.go | 10 +-
.../controllers/nodepool/capi_test.go | 306 ++++++-------
.../controllers/nodepool/conditions_test.go | 6 +-
.../nodepool/nodepool_controller_test.go | 426 +++++++++---------
.../nodepool/scale_from_zero_test.go | 2 +-
.../controllers/nodepool/version_test.go | 54 +--
.../karpenter/karpenter_controller_test.go | 2 +-
test/e2e/autoscaling_test.go | 6 +-
test/e2e/nodepool_day2_tags_test.go | 2 +-
.../e2e/nodepool_kv_advanced_multinet_test.go | 4 +-
test/e2e/nodepool_osp_advanced_test.go | 6 +-
test/e2e/nodepool_rolling_upgrade_test.go | 2 +-
.../nodepool_spot_termination_handler_test.go | 2 +-
test/e2e/upgrade_hypershift_operator_test.go | 12 +-
25 files changed, 475 insertions(+), 521 deletions(-)
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/globalps/globalps_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/globalps/globalps_test.go
index e544a4533136..7e9ee0528ee8 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/globalps/globalps_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/globalps/globalps_test.go
@@ -16,7 +16,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
@@ -82,7 +82,7 @@ func TestReconcileGlobalPullSecret(t *testing.T) {
Labels: map[string]string{"machineset": "test"},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "test-node-1"},
+ NodeRef: capiv1.MachineNodeReference{Name: "test-node-1"},
},
},
},
@@ -156,7 +156,7 @@ func TestReconcileGlobalPullSecret(t *testing.T) {
Labels: map[string]string{"machineset": "test"},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "test-node-1"},
+ NodeRef: capiv1.MachineNodeReference{Name: "test-node-1"},
},
},
},
@@ -273,7 +273,7 @@ func TestReconcileGlobalPullSecret(t *testing.T) {
Labels: map[string]string{"machineset": "test"},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "test-node-1"},
+ NodeRef: capiv1.MachineNodeReference{Name: "test-node-1"},
},
},
},
@@ -325,7 +325,7 @@ func TestReconcileGlobalPullSecret(t *testing.T) {
Labels: map[string]string{"machineset": "inplace"},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "inplace-node-1"},
+ NodeRef: capiv1.MachineNodeReference{Name: "inplace-node-1"},
},
},
},
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader_test.go
index b5f9ec3f116c..e7dd0869558c 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/inplaceupgrader/inplaceupgrader_test.go
@@ -23,7 +23,7 @@ import (
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
@@ -66,7 +66,7 @@ func TestGetNodesForMachineSet(t *testing.T) {
Labels: selector,
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{
+ NodeRef: capiv1.MachineNodeReference{
Name: "test",
},
},
@@ -85,7 +85,7 @@ func TestGetNodesForMachineSet(t *testing.T) {
Labels: selector,
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{
+ NodeRef: capiv1.MachineNodeReference{
Name: "otherOwner",
},
},
@@ -106,7 +106,7 @@ func TestGetNodesForMachineSet(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{
+ NodeRef: capiv1.MachineNodeReference{
Name: "otherSelector",
},
},
@@ -877,7 +877,7 @@ func TestReconcileInPlaceUpgradeAnnotatesMachineWithNodePoolVersion(t *testing.T
},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "test-node"},
+ NodeRef: capiv1.MachineNodeReference{Name: "test-node"},
},
}
@@ -897,7 +897,7 @@ func TestReconcileInPlaceUpgradeAnnotatesMachineWithNodePoolVersion(t *testing.T
},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "upgrading-node"},
+ NodeRef: capiv1.MachineNodeReference{Name: "upgrading-node"},
},
}
@@ -1043,7 +1043,7 @@ func TestReconcileInPlaceUpgradeDegradedNodeErrorMessage(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: tc.nodeName},
+ NodeRef: capiv1.MachineNodeReference{Name: tc.nodeName},
},
}
@@ -1186,7 +1186,7 @@ func TestReconcileReturnsRequeueAfterDuringUpgrade(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- NodeRef: &corev1.ObjectReference{Name: "test-node"},
+ NodeRef: capiv1.MachineNodeReference{Name: "test-node"},
},
}
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine_test.go
index f9518457229b..878f4a39d369 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/machine/machine_test.go
@@ -17,7 +17,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -98,7 +98,7 @@ func TestReconcileDefaultIngressEndpoints(t *testing.T) {
TypeMeta: machineTypeMeta,
ObjectMeta: worker1Meta,
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
Name: vmWorker1Meta.Name,
},
},
@@ -120,7 +120,7 @@ func TestReconcileDefaultIngressEndpoints(t *testing.T) {
TypeMeta: machineTypeMeta,
ObjectMeta: worker2Meta,
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
Name: vmWorker2Meta.Name,
},
},
@@ -388,7 +388,7 @@ func TestReconcileDefaultIngressEndpoints(t *testing.T) {
TypeMeta: machineTypeMeta,
ObjectMeta: worker1Meta,
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
Name: vmWorker1Meta.Name,
},
},
@@ -406,7 +406,7 @@ func TestReconcileDefaultIngressEndpoints(t *testing.T) {
TypeMeta: machineTypeMeta,
ObjectMeta: worker2Meta,
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
Name: vmWorker2Meta.Name,
},
},
@@ -465,7 +465,7 @@ func TestReconcileDefaultIngressEndpoints(t *testing.T) {
},
{
name: "With Failing machine with internal addresses and passthrow service should mark endpointslices as not ready/not serving",
- machines: pairOfDualStackMachines(capiv1.MachinePhaseRunning, capiv1.MachinePhaseFailed),
+ machines: pairOfDualStackMachines(capiv1.MachinePhaseRunning, capiv1.MachinePhaseDeleting),
virtualMachines: pairOfVirtualMachines,
services: []corev1.Service{defaultIngressService},
expectedServices: []corev1.Service{defaultIngressService},
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/node/node_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/node/node_test.go
index 0578ec66c16f..2a8c1e7fd4b5 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/node/node_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/node/node_test.go
@@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation_test.go
index 84c4f58dbe7a..6e569faa4f57 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/spotremediation/spotremediation_test.go
@@ -12,7 +12,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
index a2bb4c590828..e7d68ea087fb 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
@@ -64,7 +64,7 @@ import (
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
capibmv1 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
- "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -1361,12 +1361,12 @@ func TestReconcileCAPICluster(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
- capiCluster *v1beta1.Cluster
+ capiCluster *capiv1.Cluster
hostedCluster *hyperv1.HostedCluster
hostedControlPlane *hyperv1.HostedControlPlane
infraCR crclient.Object
- expectedCAPICluster *v1beta1.Cluster
+ expectedCAPICluster *capiv1.Cluster
}{
{
name: "IBM Cloud cluster",
@@ -1401,7 +1401,7 @@ func TestReconcileCAPICluster(t *testing.T) {
Namespace: "master-cluster1",
},
},
- expectedCAPICluster: &v1beta1.Cluster{
+ expectedCAPICluster: &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
k8sutil.HostedClusterAnnotation: "master/cluster1",
@@ -1409,21 +1409,20 @@ func TestReconcileCAPICluster(t *testing.T) {
Namespace: "master-cluster1",
Name: "cluster1",
},
- Spec: v1beta1.ClusterSpec{
- ControlPlaneEndpoint: v1beta1.APIEndpoint{},
- ControlPlaneRef: &corev1.ObjectReference{
- APIVersion: "hypershift.openshift.io/v1beta1",
- Kind: "HostedControlPlane",
- Namespace: "master-cluster1",
- Name: "cluster1",
+ Spec: capiv1.ClusterSpec{
+ ControlPlaneEndpoint: capiv1.APIEndpoint{},
+ ControlPlaneRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: "hypershift.openshift.io",
+ Kind: "HostedControlPlane",
+ Name: "cluster1",
},
- InfrastructureRef: &corev1.ObjectReference{
- APIVersion: capibmv1.GroupVersion.String(),
- Kind: "IBMVPCCluster",
- Namespace: "master-cluster1",
- Name: "cluster1",
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: capibmv1.GroupVersion.Group,
+ Kind: "IBMVPCCluster",
+ Name: "cluster1",
},
},
+ Status: capiv1.ClusterStatus{Initialization: capiv1.ClusterInitializationStatus{}},
},
},
{
@@ -1459,7 +1458,7 @@ func TestReconcileCAPICluster(t *testing.T) {
Namespace: "master-cluster1",
},
},
- expectedCAPICluster: &v1beta1.Cluster{
+ expectedCAPICluster: &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
k8sutil.HostedClusterAnnotation: "master/cluster1",
@@ -1467,21 +1466,20 @@ func TestReconcileCAPICluster(t *testing.T) {
Namespace: "master-cluster1",
Name: "cluster1",
},
- Spec: v1beta1.ClusterSpec{
- ControlPlaneEndpoint: v1beta1.APIEndpoint{},
- ControlPlaneRef: &corev1.ObjectReference{
- APIVersion: "hypershift.openshift.io/v1beta1",
- Kind: "HostedControlPlane",
- Namespace: "master-cluster1",
- Name: "cluster1",
+ Spec: capiv1.ClusterSpec{
+ ControlPlaneEndpoint: capiv1.APIEndpoint{},
+ ControlPlaneRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: "hypershift.openshift.io",
+ Kind: "HostedControlPlane",
+ Name: "cluster1",
},
- InfrastructureRef: &corev1.ObjectReference{
- APIVersion: capiaws.GroupVersion.String(),
- Kind: "AWSCluster",
- Namespace: "master-cluster1",
- Name: "cluster1",
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ APIGroup: capiaws.GroupVersion.Group,
+ Kind: "AWSCluster",
+ Name: "cluster1",
},
},
+ Status: capiv1.ClusterStatus{Initialization: capiv1.ClusterInitializationStatus{}},
},
},
}
@@ -3019,7 +3017,7 @@ func TestPauseCAPICluster(t *testing.T) {
inputHostedCluster *hyperv1.HostedCluster
inputObjects []crclient.Object
paused bool
- expectedCAPICluster *v1beta1.Cluster
+ expectedCAPICluster *capiv1.Cluster
}{
{
name: "When CAPI cluster exists and is paused, it should unpause when paused=false",
@@ -3033,24 +3031,24 @@ func TestPauseCAPICluster(t *testing.T) {
},
},
inputObjects: []crclient.Object{
- &v1beta1.Cluster{
+ &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: true,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(true),
},
},
},
paused: false,
- expectedCAPICluster: &v1beta1.Cluster{
+ expectedCAPICluster: &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: false,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(false),
},
},
},
@@ -3066,24 +3064,24 @@ func TestPauseCAPICluster(t *testing.T) {
},
},
inputObjects: []crclient.Object{
- &v1beta1.Cluster{
+ &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: false,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(false),
},
},
},
paused: true,
- expectedCAPICluster: &v1beta1.Cluster{
+ expectedCAPICluster: &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: true,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(true),
},
},
},
@@ -3121,24 +3119,24 @@ func TestPauseCAPICluster(t *testing.T) {
},
},
inputObjects: []crclient.Object{
- &v1beta1.Cluster{
+ &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: true,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(true),
},
},
},
paused: true,
- expectedCAPICluster: &v1beta1.Cluster{
+ expectedCAPICluster: &capiv1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: controlPlaneNamespace,
Name: fakeInfraID,
},
- Spec: v1beta1.ClusterSpec{
- Paused: true,
+ Spec: capiv1.ClusterSpec{
+ Paused: ptr.To(true),
},
},
},
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
index ca040656d58a..784fdaf133d9 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/agent/agent_test.go
@@ -19,6 +19,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -172,7 +173,7 @@ func TestReconcileCAPIInfraCR(t *testing.T) {
Url: "https://" + ignitionEndpoint + "/ignition",
CaCertificateReference: &agentv1.CaCertificateReference{Name: caSecret.Name, Namespace: caSecret.Namespace},
},
- ControlPlaneEndpoint: capiv1.APIEndpoint{
+ ControlPlaneEndpoint: capiv1beta1.APIEndpoint{
Port: APIEndpoint.Port,
Host: APIEndpoint.Host,
},
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
index 542ebec5b9f5..7ae8eff9c9f7 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/ibmcloud/ibmcloud_test.go
@@ -122,7 +122,7 @@ func TestReconcileCAPIInfraCR(t *testing.T) {
Ready: true,
},
Spec: capiibmv1.IBMVPCClusterSpec{
- ControlPlaneEndpoint: capiv1.APIEndpoint{
+ ControlPlaneEndpoint: capiv1beta1.APIEndpoint{
Port: fakeAPIEndpoint.Port,
Host: fakeAPIEndpoint.Host,
},
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt_test.go
index c104a4c84fb3..1afafe4c0363 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/kubevirt/kubevirt_test.go
@@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
diff --git a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
index 8c495a567b1f..8be33d578ec4 100644
--- a/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
+++ b/hypershift-operator/controllers/hostedcluster/internal/platform/openstack/openstack_test.go
@@ -15,6 +15,7 @@ import (
"k8s.io/utils/ptr"
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
+ capiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
"github.com/blang/semver"
"github.com/google/go-cmp/cmp"
@@ -76,7 +77,7 @@ func TestReconcileOpenStackCluster(t *testing.T) {
},
},
NetworkMTU: ptr.To(1500),
- ControlPlaneEndpoint: &capiv1.APIEndpoint{
+ ControlPlaneEndpoint: &capiv1beta1.APIEndpoint{
Host: "api-endpoint",
Port: 6443,
},
@@ -125,7 +126,7 @@ func TestReconcileOpenStackCluster(t *testing.T) {
},
Subnets: []capo.SubnetParam{{ID: ptr.To(subnetID)}},
Network: &capo.NetworkParam{ID: ptr.To(networkID)},
- ControlPlaneEndpoint: &capiv1.APIEndpoint{
+ ControlPlaneEndpoint: &capiv1beta1.APIEndpoint{
Host: "api-endpoint",
Port: 6443,
},
@@ -189,7 +190,7 @@ func TestReconcileOpenStackCluster(t *testing.T) {
},
},
},
- ControlPlaneEndpoint: &capiv1.APIEndpoint{
+ ControlPlaneEndpoint: &capiv1beta1.APIEndpoint{
Host: "api-endpoint",
Port: 6443,
},
diff --git a/hypershift-operator/controllers/nodepool/aws_test.go b/hypershift-operator/controllers/nodepool/aws_test.go
index 9bec3976807f..5bd5fd1a4746 100644
--- a/hypershift-operator/controllers/nodepool/aws_test.go
+++ b/hypershift-operator/controllers/nodepool/aws_test.go
@@ -23,7 +23,7 @@ import (
"k8s.io/utils/ptr"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -517,7 +517,7 @@ func TestAWSMachineTemplate(t *testing.T) {
md := &capiv1.MachineDeployment{
ObjectMeta: metav1.ObjectMeta{Name: tc.nodePool.GetName(), Namespace: namespace},
Spec: capiv1.MachineDeploymentSpec{Template: capiv1.MachineTemplateSpec{Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{Name: tc.existingTemplate.Name},
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{Name: tc.existingTemplate.Name},
}}},
}
existingObjs = append(existingObjs, md)
@@ -525,7 +525,7 @@ func TestAWSMachineTemplate(t *testing.T) {
ms := &capiv1.MachineSet{
ObjectMeta: metav1.ObjectMeta{Name: tc.nodePool.GetName(), Namespace: namespace},
Spec: capiv1.MachineSetSpec{Template: capiv1.MachineTemplateSpec{Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{Name: tc.existingTemplate.Name},
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{Name: tc.existingTemplate.Name},
}}},
}
existingObjs = append(existingObjs, ms)
diff --git a/hypershift-operator/controllers/nodepool/azure_test.go b/hypershift-operator/controllers/nodepool/azure_test.go
index 33bf09b283e8..3979f48110d3 100644
--- a/hypershift-operator/controllers/nodepool/azure_test.go
+++ b/hypershift-operator/controllers/nodepool/azure_test.go
@@ -52,7 +52,7 @@ func TestAzureMachineTemplateSpec(t *testing.T) {
},
expectedAzureMachineTemplateSpec: &capiazure.AzureMachineTemplateSpec{
Template: capiazure.AzureMachineTemplateResource{
- ObjectMeta: clusterv1.ObjectMeta{Labels: nil, Annotations: nil},
+ ObjectMeta: clusterv1beta1.ObjectMeta{Labels: nil, Annotations: nil},
Spec: capiazure.AzureMachineSpec{
ProviderID: nil,
VMSize: "Standard_D2_v2",
@@ -126,7 +126,7 @@ func TestAzureMachineTemplateSpec(t *testing.T) {
},
expectedAzureMachineTemplateSpec: &capiazure.AzureMachineTemplateSpec{
Template: capiazure.AzureMachineTemplateResource{
- ObjectMeta: clusterv1.ObjectMeta{Labels: nil, Annotations: nil},
+ ObjectMeta: clusterv1beta1.ObjectMeta{Labels: nil, Annotations: nil},
Spec: capiazure.AzureMachineSpec{
ProviderID: nil,
VMSize: "Standard_D2_v2",
@@ -205,7 +205,7 @@ func TestAzureMachineTemplateSpec(t *testing.T) {
},
expectedAzureMachineTemplateSpec: &capiazure.AzureMachineTemplateSpec{
Template: capiazure.AzureMachineTemplateResource{
- ObjectMeta: clusterv1.ObjectMeta{Labels: nil, Annotations: nil},
+ ObjectMeta: clusterv1beta1.ObjectMeta{Labels: nil, Annotations: nil},
Spec: capiazure.AzureMachineSpec{
ProviderID: nil,
VMSize: "Standard_D2_v2",
@@ -295,7 +295,7 @@ func TestAzureMachineTemplateSpec(t *testing.T) {
},
expectedAzureMachineTemplateSpec: &capiazure.AzureMachineTemplateSpec{
Template: capiazure.AzureMachineTemplateResource{
- ObjectMeta: clusterv1.ObjectMeta{Labels: nil, Annotations: nil},
+ ObjectMeta: clusterv1beta1.ObjectMeta{Labels: nil, Annotations: nil},
Spec: capiazure.AzureMachineSpec{
ProviderID: nil,
VMSize: "Standard_D2_v2",
@@ -391,7 +391,7 @@ func TestAzureMachineTemplateSpec(t *testing.T) {
},
expectedAzureMachineTemplateSpec: &capiazure.AzureMachineTemplateSpec{
Template: capiazure.AzureMachineTemplateResource{
- ObjectMeta: clusterv1.ObjectMeta{Labels: nil, Annotations: nil},
+ ObjectMeta: clusterv1beta1.ObjectMeta{Labels: nil, Annotations: nil},
Spec: capiazure.AzureMachineSpec{
ProviderID: nil,
VMSize: "Standard_D2_v2",
diff --git a/hypershift-operator/controllers/nodepool/capi_test.go b/hypershift-operator/controllers/nodepool/capi_test.go
index 1fe35dc09f60..ef3b743c900a 100644
--- a/hypershift-operator/controllers/nodepool/capi_test.go
+++ b/hypershift-operator/controllers/nodepool/capi_test.go
@@ -26,8 +26,7 @@ import (
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
capiazure "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
capikubevirt "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
- "sigs.k8s.io/cluster-api/util/conversion"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
@@ -815,11 +814,10 @@ func TestCleanupMachineTemplates(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: gvk.Kind,
- APIVersion: gvk.GroupVersion().String(),
- Name: template1.Name,
- Namespace: template1.Namespace,
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: gvk.Kind,
+ APIGroup: gvk.Group,
+ Name: template1.Name,
},
},
},
@@ -1100,6 +1098,8 @@ func TestReconcileMachineHealthCheck(t *testing.T) {
healthcheck := func(opts ...func(*capiv1.MachineHealthCheck)) *capiv1.MachineHealthCheck {
mhc := &capiv1.MachineHealthCheck{ObjectMeta: metav1.ObjectMeta{Namespace: "ns-cluster", Name: "nodepool"}}
resName := generateName("cluster", "cluster", "nodepool")
+ timeoutSeconds := int32(480)
+ nodeStartupTimeoutSeconds := int32(1200)
mhc.Spec = capiv1.MachineHealthCheckSpec{
ClusterName: "cluster",
Selector: metav1.LabelSelector{
@@ -1107,25 +1107,25 @@ func TestReconcileMachineHealthCheck(t *testing.T) {
resName: resName,
},
},
- UnhealthyConditions: []capiv1.UnhealthyCondition{
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionFalse,
- Timeout: metav1.Duration{
- Duration: time.Duration(8 * time.Minute),
+ Checks: capiv1.MachineHealthCheckChecks{
+ UnhealthyNodeConditions: []capiv1.UnhealthyNodeCondition{
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionFalse,
+ TimeoutSeconds: &timeoutSeconds,
},
- },
- {
- Type: corev1.NodeReady,
- Status: corev1.ConditionUnknown,
- Timeout: metav1.Duration{
- Duration: time.Duration(8 * time.Minute),
+ {
+ Type: corev1.NodeReady,
+ Status: corev1.ConditionUnknown,
+ TimeoutSeconds: &timeoutSeconds,
},
},
+ NodeStartupTimeoutSeconds: &nodeStartupTimeoutSeconds,
},
- MaxUnhealthy: &defaultMaxUnhealthy,
- NodeStartupTimeout: &metav1.Duration{
- Duration: 20 * time.Minute,
+ Remediation: capiv1.MachineHealthCheckRemediation{
+ TriggerIf: capiv1.MachineHealthCheckRemediationTriggerIf{
+ UnhealthyLessThanOrEqualTo: &defaultMaxUnhealthy,
+ },
},
}
for _, o := range opts {
@@ -1157,8 +1157,9 @@ func TestReconcileMachineHealthCheck(t *testing.T) {
}
withTimeout := func(d time.Duration) func(*capiv1.MachineHealthCheck) {
return func(mhc *capiv1.MachineHealthCheck) {
- for i := range mhc.Spec.UnhealthyConditions {
- mhc.Spec.UnhealthyConditions[i].Timeout = metav1.Duration{Duration: d}
+ s := int32(d.Seconds())
+ for i := range mhc.Spec.Checks.UnhealthyNodeConditions {
+ mhc.Spec.Checks.UnhealthyNodeConditions[i].TimeoutSeconds = &s
}
}
}
@@ -1174,7 +1175,8 @@ func TestReconcileMachineHealthCheck(t *testing.T) {
}
withNodeStartupTimeout := func(d time.Duration) func(*capiv1.MachineHealthCheck) {
return func(mhc *capiv1.MachineHealthCheck) {
- mhc.Spec.NodeStartupTimeout = &metav1.Duration{Duration: d}
+ s := int32(d.Seconds())
+ mhc.Spec.Checks.NodeStartupTimeoutSeconds = &s
}
}
@@ -1345,10 +1347,9 @@ func TestCAPIReconcile(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: "test-namespace-test-cluster",
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
// This is the generated name by machineTemplateBuilders.
// So reconciliation doesn't create a new AWSMachineTemplate but reconcile this one.
Name: awsMachineTemplateName,
@@ -1441,10 +1442,9 @@ func TestCAPIReconcile(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: "test-namespace-test-cluster",
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
// This is the generated name by machineTemplateBuilders.
// So reconciliation doesn't create a new AWSMachineTemplate but reconcile this one.
Name: awsMachineTemplateName,
@@ -1548,10 +1548,9 @@ func TestCAPIReconcile(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: "test-namespace-test-cluster",
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
// This is the generated name by machineTemplateBuilders.
// So reconciliation doesn't create a new AWSMachineTemplate but reconcile this one.
Name: awsMachineTemplateName,
@@ -1662,11 +1661,10 @@ func TestCAPIReconcile(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: "test-namespace-test-cluster",
- Name: awsMachineTemplateName,
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
+ Name: awsMachineTemplateName,
},
},
},
@@ -1765,9 +1763,9 @@ func TestCAPIReconcile(t *testing.T) {
g.Expect(md.Annotations).To(HaveKeyWithValue(nodePoolAnnotation, "test-namespace/test-nodepool"))
// Check MachineDeployment spec.
- g.Expect(md.Spec.Strategy.Type).To(Equal(capiv1.MachineDeploymentStrategyType("RollingUpdate")))
- g.Expect(md.Spec.Strategy.RollingUpdate.MaxUnavailable.IntValue()).To(Equal(0))
- g.Expect(md.Spec.Strategy.RollingUpdate.MaxSurge.IntValue()).To(Equal(1))
+ g.Expect(md.Spec.Rollout.Strategy.Type).To(Equal(capiv1.MachineDeploymentRolloutStrategyType("RollingUpdate")))
+ g.Expect(md.Spec.Rollout.Strategy.RollingUpdate.MaxUnavailable.IntValue()).To(Equal(0))
+ g.Expect(md.Spec.Rollout.Strategy.RollingUpdate.MaxSurge.IntValue()).To(Equal(1))
// Check MachineDeployment labels.
g.Expect(md.Labels).To(HaveKeyWithValue(capiv1.ClusterNameLabel, capiClusterName))
@@ -1780,14 +1778,13 @@ func TestCAPIReconcile(t *testing.T) {
// Check MachineDeployment template spec
g.Expect(md.Spec.Template.Spec.ClusterName).To(Equal(capiClusterName))
- g.Expect(md.Spec.Template.Spec.InfrastructureRef.APIVersion).To(Equal("infrastructure.cluster.x-k8s.io/v1beta2"))
+ g.Expect(md.Spec.Template.Spec.InfrastructureRef.APIGroup).To(Equal("infrastructure.cluster.x-k8s.io"))
g.Expect(md.Spec.Template.Spec.InfrastructureRef.Kind).To(Equal("AWSMachineTemplate"))
- g.Expect(md.Spec.Template.Spec.InfrastructureRef.Namespace).To(Equal(controlpaneNamespace))
g.Expect(md.Spec.Template.Spec.InfrastructureRef.Name).To(Equal(awsMachineTemplateName))
- g.Expect(*md.Spec.Template.Spec.Version).To(Equal("target-version"))
- g.Expect(md.Spec.Template.Spec.NodeDrainTimeout).To(Equal(tt.nodePool.Spec.NodeDrainTimeout))
- g.Expect(md.Spec.Template.Spec.NodeVolumeDetachTimeout).To(Equal(tt.nodePool.Spec.NodeVolumeDetachTimeout))
+ g.Expect(md.Spec.Template.Spec.Version).To(Equal("target-version"))
+ g.Expect(md.Spec.Template.Spec.Deletion.NodeDrainTimeoutSeconds).To(Equal(durationToSeconds(tt.nodePool.Spec.NodeDrainTimeout)))
+ g.Expect(md.Spec.Template.Spec.Deletion.NodeVolumeDetachTimeoutSeconds).To(Equal(durationToSeconds(tt.nodePool.Spec.NodeVolumeDetachTimeout)))
// Check Bootstrap DataSecretName.
g.Expect(md.Spec.Template.Spec.Bootstrap.DataSecretName).NotTo(BeNil())
@@ -1842,10 +1839,10 @@ func TestCAPIReconcile(t *testing.T) {
g.Expect(err).NotTo(HaveOccurred())
// Update MachineDeployment status to indicate rollout is complete.
- md.Status.Replicas = *tt.nodePool.Spec.Replicas
- md.Status.UpdatedReplicas = *tt.nodePool.Spec.Replicas
- md.Status.ReadyReplicas = *tt.nodePool.Spec.Replicas
- md.Status.AvailableReplicas = *tt.nodePool.Spec.Replicas
+ md.Status.Replicas = tt.nodePool.Spec.Replicas
+ md.Status.ReadyReplicas = tt.nodePool.Spec.Replicas
+ md.Status.AvailableReplicas = tt.nodePool.Spec.Replicas
+ md.Status.UpToDateReplicas = tt.nodePool.Spec.Replicas
md.Status.ObservedGeneration = md.Generation
err = capi.Client.Update(t.Context(), md)
g.Expect(err).NotTo(HaveOccurred())
@@ -1950,11 +1947,10 @@ func TestGlobalPSManagedLabelOnMachines(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: controlPlaneNamespace,
- Name: awsMachineTemplateName,
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
+ Name: awsMachineTemplateName,
},
},
},
@@ -2098,11 +2094,10 @@ func TestGlobalPSManagedLabelOnMachines(t *testing.T) {
Spec: capiv1.MachineSetSpec{
Template: capiv1.MachineTemplateSpec{
Spec: capiv1.MachineSpec{
- InfrastructureRef: corev1.ObjectReference{
- Kind: "AWSMachineTemplate",
- APIVersion: "infrastructure.cluster.x-k8s.io/v1beta2",
- Namespace: controlPlaneNamespace,
- Name: awsMachineTemplateName,
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
+ Kind: "AWSMachineTemplate",
+ APIGroup: "infrastructure.cluster.x-k8s.io",
+ Name: awsMachineTemplateName,
},
},
},
@@ -2405,7 +2400,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
testCases := []struct {
name string
nodePool *hyperv1.NodePool
- expectedFailureDomain *string
+ expectedFailureDomain string
}{
{
name: "When platform is OpenStack with AvailabilityZone set, it should set failure domain",
@@ -2419,7 +2414,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: ptr.To("az-1"),
+ expectedFailureDomain: "az-1",
},
{
name: "When platform is OpenStack with empty AvailabilityZone, it should not set failure domain",
@@ -2433,7 +2428,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: nil,
+ expectedFailureDomain: "",
},
{
name: "When platform is GCP with Zone set, it should set failure domain",
@@ -2447,7 +2442,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: ptr.To("us-central1-a"),
+ expectedFailureDomain: "us-central1-a",
},
{
name: "When platform is GCP with empty Zone, it should not set failure domain",
@@ -2461,7 +2456,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: nil,
+ expectedFailureDomain: "",
},
{
name: "When platform is AWS, it should not set failure domain",
@@ -2473,7 +2468,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: nil,
+ expectedFailureDomain: "",
},
{
name: "When platform is OpenStack but spec is nil, it should not set failure domain",
@@ -2484,7 +2479,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: nil,
+ expectedFailureDomain: "",
},
{
name: "When platform is GCP but spec is nil, it should not set failure domain",
@@ -2495,7 +2490,7 @@ func TestSetMachineDeploymentFailureDomain(t *testing.T) {
},
},
},
- expectedFailureDomain: nil,
+ expectedFailureDomain: "",
},
}
@@ -2605,10 +2600,10 @@ func TestPropagateVersionAndTemplate(t *testing.T) {
Bootstrap: capiv1.Bootstrap{
DataSecretName: ptr.To(bootstrapName),
},
- InfrastructureRef: corev1.ObjectReference{
+ InfrastructureRef: capiv1.ContractVersionedObjectReference{
Name: tc.currentInfraRefName,
},
- Version: ptr.To(tc.currentVersion),
+ Version: tc.currentVersion,
},
},
},
@@ -2627,7 +2622,7 @@ func TestPropagateVersionAndTemplate(t *testing.T) {
if tc.expectedUpdating && tc.useDifferentUserData {
// When updating, bootstrap should be set to the computed user data name.
g.Expect(*md.Spec.Template.Spec.Bootstrap.DataSecretName).To(Equal(computedUserDataName))
- g.Expect(*md.Spec.Template.Spec.Version).To(Equal("4.17.0"))
+ g.Expect(md.Spec.Template.Spec.Version).To(Equal("4.17.0"))
}
})
}
@@ -2655,10 +2650,10 @@ func TestReconcileMachineDeploymentStatus(t *testing.T) {
Replicas: ptr.To[int32](3),
},
Status: capiv1.MachineDeploymentStatus{
- Replicas: 3,
- UpdatedReplicas: 3,
- ReadyReplicas: 3,
- AvailableReplicas: 3,
+ Replicas: ptr.To[int32](3),
+ UpToDateReplicas: ptr.To[int32](3),
+ ReadyReplicas: ptr.To[int32](3),
+ AvailableReplicas: ptr.To[int32](3),
ObservedGeneration: 1,
},
},
@@ -2678,10 +2673,10 @@ func TestReconcileMachineDeploymentStatus(t *testing.T) {
Replicas: ptr.To[int32](3),
},
Status: capiv1.MachineDeploymentStatus{
- Replicas: 3,
- UpdatedReplicas: 1,
- ReadyReplicas: 1,
- AvailableReplicas: 2,
+ Replicas: ptr.To[int32](3),
+ UpToDateReplicas: ptr.To[int32](1),
+ ReadyReplicas: ptr.To[int32](1),
+ AvailableReplicas: ptr.To[int32](2),
ObservedGeneration: 1,
},
},
@@ -2701,11 +2696,11 @@ func TestReconcileMachineDeploymentStatus(t *testing.T) {
Replicas: ptr.To[int32](3),
},
Status: capiv1.MachineDeploymentStatus{
- AvailableReplicas: 2,
- Conditions: capiv1.Conditions{
+ AvailableReplicas: ptr.To[int32](2),
+ Conditions: []metav1.Condition{
{
- Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Type: string(capiv1.MachinesReadyCondition),
+ Status: metav1.ConditionTrue,
Reason: "SomeReason",
Message: "all good",
},
@@ -3281,136 +3276,95 @@ func TestNewCAPI(t *testing.T) {
}
func TestMachineDeploymentComplete(t *testing.T) {
- two := int32(2)
- three := int32(3)
-
- conversionData := func(replicas, upToDate, available int32, observedGen int64) string {
- data := map[string]any{
- "apiVersion": "cluster.x-k8s.io/v1beta2",
- "kind": "MachineDeployment",
- "spec": map[string]any{"replicas": replicas},
- "status": map[string]any{
- "observedGeneration": observedGen,
- "replicas": replicas,
- "upToDateReplicas": upToDate,
- "availableReplicas": available,
- },
- }
- raw, _ := json.Marshal(data)
- return string(raw)
- }
-
testCases := []struct {
name string
md *capiv1.MachineDeployment
expected bool
}{
{
- name: "When all v1beta1 and v1beta2 fields agree it should return true",
+ name: "When all fields match spec replicas and generation it should return true",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- Annotations: map[string]string{
- conversion.DataAnnotation: conversionData(2, 2, 2, 2),
- },
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ UpToDateReplicas: ptr.To[int32](2),
+ AvailableReplicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 2},
},
expected: true,
},
{
- name: "When v1beta1 looks complete but v1beta2 upToDateReplicas disagrees it should return false",
+ name: "When upToDateReplicas does not match it should return false",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- Annotations: map[string]string{
- conversion.DataAnnotation: conversionData(2, 0, 2, 2),
- },
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ UpToDateReplicas: ptr.To[int32](0),
+ AvailableReplicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 2},
},
expected: false,
},
{
- name: "When v1beta1 looks complete but v1beta2 replicas shows surge it should return false",
+ name: "When replicas shows surge it should return false",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- Annotations: map[string]string{
- conversion.DataAnnotation: conversionData(3, 2, 2, 2),
- },
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](3),
+ UpToDateReplicas: ptr.To[int32](2),
+ AvailableReplicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 2},
},
expected: false,
},
{
- name: "When v1beta1 looks complete but v1beta2 observedGeneration is stale it should return false",
+ name: "When observedGeneration is stale it should return false",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- Annotations: map[string]string{
- conversion.DataAnnotation: conversionData(2, 2, 2, 1),
- },
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ UpToDateReplicas: ptr.To[int32](2),
+ AvailableReplicas: ptr.To[int32](2),
+ ObservedGeneration: 1,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 2},
},
expected: false,
},
{
- name: "When v1beta1 is not complete it should return false without checking conversion data",
+ name: "When AvailableReplicas does not match it should return false",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ UpToDateReplicas: ptr.To[int32](2),
+ AvailableReplicas: ptr.To[int32](1),
+ ObservedGeneration: 2,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 3, UpdatedReplicas: 1, AvailableReplicas: 2, ObservedGeneration: 2},
},
expected: false,
},
{
- name: "When no conversion-data annotation exists it should fall back to v1beta1 only",
- md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 1,
- },
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 1},
- },
- expected: true,
- },
- {
- name: "When conversion-data annotation is malformed it should fall back to v1beta1 result",
+ name: "When spec replicas is nil it should default to 0",
md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 1,
- Annotations: map[string]string{
- conversion.DataAnnotation: "not-valid-json",
- },
+ ObjectMeta: metav1.ObjectMeta{Generation: 1},
+ Spec: capiv1.MachineDeploymentSpec{},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](0),
+ UpToDateReplicas: ptr.To[int32](0),
+ AvailableReplicas: ptr.To[int32](0),
+ ObservedGeneration: 1,
},
- Spec: capiv1.MachineDeploymentSpec{Replicas: &two},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 1},
},
expected: true,
},
- {
- name: "When v1beta1 replicas does not match spec it should return false",
- md: &capiv1.MachineDeployment{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- Annotations: map[string]string{
- conversion.DataAnnotation: conversionData(3, 2, 2, 2),
- },
- },
- Spec: capiv1.MachineDeploymentSpec{Replicas: &three},
- Status: capiv1.MachineDeploymentStatus{Replicas: 2, UpdatedReplicas: 2, AvailableReplicas: 2, ObservedGeneration: 2},
- },
- expected: false,
- },
}
for _, tc := range testCases {
diff --git a/hypershift-operator/controllers/nodepool/conditions_test.go b/hypershift-operator/controllers/nodepool/conditions_test.go
index c52571f328cd..d388ff30c265 100644
--- a/hypershift-operator/controllers/nodepool/conditions_test.go
+++ b/hypershift-operator/controllers/nodepool/conditions_test.go
@@ -20,7 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
- "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/blang/semver"
@@ -487,8 +487,8 @@ spec:
return pullSecret, ignitionServerCACert, machineConfig, ignitionConfig, ignitionConfig2, ignitionConfig3
}
-func setUpDummyMachineSet(nodePool *hyperv1.NodePool, hostedCluster *hyperv1.HostedCluster, machineSetUpgradeFail bool) *v1beta1.MachineSet {
- machineSet := &v1beta1.MachineSet{
+func setUpDummyMachineSet(nodePool *hyperv1.NodePool, hostedCluster *hyperv1.HostedCluster, machineSetUpgradeFail bool) *v1beta2.MachineSet {
+ machineSet := &v1beta2.MachineSet{
ObjectMeta: metav1.ObjectMeta{
Name: nodePool.Name,
Namespace: hostedCluster.Namespace + "-" + hostedCluster.Name,
diff --git a/hypershift-operator/controllers/nodepool/nodepool_controller_test.go b/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
index f3ece180df0c..e37b54cd926a 100644
--- a/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
+++ b/hypershift-operator/controllers/nodepool/nodepool_controller_test.go
@@ -34,7 +34,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -773,10 +773,10 @@ func TestFindMachineStatusCondition(t *testing.T) {
name: "When condition is False it should return the condition values",
machine: &capiv1.Machine{
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "InstanceTerminated",
Message: "i-0abc123def456 instance is in terminated state",
},
@@ -785,7 +785,7 @@ func TestFindMachineStatusCondition(t *testing.T) {
},
conditionType: string(capiv1.ReadyCondition),
expected: &machineConditionResult{
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "InstanceTerminated",
Message: "i-0abc123def456 instance is in terminated state",
},
@@ -794,10 +794,10 @@ func TestFindMachineStatusCondition(t *testing.T) {
name: "When neither has condition it should return nil",
machine: &capiv1.Machine{
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -809,10 +809,10 @@ func TestFindMachineStatusCondition(t *testing.T) {
name: "When condition is True it should return the condition values",
machine: &capiv1.Machine{
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
Reason: "InstanceProvisionStarted",
Message: "started provisioning i-0abc123def456",
},
@@ -821,7 +821,7 @@ func TestFindMachineStatusCondition(t *testing.T) {
},
conditionType: string(capiv1.ReadyCondition),
expected: &machineConditionResult{
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
Reason: "InstanceProvisionStarted",
Message: "started provisioning i-0abc123def456",
},
@@ -830,7 +830,7 @@ func TestFindMachineStatusCondition(t *testing.T) {
name: "When machine has no conditions it should return nil",
machine: &capiv1.Machine{
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{},
+ Conditions: []metav1.Condition{},
},
},
conditionType: string(capiv1.ReadyCondition),
@@ -840,15 +840,15 @@ func TestFindMachineStatusCondition(t *testing.T) {
name: "When looking up MachineNodeHealthyCondition it should return matching values",
machine: &capiv1.Machine{
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
- Reason: capiv1.NodeConditionsFailedReason,
+ Status: metav1.ConditionFalse,
+ Reason: capiv1.NodeConditionsFailedV1Beta1Reason,
Message: "Condition Ready on node is reporting status False",
},
},
@@ -856,8 +856,8 @@ func TestFindMachineStatusCondition(t *testing.T) {
},
conditionType: string(capiv1.MachineNodeHealthyCondition),
expected: &machineConditionResult{
- Status: corev1.ConditionFalse,
- Reason: capiv1.NodeConditionsFailedReason,
+ Status: metav1.ConditionFalse,
+ Reason: capiv1.NodeConditionsFailedV1Beta1Reason,
Message: "Condition Ready on node is reporting status False",
},
},
@@ -948,14 +948,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -969,14 +969,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1007,16 +1007,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
@@ -1032,16 +1032,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
@@ -1075,22 +1075,22 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "12 of 34 completed",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
@@ -1107,22 +1107,22 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "some real failed message",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
@@ -1139,14 +1139,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1178,22 +1178,22 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "some real failed message",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "test message node 1",
},
@@ -1210,22 +1210,22 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "12 of 34 completed",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "test message node 2",
},
@@ -1242,14 +1242,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1286,16 +1286,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: "not ready",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode1",
Message: longMessage,
},
@@ -1313,16 +1313,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: "not ready",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode2",
Message: longMessage,
},
@@ -1340,16 +1340,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode3",
Message: "not ready",
},
{
Type: capiv1.InfrastructureReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "TestReasonNode3",
Message: longMessage,
},
@@ -1367,10 +1367,10 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1398,14 +1398,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
Addresses: capiv1.MachineAddresses{
@@ -1425,14 +1425,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
Addresses: capiv1.MachineAddresses{
@@ -1477,10 +1477,10 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1494,7 +1494,7 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
expectedAllNodes: &testCondition{
Status: corev1.ConditionFalse,
- Reason: capiv1.WaitingForNodeRefReason,
+ Reason: capiv1.WaitingForNodeRefV1Beta1Reason,
Messages: []string{"1 of 1 machines are not healthy", "Machine node1: WaitingForNodeRef"},
},
},
@@ -1511,10 +1511,10 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1523,7 +1523,7 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
expectedAllMachine: &testCondition{
Status: corev1.ConditionFalse,
- Reason: capiv1.WaitingForInfrastructureFallbackReason,
+ Reason: capiv1.WaitingForInfrastructureFallbackV1Beta1Reason,
Messages: []string{"1 of 1 machines are not ready", "Machine node1: WaitingForInfrastructure"},
},
expectedAllNodes: &testCondition{
@@ -1545,15 +1545,15 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
- Reason: capiv1.NodeProvisioningReason,
+ Status: metav1.ConditionFalse,
+ Reason: capiv1.NodeProvisioningV1Beta1Reason,
},
},
},
@@ -1567,8 +1567,8 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
expectedAllNodes: &testCondition{
Status: corev1.ConditionFalse,
- Reason: capiv1.NodeProvisioningReason,
- Messages: []string{"1 of 1 machines are not healthy", "Machine node1: " + capiv1.NodeProvisioningReason},
+ Reason: capiv1.NodeProvisioningV1Beta1Reason,
+ Messages: []string{"1 of 1 machines are not healthy", "Machine node1: " + capiv1.NodeProvisioningV1Beta1Reason},
},
},
{
@@ -1584,10 +1584,10 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1601,15 +1601,15 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
- Reason: capiv1.NodeConditionsFailedReason,
+ Status: metav1.ConditionFalse,
+ Reason: capiv1.NodeConditionsFailedV1Beta1Reason,
Message: "Condition Ready on node is reporting status False",
},
},
@@ -1624,14 +1624,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1645,8 +1645,8 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
expectedAllNodes: &testCondition{
Status: corev1.ConditionFalse,
- Reason: capiv1.NodeConditionsFailedReason + "," + capiv1.WaitingForNodeRefReason,
- Messages: []string{"2 of 3 machines are not healthy", "Machine node1: WaitingForNodeRef", "Machine node2: " + capiv1.NodeConditionsFailedReason + ": Condition Ready on node is reporting status False"},
+ Reason: capiv1.NodeConditionsFailedV1Beta1Reason + "," + capiv1.WaitingForNodeRefV1Beta1Reason,
+ Messages: []string{"2 of 3 machines are not healthy", "Machine node1: WaitingForNodeRef", "Machine node2: " + capiv1.NodeConditionsFailedV1Beta1Reason + ": Condition Ready on node is reporting status False"},
},
},
{
@@ -1662,16 +1662,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "InstanceTerminated",
Message: "i-0abc123def456 instance is in terminated state",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1702,16 +1702,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: "InstanceProvisionStarted",
Message: "3 of 7 completed",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1742,10 +1742,10 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1759,16 +1759,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
- Reason: capiv1.MachineHasFailureReason,
+ Status: metav1.ConditionFalse,
+ Reason: capiv1.MachineHasFailureV1Beta1Reason,
Message: "Machine has FailureMessage: i-0abc123def456 is in terminated state",
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1777,8 +1777,8 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
expectedAllMachine: &testCondition{
Status: corev1.ConditionFalse,
- Reason: capiv1.MachineHasFailureReason + "," + capiv1.WaitingForInfrastructureFallbackReason,
- Messages: []string{"2 of 2 machines are not ready", "Machine node1: WaitingForInfrastructure", "Machine node2: " + capiv1.MachineHasFailureReason + ": Machine has FailureMessage: i-0abc123def456 is in terminated state"},
+ Reason: capiv1.MachineHasFailureV1Beta1Reason + "," + capiv1.WaitingForInfrastructureFallbackV1Beta1Reason,
+ Messages: []string{"2 of 2 machines are not ready", "Machine node1: WaitingForInfrastructure", "Machine node2: " + capiv1.MachineHasFailureV1Beta1Reason + ": Machine has FailureMessage: i-0abc123def456 is in terminated state"},
},
expectedAllNodes: &testCondition{
Status: corev1.ConditionTrue,
@@ -1809,16 +1809,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: fmt.Sprintf("Reason%02d", r),
Message: longMsg,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: fmt.Sprintf("Reason%02d", r),
Message: longMsg,
},
@@ -1850,40 +1850,40 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
reason string
message string
}{
- {capiv1.WaitingForInfrastructureFallbackReason, ""},
- {capiv1.MachineHasFailureReason, "Machine has FailureReason: InsufficientCapacity"},
- {capiv1.DeletingReason, "Waiting for machine volumes to be detached"},
- {capiv1.DeletionFailedReason, "failed to delete machine"},
- {capiv1.DrainingReason, "Draining node node-4"},
- {capiv1.DrainingFailedReason, "failed to drain node: cannot evict pod"},
- {capiv1.WaitingForVolumeDetachReason, "Waiting for 2 volumes to be detached"},
- {capiv1.WaitingExternalHookReason, "Waiting for external hook to complete"},
- {capiv1.PreflightCheckFailedReason, "Machine pre-flight checks failed"},
- {capiv1.MachineCreationFailedReason, "failed to create machine: quota exceeded"},
- {capiv1.ScalingUpReason, "Scaling up to 10 replicas"},
- {capiv1.ScalingDownReason, "Scaling down to 5 replicas"},
- {capiv1.WaitingForDataSecretFallbackReason, ""},
- {capiv1.WaitingForControlPlaneFallbackReason, ""},
- {capiv1.WaitingForControlPlaneAvailableReason, "Control plane is not available"},
- {capiv1.BootstrapTemplateCloningFailedReason, "failed to clone bootstrap template"},
- {capiv1.InfrastructureTemplateCloningFailedReason, "failed to clone infrastructure template"},
- {capiv1.IncorrectExternalRefReason, "external ref is incorrect"},
- {capiv1.RemediationFailedReason, "remediation failed"},
- {capiv1.RemediationInProgressReason, "remediation in progress for node-18"},
- {capiv1.WaitingForRemediationReason, "waiting for remediation to complete"},
- {capiv1.NodeStartupTimeoutReason, "Node failed to report NodeReady condition within 20m0s"},
- {capiv1.WaitingForNodeRefReason, ""},
- {capiv1.NodeProvisioningReason, "Node is provisioning"},
- {capiv1.NodeNotFoundReason, "node not found in cluster"},
- {capiv1.NodeConditionsFailedReason, "Condition Ready on node is reporting status False"},
- {capiv1.NodeInspectionFailedReason, "failed to inspect node"},
- {capiv1.UnhealthyNodeConditionReason, "Node condition ReadonlyFilesystem is True"},
- {capiv1.HasRemediateMachineAnnotationReason, "machine has remediate annotation"},
- {capiv1.TooManyUnhealthyReason, "too many unhealthy machines: 10 of 20"},
- {capiv1.ExternalRemediationTemplateNotFoundReason, "external remediation template not found"},
- {capiv1.ExternalRemediationRequestCreationFailedReason, "failed to create external remediation request"},
- {capiv1.WaitingForControlPlaneProviderInitializedReason, "control plane provider is not initialized"},
- {capiv1.MissingNodeRefReason, "machine does not have a node ref"},
+ {capiv1.WaitingForInfrastructureFallbackV1Beta1Reason, ""},
+ {capiv1.MachineHasFailureV1Beta1Reason, "Machine has FailureReason: InsufficientCapacity"},
+ {capiv1.DeletingV1Beta1Reason, "Waiting for machine volumes to be detached"},
+ {capiv1.DeletionFailedV1Beta1Reason, "failed to delete machine"},
+ {capiv1.DrainingV1Beta1Reason, "Draining node node-4"},
+ {capiv1.DrainingFailedV1Beta1Reason, "failed to drain node: cannot evict pod"},
+ {capiv1.WaitingForVolumeDetachV1Beta1Reason, "Waiting for 2 volumes to be detached"},
+ {capiv1.WaitingExternalHookV1Beta1Reason, "Waiting for external hook to complete"},
+ {capiv1.PreflightCheckFailedV1Beta1Reason, "Machine pre-flight checks failed"},
+ {capiv1.MachineCreationFailedV1Beta1Reason, "failed to create machine: quota exceeded"},
+ {capiv1.ScalingUpV1Beta1Reason, "Scaling up to 10 replicas"},
+ {capiv1.ScalingDownV1Beta1Reason, "Scaling down to 5 replicas"},
+ {capiv1.WaitingForDataSecretFallbackV1Beta1Reason, ""},
+ {capiv1.WaitingForControlPlaneFallbackV1Beta1Reason, ""},
+ {capiv1.WaitingForControlPlaneAvailableV1Beta1Reason, "Control plane is not available"},
+ {capiv1.BootstrapTemplateCloningFailedV1Beta1Reason, "failed to clone bootstrap template"},
+ {capiv1.InfrastructureTemplateCloningFailedV1Beta1Reason, "failed to clone infrastructure template"},
+ {capiv1.IncorrectExternalRefV1Beta1Reason, "external ref is incorrect"},
+ {capiv1.RemediationFailedV1Beta1Reason, "remediation failed"},
+ {capiv1.RemediationInProgressV1Beta1Reason, "remediation in progress for node-18"},
+ {capiv1.WaitingForRemediationV1Beta1Reason, "waiting for remediation to complete"},
+ {capiv1.NodeStartupTimeoutV1Beta1Reason, "Node failed to report NodeReady condition within 20m0s"},
+ {capiv1.WaitingForNodeRefV1Beta1Reason, ""},
+ {capiv1.NodeProvisioningV1Beta1Reason, "Node is provisioning"},
+ {capiv1.NodeNotFoundV1Beta1Reason, "node not found in cluster"},
+ {capiv1.NodeConditionsFailedV1Beta1Reason, "Condition Ready on node is reporting status False"},
+ {capiv1.NodeInspectionFailedV1Beta1Reason, "failed to inspect node"},
+ {capiv1.UnhealthyNodeConditionV1Beta1Reason, "Node condition ReadonlyFilesystem is True"},
+ {capiv1.HasRemediateMachineAnnotationV1Beta1Reason, "machine has remediate annotation"},
+ {capiv1.TooManyUnhealthyV1Beta1Reason, "too many unhealthy machines: 10 of 20"},
+ {capiv1.ExternalRemediationTemplateNotFoundV1Beta1Reason, "external remediation template not found"},
+ {capiv1.ExternalRemediationRequestCreationFailedV1Beta1Reason, "failed to create external remediation request"},
+ {capiv1.WaitingForControlPlaneProviderInitializedV1Beta1Reason, "control plane provider is not initialized"},
+ {capiv1.MissingNodeRefV1Beta1Reason, "machine does not have a node ref"},
// Realistic cloud-provider reasons (CAPA/CAPZ) — already used in existing tests.
{"InstanceTerminated", "i-0abc123def456 instance is in terminated state"},
{"InstanceProvisionFailed", "failed to create instance: InsufficientInstanceCapacity"},
@@ -1912,16 +1912,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: fr.reason,
Message: fr.message,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: fr.reason,
Message: fr.message,
},
@@ -1951,16 +1951,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
reason string
message string
}{
- {capiv1.NodeStartupTimeoutReason, "Node failed to report NodeReady condition within 20m0s"},
- {capiv1.NodeStartupTimeoutReason, "Node failed to report NodeReady condition within 20m0s"},
- {capiv1.MachineHasFailureReason, "Machine has FailureReason: InsufficientCapacity"},
- {capiv1.MachineHasFailureReason, "Machine has FailureMessage: i-0abc123def456 is in terminated state"},
+ {capiv1.NodeStartupTimeoutV1Beta1Reason, "Node failed to report NodeReady condition within 20m0s"},
+ {capiv1.NodeStartupTimeoutV1Beta1Reason, "Node failed to report NodeReady condition within 20m0s"},
+ {capiv1.MachineHasFailureV1Beta1Reason, "Machine has FailureReason: InsufficientCapacity"},
+ {capiv1.MachineHasFailureV1Beta1Reason, "Machine has FailureMessage: i-0abc123def456 is in terminated state"},
{"InstanceTerminated", "i-0abc123def456 instance is in terminated state"},
{"InstanceTerminated", "i-0def456abc789 instance is in terminated state"},
{"InstanceProvisionFailed", "failed to create instance: InsufficientInstanceCapacity: We currently do not have sufficient capacity in the Availability Zone you requested"},
{"InstanceProvisionFailed", "failed to create instance: Unsupported: The requested configuration is currently not supported"},
- {capiv1.WaitingForInfrastructureFallbackReason, ""},
- {capiv1.WaitingForInfrastructureFallbackReason, ""},
+ {capiv1.WaitingForInfrastructureFallbackV1Beta1Reason, ""},
+ {capiv1.WaitingForInfrastructureFallbackV1Beta1Reason, ""},
}
for i := range 10 {
machines[i] = &capiv1.Machine{
@@ -1972,16 +1972,16 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionFalse,
+ Status: metav1.ConditionFalse,
Reason: failureReasons[i].reason,
Message: failureReasons[i].message,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -1997,14 +1997,14 @@ func TestSetMachineAndNodeConditions(t *testing.T) {
},
},
Status: capiv1.MachineStatus{
- Conditions: []capiv1.Condition{
+ Conditions: []metav1.Condition{
{
Type: capiv1.ReadyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
{
Type: capiv1.MachineNodeHealthyCondition,
- Status: corev1.ConditionTrue,
+ Status: metav1.ConditionTrue,
},
},
},
@@ -2090,14 +2090,14 @@ func TestTruncateReasons(t *testing.T) {
}{
{
name: "When reasons fit within limit it should return them unchanged",
- reasons: []string{capiv1.MachineHasFailureReason, capiv1.NodeConditionsFailedReason, capiv1.WaitingForNodeRefReason},
- expectSuffix: capiv1.WaitingForNodeRefReason,
+ reasons: []string{capiv1.MachineHasFailureV1Beta1Reason, capiv1.NodeConditionsFailedV1Beta1Reason, capiv1.WaitingForNodeRefV1Beta1Reason},
+ expectSuffix: capiv1.WaitingForNodeRefV1Beta1Reason,
expectMaxLen: maxReasonLength,
},
{
name: "When a single reason fits within limit it should return it unchanged",
- reasons: []string{capiv1.ExternalRemediationRequestCreationFailedReason},
- expectSuffix: capiv1.ExternalRemediationRequestCreationFailedReason,
+ reasons: []string{capiv1.ExternalRemediationRequestCreationFailedV1Beta1Reason},
+ expectSuffix: capiv1.ExternalRemediationRequestCreationFailedV1Beta1Reason,
expectMaxLen: maxReasonLength,
},
{
@@ -2108,40 +2108,40 @@ func TestTruncateReasons(t *testing.T) {
{
name: "When many CAPI reasons exceed limit it should truncate with ReasonsTruncated suffix",
reasons: []string{
- capiv1.WaitingForInfrastructureFallbackReason,
- capiv1.MachineHasFailureReason,
- capiv1.DeletingReason,
- capiv1.DeletionFailedReason,
- capiv1.DrainingReason,
- capiv1.DrainingFailedReason,
- capiv1.WaitingForVolumeDetachReason,
- capiv1.WaitingExternalHookReason,
- capiv1.PreflightCheckFailedReason,
- capiv1.MachineCreationFailedReason,
- capiv1.ScalingUpReason,
- capiv1.ScalingDownReason,
- capiv1.WaitingForDataSecretFallbackReason,
- capiv1.WaitingForControlPlaneFallbackReason,
- capiv1.WaitingForControlPlaneAvailableReason,
- capiv1.BootstrapTemplateCloningFailedReason,
- capiv1.InfrastructureTemplateCloningFailedReason,
- capiv1.IncorrectExternalRefReason,
- capiv1.RemediationFailedReason,
- capiv1.RemediationInProgressReason,
- capiv1.WaitingForRemediationReason,
- capiv1.NodeStartupTimeoutReason,
- capiv1.WaitingForNodeRefReason,
- capiv1.NodeProvisioningReason,
- capiv1.NodeNotFoundReason,
- capiv1.NodeConditionsFailedReason,
- capiv1.NodeInspectionFailedReason,
- capiv1.UnhealthyNodeConditionReason,
- capiv1.HasRemediateMachineAnnotationReason,
- capiv1.TooManyUnhealthyReason,
- capiv1.ExternalRemediationTemplateNotFoundReason,
- capiv1.ExternalRemediationRequestCreationFailedReason,
- capiv1.WaitingForControlPlaneProviderInitializedReason,
- capiv1.MissingNodeRefReason,
+ capiv1.WaitingForInfrastructureFallbackV1Beta1Reason,
+ capiv1.MachineHasFailureV1Beta1Reason,
+ capiv1.DeletingV1Beta1Reason,
+ capiv1.DeletionFailedV1Beta1Reason,
+ capiv1.DrainingV1Beta1Reason,
+ capiv1.DrainingFailedV1Beta1Reason,
+ capiv1.WaitingForVolumeDetachV1Beta1Reason,
+ capiv1.WaitingExternalHookV1Beta1Reason,
+ capiv1.PreflightCheckFailedV1Beta1Reason,
+ capiv1.MachineCreationFailedV1Beta1Reason,
+ capiv1.ScalingUpV1Beta1Reason,
+ capiv1.ScalingDownV1Beta1Reason,
+ capiv1.WaitingForDataSecretFallbackV1Beta1Reason,
+ capiv1.WaitingForControlPlaneFallbackV1Beta1Reason,
+ capiv1.WaitingForControlPlaneAvailableV1Beta1Reason,
+ capiv1.BootstrapTemplateCloningFailedV1Beta1Reason,
+ capiv1.InfrastructureTemplateCloningFailedV1Beta1Reason,
+ capiv1.IncorrectExternalRefV1Beta1Reason,
+ capiv1.RemediationFailedV1Beta1Reason,
+ capiv1.RemediationInProgressV1Beta1Reason,
+ capiv1.WaitingForRemediationV1Beta1Reason,
+ capiv1.NodeStartupTimeoutV1Beta1Reason,
+ capiv1.WaitingForNodeRefV1Beta1Reason,
+ capiv1.NodeProvisioningV1Beta1Reason,
+ capiv1.NodeNotFoundV1Beta1Reason,
+ capiv1.NodeConditionsFailedV1Beta1Reason,
+ capiv1.NodeInspectionFailedV1Beta1Reason,
+ capiv1.UnhealthyNodeConditionV1Beta1Reason,
+ capiv1.HasRemediateMachineAnnotationV1Beta1Reason,
+ capiv1.TooManyUnhealthyV1Beta1Reason,
+ capiv1.ExternalRemediationTemplateNotFoundV1Beta1Reason,
+ capiv1.ExternalRemediationRequestCreationFailedV1Beta1Reason,
+ capiv1.WaitingForControlPlaneProviderInitializedV1Beta1Reason,
+ capiv1.MissingNodeRefV1Beta1Reason,
// Realistic cloud-provider reasons (CAPA/CAPZ).
"InstanceTerminated",
"InstanceProvisionFailed",
@@ -2196,30 +2196,30 @@ func TestAggregateMachineReasonsAndMessages(t *testing.T) {
{
name: "When a single machine fails it should return its reason and message",
messageMap: map[string][]string{
- capiv1.NodeConditionsFailedReason: {
+ capiv1.NodeConditionsFailedV1Beta1Reason: {
"Machine machine-0: NodeConditionsFailed: Condition Ready on node is reporting status False\n",
},
},
numMachines: 3,
numNotReady: 1,
state: aggregatorMachineStateHealthy,
- expectReason: capiv1.NodeConditionsFailedReason,
+ expectReason: capiv1.NodeConditionsFailedV1Beta1Reason,
expectMessages: []string{"1 of 3 machines are not healthy", "Machine machine-0: NodeConditionsFailed: Condition Ready on node is reporting status False"},
},
{
name: "When machines fail with two reasons it should join reasons with comma",
messageMap: map[string][]string{
- capiv1.MachineHasFailureReason: {
+ capiv1.MachineHasFailureV1Beta1Reason: {
"Machine machine-0: MachineHasFailure: Machine has FailureReason: InsufficientCapacity\n",
},
- capiv1.WaitingForInfrastructureFallbackReason: {
+ capiv1.WaitingForInfrastructureFallbackV1Beta1Reason: {
"Machine machine-1: WaitingForInfrastructure\n",
},
},
numMachines: 5,
numNotReady: 2,
state: aggregatorMachineStateReady,
- expectReason: capiv1.MachineHasFailureReason + "," + capiv1.WaitingForInfrastructureFallbackReason,
+ expectReason: capiv1.MachineHasFailureV1Beta1Reason + "," + capiv1.WaitingForInfrastructureFallbackV1Beta1Reason,
expectMessages: []string{"2 of 5 machines are not ready", "Machine machine-0: MachineHasFailure", "Machine machine-1: WaitingForInfrastructure"},
},
{
@@ -2230,13 +2230,13 @@ func TestAggregateMachineReasonsAndMessages(t *testing.T) {
msgs[i] = fmt.Sprintf("Machine machine-%d: MachineHasFailure: Machine has FailureMessage: i-%012d is in terminated state\n", i, i)
}
return map[string][]string{
- capiv1.MachineHasFailureReason: msgs,
+ capiv1.MachineHasFailureV1Beta1Reason: msgs,
}
}(),
numMachines: 30,
numNotReady: 30,
state: aggregatorMachineStateReady,
- expectReason: capiv1.MachineHasFailureReason,
+ expectReason: capiv1.MachineHasFailureV1Beta1Reason,
expectMessages: []string{"30 of 30 machines are not ready", "Machine machine-0: MachineHasFailure", endOfMessage},
},
{
@@ -2245,16 +2245,16 @@ func TestAggregateMachineReasonsAndMessages(t *testing.T) {
m := make(map[string][]string)
// 10 distinct reasons, each with 20 machines producing ~1000 char blocks.
reasons := []string{
- capiv1.MachineHasFailureReason,
- capiv1.NodeConditionsFailedReason,
- capiv1.WaitingForInfrastructureFallbackReason,
- capiv1.DeletingReason,
- capiv1.DrainingReason,
- capiv1.NodeStartupTimeoutReason,
- capiv1.WaitingForNodeRefReason,
- capiv1.RemediationInProgressReason,
- capiv1.PreflightCheckFailedReason,
- capiv1.MachineCreationFailedReason,
+ capiv1.MachineHasFailureV1Beta1Reason,
+ capiv1.NodeConditionsFailedV1Beta1Reason,
+ capiv1.WaitingForInfrastructureFallbackV1Beta1Reason,
+ capiv1.DeletingV1Beta1Reason,
+ capiv1.DrainingV1Beta1Reason,
+ capiv1.NodeStartupTimeoutV1Beta1Reason,
+ capiv1.WaitingForNodeRefV1Beta1Reason,
+ capiv1.RemediationInProgressV1Beta1Reason,
+ capiv1.PreflightCheckFailedV1Beta1Reason,
+ capiv1.MachineCreationFailedV1Beta1Reason,
}
longMsg := strings.Repeat("x", 80)
machineIdx := 0
@@ -2277,7 +2277,7 @@ func TestAggregateMachineReasonsAndMessages(t *testing.T) {
{
name: "When messages within a reason are unsorted it should sort them deterministically",
messageMap: map[string][]string{
- capiv1.NodeConditionsFailedReason: {
+ capiv1.NodeConditionsFailedV1Beta1Reason: {
"Machine machine-2: NodeConditionsFailed: Condition MemoryPressure is True\n",
"Machine machine-0: NodeConditionsFailed: Condition Ready is False\n",
"Machine machine-1: NodeConditionsFailed: Condition DiskPressure is True\n",
@@ -2286,7 +2286,7 @@ func TestAggregateMachineReasonsAndMessages(t *testing.T) {
numMachines: 5,
numNotReady: 3,
state: aggregatorMachineStateHealthy,
- expectReason: capiv1.NodeConditionsFailedReason,
+ expectReason: capiv1.NodeConditionsFailedV1Beta1Reason,
// After sorting, machine-0 should come first, then machine-1, then machine-2.
expectMessages: []string{
"3 of 5 machines are not healthy",
diff --git a/hypershift-operator/controllers/nodepool/scale_from_zero_test.go b/hypershift-operator/controllers/nodepool/scale_from_zero_test.go
index bec100f788b2..281d8a31b655 100644
--- a/hypershift-operator/controllers/nodepool/scale_from_zero_test.go
+++ b/hypershift-operator/controllers/nodepool/scale_from_zero_test.go
@@ -15,7 +15,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
)
type mockProvider struct {
diff --git a/hypershift-operator/controllers/nodepool/version_test.go b/hypershift-operator/controllers/nodepool/version_test.go
index 581ad975c5ab..714ad85701f4 100644
--- a/hypershift-operator/controllers/nodepool/version_test.go
+++ b/hypershift-operator/controllers/nodepool/version_test.go
@@ -13,7 +13,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
- "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
@@ -21,7 +21,7 @@ import (
func TestNodeVersionsFromMachines(t *testing.T) {
testCases := []struct {
name string
- machines []*v1beta1.Machine
+ machines []*capiv1.Machine
nodePool *hyperv1.NodePool
expected []hyperv1.NodeVersion
}{
@@ -35,7 +35,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When all machines have the same version and are healthy it should return a single entry",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m2", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m3", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
@@ -49,7 +49,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When there are mixed versions during rolling upgrade it should return one entry per version",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m2", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m3", "v1.32.1", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.19.1"}),
@@ -64,7 +64,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When there is mixed health it should report ready and unready counts per version",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m2", "v1.32.1", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.19.1"}),
machineWithVersionAndHealth("m3", "v1.32.1", false, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.19.1"}),
@@ -79,7 +79,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When NodeHealthy condition is absent it should count the node as unready",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndConditions("m1", "v1.31.4", nil, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
},
nodePool: &hyperv1.NodePool{
@@ -91,14 +91,14 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When some machines have no NodeInfo it should skip them",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
{
ObjectMeta: metav1.ObjectMeta{
Name: "m2",
Annotations: map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.19.1"},
},
- Status: v1beta1.MachineStatus{
+ Status: capiv1.MachineStatus{
// NodeInfo is nil — not yet provisioned
},
},
@@ -112,10 +112,10 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When all machines have no NodeInfo it should return nil",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
{
ObjectMeta: metav1.ObjectMeta{Name: "m1"},
- Status: v1beta1.MachineStatus{},
+ Status: capiv1.MachineStatus{},
},
},
nodePool: &hyperv1.NodePool{
@@ -125,7 +125,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When machine has release-version annotation it should use it for ocpVersion",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
},
nodePool: &hyperv1.NodePool{
@@ -137,7 +137,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When machine has no annotation it should fall back to nodePool.Status.Version",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.31.4", true, nil),
},
nodePool: &hyperv1.NodePool{
@@ -149,7 +149,7 @@ func TestNodeVersionsFromMachines(t *testing.T) {
},
{
name: "When there are multiple versions it should sort by ocpVersion then kubeletVersion",
- machines: []*v1beta1.Machine{
+ machines: []*capiv1.Machine{
machineWithVersionAndHealth("m1", "v1.32.1", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.19.1"}),
machineWithVersionAndHealth("m2", "v1.31.4", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
machineWithVersionAndHealth("m3", "v1.31.5", true, map[string]string{hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12"}),
@@ -214,7 +214,7 @@ func TestSetNodesInfoStatus(t *testing.T) {
{
name: "When machines exist with NodeInfo it should populate NodesInfo",
machines: []client.Object{
- &v1beta1.Machine{
+ &capiv1.Machine{
ObjectMeta: metav1.ObjectMeta{
Name: "m1",
Namespace: "clusters-test-cluster",
@@ -223,10 +223,10 @@ func TestSetNodesInfoStatus(t *testing.T) {
hyperv1.NodePoolReleaseVersionAnnotation: "4.18.12",
},
},
- Status: v1beta1.MachineStatus{
+ Status: capiv1.MachineStatus{
NodeInfo: &corev1.NodeSystemInfo{KubeletVersion: "v1.31.4"},
- Conditions: v1beta1.Conditions{
- {Type: v1beta1.MachineNodeHealthyCondition, Status: corev1.ConditionTrue},
+ Conditions: []metav1.Condition{
+ {Type: capiv1.MachineNodeHealthyCondition, Status: metav1.ConditionStatus(corev1.ConditionTrue)},
},
},
},
@@ -252,7 +252,7 @@ func TestSetNodesInfoStatus(t *testing.T) {
{
name: "When all machines lack NodeInfo it should clear previously set NodesInfo",
machines: []client.Object{
- &v1beta1.Machine{
+ &capiv1.Machine{
ObjectMeta: metav1.ObjectMeta{
Name: "m1",
Namespace: "clusters-test-cluster",
@@ -260,7 +260,7 @@ func TestSetNodesInfoStatus(t *testing.T) {
nodePoolAnnotation: "clusters/test-nodepool",
},
},
- Status: v1beta1.MachineStatus{},
+ Status: capiv1.MachineStatus{},
},
},
nodePool: &hyperv1.NodePool{
@@ -303,23 +303,23 @@ func TestSetNodesInfoStatus(t *testing.T) {
}
}
-func machineWithVersionAndHealth(name, kubeletVersion string, healthy bool, annotations map[string]string) *v1beta1.Machine {
- healthStatus := corev1.ConditionTrue
+func machineWithVersionAndHealth(name, kubeletVersion string, healthy bool, annotations map[string]string) *capiv1.Machine {
+ healthStatus := metav1.ConditionStatus(corev1.ConditionTrue)
if !healthy {
- healthStatus = corev1.ConditionFalse
+ healthStatus = metav1.ConditionStatus(corev1.ConditionFalse)
}
- return machineWithVersionAndConditions(name, kubeletVersion, v1beta1.Conditions{
- {Type: v1beta1.MachineNodeHealthyCondition, Status: healthStatus},
+ return machineWithVersionAndConditions(name, kubeletVersion, []metav1.Condition{
+ {Type: capiv1.MachineNodeHealthyCondition, Status: healthStatus},
}, annotations)
}
-func machineWithVersionAndConditions(name, kubeletVersion string, conditions v1beta1.Conditions, annotations map[string]string) *v1beta1.Machine {
- return &v1beta1.Machine{
+func machineWithVersionAndConditions(name, kubeletVersion string, conditions []metav1.Condition, annotations map[string]string) *capiv1.Machine {
+ return &capiv1.Machine{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Annotations: annotations,
},
- Status: v1beta1.MachineStatus{
+ Status: capiv1.MachineStatus{
NodeInfo: &corev1.NodeSystemInfo{KubeletVersion: kubeletVersion},
Conditions: conditions,
},
diff --git a/karpenter-operator/controllers/karpenter/karpenter_controller_test.go b/karpenter-operator/controllers/karpenter/karpenter_controller_test.go
index 7cfb9e94301a..2ce6451a9d1a 100644
--- a/karpenter-operator/controllers/karpenter/karpenter_controller_test.go
+++ b/karpenter-operator/controllers/karpenter/karpenter_controller_test.go
@@ -20,7 +20,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
diff --git a/test/e2e/autoscaling_test.go b/test/e2e/autoscaling_test.go
index 62f5c07374bd..584a615672ab 100644
--- a/test/e2e/autoscaling_test.go
+++ b/test/e2e/autoscaling_test.go
@@ -26,7 +26,7 @@ import (
"k8s.io/client-go/util/retry"
"k8s.io/utils/ptr"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -779,7 +779,7 @@ func testScaleFromZero(ctx context.Context, mgtClient crclient.Client, hostedClu
// Get the AWSMachineTemplate to check for Status.Capacity
awsMachineTemplate := &capiaws.AWSMachineTemplate{}
err = mgtClient.Get(ctx, crclient.ObjectKey{
- Namespace: md.Spec.Template.Spec.InfrastructureRef.Namespace,
+ Namespace: md.Namespace,
Name: md.Spec.Template.Spec.InfrastructureRef.Name,
}, awsMachineTemplate)
if err != nil {
@@ -830,7 +830,7 @@ func testScaleFromZero(ctx context.Context, mgtClient crclient.Client, hostedClu
// Get the AWSMachineTemplate again to display capacity info
awsMachineTemplate := &capiaws.AWSMachineTemplate{}
err = mgtClient.Get(ctx, crclient.ObjectKey{
- Namespace: md.Spec.Template.Spec.InfrastructureRef.Namespace,
+ Namespace: md.Namespace,
Name: md.Spec.Template.Spec.InfrastructureRef.Name,
}, awsMachineTemplate)
g.Expect(err).NotTo(HaveOccurred(), "failed to get AWSMachineTemplate for logging")
diff --git a/test/e2e/nodepool_day2_tags_test.go b/test/e2e/nodepool_day2_tags_test.go
index 2267acc635da..c43eebe5d6b3 100644
--- a/test/e2e/nodepool_day2_tags_test.go
+++ b/test/e2e/nodepool_day2_tags_test.go
@@ -17,7 +17,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/test/e2e/nodepool_kv_advanced_multinet_test.go b/test/e2e/nodepool_kv_advanced_multinet_test.go
index 4934ced402e5..b71e54c0f09c 100644
--- a/test/e2e/nodepool_kv_advanced_multinet_test.go
+++ b/test/e2e/nodepool_kv_advanced_multinet_test.go
@@ -22,7 +22,7 @@ import (
"k8s.io/utils/ptr"
kubevirtv1 "kubevirt.io/api/core/v1"
capkv1alpha1 "sigs.k8s.io/cluster-api-provider-kubevirt/api/v1alpha1"
- clusterapiv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/controller-runtime/pkg/client"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -261,7 +261,7 @@ func (k KubeVirtAdvancedMultinetTest) firstMachineAddress() (string, error) {
namespace := manifests.HostedControlPlaneNamespace(k.infra.HostedCluster().Namespace, k.infra.HostedCluster().Name)
if err := k.infra.MGMTClient().List(k.infra.Ctx(), &machineList, client.InNamespace(namespace),
client.MatchingLabels{
- clusterapiv1beta1.MachineDeploymentNameLabel: k.nodePoolName,
+ capiv1.MachineDeploymentNameLabel: k.nodePoolName,
}); err != nil {
return "", err
}
diff --git a/test/e2e/nodepool_osp_advanced_test.go b/test/e2e/nodepool_osp_advanced_test.go
index 4d03a9aa2330..f7b726362ed5 100644
--- a/test/e2e/nodepool_osp_advanced_test.go
+++ b/test/e2e/nodepool_osp_advanced_test.go
@@ -16,7 +16,7 @@ import (
"k8s.io/utils/ptr"
capiopenstackv1alpha1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha1"
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -167,10 +167,10 @@ func (o OpenStackAdvancedTest) Run(t *testing.T, nodePool hyperv1.NodePool, _ []
},
[]e2eutil.Predicate[*capiv1.Machine]{
func(machine *capiv1.Machine) (done bool, reasons string, err error) {
- if machine.Spec.FailureDomain == nil {
+ if machine.Spec.FailureDomain == "" {
return false, "Machine does not have a failure domain", nil
}
- want, got := getAZName(), *machine.Spec.FailureDomain
+ want, got := getAZName(), machine.Spec.FailureDomain
return want == got, fmt.Sprintf("expected Machine to have failure domain %s, got %s", want, got), nil
},
},
diff --git a/test/e2e/nodepool_rolling_upgrade_test.go b/test/e2e/nodepool_rolling_upgrade_test.go
index 120a78dd6c84..6a3e9402c912 100644
--- a/test/e2e/nodepool_rolling_upgrade_test.go
+++ b/test/e2e/nodepool_rolling_upgrade_test.go
@@ -17,7 +17,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiaws "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
capiazure "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util/labels/format"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/test/e2e/nodepool_spot_termination_handler_test.go b/test/e2e/nodepool_spot_termination_handler_test.go
index 2ade4368de71..1b4a66bfbcd7 100644
--- a/test/e2e/nodepool_spot_termination_handler_test.go
+++ b/test/e2e/nodepool_spot_termination_handler_test.go
@@ -20,7 +20,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
diff --git a/test/e2e/upgrade_hypershift_operator_test.go b/test/e2e/upgrade_hypershift_operator_test.go
index bf8aca31e9ef..7243355d5388 100644
--- a/test/e2e/upgrade_hypershift_operator_test.go
+++ b/test/e2e/upgrade_hypershift_operator_test.go
@@ -14,7 +14,7 @@ import (
e2eutil "github.com/openshift/hypershift/test/e2e/util"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
- "sigs.k8s.io/cluster-api/api/core/v1beta1"
+ capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -38,7 +38,7 @@ func TestUpgradeHyperShiftOperator(t *testing.T) {
var hostedCluster *hyperv1.HostedCluster
var hcpNameSpace string
var nodePoolsMap map[string]*hyperv1.NodePool
- var machineDeploymentMap map[string]*v1beta1.MachineDeployment
+ var machineDeploymentMap map[string]*capiv1.MachineDeployment
hyperShiftOperatorLatestImage := globalOpts.HyperShiftOperatorLatestImage
@@ -110,7 +110,7 @@ func TestUpgradeHyperShiftOperator(t *testing.T) {
}
// Get the MachineDeployments
- machineDeployments := &v1beta1.MachineDeploymentList{}
+ machineDeployments := &capiv1.MachineDeploymentList{}
hcpNameSpace = manifests.HostedControlPlaneNamespace(hostedCluster.Namespace, hostedCluster.Name)
err = mgmtClient.List(ctx, machineDeployments, crclient.InNamespace(hcpNameSpace))
@@ -122,7 +122,7 @@ func TestUpgradeHyperShiftOperator(t *testing.T) {
g.Expect(len(machineDeployments.Items)).To(gomega.BeEquivalentTo(len(nodepools.Items)),
"Number of MachineDeployments and NodePools should match")
- machineDeploymentMap = make(map[string]*v1beta1.MachineDeployment)
+ machineDeploymentMap = make(map[string]*capiv1.MachineDeployment)
t.Logf("Found %d MachineDeployments", len(machineDeployments.Items))
for i := range machineDeployments.Items {
t.Logf("Found MachineDeployment %s", machineDeployments.Items[i].Name)
@@ -202,7 +202,7 @@ func TestUpgradeHyperShiftOperator(t *testing.T) {
}
}
- postUpgradeMachineDeployments := &v1beta1.MachineDeploymentList{}
+ postUpgradeMachineDeployments := &capiv1.MachineDeploymentList{}
err = mgmtClient.List(ctx, postUpgradeMachineDeployments, crclient.InNamespace(hcpNameSpace))
if err != nil {
gomega.StopTrying(fmt.Sprintf("Error listing MachineDeployments: %v", err)).Now()
@@ -213,7 +213,7 @@ func TestUpgradeHyperShiftOperator(t *testing.T) {
}
for _, machineDeployment := range postUpgradeMachineDeployments.Items {
t.Logf("Verifying MachineDeployment %s", machineDeployment.Name)
- var preUpgradeMachineDeployment *v1beta1.MachineDeployment
+ var preUpgradeMachineDeployment *capiv1.MachineDeployment
var ok bool
if preUpgradeMachineDeployment, ok = machineDeploymentMap[machineDeployment.Name]; !ok {
gomega.StopTrying(fmt.Sprintf("MachineDeployment %s not found", machineDeployment.Name)).Now()
From 5e45908fed41099062fe723731cd480548d64032 Mon Sep 17 00:00:00 2001
From: Borja Clemente
Date: Thu, 11 Jun 2026 15:27:02 +0200
Subject: [PATCH 3/5] build(vendor): Update vendor
Update vendored dependencies after updating clients.
Signed-off-by: Borja Clemente
---
.../hypershift/v1beta1/hosted_controlplane.go | 16 ++++++++++----
.../v1beta1/zz_generated.deepcopy.go | 21 +++++++++++++++++++
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
index a2dfc2449c90..cfc63ec4be22 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/hosted_controlplane.go
@@ -420,16 +420,24 @@ type HostedControlPlaneStatus struct {
// +optional
Configuration *ConfigurationStatus `json:"configuration,omitempty"`
- // Initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ // initialization contains fields that track the status of the initialization of the HostedControlPlane.
+ // This satisfies the CAPI v1beta2 ControlPlane provider contract:
+ // https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
// +optional
- // +kubebuilder:validation:MinProperties=1
Initialization HostedControlPlaneInitializationStatus `json:"initialization,omitzero"`
}
-// HostedControlPlaneInitializationStatus defines the observed initialization state of the HostedControlPlane.
+// HostedControlPlaneInitializationStatus provides observations of the HostedControlPlane initialization process.
+// This satisfies the CAPI v1beta2 ControlPlane provider contract:
+// https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1361-L1379
+// +kubebuilder:validation:MinProperties=1
type HostedControlPlaneInitializationStatus struct {
- // ControlPlaneInitialized denotes whether the control plane has been initialized.
+ // controlPlaneInitialized is true when the control plane is functional enough to accept requests.
+ // Once this condition is marked true, its value is never changed. See the Ready condition for an
+ // indication of the current readiness of the cluster's control plane.
+ // This satisfies CAPI contract https://github.com/kubernetes-sigs/cluster-api/blob/v1.11.5/api/core/v1beta2/cluster_types.go#L1371-L1379
// +optional
+ // +default=false
ControlPlaneInitialized *bool `json:"controlPlaneInitialized,omitempty"`
}
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 454f86378499..b9e2e2546e76 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -2500,6 +2500,26 @@ func (in *HostedControlPlane) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HostedControlPlaneInitializationStatus) DeepCopyInto(out *HostedControlPlaneInitializationStatus) {
+ *out = *in
+ if in.ControlPlaneInitialized != nil {
+ in, out := &in.ControlPlaneInitialized, &out.ControlPlaneInitialized
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneInitializationStatus.
+func (in *HostedControlPlaneInitializationStatus) DeepCopy() *HostedControlPlaneInitializationStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(HostedControlPlaneInitializationStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HostedControlPlaneList) DeepCopyInto(out *HostedControlPlaneList) {
*out = *in
@@ -2697,6 +2717,7 @@ func (in *HostedControlPlaneStatus) DeepCopyInto(out *HostedControlPlaneStatus)
*out = new(ConfigurationStatus)
(*in).DeepCopyInto(*out)
}
+ in.Initialization.DeepCopyInto(&out.Initialization)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostedControlPlaneStatus.
From 0558b2b85fe3d31f67d3bff4266ad694f82d2837 Mon Sep 17 00:00:00 2001
From: Borja Clemente
Date: Wed, 17 Jun 2026 18:18:57 +0200
Subject: [PATCH 4/5] fix(machineDeployment): fallback to v1beta1 fields
If v1beta2 fields have been nilled out after conversion, fallback to
v1beta1 fields to check for MD completion.
Signed-off-by: Borja Clemente
---
.../controllers/nodepool/capi.go | 4 +-
.../nodepool/nodepool_controller.go | 85 ++++++++++---------
2 files changed, 49 insertions(+), 40 deletions(-)
diff --git a/hypershift-operator/controllers/nodepool/capi.go b/hypershift-operator/controllers/nodepool/capi.go
index 9e9bf8bed4fa..d9cea0256b77 100644
--- a/hypershift-operator/controllers/nodepool/capi.go
+++ b/hypershift-operator/controllers/nodepool/capi.go
@@ -638,7 +638,7 @@ func (c *CAPI) reconcileMachineDeploymentStatus(log logr.Logger, machineDeployme
}
}
- nodePool.Status.Replicas = ptr.Deref(machineDeployment.Status.AvailableReplicas, 0)
+ nodePool.Status.Replicas = availableReplicasFromMachineDeployment(machineDeployment)
for _, c := range machineDeployment.Status.Conditions {
// In CAPI v1beta2 "Ready" was replaced by "MachinesReady" (True when all machines are ready).
// https://github.com/kubernetes-sigs/cluster-api/issues/3486.
@@ -1054,7 +1054,7 @@ func (c *CAPI) reconcileMachineSet(ctx context.Context,
}
// Bubble up AvailableReplicas and Ready condition from MachineSet.
- nodePool.Status.Replicas = ptr.Deref(machineSet.Status.AvailableReplicas, 0)
+ nodePool.Status.Replicas = availableReplicasFromMachineSet(machineSet)
for _, c := range machineSet.Status.Conditions {
// In CAPI v1beta2 "Ready" was replaced by "MachinesReady" (True when all machines are ready).
// https://github.com/kubernetes-sigs/cluster-api/issues/3486.
diff --git a/hypershift-operator/controllers/nodepool/nodepool_controller.go b/hypershift-operator/controllers/nodepool/nodepool_controller.go
index f0463f70d70e..e3d42c6b5566 100644
--- a/hypershift-operator/controllers/nodepool/nodepool_controller.go
+++ b/hypershift-operator/controllers/nodepool/nodepool_controller.go
@@ -2,7 +2,6 @@ package nodepool
import (
"context"
- "encoding/json"
coreerrors "errors"
"fmt"
"os"
@@ -44,7 +43,6 @@ import (
capiopenstackv1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
capiv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util"
- "sigs.k8s.io/cluster-api/util/conversion"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -780,53 +778,64 @@ func defaultNodePoolGCPImage(specifiedArch string, releaseImage *releaseinfo.Rel
// MachineDeploymentComplete considers a MachineDeployment to be complete once all of its desired replicas
// are updated and available, and no old machines are running.
+//
+// When v1beta1 is the storage version, a v1beta1-native CAPI controller populates only the
+// deprecated v1beta1 status fields; the v1beta2 conversion resets the top-level replica
+// counters and only restores them from the V1Beta2 substruct (which a v1beta1 controller
+// never writes). We therefore fall back to the deprecated fields when the top-level ones
+// are nil.
func MachineDeploymentComplete(deployment *capiv1.MachineDeployment) bool {
+ if deployment.Status.ObservedGeneration < deployment.Generation {
+ return false
+ }
+
desired := ptr.Deref(deployment.Spec.Replicas, 0)
- s := &deployment.Status
- // As long as storage version is v1beta1 conversion happens, causing flickering on this check.
- // TODO(bclement): Remove conversion data check when storage version is v1beta2
- conversionComplete := ptr.Deref(s.UpToDateReplicas, 0) == desired &&
- ptr.Deref(s.Replicas, 0) == desired &&
- ptr.Deref(s.AvailableReplicas, 0) == desired &&
- s.ObservedGeneration >= deployment.Generation
+ available := ptr.Deref(deployment.Status.AvailableReplicas, 0)
+ replicas := ptr.Deref(deployment.Status.Replicas, 0)
- if !conversionComplete {
- return false
+ // When v1beta2 fields are populated (v1beta2-native CAPI controller or V1Beta2 substruct
+ // present in storage), also require UpToDateReplicas to match.
+ if deployment.Status.UpToDateReplicas != nil {
+ return ptr.Deref(deployment.Status.UpToDateReplicas, 0) == desired &&
+ replicas == desired &&
+ available == desired
}
- return machineDeploymentCompleteFromConversionData(deployment)
-}
-// machineDeploymentCompleteFromConversionData parses the v1beta2 conversion-data annotation
-// and verifies that the native v1beta2 status also indicates completion. If the annotation
-// is absent (e.g. CAPI < v1.11), returns true to preserve backwards compatibility.
-func machineDeploymentCompleteFromConversionData(deployment *capiv1.MachineDeployment) bool {
- raw, ok := deployment.Annotations[conversion.DataAnnotation]
- if !ok {
- return true
+ // Fall back to deprecated v1beta1 fields for controllers that only write v1beta1 status.
+ if deployment.Status.Deprecated != nil && deployment.Status.Deprecated.V1Beta1 != nil {
+ dep := deployment.Status.Deprecated.V1Beta1
+ return dep.UpdatedReplicas == desired && //nolint:staticcheck
+ dep.AvailableReplicas == desired && //nolint:staticcheck
+ replicas == desired
}
- var v1beta2MD struct {
- Spec struct {
- Replicas *int32 `json:"replicas"`
- } `json:"spec"`
- Status struct {
- ObservedGeneration int64 `json:"observedGeneration"`
- Replicas *int32 `json:"replicas"`
- AvailableReplicas *int32 `json:"availableReplicas"`
- UpToDateReplicas *int32 `json:"upToDateReplicas"`
- } `json:"status"`
+ return replicas == desired && available == desired
+}
+
+func availableReplicasFromMachineSet(ms *capiv1.MachineSet) int32 {
+ if ms.Status.AvailableReplicas != nil {
+ return *ms.Status.AvailableReplicas
}
- if err := json.Unmarshal([]byte(raw), &v1beta2MD); err != nil {
- ctrl.Log.WithName("nodepool").Error(err, "Failed to unmarshal conversion-data annotation, falling back to v1beta1 status")
- return true
+ if ms.Status.Deprecated != nil && ms.Status.Deprecated.V1Beta1 != nil {
+ return ms.Status.Deprecated.V1Beta1.AvailableReplicas //nolint:staticcheck
}
+ return 0
+}
- desired := ptr.Deref(v1beta2MD.Spec.Replicas, 0)
- return ptr.Deref(v1beta2MD.Status.UpToDateReplicas, 0) == desired &&
- ptr.Deref(v1beta2MD.Status.Replicas, 0) == desired &&
- ptr.Deref(v1beta2MD.Status.AvailableReplicas, 0) == desired &&
- v1beta2MD.Status.ObservedGeneration >= deployment.Generation
+// availableReplicasFromMachineDeployment returns the number of available replicas from a MachineDeployment,
+// falling back to the deprecated v1beta1 status fields when the v1beta2 top-level fields are nil.
+// This fallback is necessary while v1beta1 is the storage version: the v1beta1→v1beta2 conversion
+// resets the top-level AvailableReplicas to nil and only restores it from the V1Beta2 substruct,
+// which a v1beta1-native CAPI controller never populates.
+func availableReplicasFromMachineDeployment(deployment *capiv1.MachineDeployment) int32 {
+ if deployment.Status.AvailableReplicas != nil {
+ return *deployment.Status.AvailableReplicas
+ }
+ if deployment.Status.Deprecated != nil && deployment.Status.Deprecated.V1Beta1 != nil {
+ return deployment.Status.Deprecated.V1Beta1.AvailableReplicas //nolint:staticcheck
+ }
+ return 0
}
// GetHostedClusterByName finds and return a HostedCluster object using the specified params.
From 91ae6c1126f7ededc69fb421053db5188a579faa Mon Sep 17 00:00:00 2001
From: Borja Clemente
Date: Wed, 17 Jun 2026 18:19:59 +0200
Subject: [PATCH 5/5] test(MachineDeployment): update tests after fixing
completion check
Signed-off-by: Borja Clemente
---
.../controllers/nodepool/capi_test.go | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/hypershift-operator/controllers/nodepool/capi_test.go b/hypershift-operator/controllers/nodepool/capi_test.go
index ef3b743c900a..472cf0d029b1 100644
--- a/hypershift-operator/controllers/nodepool/capi_test.go
+++ b/hypershift-operator/controllers/nodepool/capi_test.go
@@ -3365,6 +3365,55 @@ func TestMachineDeploymentComplete(t *testing.T) {
},
expected: true,
},
+ {
+ name: "When v1beta2 fields are nil but deprecated v1beta1 fields match it should return true",
+ md: &capiv1.MachineDeployment{
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
+ Deprecated: &capiv1.MachineDeploymentDeprecatedStatus{
+ V1Beta1: &capiv1.MachineDeploymentV1Beta1DeprecatedStatus{
+ UpdatedReplicas: 2,
+ AvailableReplicas: 2,
+ },
+ },
+ },
+ },
+ expected: true,
+ },
+ {
+ name: "When v1beta2 fields are nil and deprecated v1beta1 available does not match it should return false",
+ md: &capiv1.MachineDeployment{
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
+ Deprecated: &capiv1.MachineDeploymentDeprecatedStatus{
+ V1Beta1: &capiv1.MachineDeploymentV1Beta1DeprecatedStatus{
+ UpdatedReplicas: 2,
+ AvailableReplicas: 1,
+ },
+ },
+ },
+ },
+ expected: false,
+ },
+ {
+ name: "When all v1beta2 and deprecated fields are nil it should fall back to replicas check",
+ md: &capiv1.MachineDeployment{
+ ObjectMeta: metav1.ObjectMeta{Generation: 2},
+ Spec: capiv1.MachineDeploymentSpec{Replicas: ptr.To[int32](2)},
+ Status: capiv1.MachineDeploymentStatus{
+ Replicas: ptr.To[int32](2),
+ AvailableReplicas: ptr.To[int32](2),
+ ObservedGeneration: 2,
+ },
+ },
+ expected: true,
+ },
}
for _, tc := range testCases {