Skip to content

Commit e341dd1

Browse files
committed
Introduce NodeDeletionStrategy to allow drain node when deleting cluster
Signed-off-by: Lubron Zhan <[email protected]>
1 parent f1da05a commit e341dd1

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

api/v1beta2/cluster_types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,14 @@ type Topology struct {
585585
// +listMapKey=name
586586
// +kubebuilder:validation:MaxItems=1000
587587
Variables []ClusterVariable `json:"variables,omitempty"`
588+
589+
// nodeDeletionStrategy specifies the strategy to delete nodes in the cluster.
590+
// Avilable options:
591+
// - graceful
592+
// - force
593+
// By default it's "force"
594+
// +optional
595+
NodeDeletionStrategy *NodeDrainStrategyType `json:"nodeDrainStrategy,omitempty"`
588596
}
589597

590598
// ControlPlaneTopology specifies the parameters for the control plane nodes in the cluster.
@@ -901,6 +909,13 @@ type MachinePoolVariables struct {
901909
Overrides []ClusterVariable `json:"overrides,omitempty"`
902910
}
903911

912+
type NodeDrainStrategyType string
913+
914+
const (
915+
NodeDrainStrategyForce NodeDrainStrategyType = "force"
916+
NodeDrainStrategyGracefulWithTimeout NodeDrainStrategyType = "gracefulWithTimeout"
917+
)
918+
904919
// ANCHOR_END: ClusterSpec
905920

906921
// ANCHOR: ClusterNetwork

internal/controllers/machine/machine_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,8 +714,8 @@ func (r *Reconciler) nodeVolumeDetachTimeoutExceeded(machine *clusterv1.Machine)
714714
// and if the Machine is not the last control plane node in the cluster.
715715
func (r *Reconciler) isDeleteNodeAllowed(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine) error {
716716
log := ctrl.LoggerFrom(ctx)
717-
// Return early if the cluster is being deleted.
718-
if !cluster.DeletionTimestamp.IsZero() {
717+
// Return early if the cluster is being deleted and cluster's nodeDeletionStrategy is not set or set to `force`.
718+
if !cluster.DeletionTimestamp.IsZero() && (cluster.Spec.Topology.NodeDeletionStrategy == nil || *cluster.Spec.Topology.NodeDeletionStrategy == clusterv1.NodeDrainStrategyForce) {
719719
return errClusterIsBeingDeleted
720720
}
721721

internal/controllers/machine/machine_controller_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,6 +2668,59 @@ func TestIsDeleteNodeAllowed(t *testing.T) {
26682668
machine: &clusterv1.Machine{},
26692669
expectedError: errClusterIsBeingDeleted,
26702670
},
2671+
{
2672+
name: "has nodeRef and cluster is being deleted, nodeDeletionStrategy set to force",
2673+
cluster: &clusterv1.Cluster{
2674+
ObjectMeta: metav1.ObjectMeta{
2675+
Name: "test-cluster",
2676+
Namespace: metav1.NamespaceDefault,
2677+
DeletionTimestamp: &deletionts,
2678+
Finalizers: []string{clusterv1.ClusterFinalizer},
2679+
},
2680+
Spec: clusterv1.ClusterSpec{
2681+
Topology: &clusterv1.Topology{
2682+
NodeDeletionStrategy: ptr.To(clusterv1.NodeDrainStrategyForce),
2683+
},
2684+
},
2685+
},
2686+
machine: &clusterv1.Machine{},
2687+
expectedError: errClusterIsBeingDeleted,
2688+
},
2689+
{
2690+
name: "has nodeRef and control plane is healthy, with nodeDeletionStrategy set to graceful",
2691+
cluster: &clusterv1.Cluster{
2692+
ObjectMeta: metav1.ObjectMeta{
2693+
Name: "test-cluster",
2694+
Namespace: metav1.NamespaceDefault,
2695+
},
2696+
Spec: clusterv1.ClusterSpec{
2697+
Topology: &clusterv1.Topology{
2698+
NodeDeletionStrategy: ptr.To(clusterv1.NodeDrainStrategyForce),
2699+
},
2700+
},
2701+
},
2702+
machine: &clusterv1.Machine{
2703+
ObjectMeta: metav1.ObjectMeta{
2704+
Name: "created",
2705+
Namespace: metav1.NamespaceDefault,
2706+
Labels: map[string]string{
2707+
clusterv1.ClusterNameLabel: "test-cluster",
2708+
},
2709+
Finalizers: []string{clusterv1.MachineFinalizer},
2710+
},
2711+
Spec: clusterv1.MachineSpec{
2712+
ClusterName: "test-cluster",
2713+
InfrastructureRef: corev1.ObjectReference{},
2714+
Bootstrap: clusterv1.Bootstrap{DataSecretName: ptr.To("data")},
2715+
},
2716+
Status: clusterv1.MachineStatus{
2717+
NodeRef: &corev1.ObjectReference{
2718+
Name: "test",
2719+
},
2720+
},
2721+
},
2722+
expectedError: nil,
2723+
},
26712724
{
26722725
name: "has nodeRef and control plane is healthy and externally managed",
26732726
cluster: &clusterv1.Cluster{

0 commit comments

Comments
 (0)