diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 088de569..2e6eac85 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ // Features to add to the dev container. More info: https://containers.dev/features. "features": { "ghcr.io/devcontainers/features/go:1": { - "version": "1.23" + "version": "1.24" }, "ghcr.io/devcontainers/features/docker-in-docker:2": {}, "ghcr.io/mpriscella/features/kind:1": {}, diff --git a/.golangci.yml b/.golangci.yml index 0d18f343..0761b112 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,6 @@ version: "2" run: - go: "1.23" + go: "1.24" allow-parallel-runners: true linters: default: all diff --git a/bootstrap/api/v1beta1/condition_consts.go b/bootstrap/api/v1beta1/condition_consts.go index 839d5674..e5945a13 100644 --- a/bootstrap/api/v1beta1/condition_consts.go +++ b/bootstrap/api/v1beta1/condition_consts.go @@ -17,7 +17,7 @@ limitations under the License. package v1beta1 import ( - clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1" // nolint:staticcheck + clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta2" ) const ( diff --git a/bootstrap/api/v1beta1/conversion.go b/bootstrap/api/v1beta1/conversion.go index b412403d..8ee29ffa 100644 --- a/bootstrap/api/v1beta1/conversion.go +++ b/bootstrap/api/v1beta1/conversion.go @@ -165,7 +165,6 @@ func Convert_v1beta1_RKE2ConfigStatus_To_v1beta2_RKE2ConfigStatus(in *RKE2Config } // Reset conditions from autogenerated conversions - // NOTE: v1beta1 conditions should not be automatically be converted into v1beta2 conditions. out.Conditions = nil // Retrieve new conditions (v1beta2) from the v1beta2 field. @@ -173,19 +172,6 @@ func Convert_v1beta1_RKE2ConfigStatus_To_v1beta2_RKE2ConfigStatus(in *RKE2Config out.Conditions = in.V1Beta2.Conditions } - // Move legacy conditions (v1beta1), failureReason and failureMessage to the deprecated field. - if out.Deprecated == nil { - out.Deprecated = &bootstrapv1.RKE2ConfigDeprecatedStatus{} - } - if out.Deprecated.V1Beta1 == nil { - out.Deprecated.V1Beta1 = &bootstrapv1.RKE2ConfigV1Beta1DeprecatedStatus{} - } - if in.Conditions != nil { - clusterv1beta1.Convert_v1beta1_Conditions_To_v1beta2_Deprecated_V1Beta1_Conditions(&in.Conditions, &out.Deprecated.V1Beta1.Conditions) - } - out.Deprecated.V1Beta1.FailureReason = in.FailureReason - out.Deprecated.V1Beta1.FailureMessage = in.FailureMessage - return nil } @@ -196,17 +182,10 @@ func Convert_v1beta2_RKE2ConfigStatus_To_v1beta1_RKE2ConfigStatus(in *bootstrapv } // Reset conditions from autogenerated conversions - // NOTE: v1beta2 conditions should not be automatically be converted into legacy conditions (v1beta1). out.Conditions = nil - // Retrieve legacy conditions (v1beta1), failureReason and failureMessage from the deprecated field. - if in.Deprecated != nil && in.Deprecated.V1Beta1 != nil { - if in.Deprecated.V1Beta1.Conditions != nil { - clusterv1beta1.Convert_v1beta2_Deprecated_V1Beta1_Conditions_To_v1beta1_Conditions(&in.Deprecated.V1Beta1.Conditions, &out.Conditions) - } - out.FailureReason = in.Deprecated.V1Beta1.FailureReason - out.FailureMessage = in.Deprecated.V1Beta1.FailureMessage - } + // v1beta1 conditions are no longer stored in v1beta2, so out.Conditions stays empty on down-conversion. + // FailureReason and FailureMessage are also dropped. // Move initialization to old fields out.Ready = ptr.Deref(in.Initialization.DataSecretCreated, false) diff --git a/bootstrap/api/v1beta1/zz_generated.conversion.go b/bootstrap/api/v1beta1/zz_generated.conversion.go index 18b50ae3..b81ea351 100644 --- a/bootstrap/api/v1beta1/zz_generated.conversion.go +++ b/bootstrap/api/v1beta1/zz_generated.conversion.go @@ -683,7 +683,6 @@ func autoConvert_v1beta2_RKE2ConfigStatus_To_v1beta1_RKE2ConfigStatus(in *v1beta // WARNING: in.Initialization requires manual conversion: does not exist in peer-type out.DataSecretName = (*string)(unsafe.Pointer(in.DataSecretName)) out.ObservedGeneration = in.ObservedGeneration - // WARNING: in.Deprecated requires manual conversion: does not exist in peer-type return nil } diff --git a/bootstrap/api/v1beta2/rke2config_types.go b/bootstrap/api/v1beta2/rke2config_types.go index 28c11d9a..972adc62 100644 --- a/bootstrap/api/v1beta2/rke2config_types.go +++ b/bootstrap/api/v1beta2/rke2config_types.go @@ -19,8 +19,6 @@ package v1beta2 import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" ) // Format specifies the output format of the bootstrap data @@ -226,10 +224,6 @@ type RKE2ConfigStatus struct { // ObservedGeneration is the latest generation observed by the controller. //+optional ObservedGeneration int64 `json:"observedGeneration,omitempty"` - - // deprecated groups all the status fields that are deprecated and will be removed when all the nested field are removed. - // +optional - Deprecated *RKE2ConfigDeprecatedStatus `json:"deprecated,omitempty"` } // RKE2ConfigInitializationStatus provides observations of the RKE2Config initialization process. @@ -241,41 +235,6 @@ type RKE2ConfigInitializationStatus struct { DataSecretCreated *bool `json:"dataSecretCreated,omitempty"` } -// RKE2ConfigDeprecatedStatus groups all the status fields that are deprecated and will be removed in a future version. -type RKE2ConfigDeprecatedStatus struct { - // v1beta1 groups all the status fields that are deprecated and will be removed when support for v1beta1 is dropped. - // +optional - V1Beta1 *RKE2ConfigV1Beta1DeprecatedStatus `json:"v1beta1,omitempty"` -} - -// RKE2ConfigV1Beta1DeprecatedStatus groups all the status fields that are deprecated and will be removed when support for v1beta1 is dropped. -type RKE2ConfigV1Beta1DeprecatedStatus struct { - // conditions defines current service state of the RKE2Config. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - Conditions clusterv1.Conditions `json:"conditions,omitempty"` - - // failureReason will be set on non-retryable errors - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=256 - FailureReason string `json:"failureReason,omitempty"` - - // failureMessage will be set on non-retryable errors - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=10240 - FailureMessage string `json:"failureMessage,omitempty"` -} - // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:storageversion @@ -303,28 +262,6 @@ func (r *RKE2Config) SetConditions(conditions []metav1.Condition) { r.Status.Conditions = conditions } -// GetV1Beta1Conditions returns the set of conditions for this object. -func (r *RKE2Config) GetV1Beta1Conditions() clusterv1.Conditions { - if r.Status.Deprecated == nil || r.Status.Deprecated.V1Beta1 == nil { - return nil - } - - return r.Status.Deprecated.V1Beta1.Conditions -} - -// SetV1Beta1Conditions sets the conditions on this object. -func (r *RKE2Config) SetV1Beta1Conditions(conditions clusterv1.Conditions) { - if r.Status.Deprecated == nil { - r.Status.Deprecated = &RKE2ConfigDeprecatedStatus{} - } - - if r.Status.Deprecated.V1Beta1 == nil { - r.Status.Deprecated.V1Beta1 = &RKE2ConfigV1Beta1DeprecatedStatus{} - } - - r.Status.Deprecated.V1Beta1.Conditions = conditions -} - // +kubebuilder:object:root=true // RKE2ConfigList contains a list of RKE2Config. diff --git a/bootstrap/api/v1beta2/zz_generated.deepcopy.go b/bootstrap/api/v1beta2/zz_generated.deepcopy.go index cb941421..ce8fd272 100644 --- a/bootstrap/api/v1beta2/zz_generated.deepcopy.go +++ b/bootstrap/api/v1beta2/zz_generated.deepcopy.go @@ -24,7 +24,6 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - corev1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -280,26 +279,6 @@ func (in *RKE2Config) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RKE2ConfigDeprecatedStatus) DeepCopyInto(out *RKE2ConfigDeprecatedStatus) { - *out = *in - if in.V1Beta1 != nil { - in, out := &in.V1Beta1, &out.V1Beta1 - *out = new(RKE2ConfigV1Beta1DeprecatedStatus) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ConfigDeprecatedStatus. -func (in *RKE2ConfigDeprecatedStatus) DeepCopy() *RKE2ConfigDeprecatedStatus { - if in == nil { - return nil - } - out := new(RKE2ConfigDeprecatedStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RKE2ConfigInitializationStatus) DeepCopyInto(out *RKE2ConfigInitializationStatus) { *out = *in @@ -407,11 +386,6 @@ func (in *RKE2ConfigStatus) DeepCopyInto(out *RKE2ConfigStatus) { *out = new(string) **out = **in } - if in.Deprecated != nil { - in, out := &in.Deprecated, &out.Deprecated - *out = new(RKE2ConfigDeprecatedStatus) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ConfigStatus. @@ -514,28 +488,6 @@ func (in *RKE2ConfigTemplateSpec) DeepCopy() *RKE2ConfigTemplateSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RKE2ConfigV1Beta1DeprecatedStatus) DeepCopyInto(out *RKE2ConfigV1Beta1DeprecatedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make(corev1beta2.Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ConfigV1Beta1DeprecatedStatus. -func (in *RKE2ConfigV1Beta1DeprecatedStatus) DeepCopy() *RKE2ConfigV1Beta1DeprecatedStatus { - if in == nil { - return nil - } - out := new(RKE2ConfigV1Beta1DeprecatedStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Registry) DeepCopyInto(out *Registry) { *out = *in diff --git a/bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configs.yaml b/bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configs.yaml index 3408d93f..4dd5f83b 100644 --- a/bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configs.yaml +++ b/bootstrap/config/crd/bases/bootstrap.cluster.x-k8s.io_rke2configs.yaml @@ -1305,88 +1305,6 @@ spec: description: DataSecretName is the name of the secret that stores the bootstrap data script. type: string - deprecated: - description: deprecated groups all the status fields that are deprecated - and will be removed when all the nested field are removed. - properties: - v1beta1: - description: v1beta1 groups all the status fields that are deprecated - and will be removed when support for v1beta1 is dropped. - properties: - conditions: - description: |- - conditions defines current service state of the RKE2Config. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - items: - description: Condition defines an observation of a Cluster - API resource operational state. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when - the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This field may be empty. - maxLength: 10240 - minLength: 1 - type: string - reason: - description: |- - reason is the reason for the condition's last transition in CamelCase. - The specific API may choose whether or not this field is considered a guaranteed API. - This field may be empty. - maxLength: 256 - minLength: 1 - type: string - severity: - description: |- - severity provides an explicit classification of Reason code, so the users or machines can immediately - understand the current situation and act accordingly. - The Severity field MUST be set only when Status=False. - maxLength: 32 - type: string - status: - description: status of the condition, one of True, False, - Unknown. - type: string - type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - Many .condition.type values are consistent across resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability to deconflict is important. - maxLength: 256 - minLength: 1 - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - failureMessage: - description: |- - failureMessage will be set on non-retryable errors - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - maxLength: 10240 - minLength: 1 - type: string - failureReason: - description: |- - failureReason will be set on non-retryable errors - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - maxLength: 256 - minLength: 1 - type: string - type: object - type: object initialization: description: |- initialization provides observations of the RKE2Config initialization process. diff --git a/bootstrap/internal/controllers/rke2config_controller.go b/bootstrap/internal/controllers/rke2config_controller.go index bb893efc..3c78de14 100644 --- a/bootstrap/internal/controllers/rke2config_controller.go +++ b/bootstrap/internal/controllers/rke2config_controller.go @@ -45,7 +45,6 @@ import ( "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/annotations" "sigs.k8s.io/cluster-api/util/conditions" - v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" "sigs.k8s.io/cluster-api/util/patch" bootstrapv1 "github.com/rancher/cluster-api-provider-rke2/bootstrap/api/v1beta2" @@ -126,13 +125,6 @@ func (r *RKE2ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Attempt to Patch the RKE2Config object and status after each reconciliation if no error occurs. defer func() { - v1beta1conditions.SetSummary(scope.Config, - v1beta1conditions.WithConditions( - bootstrapv1.DataSecretAvailableV1Beta1Condition, - bootstrapv1.CertificatesAvailableV1Beta1Condition, - ), - ) - if err := conditions.SetSummaryCondition(scope.Config, scope.Config, bootstrapv1.RKE2ConfigReadyCondition, conditions.ForConditionTypes{ bootstrapv1.RKE2ConfigDataSecretAvailableCondition, @@ -155,11 +147,6 @@ func (r *RKE2ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) } patchOpts := []patch.Option{ - patch.WithOwnedV1Beta1Conditions{Conditions: []clusterv1.ConditionType{ - clusterv1.ReadyV1Beta1Condition, - bootstrapv1.DataSecretAvailableV1Beta1Condition, - bootstrapv1.CertificatesAvailableV1Beta1Condition, - }}, patch.WithOwnedConditions{Conditions: []string{ clusterv1.PausedCondition, bootstrapv1.RKE2ConfigReadyCondition, @@ -183,12 +170,6 @@ func (r *RKE2ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) if !ptr.Deref(scope.Cluster.Status.Initialization.InfrastructureProvisioned, false) { logger.Info("Infrastructure machine not yet ready") - v1beta1conditions.MarkFalse( - scope.Config, - bootstrapv1.DataSecretAvailableV1Beta1Condition, - bootstrapv1.WaitingForClusterInfrastructureV1Beta1Reason, - clusterv1.ConditionSeverityInfo, - "") conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigDataSecretAvailableCondition, Status: metav1.ConditionFalse, @@ -206,13 +187,11 @@ func (r *RKE2ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) if scope.Machine.Spec.Bootstrap.DataSecretName != nil && (!dataSecretCreated || scope.Config.Status.DataSecretName == nil) { scope.Config.Status.Initialization.DataSecretCreated = ptr.To(true) scope.Config.Status.DataSecretName = scope.Machine.Spec.Bootstrap.DataSecretName - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.DataSecretAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigDataSecretAvailableCondition, Status: metav1.ConditionTrue, Reason: bootstrapv1.RKE2ConfigDataSecretAvailableReason, }) - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -228,13 +207,11 @@ func (r *RKE2ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (!ptr.Deref(scope.Config.Status.Initialization.DataSecretCreated, false) || scope.Config.Status.DataSecretName == nil) { scope.Config.Status.Initialization.DataSecretCreated = ptr.To(true) scope.Config.Status.DataSecretName = scope.MachinePool.Spec.Template.Spec.Bootstrap.DataSecretName - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.DataSecretAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigDataSecretAvailableCondition, Status: metav1.ConditionTrue, Reason: bootstrapv1.RKE2ConfigDataSecretAvailableReason, }) - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -435,12 +412,6 @@ func (r *RKE2ConfigReconciler) handleClusterNotInitialized(ctx context.Context, util.ObjectKey(scope.Cluster), *metav1.NewControllerRef(scope.Config, bootstrapv1.GroupVersion.WithKind("RKE2Config")), ); err != nil { - v1beta1conditions.MarkFalse( - scope.Config, - bootstrapv1.CertificatesAvailableV1Beta1Condition, - bootstrapv1.CertificatesGenerationFailedV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "%s", err.Error()) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionFalse, @@ -451,7 +422,6 @@ func (r *RKE2ConfigReconciler) handleClusterNotInitialized(ctx context.Context, return ctrl.Result{}, err } - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -843,7 +813,6 @@ func (r *RKE2ConfigReconciler) joinControlplane(ctx context.Context, scope *Scop // Set CertificatesAvailable condition for joining control plane nodes. // Note: Joining servers don't generate new CA certificates - they retrieve existing // cluster CA certificates during the RKE2 join process. - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -973,7 +942,6 @@ func (r *RKE2ConfigReconciler) joinWorker(ctx context.Context, scope *Scope) (re // Set CertificatesAvailable condition for joining worker nodes. // Note: Worker nodes (RKE2 agents) don't manage CA certificates - they only need // the registration token to join the cluster. RKE2 handles agent certificates internally. - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.CertificatesAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -1097,7 +1065,6 @@ func (r *RKE2ConfigReconciler) storeBootstrapData(ctx context.Context, scope *Sc scope.Config.Status.DataSecretName = ptr.To(secret.Name) scope.Config.Status.Initialization.DataSecretCreated = ptr.To(true) - v1beta1conditions.MarkTrue(scope.Config, bootstrapv1.DataSecretAvailableV1Beta1Condition) conditions.Set(scope.Config, metav1.Condition{ Type: bootstrapv1.RKE2ConfigDataSecretAvailableCondition, Status: metav1.ConditionTrue, diff --git a/controlplane/api/v1beta1/conversion.go b/controlplane/api/v1beta1/conversion.go index 4c8bd782..3e12cb42 100644 --- a/controlplane/api/v1beta1/conversion.go +++ b/controlplane/api/v1beta1/conversion.go @@ -225,21 +225,18 @@ func Convert_v1beta2_RKE2ControlPlaneTemplateResourceSpec_To_v1beta1_RKE2Control return nil } -// Convert_v1beta1_RKE2ControlPlaneStatus_To_v1beta2_RKE2ControlPlaneStatus handles manual conversion of status fields. func Convert_v1beta1_RKE2ControlPlaneStatus_To_v1beta2_RKE2ControlPlaneStatus(in *RKE2ControlPlaneStatus, out *controlplanev1.RKE2ControlPlaneStatus, s apimachineryconversion.Scope) error { if err := autoConvert_v1beta1_RKE2ControlPlaneStatus_To_v1beta2_RKE2ControlPlaneStatus(in, out, s); err != nil { return err } // Reset conditions from autogenerated conversions - // NOTE: v1beta1 conditions should not be automatically be converted into v1beta2 conditions. out.Conditions = nil // Reset replica counters from autogenerated conversions - // NOTE: old replica counters should not be automatically be converted into replica counters with a new semantic. out.ReadyReplicas = nil - // Retrieve new conditions (v1beta2) and replica counter from the v1beta2 field. + // Retrieve new conditions (v1beta2) and replica counters from the v1beta2 field. if in.V1Beta2 != nil { out.Conditions = in.V1Beta2.Conditions out.ReadyReplicas = in.V1Beta2.ReadyReplicas @@ -247,57 +244,32 @@ func Convert_v1beta1_RKE2ControlPlaneStatus_To_v1beta2_RKE2ControlPlaneStatus(in out.UpToDateReplicas = in.V1Beta2.UpToDateReplicas } - // Move legacy conditions (v1beta1), failureReason, failureMessage and replica counters to the deprecated field. - if out.Deprecated == nil { - out.Deprecated = &controlplanev1.RKE2ControlPlaneDeprecatedStatus{} - } - if out.Deprecated.V1Beta1 == nil { - out.Deprecated.V1Beta1 = &controlplanev1.RKE2ControlPlaneV1Beta1DeprecatedStatus{} - } - if in.Conditions != nil { - clusterv1beta1.Convert_v1beta1_Conditions_To_v1beta2_Deprecated_V1Beta1_Conditions(&in.Conditions, &out.Deprecated.V1Beta1.Conditions) - } - out.Deprecated.V1Beta1.FailureReason = in.FailureReason - out.Deprecated.V1Beta1.FailureMessage = in.FailureMessage - out.Deprecated.V1Beta1.UpdatedReplicas = in.UpdatedReplicas - out.Deprecated.V1Beta1.ReadyReplicas = in.ReadyReplicas - out.Deprecated.V1Beta1.UnavailableReplicas = in.UnavailableReplicas + // v1beta1 conditions, failureReason, failureMessage and replica counters are no longer + // stored in v1beta2 deprecated fields — they are dropped on up-conversion. // Move `initialized` to `ControlPlaneInitialized` is implemented in `ConvertTo`. return nil } -// Convert_v1beta2_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatus handles manual conversion of status fields. func Convert_v1beta2_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatus(in *controlplanev1.RKE2ControlPlaneStatus, out *RKE2ControlPlaneStatus, s apimachineryconversion.Scope) error { if err := autoConvert_v1beta2_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatus(in, out, s); err != nil { return err } // Reset conditions from autogenerated conversions - // NOTE: v1beta2 conditions should not be automatically be converted into legacy conditions (v1beta1). out.Conditions = nil // Reset replica counters from autogenerated conversions - // NOTE: replica counters with a new semantic should not be automatically be converted into old replica counters. out.ReadyReplicas = 0 - // Retrieve legacy conditions (v1beta1), failureReason, failureMessage and replica counters from the deprecated field. - if in.Deprecated != nil && in.Deprecated.V1Beta1 != nil { - if in.Deprecated.V1Beta1.Conditions != nil { - clusterv1beta1.Convert_v1beta2_Deprecated_V1Beta1_Conditions_To_v1beta1_Conditions(&in.Deprecated.V1Beta1.Conditions, &out.Conditions) - } - out.FailureReason = in.Deprecated.V1Beta1.FailureReason - out.FailureMessage = in.Deprecated.V1Beta1.FailureMessage - out.UpdatedReplicas = in.Deprecated.V1Beta1.UpdatedReplicas - out.ReadyReplicas = in.Deprecated.V1Beta1.ReadyReplicas - out.UnavailableReplicas = in.Deprecated.V1Beta1.UnavailableReplicas - } + // v1beta1 conditions, failureReason, failureMessage and replica counters are no longer + // stored in v1beta2 deprecated fields — they will be empty on down-conversion. out.Initialized = ptr.Deref(in.Initialization.ControlPlaneInitialized, false) out.Ready = out.ReadyReplicas > 0 - // Move new conditions (v1beta2) and replica counter to the v1beta2 field. + // Move new conditions (v1beta2) and replica counters to the v1beta2 field. if in.Conditions == nil && in.ReadyReplicas == nil && in.AvailableReplicas == nil && in.UpToDateReplicas == nil { return nil } diff --git a/controlplane/api/v1beta1/zz_generated.conversion.go b/controlplane/api/v1beta1/zz_generated.conversion.go index 0be50c3e..cf793a25 100644 --- a/controlplane/api/v1beta1/zz_generated.conversion.go +++ b/controlplane/api/v1beta1/zz_generated.conversion.go @@ -684,7 +684,6 @@ func autoConvert_v1beta2_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatu // WARNING: in.UpToDateReplicas requires manual conversion: does not exist in peer-type out.AvailableServerIPs = *(*[]string)(unsafe.Pointer(&in.AvailableServerIPs)) out.LastRemediation = (*LastRemediationStatus)(unsafe.Pointer(in.LastRemediation)) - // WARNING: in.Deprecated requires manual conversion: does not exist in peer-type return nil } diff --git a/controlplane/api/v1beta2/rke2controlplane_types.go b/controlplane/api/v1beta2/rke2controlplane_types.go index f956a80b..ea0d5bb9 100644 --- a/controlplane/api/v1beta2/rke2controlplane_types.go +++ b/controlplane/api/v1beta2/rke2controlplane_types.go @@ -298,10 +298,6 @@ type RKE2ControlPlaneStatus struct { // lastRemediation stores info about last remediation performed. // +optional LastRemediation *LastRemediationStatus `json:"lastRemediation,omitempty"` - - // deprecated groups all the status fields that are deprecated and will be removed when all the nested field are removed. - // +optional - Deprecated *RKE2ControlPlaneDeprecatedStatus `json:"deprecated,omitempty"` } // RKE2ControlPlaneInitializationStatus provides observations of the RKE2ControlPlane initialization process. @@ -315,68 +311,6 @@ type RKE2ControlPlaneInitializationStatus struct { ControlPlaneInitialized *bool `json:"controlPlaneInitialized,omitempty"` } -// RKE2ControlPlaneDeprecatedStatus groups all the status fields that are deprecated and will be removed in a future version. -type RKE2ControlPlaneDeprecatedStatus struct { - // v1beta1 groups all the status fields that are deprecated and will be removed when support for v1beta1 will be dropped. - // +optional - V1Beta1 *RKE2ControlPlaneV1Beta1DeprecatedStatus `json:"v1beta1,omitempty"` -} - -// RKE2ControlPlaneV1Beta1DeprecatedStatus groups all the status fields that are deprecated and will be removed when support for v1beta1 is dropped. -type RKE2ControlPlaneV1Beta1DeprecatedStatus struct { - // conditions defines current service state of the RKE2ControlPlane. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - Conditions clusterv1.Conditions `json:"conditions,omitempty"` - - // failureReason indicates that there is a terminal problem reconciling the - // state, and will be set to a token value suitable for - // programmatic interpretation. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - FailureReason string `json:"failureReason,omitempty"` - - // failureMessage indicates that there is a terminal problem reconciling the - // state, and will be set to a descriptive error message. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=10240 - FailureMessage string `json:"failureMessage,omitempty"` //nolint:kubeapilinter // field will be removed when v1beta1 is removed - - // updatedReplicas is the total number of non-terminated machines targeted by this control plane - // that have the desired template spec. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - UpdatedReplicas int32 `json:"updatedReplicas"` //nolint:kubeapilinter // field will be removed when v1beta1 is removed - - // readyReplicas is the total number of fully running and ready control plane machines. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - ReadyReplicas int32 `json:"readyReplicas"` //nolint:kubeapilinter // field will be removed when v1beta1 is removed - - // unavailableReplicas is the total number of unavailable machines targeted by this control plane. - // This is the total number of machines that are still required for - // the deployment to have 100% available capacity. They may either - // be machines that are running but not yet ready or machines - // that still have not been created. - // - // Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - // - // +optional - UnavailableReplicas int32 `json:"unavailableReplicas"` //nolint:kubeapilinter // field will be removed when v1beta1 is removed -} - // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:storageversion @@ -669,28 +603,6 @@ func (r *RKE2ControlPlane) SetConditions(conditions []metav1.Condition) { r.Status.Conditions = conditions } -// GetV1Beta1Conditions returns the set of conditions for this object. -func (r *RKE2ControlPlane) GetV1Beta1Conditions() clusterv1.Conditions { - if r.Status.Deprecated == nil || r.Status.Deprecated.V1Beta1 == nil { - return nil - } - - return r.Status.Deprecated.V1Beta1.Conditions -} - -// SetV1Beta1Conditions sets the conditions on this object. -func (r *RKE2ControlPlane) SetV1Beta1Conditions(conditions clusterv1.Conditions) { - if r.Status.Deprecated == nil { - r.Status.Deprecated = &RKE2ControlPlaneDeprecatedStatus{} - } - - if r.Status.Deprecated.V1Beta1 == nil { - r.Status.Deprecated.V1Beta1 = &RKE2ControlPlaneV1Beta1DeprecatedStatus{} - } - - r.Status.Deprecated.V1Beta1.Conditions = conditions -} - // GetDesiredVersion returns the desired version of the RKE2ControlPlane using Spec.Version field as a default field. func (r *RKE2ControlPlane) GetDesiredVersion() string { return r.Spec.Version diff --git a/controlplane/api/v1beta2/zz_generated.deepcopy.go b/controlplane/api/v1beta2/zz_generated.deepcopy.go index 06fb4c84..b4bc07e6 100644 --- a/controlplane/api/v1beta2/zz_generated.deepcopy.go +++ b/controlplane/api/v1beta2/zz_generated.deepcopy.go @@ -26,7 +26,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" - corev1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -168,26 +167,6 @@ func (in *RKE2ControlPlane) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RKE2ControlPlaneDeprecatedStatus) DeepCopyInto(out *RKE2ControlPlaneDeprecatedStatus) { - *out = *in - if in.V1Beta1 != nil { - in, out := &in.V1Beta1, &out.V1Beta1 - *out = new(RKE2ControlPlaneV1Beta1DeprecatedStatus) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ControlPlaneDeprecatedStatus. -func (in *RKE2ControlPlaneDeprecatedStatus) DeepCopy() *RKE2ControlPlaneDeprecatedStatus { - if in == nil { - return nil - } - out := new(RKE2ControlPlaneDeprecatedStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RKE2ControlPlaneInitializationStatus) DeepCopyInto(out *RKE2ControlPlaneInitializationStatus) { *out = *in @@ -379,11 +358,6 @@ func (in *RKE2ControlPlaneStatus) DeepCopyInto(out *RKE2ControlPlaneStatus) { *out = new(LastRemediationStatus) (*in).DeepCopyInto(*out) } - if in.Deprecated != nil { - in, out := &in.Deprecated, &out.Deprecated - *out = new(RKE2ControlPlaneDeprecatedStatus) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ControlPlaneStatus. @@ -515,28 +489,6 @@ func (in *RKE2ControlPlaneTemplateSpec) DeepCopy() *RKE2ControlPlaneTemplateSpec return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RKE2ControlPlaneV1Beta1DeprecatedStatus) DeepCopyInto(out *RKE2ControlPlaneV1Beta1DeprecatedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make(corev1beta2.Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKE2ControlPlaneV1Beta1DeprecatedStatus. -func (in *RKE2ControlPlaneV1Beta1DeprecatedStatus) DeepCopy() *RKE2ControlPlaneV1Beta1DeprecatedStatus { - if in == nil { - return nil - } - out := new(RKE2ControlPlaneV1Beta1DeprecatedStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RKE2ServerConfig) DeepCopyInto(out *RKE2ServerConfig) { *out = *in diff --git a/controlplane/config/crd/bases/controlplane.cluster.x-k8s.io_rke2controlplanes.yaml b/controlplane/config/crd/bases/controlplane.cluster.x-k8s.io_rke2controlplanes.yaml index 9153a302..c32754af 100644 --- a/controlplane/config/crd/bases/controlplane.cluster.x-k8s.io_rke2controlplanes.yaml +++ b/controlplane/config/crd/bases/controlplane.cluster.x-k8s.io_rke2controlplanes.yaml @@ -3063,115 +3063,6 @@ spec: - type type: object type: array - deprecated: - description: deprecated groups all the status fields that are deprecated - and will be removed when all the nested field are removed. - properties: - v1beta1: - description: v1beta1 groups all the status fields that are deprecated - and will be removed when support for v1beta1 will be dropped. - properties: - conditions: - description: |- - conditions defines current service state of the RKE2ControlPlane. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - items: - description: Condition defines an observation of a Cluster - API resource operational state. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when - the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This field may be empty. - maxLength: 10240 - minLength: 1 - type: string - reason: - description: |- - reason is the reason for the condition's last transition in CamelCase. - The specific API may choose whether or not this field is considered a guaranteed API. - This field may be empty. - maxLength: 256 - minLength: 1 - type: string - severity: - description: |- - severity provides an explicit classification of Reason code, so the users or machines can immediately - understand the current situation and act accordingly. - The Severity field MUST be set only when Status=False. - maxLength: 32 - type: string - status: - description: status of the condition, one of True, False, - Unknown. - type: string - type: - description: |- - type of condition in CamelCase or in foo.example.com/CamelCase. - Many .condition.type values are consistent across resources like Available, but because arbitrary conditions - can be useful (see .node.status.conditions), the ability to deconflict is important. - maxLength: 256 - minLength: 1 - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - failureMessage: - description: |- - failureMessage indicates that there is a terminal problem reconciling the - state, and will be set to a descriptive error message. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - maxLength: 10240 - minLength: 1 - type: string - failureReason: - description: |- - failureReason indicates that there is a terminal problem reconciling the - state, and will be set to a token value suitable for - programmatic interpretation. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - type: string - readyReplicas: - description: |- - readyReplicas is the total number of fully running and ready control plane machines. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - format: int32 - type: integer - unavailableReplicas: - description: |- - unavailableReplicas is the total number of unavailable machines targeted by this control plane. - This is the total number of machines that are still required for - the deployment to have 100% available capacity. They may either - be machines that are running but not yet ready or machines - that still have not been created. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - format: int32 - type: integer - updatedReplicas: - description: |- - updatedReplicas is the total number of non-terminated machines targeted by this control plane - that have the desired template spec. - - Deprecated: This field is deprecated and is going to be removed when support for v1beta1 is dropped. - format: int32 - type: integer - type: object - type: object initialization: description: |- initialization provides observations of the RKE2ControlPlane initialization process. diff --git a/controlplane/internal/controllers/remediation.go b/controlplane/internal/controllers/remediation.go index 3720049d..6fd5b136 100644 --- a/controlplane/internal/controllers/remediation.go +++ b/controlplane/internal/controllers/remediation.go @@ -35,7 +35,6 @@ import ( "sigs.k8s.io/cluster-api/util/annotations" "sigs.k8s.io/cluster-api/util/collections" "sigs.k8s.io/cluster-api/util/conditions" - v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" "sigs.k8s.io/cluster-api/util/patch" controlplanev1 "github.com/rancher/cluster-api-provider-rke2/controlplane/api/v1beta2" @@ -62,11 +61,10 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont continue } - shouldCleanupV1Beta1 := v1beta1conditions.IsTrue(m, clusterv1.MachineHealthCheckSucceededV1Beta1Condition) && v1beta1conditions.IsFalse(m, clusterv1.MachineOwnerRemediatedV1Beta1Condition) shouldCleanup := conditions.IsTrue(m, clusterv1.MachineHealthCheckSucceededCondition) && conditions.IsFalse(m, clusterv1.MachineOwnerRemediatedCondition) - if !shouldCleanupV1Beta1 && !shouldCleanup { + if !shouldCleanup { continue } @@ -77,10 +75,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont continue } - if shouldCleanupV1Beta1 { - v1beta1conditions.Delete(m, clusterv1.MachineOwnerRemediatedV1Beta1Condition) - } - if shouldCleanup { conditions.Delete(m, clusterv1.MachineOwnerRemediatedCondition) } @@ -212,13 +206,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont "A control plane machine needs remediation, but the number of current replicas is less or equal to 1. Skipping remediation", "replicas", controlPlane.Machines.Len(), ) - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane can't remediate if current replicas are less or equal to 1", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -234,13 +221,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont // This rule prevents RKE2ControlPlane taking actions while the cluster is in a transitional state. if controlPlane.HasHealthyMachineStillProvisioning() { log.Info("A control plane machine needs remediation, but there are other control-plane machines being provisioned. Skipping remediation") - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane waiting for control plane machine provisioning to complete before triggering remediation", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -255,13 +235,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont // The cluster MUST have no machines with a deletion timestamp. This rule prevents RKE2ControlPlane taking actions while the cluster is in a transitional state. if controlPlane.HasDeletingMachine() { log.Info("A control plane machine needs remediation, but there are other control-plane machines being deleted. Skipping remediation") - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane waiting for control plane machine deletion to complete before triggering remediation", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -278,14 +251,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont if controlPlane.IsEtcdManaged() && controlPlane.UsesEmbeddedEtcd() { canSafelyRemediate, err := r.canSafelyRemoveEtcdMember(ctx, controlPlane, machineToBeRemediated) if err != nil { - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.RemediationFailedV1Beta1Reason, - clusterv1.ConditionSeverityError, - "%s", err.Error(), - ) - conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, Status: metav1.ConditionFalse, @@ -298,13 +263,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont if !canSafelyRemediate { log.Info("A control plane machine needs remediation, but removing this machine could result in etcd quorum loss. Skipping remediation") - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane can't remediate this machine because this could result in etcd loosing quorum", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -336,13 +294,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont etcdLeaderCandidate := controlPlane.HealthyMachines().Newest() if etcdLeaderCandidate == nil { log.Info("A control plane machine needs remediation, but there is no healthy machine to forward etcd leadership to") - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.RemediationFailedV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "A control plane machine needs remediation, but there is no healthy machine to forward etcd leadership to. Skipping remediation", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -356,13 +307,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont if err := workloadCluster.ForwardEtcdLeadership(ctx, machineToBeRemediated, etcdLeaderCandidate); err != nil { log.Error(err, "Failed to move etcd leadership to candidate machine", "candidate", klog.KObj(etcdLeaderCandidate)) - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.RemediationFailedV1Beta1Reason, - clusterv1.ConditionSeverityError, - "%s", err.Error(), - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -378,14 +322,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont // Delete the machine if err := r.Delete(ctx, machineToBeRemediated); err != nil { - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.RemediationFailedV1Beta1Reason, - clusterv1.ConditionSeverityError, - "%s", err.Error(), - ) - conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, Status: metav1.ConditionFalse, @@ -400,13 +336,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileUnhealthyMachines(ctx context.Cont // Note: We intentionally log after Delete because we want this log line to show up only after DeletionTimestamp has been set. // Also, setting DeletionTimestamp doesn't mean the Machine is actually deleted (deletion takes some time). log.Info("Remediating unhealthy machine") - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedV1Beta1Condition, - clusterv1.RemediationInProgressV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "", - ) conditions.Set(machineToBeRemediated, metav1.Condition{ Type: clusterv1.MachineOwnerRemediatedCondition, @@ -599,14 +528,13 @@ func (r *RKE2ControlPlaneReconciler) checkRetryLimits( retryPeriod, ), ) - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedCondition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane can't remediate this machine because the operation already failed in the latest %s (RetryPeriod)", - retryPeriod, - ) + conditions.Set(machineToBeRemediated, metav1.Condition{ + Type: clusterv1.MachineOwnerRemediatedCondition, + Status: metav1.ConditionFalse, + Reason: controlplanev1.RKE2ControlPlaneMachineCannotBeRemediatedReason, + Message: fmt.Sprintf("RKE2ControlPlane can't remediate this machine because the operation "+ + "already failed in the latest %s (RetryPeriod)", retryPeriod), + }) return remediationInProgressData, false, nil } @@ -622,14 +550,12 @@ func (r *RKE2ControlPlaneReconciler) checkRetryLimits( maxRetry, ), ) - v1beta1conditions.MarkFalse( - machineToBeRemediated, - clusterv1.MachineOwnerRemediatedCondition, - clusterv1.WaitingForRemediationV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "RKE2ControlPlane can't remediate this machine because the operation already failed %d times (MaxRetry)", - maxRetry, - ) + conditions.Set(machineToBeRemediated, metav1.Condition{ + Type: clusterv1.MachineOwnerRemediatedCondition, + Status: metav1.ConditionFalse, + Reason: controlplanev1.RKE2ControlPlaneMachineCannotBeRemediatedReason, + Message: fmt.Sprintf("RKE2ControlPlane can't remediate this machine because the operation already failed %d times (MaxRetry)", maxRetry), + }) return remediationInProgressData, false, nil } diff --git a/controlplane/internal/controllers/rke2controlplane_controller.go b/controlplane/internal/controllers/rke2controlplane_controller.go index 2e114978..a4964200 100644 --- a/controlplane/internal/controllers/rke2controlplane_controller.go +++ b/controlplane/internal/controllers/rke2controlplane_controller.go @@ -53,7 +53,6 @@ import ( "sigs.k8s.io/cluster-api/util/certs" "sigs.k8s.io/cluster-api/util/collections" "sigs.k8s.io/cluster-api/util/conditions" - v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" capikubeconfig "sigs.k8s.io/cluster-api/util/kubeconfig" "sigs.k8s.io/cluster-api/util/patch" @@ -186,17 +185,6 @@ func (r *RKE2ControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req } } - // Always attempt to update V1Beta1 status. - if err := r.updateV1Beta1Status(ctx, rcp, cluster); err != nil { - var connFailure *rke2.RemoteClusterConnectionError - if errors.As(err, &connFailure) { - logger.Info("Could not connect to workload cluster to fetch status", "err", err.Error()) - } else { - logger.Error(err, "Failed to update RKE2ControlPlane V1Beta1 Status") - reterr = kerrors.NewAggregate([]error{reterr, err}) - } - } - // Always attempt to Patch the RKE2ControlPlane object and status after each reconciliation. if err := patchRKE2ControlPlane(ctx, patchHelper, rcp); err != nil { reterr = kerrors.NewAggregate([]error{reterr, err}) @@ -241,29 +229,10 @@ func (r *RKE2ControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req } func patchRKE2ControlPlane(ctx context.Context, patchHelper *patch.Helper, rcp *controlplanev1.RKE2ControlPlane) error { - // Always update the readyCondition by summarizing the state of other conditions. - v1beta1conditions.SetSummary(rcp, - v1beta1conditions.WithConditions( - clusterv1.ReadyV1Beta1Condition, - controlplanev1.MachinesSpecUpToDateV1Beta1Condition, - controlplanev1.ResizedV1Beta1Condition, - controlplanev1.MachinesReadyV1Beta1Condition, - controlplanev1.AvailableV1Beta1Condition, - controlplanev1.CertificatesAvailableV1Beta1Condition, - ), - ) - // Patch the object, ignoring conflicts on the conditions owned by this controller. return patchHelper.Patch( ctx, rcp, - patch.WithOwnedV1Beta1Conditions{Conditions: []clusterv1.ConditionType{ - clusterv1.ReadyV1Beta1Condition, - controlplanev1.MachinesReadyV1Beta1Condition, - controlplanev1.MachinesSpecUpToDateV1Beta1Condition, - controlplanev1.ResizedV1Beta1Condition, - controlplanev1.AvailableV1Beta1Condition, - }}, patch.WithOwnedConditions{Conditions: []string{ clusterv1.PausedCondition, controlplanev1.RKE2ControlPlaneAvailableCondition, @@ -420,11 +389,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileNormal( if err := certificates.LookupOrGenerate(ctx, r.Client, util.ObjectKey(cluster), *controllerRef); err != nil { logger.Error(err, "unable to lookup or create cluster certificates") - v1beta1conditions.MarkFalse( - rcp, controlplanev1.CertificatesAvailableV1Beta1Condition, - controlplanev1.CertificatesGenerationFailedV1Beta1Reason, - clusterv1.ConditionSeverityWarning, "%s", err.Error()) - conditions.Set(rcp, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneCertificatesAvailableCondition, Status: metav1.ConditionUnknown, @@ -435,8 +399,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileNormal( return ctrl.Result{}, err } - v1beta1conditions.MarkTrue(rcp, controlplanev1.CertificatesAvailableV1Beta1Condition) - conditions.Set(rcp, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneCertificatesAvailableCondition, Status: metav1.ConditionTrue, @@ -509,13 +471,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileNormal( return ctrl.Result{}, fmt.Errorf("failed to sync Machines: %w", err) } - // Aggregate the operational state of all the machines; while aggregating we are adding the - // source ref (reason@machine/name) so the problem can be easily tracked down to its source machine. - v1beta1conditions.SetAggregate(controlPlane.RCP, controlplanev1.MachinesReadyV1Beta1Condition, - ownedMachines.ConditionGetters(), - v1beta1conditions.AddSourceRef(), - v1beta1conditions.WithStepCounterIf(false)) - // Updates conditions reporting the status of static pods and the status of the etcd cluster. // NOTE: Conditions reporting RCP operation progress like e.g. Resized or SpecUpToDate are inlined with the rest of the execution. if result, err := r.reconcileControlPlaneConditions(ctx, controlPlane); err != nil || !result.IsZero() { @@ -540,21 +495,22 @@ func (r *RKE2ControlPlaneReconciler) reconcileNormal( switch { case len(needRollout) > 0: logger.Info("Rolling out Control Plane machines", "needRollout", needRollout.Names()) - v1beta1conditions.MarkFalse(controlPlane.RCP, - controlplanev1.MachinesSpecUpToDateV1Beta1Condition, - controlplanev1.RollingUpdateInProgressV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "Rolling %d replicas with outdated spec (%d replicas up to date)", - len(needRollout), - len(controlPlane.Machines)-len(needRollout)) + conditions.Set(controlPlane.RCP, metav1.Condition{ + Type: controlplanev1.RKE2ControlPlaneRollingOutCondition, + Status: metav1.ConditionTrue, + Reason: controlplanev1.RKE2ControlPlaneRollingOutReason, + Message: fmt.Sprintf("Rolling %d replicas with outdated spec"+ + "(%d replicas up to date)", len(needRollout), len(controlPlane.Machines)-len(needRollout)), + }) return r.upgradeControlPlane(ctx, cluster, rcp, controlPlane, needRollout) default: - // make sure last upgrade operation is marked as completed. - // NOTE: we are checking the condition already exists in order to avoid to set this condition at the first - // reconciliation/before a rolling upgrade actually starts. - if v1beta1conditions.Has(controlPlane.RCP, controlplanev1.MachinesSpecUpToDateV1Beta1Condition) { - v1beta1conditions.MarkTrue(controlPlane.RCP, controlplanev1.MachinesSpecUpToDateV1Beta1Condition) + if conditions.Has(controlPlane.RCP, controlplanev1.RKE2ControlPlaneRollingOutCondition) { + conditions.Set(controlPlane.RCP, metav1.Condition{ + Type: controlplanev1.RKE2ControlPlaneRollingOutCondition, + Status: metav1.ConditionFalse, + Reason: controlplanev1.RKE2ControlPlaneNotRollingOutReason, + }) } } @@ -568,10 +524,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileNormal( case numMachines < desiredReplicas && numMachines == 0: // Create new Machine w/ init logger.Info("Initializing control plane", "Desired", desiredReplicas, "Existing", numMachines) - v1beta1conditions.MarkFalse(controlPlane.RCP, - controlplanev1.AvailableV1Beta1Condition, - controlplanev1.WaitingForRKE2ServerV1Beta1Reason, - clusterv1.ConditionSeverityInfo, "") return r.initializeControlPlane(ctx, cluster, rcp, controlPlane) // We are scaling up @@ -636,24 +588,9 @@ func (r *RKE2ControlPlaneReconciler) reconcileDelete(ctx context.Context, logger.Info("failed to reconcile conditions", "error", err.Error()) } - // Aggregate the operational state of all the machines; while aggregating we are adding the - // source ref (reason@machine/name) so the problem can be easily tracked down to its source machine. - // However, during delete we are hiding the counter (1 of x) because it does not make sense given that - // all the machines are deleted in parallel. - v1beta1conditions.SetAggregate(rcp, - controlplanev1.MachinesReadyV1Beta1Condition, - ownedMachines.ConditionGetters(), - v1beta1conditions.AddSourceRef(), - v1beta1conditions.WithStepCounterIf(false)) - // Verify that only control plane machines remain if len(allMachines) != len(ownedMachines) { logger.Info("Waiting for worker nodes to be deleted first") - v1beta1conditions.MarkFalse(rcp, - controlplanev1.ResizedV1Beta1Condition, - clusterv1.DeletingV1Beta1Reason, - clusterv1.ConditionSeverityInfo, - "Waiting for worker nodes to be deleted first") conditions.Set(rcp, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneDeletingCondition, @@ -713,8 +650,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileDelete(ctx context.Context, logger.Info("Waiting for control plane Machines to not exist anymore") - v1beta1conditions.MarkFalse(rcp, controlplanev1.ResizedV1Beta1Condition, clusterv1.DeletingV1Beta1Reason, clusterv1.ConditionSeverityInfo, "") - conditions.Set(rcp, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneDeletingCondition, Status: metav1.ConditionTrue, @@ -827,12 +762,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileControlPlaneConditions( controlPlane.RCP.Status.ReadyReplicas = ptr.To(int32(0)) controlPlane.RCP.Status.AvailableServerIPs = nil - v1beta1conditions.MarkFalse( - controlPlane.RCP, - controlplanev1.AvailableV1Beta1Condition, - controlplanev1.WaitingForRKE2ServerV1Beta1Reason, - clusterv1.ConditionSeverityInfo, "") - conditions.Set(controlPlane.RCP, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneAvailableCondition, Status: metav1.ConditionFalse, @@ -840,12 +769,6 @@ func (r *RKE2ControlPlaneReconciler) reconcileControlPlaneConditions( Message: "Waiting for at least one machine to be ready for control plane " + controlPlane.RCP.Name, }) - v1beta1conditions.MarkFalse( - controlPlane.RCP, - controlplanev1.MachinesReadyV1Beta1Condition, - controlplanev1.WaitingForRKE2ServerV1Beta1Reason, - clusterv1.ConditionSeverityInfo, "") - conditions.Set(controlPlane.RCP, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneMachinesReadyCondition, Status: metav1.ConditionFalse, diff --git a/controlplane/internal/controllers/status.go b/controlplane/internal/controllers/status.go index e779b408..eb6c96c0 100644 --- a/controlplane/internal/controllers/status.go +++ b/controlplane/internal/controllers/status.go @@ -36,7 +36,6 @@ import ( "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/collections" "sigs.k8s.io/cluster-api/util/conditions" - v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" clog "sigs.k8s.io/cluster-api/util/log" controlplanev1 "github.com/rancher/cluster-api-provider-rke2/controlplane/api/v1beta2" @@ -180,7 +179,6 @@ func (r *RKE2ControlPlaneReconciler) updateStatus(ctx context.Context, rcp *cont } if ptr.Deref(rcp.Status.Initialization.ControlPlaneInitialized, false) { - v1beta1conditions.MarkTrue(rcp, controlplanev1.AvailableV1Beta1Condition) conditions.Set(rcp, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneAvailableCondition, Status: metav1.ConditionTrue, @@ -229,232 +227,6 @@ func (r *RKE2ControlPlaneReconciler) updateStatus(ctx context.Context, rcp *cont return nil } -// updateV1Beta1Status is called after every reconciliation loop in a defer statement to always make sure we have the -// RKE2ControlPlane status up-to-date. -// nolint:gocyclo -func (r *RKE2ControlPlaneReconciler) updateV1Beta1Status(ctx context.Context, rcp *controlplanev1.RKE2ControlPlane, cluster *clusterv1.Cluster) error { // nolint:lll - logger := log.FromContext(ctx) - - if cluster == nil { - logger.Info("Cluster is nil, skipping status update") - - return nil - } - - if rcp.Spec.Replicas == nil { - logger.Info("RKE2ControlPlane.Spec.Replicas is nil, skipping status update") - - return nil - } - - ownedMachines, err := r.managementCluster.GetMachinesForCluster( - ctx, - cluster, - collections.OwnedMachines(rcp, controlplanev1.GroupVersion.WithKind("RKE2ControlPlane").GroupKind())) - if err != nil { - return fmt.Errorf("failed to get list of owned machines: %w", err) - } - - if ownedMachines == nil { - logger.Info("Owned machines list is nil, skipping status update") - - return nil - } - - readyMachines := ownedMachines.Filter(collections.IsReady()) - if readyMachines == nil { - logger.Info("Ready machines list is nil, skipping status update") - - return nil - } - - for _, readyMachine := range readyMachines { - logger.V(3).Info("Ready Machine : " + readyMachine.Name) - } - - controlPlane, err := rke2.NewControlPlane(ctx, r.managementCluster, r.Client, cluster, rcp, ownedMachines) - if err != nil { - logger.Error(err, "failed to initialize control plane") - - return err - } - - if rcp.Status.Deprecated == nil { - rcp.Status.Deprecated = &controlplanev1.RKE2ControlPlaneDeprecatedStatus{} - } - - if rcp.Status.Deprecated.V1Beta1 == nil { - rcp.Status.Deprecated.V1Beta1 = &controlplanev1.RKE2ControlPlaneV1Beta1DeprecatedStatus{} - } - - rcp.Status.Deprecated.V1Beta1.UpdatedReplicas = rke2util.SafeInt32(len(controlPlane.UpToDateMachines())) // nolint:staticcheck - - replicas := rke2util.SafeInt32(len(ownedMachines)) - desiredReplicas := *rcp.Spec.Replicas - - // set basic data that does not require interacting with the workload cluster - // ReadyReplicas and UnavailableReplicas are set in case the function returns before updating them - rcp.Status.Deprecated.V1Beta1.ReadyReplicas = 0 // nolint:staticcheck - rcp.Status.Deprecated.V1Beta1.UnavailableReplicas = replicas // nolint:staticcheck - - // Return early if the deletion timestamp is set, because we don't want to try to connect to the workload cluster - // and we don't want to report resize condition (because it is set to deletin into reconcile delete). - if !rcp.DeletionTimestamp.IsZero() { - return nil - } - - switch { - // We are scaling up - case replicas < desiredReplicas: - v1beta1conditions.MarkFalse( - rcp, - controlplanev1.ResizedV1Beta1Condition, - controlplanev1.ScalingUpV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "Scaling up control plane to %d replicas (actual %d)", - desiredReplicas, - replicas) - - // We are scaling down - case replicas > desiredReplicas: - v1beta1conditions.MarkFalse( - rcp, - controlplanev1.ResizedV1Beta1Condition, - controlplanev1.ScalingDownV1Beta1Reason, - clusterv1.ConditionSeverityWarning, - "Scaling down control plane to %d replicas (actual %d)", - desiredReplicas, - replicas) - - default: - // make sure last resize operation is marked as completed. - // NOTE: we are checking the number of machines ready so we report resize completed only when the machines - // are actually provisioned (vs reporting completed immediately after the last machine object is created). - if rke2util.SafeInt32(len(readyMachines)) == replicas { - v1beta1conditions.MarkTrue(rcp, controlplanev1.ResizedV1Beta1Condition) - } - } - - kubeconfigSecret := corev1.Secret{} - - err = r.Get(ctx, types.NamespacedName{ - Namespace: cluster.Namespace, - Name: secret.Name(cluster.Name, secret.Kubeconfig), - }, &kubeconfigSecret) - if err != nil { - logger.Info("Kubeconfig secret does not yet exist") - - return err - } - - kubeConfig := kubeconfigSecret.Data[secret.KubeconfigDataName] - if kubeConfig == nil { - return errors.New("unable to find a value entry in the kubeconfig secret") - } - - rcp.Status.Deprecated.V1Beta1.ReadyReplicas = rke2util.SafeInt32(len(readyMachines)) // nolint:staticcheck - rcp.Status.Deprecated.V1Beta1.UnavailableReplicas = replicas - rke2util.SafeInt32(len(readyMachines)) // nolint:staticcheck - - workloadCluster, err := controlPlane.GetWorkloadCluster(ctx) - if err != nil { - logger.Error(err, "Failed to get remote client for workload cluster", "cluster key", util.ObjectKey(cluster)) - - return fmt.Errorf("getting workload cluster: %w", err) - } - - if workloadCluster == nil { - logger.Info("Workload cluster is nil, skipping status update") - - return nil - } - - status := workloadCluster.ClusterStatus(ctx) - - if status.HasRKE2ServingSecret { - rcp.Status.Initialization.ControlPlaneInitialized = ptr.To(true) - } - - if len(ownedMachines) == 0 || len(readyMachines) == 0 { - logger.Info(fmt.Sprintf("No Control Plane Machines exist or are ready for RKE2ControlPlane %s/%s", rcp.Namespace, rcp.Name)) - - return nil - } - - availableCPMachines := readyMachines - - registrationMethod, err := registration.NewRegistrationMethod(string(rcp.Spec.RegistrationMethod)) - if err != nil { - logger.Error(err, "Failed to get node registration method") - - return fmt.Errorf("getting node registration method: %w", err) - } - - validIPAddresses, err := registrationMethod(cluster, rcp, availableCPMachines) - if err != nil { - logger.Error(err, "Failed to get registration addresses") - - return fmt.Errorf("getting registration addresses: %w", err) - } - - rcp.Status.AvailableServerIPs = validIPAddresses - if len(rcp.Status.AvailableServerIPs) == 0 { - return errors.New("some Control Plane machines exist and are ready but they have no IP Address available") - } - - if len(readyMachines) == len(ownedMachines) { - rcp.Status.Initialization.ControlPlaneInitialized = ptr.To(true) - } - - if ptr.Deref(rcp.Status.Initialization.ControlPlaneInitialized, false) { - v1beta1conditions.MarkTrue(rcp, controlplanev1.AvailableV1Beta1Condition) - conditions.Set(rcp, metav1.Condition{ - Type: controlplanev1.RKE2ControlPlaneAvailableCondition, - Status: metav1.ConditionTrue, - Reason: controlplanev1.RKE2ControlPlaneAvailableReason, - }) - } - - lowestVersion := controlPlane.Machines.LowestVersion() - if lowestVersion != "" { - controlPlane.RCP.Status.Version = lowestVersion - } - - // Surface lastRemediation data in status. - // LastRemediation is the remediation currently in progress, in any, or the - // most recent of the remediation we are keeping track on machines. - var lastRemediation *RemediationData - - if v, ok := controlPlane.RCP.Annotations[controlplanev1.RemediationInProgressAnnotation]; ok { - remediationData, err := RemediationDataFromAnnotation(v) - if err != nil { - return err - } - - lastRemediation = remediationData - } else { - for _, m := range controlPlane.Machines.UnsortedList() { - if v, ok := m.Annotations[controlplanev1.RemediationForAnnotation]; ok { - remediationData, err := RemediationDataFromAnnotation(v) - if err != nil { - return err - } - - if lastRemediation == nil || lastRemediation.Timestamp.Time.Before(remediationData.Timestamp.Time) { - lastRemediation = remediationData - } - } - } - } - - if lastRemediation != nil { - controlPlane.RCP.Status.LastRemediation = lastRemediation.ToStatus() - } - - logger.Info("Successfully updated RKE2ControlPlane V1Beta1 Status", "namespace", rcp.Namespace, "name", rcp.Name) - - return nil -} - func setReplicas(_ context.Context, rcp *controlplanev1.RKE2ControlPlane, machines collections.Machines) { var readyReplicas, availableReplicas, upToDateReplicas int32 diff --git a/go.mod b/go.mod index 8ba30124..b85690b7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/rancher/cluster-api-provider-rke2 -go 1.24.11 +go 1.24.13 require ( github.com/coreos/butane v0.26.0 diff --git a/hack/tools/go.mod b/hack/tools/go.mod index 54b449d2..6afbb687 100644 --- a/hack/tools/go.mod +++ b/hack/tools/go.mod @@ -1,6 +1,6 @@ module github.com/rancher/cluster-api-provider-rke2/hack/tools -go 1.23.0 +go 1.24.13 require sigs.k8s.io/cluster-api/hack/tools v0.0.0-20240820112706-3abe3058a6a8 diff --git a/pkg/rke2/workload_cluster.go b/pkg/rke2/workload_cluster.go index 3ad1fd97..d772b04f 100644 --- a/pkg/rke2/workload_cluster.go +++ b/pkg/rke2/workload_cluster.go @@ -152,10 +152,6 @@ func (m *Management) NewWorkload(ctx context.Context, cl ctrlclient.Client, rest func (w *Workload) InitWorkload(ctx context.Context, cp *ControlPlane) error { nodes, err := w.getControlPlaneNodes(ctx) if err != nil { - v1beta1conditions.MarkUnknown( - cp.RCP, - controlplanev1.ControlPlaneComponentsHealthyV1Beta1Condition, - controlplanev1.ControlPlaneComponentsInspectionFailedV1Beta1Reason, "Failed to list nodes which are hosting control plane components") conditions.Set(cp.RCP, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneControlPlaneComponentsHealthyCondition, Status: metav1.ConditionUnknown, @@ -174,10 +170,6 @@ func (w *Workload) InitWorkload(ctx context.Context, cp *ControlPlane) error { for _, node := range w.Nodes { patchHelper, err := patch.NewHelper(node, w.Client) if err != nil { - v1beta1conditions.MarkUnknown( - cp.RCP, - controlplanev1.ControlPlaneComponentsHealthyV1Beta1Condition, - controlplanev1.ControlPlaneComponentsInspectionFailedV1Beta1Reason, "Failed to create patch helpers for control plane nodes") conditions.Set(cp.RCP, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneControlPlaneComponentsHealthyCondition, Status: metav1.ConditionUnknown, diff --git a/pkg/rke2/workload_cluster_conditions.go b/pkg/rke2/workload_cluster_conditions.go index 7f3f048c..d44cf25d 100644 --- a/pkg/rke2/workload_cluster_conditions.go +++ b/pkg/rke2/workload_cluster_conditions.go @@ -25,9 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" - clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/util/conditions" - v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1" clog "sigs.k8s.io/cluster-api/util/log" controlplanev1 "github.com/rancher/cluster-api-provider-rke2/controlplane/api/v1beta2" @@ -67,9 +65,6 @@ func (w *Workload) updateManagedEtcdConditions(controlPlane *ControlPlane) { // If the machine is deleting, report all the conditions as deleting if !machine.DeletionTimestamp.IsZero() { - v1beta1conditions.MarkFalse( - machine, controlplanev1.MachineEtcdMemberHealthyV1Beta1Condition, clusterv1.DeletingV1Beta1Reason, clusterv1.ConditionSeverityInfo, "") - conditions.Set(machine, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneMachineEtcdMemberHealthyCondition, Status: metav1.ConditionFalse, @@ -80,8 +75,6 @@ func (w *Workload) updateManagedEtcdConditions(controlPlane *ControlPlane) { continue } - v1beta1conditions.MarkTrue(machine, controlplanev1.MachineEtcdMemberHealthyV1Beta1Condition) - conditions.Set(machine, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneMachineEtcdMemberHealthyCondition, Status: metav1.ConditionTrue, @@ -96,10 +89,6 @@ func (w *Workload) updateManagedEtcdConditions(controlPlane *ControlPlane) { // if the corresponding Kubernetes node is in Ready state. This operation is best effort - in case // of problems retrieving node status, it sets conditions to Unknown state without returning any error. func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { - allMachinePodV1Beta1Conditions := []clusterv1.ConditionType{ - controlplanev1.MachineAgentHealthyV1Beta1Condition, - } - allMachinePodConditions := []string{ controlplanev1.RKE2ControlPlaneMachineAgentHealthyCondition, } @@ -138,10 +127,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { // If the machine is deleting, report all the conditions as deleting if !machine.DeletionTimestamp.IsZero() { - for _, condition := range allMachinePodV1Beta1Conditions { - v1beta1conditions.MarkFalse(machine, condition, clusterv1.DeletingV1Beta1Reason, clusterv1.ConditionSeverityInfo, "") - } - for _, condition := range allMachinePodConditions { conditions.Set(machine, metav1.Condition{ Type: condition, @@ -158,10 +143,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { if nodeHasUnreachableTaint(*node) { // NOTE: We are assuming unreachable as a temporary condition, leaving to MHC // the responsibility to determine if the node is unhealthy or not. - for _, condition := range allMachinePodV1Beta1Conditions { - v1beta1conditions.MarkUnknown(machine, condition, controlplanev1.PodInspectionFailedV1Beta1Reason, "Node is unreachable") - } - for _, condition := range allMachinePodConditions { conditions.Set(machine, metav1.Condition{ Type: condition, @@ -176,7 +157,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { // Node is reachable and machine is not deleting - set AgentHealthy based on node Ready condition. if isNodeReady(node) { - v1beta1conditions.MarkTrue(machine, controlplanev1.MachineAgentHealthyV1Beta1Condition) conditions.Set(machine, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneMachineAgentHealthyCondition, Status: metav1.ConditionTrue, @@ -184,8 +164,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { Message: "", }) } else { - v1beta1conditions.MarkFalse(machine, controlplanev1.MachineAgentHealthyV1Beta1Condition, - controlplanev1.PodFailedV1Beta1Reason, clusterv1.ConditionSeverityWarning, "Node is not ready") conditions.Set(machine, metav1.Condition{ Type: controlplanev1.RKE2ControlPlaneMachineAgentHealthyCondition, Status: metav1.ConditionFalse, @@ -209,10 +187,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { // Machine doesn't have a node yet (either NodeRef not set or node not found). // If there are machines still provisioning, this might be a timing issue - set to Unknown. if hasProvisioningMachine(controlPlane.Machines) { - for _, condition := range allMachinePodV1Beta1Conditions { - v1beta1conditions.MarkUnknown(machine, condition, controlplanev1.PodInspectionFailedV1Beta1Reason, "Waiting for node to be provisioned") - } - for _, condition := range allMachinePodConditions { conditions.Set(machine, metav1.Condition{ Type: condition, @@ -226,10 +200,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { } // No machines provisioning but node still missing - this is an error. - for _, condition := range allMachinePodV1Beta1Conditions { - v1beta1conditions.MarkFalse(machine, condition, controlplanev1.PodFailedV1Beta1Reason, clusterv1.ConditionSeverityError, "Missing node") - } - for _, condition := range allMachinePodConditions { conditions.Set(machine, metav1.Condition{ Type: condition, @@ -240,17 +210,6 @@ func (w *Workload) UpdateAgentConditions(controlPlane *ControlPlane) { } } - // Aggregate components error from machines at RCP level. - aggregateV1Beta1ConditionsFromMachinesToRCP(aggregateV1Beta1ConditionsFromMachinesToRCPInput{ - controlPlane: controlPlane, - machineConditions: allMachinePodV1Beta1Conditions, - rcpErrors: rcpErrors, - condition: controlplanev1.ControlPlaneComponentsHealthyV1Beta1Condition, - unhealthyReason: controlplanev1.ControlPlaneComponentsUnhealthyV1Beta1Reason, - unknownReason: controlplanev1.ControlPlaneComponentsUnknownV1Beta1Reason, - note: "control plane", - }) - aggregateConditionsFromMachinesToRCP(aggregateConditionsFromMachinesToRCPInput{ controlPlane: controlPlane, machineConditions: allMachinePodConditions, @@ -285,117 +244,6 @@ func nodeHasUnreachableTaint(node corev1.Node) bool { return false } -type aggregateV1Beta1ConditionsFromMachinesToRCPInput struct { - controlPlane *ControlPlane - machineConditions []clusterv1.ConditionType - rcpErrors []string - condition clusterv1.ConditionType - unhealthyReason string - unknownReason string - note string -} - -// aggregateV1Beta1ConditionsFromMachinesToRCP aggregates a group of conditions from machines to RCP. -// NOTE: this func follows the same aggregation rules used by conditions.Merge thus giving priority to -// errors, then warning, info down to unknown. -func aggregateV1Beta1ConditionsFromMachinesToRCP(input aggregateV1Beta1ConditionsFromMachinesToRCPInput) { - // Aggregates machines for condition status. - // NB. A machine could be assigned to many groups, but only the group with the highest severity will be reported. - rcpMachinesWithErrors := sets.NewString() - rcpMachinesWithWarnings := sets.NewString() - rcpMachinesWithInfo := sets.NewString() - rcpMachinesWithTrue := sets.NewString() - rcpMachinesWithUnknown := sets.NewString() - - for i := range input.controlPlane.Machines { - machine := input.controlPlane.Machines[i] - for _, condition := range input.machineConditions { - if machineCondition := v1beta1conditions.Get(machine, condition); machineCondition != nil { - switch machineCondition.Status { - case corev1.ConditionTrue: - rcpMachinesWithTrue.Insert(machine.Name) - case corev1.ConditionFalse: - switch machineCondition.Severity { - case clusterv1.ConditionSeverityInfo: - rcpMachinesWithInfo.Insert(machine.Name) - case clusterv1.ConditionSeverityWarning: - rcpMachinesWithWarnings.Insert(machine.Name) - case clusterv1.ConditionSeverityError: - rcpMachinesWithErrors.Insert(machine.Name) - } - case corev1.ConditionUnknown: - rcpMachinesWithUnknown.Insert(machine.Name) - } - } - } - } - - // In case of at least one machine with errors or RCP level errors (nodes without machines), report false, error. - if len(rcpMachinesWithErrors) > 0 { - input.rcpErrors = append( - input.rcpErrors, - fmt.Sprintf("Following machines are reporting %s errors: %s", - input.note, - strings.Join(rcpMachinesWithErrors.List(), ", "))) - } - - if len(input.rcpErrors) > 0 { - v1beta1conditions.MarkFalse( - input.controlPlane.RCP, - input.condition, - input.unhealthyReason, - clusterv1.ConditionSeverityError, - "%s", strings.Join(input.rcpErrors, "; ")) - - return - } - - // In case of no errors and at least one machine with warnings, report false, warnings. - if len(rcpMachinesWithWarnings) > 0 { - v1beta1conditions.MarkFalse( - input.controlPlane.RCP, - input.condition, - input.unhealthyReason, - clusterv1.ConditionSeverityWarning, - "Following machines are reporting %s warnings: %s", - input.note, - strings.Join(rcpMachinesWithWarnings.List(), ", ")) - - return - } - - // In case of no errors, no warning, and at least one machine with info, report false, info. - if len(rcpMachinesWithWarnings) > 0 { - v1beta1conditions.MarkFalse( - input.controlPlane.RCP, - input.condition, - input.unhealthyReason, - clusterv1.ConditionSeverityWarning, - "Following machines are reporting %s info: %s", - input.note, strings.Join(rcpMachinesWithInfo.List(), ", ")) - - return - } - - // In case of no errors, no warning, no Info, and at least one machine with true conditions, report true. - if len(rcpMachinesWithTrue) > 0 { - v1beta1conditions.MarkTrue(input.controlPlane.RCP, input.condition) - - return - } - - // Otherwise, if there is at least one machine with unknown, report unknown. - if len(rcpMachinesWithUnknown) > 0 { - v1beta1conditions.MarkUnknown( - input.controlPlane.RCP, - input.condition, - input.unknownReason, - "Following machines are reporting unknown %s status: %s", input.note, strings.Join(rcpMachinesWithUnknown.List(), ", ")) - - return - } -} - type aggregateConditionsFromMachinesToRCPInput struct { controlPlane *ControlPlane machineConditions []string diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 53ef607c..b23b7744 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -38,7 +38,6 @@ import ( controlplanev1beta1 "github.com/rancher/cluster-api-provider-rke2/controlplane/api/v1beta1" controlplanev1 "github.com/rancher/cluster-api-provider-rke2/controlplane/api/v1beta2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1" clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2" "sigs.k8s.io/cluster-api/test/framework" "sigs.k8s.io/cluster-api/test/framework/bootstrap" @@ -180,7 +179,6 @@ func initScheme() *runtime.Scheme { Expect(bootstrapv1.AddToScheme(scheme)).To(Succeed()) Expect(bootstrapv1beta1.AddToScheme(scheme)).To(Succeed()) Expect(clusterv1.AddToScheme(scheme)).To(Succeed()) - Expect(clusterv1beta1.AddToScheme(scheme)).To(Succeed()) Expect(dockerinfrav1.AddToScheme(scheme)).To(Succeed()) return scheme }