Skip to content
Permalink
Browse files

fix: clean up isDeleteReady logic

Signed-off-by: Andrew Rudoi <arudoi@newrelic.com>
  • Loading branch information...
rudoi committed Aug 21, 2019
1 parent 801b1c1 commit c8ce2c73791399108125da4eadc53f8e25139397
Showing with 125 additions and 20 deletions.
  1. +20 −20 controllers/machine_controller.go
  2. +105 −0 controllers/machine_controller_test.go
@@ -18,7 +18,6 @@ package controllers

import (
"context"
"path"
"sync"
"time"

@@ -249,32 +248,33 @@ func (r *MachineReconciler) getMachinesInCluster(ctx context.Context, namespace,

// isDeleteReady returns an error if any of Boostrap.ConfigRef or InfrastructureRef referenced objects still exist.
func (r *MachineReconciler) isDeleteReady(ctx context.Context, m *clusterv1.Machine) error {
if m.Spec.Bootstrap.ConfigRef != nil {
_, err := external.Get(r.Client, m.Spec.Bootstrap.ConfigRef, m.Namespace)
if apierrors.IsNotFound(err) {
return nil
}
if err != nil {
return errors.Wrapf(err, "failed to get %s %q for Machine %q in namespace %q",
path.Join(m.Spec.Bootstrap.ConfigRef.APIVersion, m.Spec.Bootstrap.ConfigRef.Kind),
m.Spec.Bootstrap.ConfigRef.Name, m.Name, m.Namespace)
}
return errors.Wrapf(&capierrors.RequeueAfterError{RequeueAfter: 10 * time.Second},
"delete is not ready, Bootstrap configuration still exists")
}
bootstrapConfigReady := r.isExternalDeleteReady(ctx, m.Namespace, m.Spec.Bootstrap.ConfigRef)
infraReady := r.isExternalDeleteReady(ctx, m.Namespace, &m.Spec.InfrastructureRef)

if _, err := external.Get(r.Client, &m.Spec.InfrastructureRef, m.Namespace); err != nil && !apierrors.IsNotFound(err) {
return errors.Wrapf(err, "failed to get %s %q for Machine %q in namespace %q",
path.Join(m.Spec.InfrastructureRef.APIVersion, m.Spec.InfrastructureRef.Kind),
m.Spec.InfrastructureRef.Name, m.Name, m.Namespace)
} else if err == nil {
if !bootstrapConfigReady || !infraReady {
return errors.Wrapf(&capierrors.RequeueAfterError{RequeueAfter: 10 * time.Second},
"delete is not ready, Infrastructure configuration still exists")
"delete is not ready, Bootstrap configuration or Infrastructure configuration still exists")
}

return nil
}

func (r *MachineReconciler) isExternalDeleteReady(ctx context.Context, namespace string, ref *corev1.ObjectReference) bool {
if ref == nil {
return true
}

_, err := external.Get(r.Client, ref, namespace)
if apierrors.IsNotFound(err) {
return true
}
if err != nil {
return false
}

return false
}

func (r *MachineReconciler) shouldAdopt(m *clusterv1.Machine) bool {
return !util.HasOwner(m.OwnerReferences, clusterv1.GroupVersion.String(), []string{"MachineSet", "Cluster"})
}
@@ -24,6 +24,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/utils/pointer"
@@ -198,3 +199,107 @@ func TestReconcileRequest(t *testing.T) {
Expect(result).To(Equal(tc.expected.result))
}
}

func TestIsDeletionReady(t *testing.T) {
RegisterTestingT(t)

bootstrapConfig := &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "BootstrapConfig",
"apiVersion": "bootstrap.cluster.x-k8s.io/v1alpha2",
"metadata": map[string]interface{}{
"name": "delete-bootstrap",
"namespace": "default",
},
},
}

infraConfig := &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "InfrastructureConfig",
"apiVersion": "infrastructure.cluster.x-k8s.io/v1alpha2",
"metadata": map[string]interface{}{
"name": "delete-infra",
"namespace": "default",
},
},
}

machine := v1alpha2.Machine{
TypeMeta: metav1.TypeMeta{
Kind: "Machine",
},
ObjectMeta: metav1.ObjectMeta{
Name: "delete",
Namespace: "default",
},
Spec: v1alpha2.MachineSpec{
InfrastructureRef: corev1.ObjectReference{
APIVersion: "infrastructure.cluster.x-k8s.io/v1alpha2",
Kind: "InfrastructureConfig",
Name: "delete-infra",
},
Bootstrap: v1alpha2.Bootstrap{
ConfigRef: &corev1.ObjectReference{
APIVersion: "bootstrap.cluster.x-k8s.io/v1alpha2",
Kind: "BootstrapConfig",
Name: "delete-bootstrap",
},
},
},
}

testCases := []struct {
bootstrapExists bool
infraExists bool
expectedErr bool
}{
{
bootstrapExists: true,
infraExists: true,
expectedErr: true,
},
{
bootstrapExists: false,
infraExists: true,
expectedErr: true,
},
{
bootstrapExists: true,
infraExists: false,
expectedErr: true,
},
{
bootstrapExists: false,
infraExists: false,
expectedErr: false,
},
}

for _, tc := range testCases {
myscheme := runtime.NewScheme()
v1alpha2.AddToScheme(myscheme)

objs := []runtime.Object{&machine}

if tc.bootstrapExists {
objs = append(objs, bootstrapConfig)
}

if tc.infraExists {
objs = append(objs, infraConfig)
}

r := &MachineReconciler{
Client: fake.NewFakeClientWithScheme(myscheme, objs...),
Log: log.Log,
}

err := r.isDeleteReady(ctx, &machine)
if tc.expectedErr {
Expect(err).ToNot(BeNil())
} else {
Expect(err).To(BeNil())
}
}
}

0 comments on commit c8ce2c7

Please sign in to comment.
You can’t perform that action at this time.