Skip to content

Commit efe7de7

Browse files
committed
ASOAPI: add/remove finalizers
1 parent 64eaa63 commit efe7de7

7 files changed

+257
-13
lines changed

exp/api/v1alpha1/azureasomanagedcluster_types.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
)
2222

23-
// AzureASOManagedClusterKind is the kind for AzureASOManagedCluster.
24-
const AzureASOManagedClusterKind = "AzureASOManagedCluster"
23+
const (
24+
// AzureASOManagedClusterKind is the kind for AzureASOManagedCluster.
25+
AzureASOManagedClusterKind = "AzureASOManagedCluster"
26+
27+
// AzureASOManagedControlPlaneFinalizer is the finalizer added to AzureASOManagedControlPlanes.
28+
AzureASOManagedControlPlaneFinalizer = "azureasomanagedcontrolplane.infrastructure.cluster.x-k8s.io"
29+
)
2530

2631
// AzureASOManagedClusterSpec defines the desired state of AzureASOManagedCluster.
2732
type AzureASOManagedClusterSpec struct {

exp/controllers/azureasomanagedcluster_controller.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controllers
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223

2324
infracontroller "sigs.k8s.io/cluster-api-provider-azure/controllers"
@@ -31,9 +32,13 @@ import (
3132
ctrl "sigs.k8s.io/controller-runtime"
3233
"sigs.k8s.io/controller-runtime/pkg/builder"
3334
"sigs.k8s.io/controller-runtime/pkg/client"
35+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3436
"sigs.k8s.io/controller-runtime/pkg/handler"
37+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3538
)
3639

40+
var errInvalidControlPlaneKind = errors.New("AzureASOManagedCluster cannot be used without AzureASOManagedControlPlane")
41+
3742
// AzureASOManagedClusterReconciler reconciles a AzureASOManagedCluster object.
3843
type AzureASOManagedClusterReconciler struct {
3944
client.Client
@@ -120,7 +125,6 @@ func (r *AzureASOManagedClusterReconciler) Reconcile(ctx context.Context, req ct
120125
return r.reconcileNormal(ctx, asoManagedCluster, cluster)
121126
}
122127

123-
//nolint:unparam // these parameters will be used soon enough
124128
func (r *AzureASOManagedClusterReconciler) reconcileNormal(ctx context.Context, asoManagedCluster *infrav1exp.AzureASOManagedCluster, cluster *clusterv1.Cluster) (ctrl.Result, error) {
125129
//nolint:all // ctx will be used soon
126130
ctx, log, done := tele.StartSpanWithLogger(ctx,
@@ -129,6 +133,21 @@ func (r *AzureASOManagedClusterReconciler) reconcileNormal(ctx context.Context,
129133
defer done()
130134
log.V(4).Info("reconciling normally")
131135

136+
if cluster == nil {
137+
log.V(4).Info("Cluster Controller has not yet set OwnerRef")
138+
return ctrl.Result{}, nil
139+
}
140+
if cluster.Spec.ControlPlaneRef == nil ||
141+
cluster.Spec.ControlPlaneRef.APIVersion != infrav1exp.GroupVersion.Identifier() ||
142+
cluster.Spec.ControlPlaneRef.Kind != infrav1exp.AzureASOManagedControlPlaneKind {
143+
return ctrl.Result{}, reconcile.TerminalError(errInvalidControlPlaneKind)
144+
}
145+
146+
needsPatch := controllerutil.AddFinalizer(asoManagedCluster, clusterv1.ClusterFinalizer)
147+
if needsPatch {
148+
return ctrl.Result{Requeue: true}, nil
149+
}
150+
132151
return ctrl.Result{}, nil
133152
}
134153

@@ -153,5 +172,6 @@ func (r *AzureASOManagedClusterReconciler) reconcileDelete(ctx context.Context,
153172
defer done()
154173
log.V(4).Info("reconciling delete")
155174

175+
controllerutil.RemoveFinalizer(asoManagedCluster, clusterv1.ClusterFinalizer)
156176
return ctrl.Result{}, nil
157177
}

exp/controllers/azureasomanagedcluster_controller_test.go

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"time"
2323

2424
. "github.com/onsi/gomega"
25+
corev1 "k8s.io/api/core/v1"
26+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/apimachinery/pkg/runtime"
2729
"k8s.io/apimachinery/pkg/types"
@@ -87,17 +89,81 @@ func TestAzureASOManagedClusterReconcile(t *testing.T) {
8789
g.Expect(err).To(HaveOccurred())
8890
})
8991

90-
t.Run("successfully reconciles normally", func(t *testing.T) {
92+
t.Run("adds a finalizer", func(t *testing.T) {
9193
g := NewGomegaWithT(t)
9294

95+
cluster := &clusterv1.Cluster{
96+
ObjectMeta: metav1.ObjectMeta{
97+
Name: "cluster",
98+
Namespace: "ns",
99+
},
100+
Spec: clusterv1.ClusterSpec{
101+
ControlPlaneRef: &corev1.ObjectReference{
102+
APIVersion: infrav1exp.GroupVersion.Identifier(),
103+
Kind: infrav1exp.AzureASOManagedControlPlaneKind,
104+
},
105+
},
106+
}
93107
asoManagedCluster := &infrav1exp.AzureASOManagedCluster{
94108
ObjectMeta: metav1.ObjectMeta{
95109
Name: "amc",
110+
Namespace: cluster.Namespace,
111+
OwnerReferences: []metav1.OwnerReference{
112+
{
113+
APIVersion: clusterv1.GroupVersion.Identifier(),
114+
Kind: "Cluster",
115+
Name: cluster.Name,
116+
},
117+
},
118+
},
119+
}
120+
c := fakeClientBuilder().
121+
WithObjects(cluster, asoManagedCluster).
122+
Build()
123+
r := &AzureASOManagedClusterReconciler{
124+
Client: c,
125+
}
126+
result, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(asoManagedCluster)})
127+
g.Expect(err).NotTo(HaveOccurred())
128+
g.Expect(result).To(Equal(ctrl.Result{Requeue: true}))
129+
130+
g.Expect(c.Get(ctx, client.ObjectKeyFromObject(asoManagedCluster), asoManagedCluster)).To(Succeed())
131+
g.Expect(asoManagedCluster.GetFinalizers()).To(ContainElement(clusterv1.ClusterFinalizer))
132+
})
133+
134+
t.Run("successfully reconciles normally", func(t *testing.T) {
135+
g := NewGomegaWithT(t)
136+
137+
cluster := &clusterv1.Cluster{
138+
ObjectMeta: metav1.ObjectMeta{
139+
Name: "cluster",
96140
Namespace: "ns",
97141
},
142+
Spec: clusterv1.ClusterSpec{
143+
ControlPlaneRef: &corev1.ObjectReference{
144+
APIVersion: infrav1exp.GroupVersion.Identifier(),
145+
Kind: infrav1exp.AzureASOManagedControlPlaneKind,
146+
},
147+
},
148+
}
149+
asoManagedCluster := &infrav1exp.AzureASOManagedCluster{
150+
ObjectMeta: metav1.ObjectMeta{
151+
Name: "amc",
152+
Namespace: cluster.Namespace,
153+
OwnerReferences: []metav1.OwnerReference{
154+
{
155+
APIVersion: clusterv1.GroupVersion.Identifier(),
156+
Kind: "Cluster",
157+
Name: cluster.Name,
158+
},
159+
},
160+
Finalizers: []string{
161+
clusterv1.ClusterFinalizer,
162+
},
163+
},
98164
}
99165
c := fakeClientBuilder().
100-
WithObjects(asoManagedCluster).
166+
WithObjects(cluster, asoManagedCluster).
101167
Build()
102168
r := &AzureASOManagedClusterReconciler{
103169
Client: c,
@@ -165,5 +231,8 @@ func TestAzureASOManagedClusterReconcile(t *testing.T) {
165231
result, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(asoManagedCluster)})
166232
g.Expect(err).NotTo(HaveOccurred())
167233
g.Expect(result).To(Equal(ctrl.Result{}))
234+
235+
err = c.Get(ctx, client.ObjectKeyFromObject(asoManagedCluster), asoManagedCluster)
236+
g.Expect(apierrors.IsNotFound(err)).To(BeTrue())
168237
})
169238
}

exp/controllers/azureasomanagedcontrolplane_controller.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controllers
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223

2324
infracontroller "sigs.k8s.io/cluster-api-provider-azure/controllers"
@@ -31,9 +32,13 @@ import (
3132
ctrl "sigs.k8s.io/controller-runtime"
3233
"sigs.k8s.io/controller-runtime/pkg/builder"
3334
"sigs.k8s.io/controller-runtime/pkg/client"
35+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3436
"sigs.k8s.io/controller-runtime/pkg/handler"
37+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3538
)
3639

40+
var errInvalidClusterKind = errors.New("AzureASOManagedControlPlane cannot be used without AzureASOManagedCluster")
41+
3742
// AzureASOManagedControlPlaneReconciler reconciles a AzureASOManagedControlPlane object.
3843
type AzureASOManagedControlPlaneReconciler struct {
3944
client.Client
@@ -125,7 +130,6 @@ func (r *AzureASOManagedControlPlaneReconciler) Reconcile(ctx context.Context, r
125130
return r.reconcileNormal(ctx, asoManagedControlPlane, cluster)
126131
}
127132

128-
//nolint:unparam // these parameters will be used soon enough
129133
func (r *AzureASOManagedControlPlaneReconciler) reconcileNormal(ctx context.Context, asoManagedControlPlane *infrav1exp.AzureASOManagedControlPlane, cluster *clusterv1.Cluster) (ctrl.Result, error) {
130134
//nolint:all // ctx will be used soon
131135
ctx, log, done := tele.StartSpanWithLogger(ctx,
@@ -134,6 +138,21 @@ func (r *AzureASOManagedControlPlaneReconciler) reconcileNormal(ctx context.Cont
134138
defer done()
135139
log.V(4).Info("reconciling normally")
136140

141+
if cluster == nil {
142+
log.V(4).Info("Cluster Controller has not yet set OwnerRef")
143+
return ctrl.Result{}, nil
144+
}
145+
if cluster.Spec.InfrastructureRef == nil ||
146+
cluster.Spec.InfrastructureRef.APIVersion != infrav1exp.GroupVersion.Identifier() ||
147+
cluster.Spec.InfrastructureRef.Kind != infrav1exp.AzureASOManagedClusterKind {
148+
return ctrl.Result{}, reconcile.TerminalError(errInvalidClusterKind)
149+
}
150+
151+
needsPatch := controllerutil.AddFinalizer(asoManagedControlPlane, infrav1exp.AzureASOManagedControlPlaneFinalizer)
152+
if needsPatch {
153+
return ctrl.Result{Requeue: true}, nil
154+
}
155+
137156
return ctrl.Result{}, nil
138157
}
139158

@@ -158,5 +177,6 @@ func (r *AzureASOManagedControlPlaneReconciler) reconcileDelete(ctx context.Cont
158177
defer done()
159178
log.V(4).Info("reconciling delete")
160179

180+
controllerutil.RemoveFinalizer(asoManagedControlPlane, infrav1exp.AzureASOManagedControlPlaneFinalizer)
161181
return ctrl.Result{}, nil
162182
}

exp/controllers/azureasomanagedcontrolplane_controller_test.go

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"time"
2323

2424
. "github.com/onsi/gomega"
25+
corev1 "k8s.io/api/core/v1"
26+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/apimachinery/pkg/runtime"
2729
"k8s.io/apimachinery/pkg/types"
@@ -86,17 +88,81 @@ func TestAzureASOManagedControlPlaneReconcile(t *testing.T) {
8688
g.Expect(err).To(HaveOccurred())
8789
})
8890

89-
t.Run("successfully reconciles normally", func(t *testing.T) {
91+
t.Run("adds a finalizer", func(t *testing.T) {
9092
g := NewGomegaWithT(t)
9193

94+
cluster := &clusterv1.Cluster{
95+
ObjectMeta: metav1.ObjectMeta{
96+
Name: "cluster",
97+
Namespace: "ns",
98+
},
99+
Spec: clusterv1.ClusterSpec{
100+
InfrastructureRef: &corev1.ObjectReference{
101+
APIVersion: infrav1exp.GroupVersion.Identifier(),
102+
Kind: infrav1exp.AzureASOManagedClusterKind,
103+
},
104+
},
105+
}
92106
asoManagedControlPlane := &infrav1exp.AzureASOManagedControlPlane{
93107
ObjectMeta: metav1.ObjectMeta{
94-
Name: "amc",
108+
Name: "amcp",
109+
Namespace: cluster.Namespace,
110+
OwnerReferences: []metav1.OwnerReference{
111+
{
112+
APIVersion: clusterv1.GroupVersion.Identifier(),
113+
Kind: "Cluster",
114+
Name: cluster.Name,
115+
},
116+
},
117+
},
118+
}
119+
c := fakeClientBuilder().
120+
WithObjects(cluster, asoManagedControlPlane).
121+
Build()
122+
r := &AzureASOManagedControlPlaneReconciler{
123+
Client: c,
124+
}
125+
result, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(asoManagedControlPlane)})
126+
g.Expect(err).NotTo(HaveOccurred())
127+
g.Expect(result).To(Equal(ctrl.Result{Requeue: true}))
128+
129+
g.Expect(c.Get(ctx, client.ObjectKeyFromObject(asoManagedControlPlane), asoManagedControlPlane)).To(Succeed())
130+
g.Expect(asoManagedControlPlane.GetFinalizers()).To(ContainElement(infrav1exp.AzureASOManagedControlPlaneFinalizer))
131+
})
132+
133+
t.Run("successfully reconciles normally", func(t *testing.T) {
134+
g := NewGomegaWithT(t)
135+
136+
cluster := &clusterv1.Cluster{
137+
ObjectMeta: metav1.ObjectMeta{
138+
Name: "cluster",
95139
Namespace: "ns",
96140
},
141+
Spec: clusterv1.ClusterSpec{
142+
InfrastructureRef: &corev1.ObjectReference{
143+
APIVersion: infrav1exp.GroupVersion.Identifier(),
144+
Kind: infrav1exp.AzureASOManagedClusterKind,
145+
},
146+
},
147+
}
148+
asoManagedControlPlane := &infrav1exp.AzureASOManagedControlPlane{
149+
ObjectMeta: metav1.ObjectMeta{
150+
Name: "amcp",
151+
Namespace: cluster.Namespace,
152+
OwnerReferences: []metav1.OwnerReference{
153+
{
154+
APIVersion: clusterv1.GroupVersion.Identifier(),
155+
Kind: "Cluster",
156+
Name: cluster.Name,
157+
},
158+
},
159+
Finalizers: []string{
160+
infrav1exp.AzureASOManagedControlPlaneFinalizer,
161+
},
162+
},
97163
}
98164
c := fakeClientBuilder().
99-
WithObjects(asoManagedControlPlane).
165+
WithObjects(cluster, asoManagedControlPlane).
100166
Build()
101167
r := &AzureASOManagedControlPlaneReconciler{
102168
Client: c,
@@ -120,7 +186,7 @@ func TestAzureASOManagedControlPlaneReconcile(t *testing.T) {
120186
}
121187
asoManagedControlPlane := &infrav1exp.AzureASOManagedControlPlane{
122188
ObjectMeta: metav1.ObjectMeta{
123-
Name: "amc",
189+
Name: "amcp",
124190
Namespace: cluster.Namespace,
125191
OwnerReferences: []metav1.OwnerReference{
126192
{
@@ -147,10 +213,10 @@ func TestAzureASOManagedControlPlaneReconcile(t *testing.T) {
147213

148214
asoManagedControlPlane := &infrav1exp.AzureASOManagedControlPlane{
149215
ObjectMeta: metav1.ObjectMeta{
150-
Name: "amc",
216+
Name: "amcp",
151217
Namespace: "ns",
152218
Finalizers: []string{
153-
clusterv1.ClusterFinalizer,
219+
infrav1exp.AzureASOManagedControlPlaneFinalizer,
154220
},
155221
DeletionTimestamp: &metav1.Time{Time: time.Date(1, 0, 0, 0, 0, 0, 0, time.UTC)},
156222
},
@@ -164,5 +230,8 @@ func TestAzureASOManagedControlPlaneReconcile(t *testing.T) {
164230
result, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(asoManagedControlPlane)})
165231
g.Expect(err).NotTo(HaveOccurred())
166232
g.Expect(result).To(Equal(ctrl.Result{}))
233+
234+
err = c.Get(ctx, client.ObjectKeyFromObject(asoManagedControlPlane), asoManagedControlPlane)
235+
g.Expect(apierrors.IsNotFound(err)).To(BeTrue())
167236
})
168237
}

exp/controllers/azureasomanagedmachinepool_controller.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
ctrl "sigs.k8s.io/controller-runtime"
3434
"sigs.k8s.io/controller-runtime/pkg/builder"
3535
"sigs.k8s.io/controller-runtime/pkg/client"
36+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3637
"sigs.k8s.io/controller-runtime/pkg/handler"
3738
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3839
)
@@ -172,6 +173,11 @@ func (r *AzureASOManagedMachinePoolReconciler) reconcileNormal(ctx context.Conte
172173
defer done()
173174
log.V(4).Info("reconciling normally")
174175

176+
needsPatch := controllerutil.AddFinalizer(asoManagedMachinePool, clusterv1.ClusterFinalizer)
177+
if needsPatch {
178+
return ctrl.Result{Requeue: true}, nil
179+
}
180+
175181
return ctrl.Result{}, nil
176182
}
177183

@@ -196,5 +202,6 @@ func (r *AzureASOManagedMachinePoolReconciler) reconcileDelete(ctx context.Conte
196202
defer done()
197203
log.V(4).Info("reconciling delete")
198204

205+
controllerutil.RemoveFinalizer(asoManagedMachinePool, clusterv1.ClusterFinalizer)
199206
return ctrl.Result{}, nil
200207
}

0 commit comments

Comments
 (0)