Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions pkg/util/provider/machinecontroller/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,6 @@ func (c *controller) triggerDeletionFlow(ctx context.Context, deleteMachineReque
case strings.Contains(machine.Status.LastOperation.Description, machineutils.InitiateVMDeletion):
return c.deleteVM(ctx, deleteMachineRequest)

case strings.Contains(machine.Status.LastOperation.Description, machineutils.RemoveNodeFinalizers):
return c.deleteNodeFinalizers(ctx, machine)

case strings.Contains(machine.Status.LastOperation.Description, machineutils.InitiateNodeDeletion):
return c.deleteNodeObject(ctx, machine)

Expand Down
116 changes: 7 additions & 109 deletions pkg/util/provider/machinecontroller/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3015,7 +3015,7 @@ var _ = Describe("machine", func() {
},
},
expect: expect{
err: fmt.Errorf("Machine deletion in process. VM deletion was successful. " + machineutils.RemoveNodeFinalizers),
err: fmt.Errorf("Machine deletion in process. VM deletion was successful. " + machineutils.InitiateNodeDeletion),
retry: machineutils.ShortRetry,
machine: newMachine(
&v1alpha1.MachineTemplateSpec{
Expand All @@ -3034,7 +3034,7 @@ var _ = Describe("machine", func() {
LastUpdateTime: metav1.Now(),
},
LastOperation: v1alpha1.LastOperation{
Description: fmt.Sprintf("VM deletion was successful. %s", machineutils.RemoveNodeFinalizers),
Description: fmt.Sprintf("VM deletion was successful. %s", machineutils.InitiateNodeDeletion),
State: v1alpha1.MachineStateProcessing,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
Expand All @@ -3052,7 +3052,7 @@ var _ = Describe("machine", func() {
),
},
}),
Entry("Delete node finalizers successfully", &data{
Entry("Delete node object successfully", &data{
setup: setup{
secrets: []*corev1.Secret{
{
Expand Down Expand Up @@ -3083,7 +3083,7 @@ var _ = Describe("machine", func() {
LastUpdateTime: metav1.Now(),
},
LastOperation: v1alpha1.LastOperation{
Description: fmt.Sprintf("VM deletion was successful. %s", machineutils.RemoveNodeFinalizers),
Description: fmt.Sprintf("VM deletion was successful. %s", machineutils.InitiateNodeDeletion),
State: v1alpha1.MachineStateProcessing,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
Expand Down Expand Up @@ -3120,109 +3120,7 @@ var _ = Describe("machine", func() {
},
},
expect: expect{
err: fmt.Errorf("machine deletion in process. Removal of finalizers from Node Object \"fakeID-0\" is successful. " + machineutils.InitiateNodeDeletion),
retry: machineutils.ShortRetry,
machine: newMachine(
&v1alpha1.MachineTemplateSpec{
ObjectMeta: *newObjectMeta(objMeta, 0),
Spec: v1alpha1.MachineSpec{
Class: v1alpha1.ClassSpec{
Kind: "MachineClass",
Name: "machine-0",
},
ProviderID: "fakeID",
},
},
&v1alpha1.MachineStatus{
CurrentStatus: v1alpha1.CurrentStatus{
Phase: v1alpha1.MachineTerminating,
LastUpdateTime: metav1.Now(),
},
LastOperation: v1alpha1.LastOperation{
Description: fmt.Sprintf("Removal of finalizers from Node Object %q is successful. %s", "fakeID-0", machineutils.InitiateNodeDeletion),
State: v1alpha1.MachineStateProcessing,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
},
},
nil,
map[string]string{
machineutils.MachinePriority: "3",
},
map[string]string{
v1alpha1.NodeLabelKey: "fakeID-0",
},
true,
metav1.Now(),
),
},
}),
Entry("Delete node object successfully", &data{
setup: setup{
secrets: []*corev1.Secret{
{
ObjectMeta: *newObjectMeta(objMeta, 0),
},
},
machineClasses: []*v1alpha1.MachineClass{
{
ObjectMeta: *newObjectMeta(objMeta, 0),
SecretRef: newSecretReference(objMeta, 0),
},
},
machines: newMachines(
1,
&v1alpha1.MachineTemplateSpec{
ObjectMeta: *newObjectMeta(objMeta, 0),
Spec: v1alpha1.MachineSpec{
Class: v1alpha1.ClassSpec{
Kind: "MachineClass",
Name: "machine-0",
},
ProviderID: "fakeID",
},
},
&v1alpha1.MachineStatus{
CurrentStatus: v1alpha1.CurrentStatus{
Phase: v1alpha1.MachineTerminating,
LastUpdateTime: metav1.Now(),
},
LastOperation: v1alpha1.LastOperation{
Description: fmt.Sprintf("Removal of finalizers from Node Object %q is successful. %s", "fakeID-0", machineutils.InitiateNodeDeletion),
State: v1alpha1.MachineStateProcessing,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
},
},
nil,
map[string]string{
machineutils.MachinePriority: "3",
},
map[string]string{
v1alpha1.NodeLabelKey: "fakeID-0",
},
true,
metav1.Now(),
),
nodes: []*corev1.Node{
{
ObjectMeta: metav1.ObjectMeta{
Name: "fakeID-0",
},
},
},
},
action: action{
machine: "machine-0",
fakeDriver: &driver.FakeDriver{
VMExists: true,
ProviderID: "fakeID-0",
NodeName: "fakeNode-0",
Err: nil,
},
},
expect: expect{
err: fmt.Errorf("Machine deletion in process. Deletion of node object was successful"),
err: fmt.Errorf("machine deletion in process: Deletion of Node Object %q is successful. %s", "fakeID-0", machineutils.InitiateFinalizerRemoval),
retry: machineutils.ShortRetry,
nodeDeleted: true,
machine: newMachine(
Expand Down Expand Up @@ -3604,7 +3502,7 @@ var _ = Describe("machine", func() {
},
},
expect: expect{
err: fmt.Errorf("Machine deletion in process. No node object found"),
err: fmt.Errorf("machine deletion in process: no node label found"),
retry: machineutils.ShortRetry,
nodeDeleted: false,
machine: newMachine(
Expand All @@ -3624,7 +3522,7 @@ var _ = Describe("machine", func() {
LastUpdateTime: metav1.Now(),
},
LastOperation: v1alpha1.LastOperation{
Description: fmt.Sprintf("Label %q not present on machine %q or no associated node object found, continuing deletion flow. %s", v1alpha1.NodeLabelKey, "machine-0", machineutils.InitiateFinalizerRemoval),
Description: fmt.Sprintf("Label %q not present on machine %q, continuing deletion flow. %s", v1alpha1.NodeLabelKey, "machine-0", machineutils.InitiateFinalizerRemoval),
State: v1alpha1.MachineStateProcessing,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
Expand Down
135 changes: 54 additions & 81 deletions pkg/util/provider/machinecontroller/machine_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ func (c *controller) deleteVM(ctx context.Context, deleteMachineRequest *driver.
state = v1alpha1.MachineStateFailed
case codes.NotFound:
retryRequired = machineutils.ShortRetry
description = fmt.Sprintf("VM not found. Continuing deletion flow. %s", machineutils.RemoveNodeFinalizers)
description = fmt.Sprintf("VM not found. Continuing deletion flow. %s", machineutils.InitiateNodeDeletion)
state = v1alpha1.MachineStateProcessing
default:
retryRequired = machineutils.LongRetry
Expand All @@ -1847,7 +1847,7 @@ func (c *controller) deleteVM(ctx context.Context, deleteMachineRequest *driver.

} else {
retryRequired = machineutils.ShortRetry
description = fmt.Sprintf("VM deletion was successful. %s", machineutils.RemoveNodeFinalizers)
description = fmt.Sprintf("VM deletion was successful. %s", machineutils.InitiateNodeDeletion)
state = v1alpha1.MachineStateProcessing

err = fmt.Errorf("Machine deletion in process. %s", description)
Expand Down Expand Up @@ -1880,105 +1880,78 @@ func (c *controller) deleteVM(ctx context.Context, deleteMachineRequest *driver.
return retryRequired, err
}

// deleteNodeFinalizers attempts to remove finalizers from the node object backed by the machine object
func (c *controller) deleteNodeFinalizers(ctx context.Context, machine *v1alpha1.Machine) (machineutils.RetryPeriod, error) {
// deleteNodeObject attempts to remove finalizers from and delete the node object backed by the machine object
func (c *controller) deleteNodeObject(ctx context.Context, machine *v1alpha1.Machine) (machineutils.RetryPeriod, error) {
var (
err error
description string
state v1alpha1.MachineState
node *v1.Node
)

// nodeName label is expected to be present on machine object, but in case it is not present
// we should not block deletion of machine and should move forward with flow.
nodeName := machine.Labels[v1alpha1.NodeLabelKey]

if nodeName != "" {
var node *v1.Node
node, err = c.nodeLister.Get(nodeName)
if err != nil {
switch {
case apierrors.IsNotFound(err):
description = fmt.Sprintf("No node object found for %q, skipping node finalizer removal. %s", nodeName, machineutils.InitiateNodeDeletion)
klog.Warning(description)
state = v1alpha1.MachineStateProcessing
default:
description = fmt.Sprintf("Retrieval of Node Object %q failed due to error: %s, Retrying node finalizer removal. %s", nodeName, err, machineutils.RemoveNodeFinalizers)
klog.Errorf(description)
state = v1alpha1.MachineStateFailed
}
} else {
err = c.removeNodeFinalizers(ctx, node)
if err != nil {
description = fmt.Sprintf("Removal of finalizers from Node Object %q failed due to error: %s, Retrying node finalizer removal. %s", nodeName, err, machineutils.RemoveNodeFinalizers)
klog.Errorf(description)
state = v1alpha1.MachineStateFailed
} else {
description = fmt.Sprintf("Removal of finalizers from Node Object %q is successful. %s", nodeName, machineutils.InitiateNodeDeletion)
state = v1alpha1.MachineStateProcessing
err = fmt.Errorf("machine deletion in process. %s", description)
}
}
} else {
description = fmt.Sprintf("Label %q not present on machine %q, skipping node finalizer removal. %s", v1alpha1.NodeLabelKey, machine.Name, machineutils.InitiateNodeDeletion)
if nodeName == "" {
description = fmt.Sprintf("Label %q not present on machine %q, continuing deletion flow. %s", v1alpha1.NodeLabelKey, machine.Name, machineutils.InitiateFinalizerRemoval)
klog.Warning(description)
state = v1alpha1.MachineStateProcessing
}

updateRetryPeriod, updateErr := c.machineStatusUpdate(
ctx,
machine,
v1alpha1.LastOperation{
Description: description,
State: state,
Type: v1alpha1.MachineOperationDelete,
LastUpdateTime: metav1.Now(),
},
// Let the clone.Status.CurrentStatus (LastUpdateTime) be as it was before.
// This helps while computing when the drain timeout to determine if force deletion is to be triggered.
machine.Status.CurrentStatus,
machine.Status.LastKnownState,
)
err = errors.New("machine deletion in process: no node label found")

if updateErr != nil {
return updateRetryPeriod, updateErr
return c.updateStatusForNodeDeletion(ctx, machine, description, state, err)
}
return machineutils.ShortRetry, err
}

// deleteNodeObject attempts to delete the node object backed by the machine object
func (c *controller) deleteNodeObject(ctx context.Context, machine *v1alpha1.Machine) (machineutils.RetryPeriod, error) {
var (
err error
description string
state v1alpha1.MachineState
)

nodeName := machine.Labels[v1alpha1.NodeLabelKey]

if nodeName != "" {
// Delete node object
err = c.targetCoreClient.CoreV1().Nodes().Delete(ctx, nodeName, metav1.DeleteOptions{})
klog.V(3).Infof("Deleting node %q associated with machine %q", nodeName, machine.Name)
if err != nil && !apierrors.IsNotFound(err) {
// If its an error, and any other error than object not found
description = fmt.Sprintf("Deletion of Node Object %q failed due to error: %s. %s", nodeName, err, machineutils.InitiateNodeDeletion)
klog.Error(description)
state = v1alpha1.MachineStateFailed
} else if err == nil {
description = fmt.Sprintf("Deletion of Node Object %q is successful. %s", nodeName, machineutils.InitiateFinalizerRemoval)
klog.V(3).Info(description)
state = v1alpha1.MachineStateProcessing
err = fmt.Errorf("Machine deletion in process. Deletion of node object was successful")
} else {
node, err = c.nodeLister.Get(nodeName)
if err != nil {
// If node object is not found, then it could have already been deleted,
// therefore we should not block deletion of machine. But if error is other than NotFound,
// then we should retry as it could be a transient error.
switch {
case apierrors.IsNotFound(err):
description = fmt.Sprintf("No node object found for %q, continuing deletion flow. %s", nodeName, machineutils.InitiateFinalizerRemoval)
klog.Warning(description)
state = v1alpha1.MachineStateProcessing
default:
description = fmt.Sprintf("Retrieval of Node Object %q failed due to error: %s, Retrying. %s", nodeName, err, machineutils.InitiateNodeDeletion)
klog.Error(description)
state = v1alpha1.MachineStateFailed
}
} else {
description = fmt.Sprintf("Label %q not present on machine %q or no associated node object found, continuing deletion flow. %s", v1alpha1.NodeLabelKey, machine.Name, machineutils.InitiateFinalizerRemoval)

return c.updateStatusForNodeDeletion(ctx, machine, description, state, err)
}

// Remove finalizers from node object before deletion.
klog.V(3).Infof("Removing finalizers from node %q associated with machine %q", nodeName, machine.Name)
err = c.removeNodeFinalizers(ctx, node)
if err != nil {
description = fmt.Sprintf("Removal of finalizers from Node Object %q failed due to error: %s, Retrying. %s", nodeName, err, machineutils.InitiateNodeDeletion)
klog.Error(description)
state = v1alpha1.MachineStateFailed
return c.updateStatusForNodeDeletion(ctx, machine, description, state, err)
}

// Delete node object.
klog.V(3).Infof("Deleting node %q associated with machine %q", nodeName, machine.Name)
err = c.targetCoreClient.CoreV1().Nodes().Delete(ctx, nodeName, metav1.DeleteOptions{})
switch {
case err == nil:
description = fmt.Sprintf("Deletion of Node Object %q is successful. %s", nodeName, machineutils.InitiateFinalizerRemoval)
klog.V(3).Info(description)
state = v1alpha1.MachineStateProcessing
err = fmt.Errorf("Machine deletion in process. No node object found")
err = fmt.Errorf("machine deletion in process: %s", description)
case apierrors.IsNotFound(err):
description = fmt.Sprintf("No node object found for %q, continuing deletion flow. %s", nodeName, machineutils.InitiateFinalizerRemoval)
klog.Warning(description)
state = v1alpha1.MachineStateProcessing
default:
description = fmt.Sprintf("Deletion of Node Object %q failed due to error: %s. %s", nodeName, err, machineutils.InitiateNodeDeletion)
klog.Error(description)
state = v1alpha1.MachineStateFailed
}
return c.updateStatusForNodeDeletion(ctx, machine, description, state, err)
}

func (c *controller) updateStatusForNodeDeletion(ctx context.Context, machine *v1alpha1.Machine, description string, state v1alpha1.MachineState, err error) (machineutils.RetryPeriod, error) {
Comment thread
takoverflow marked this conversation as resolved.
Outdated
updateRetryPeriod, updateErr := c.machineStatusUpdate(
ctx,
machine,
Expand Down
Loading
Loading