Skip to content

Commit 71df89d

Browse files
authored
Delete DAP DDAIs when DAP deleted (#2019)
* Delete DDAIs when DAP deleted * Review suggestions
1 parent b7de624 commit 71df89d

File tree

4 files changed

+195
-7
lines changed

4 files changed

+195
-7
lines changed

internal/controller/datadogagent/controller_reconcile_v2.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ func (r *Reconciler) reconcileInstanceV3(ctx context.Context, logger logr.Logger
107107
// TODO: copy remote config status from DDA to DDAI
108108
}
109109

110+
// Clean up unused DDAI objects
111+
if e := r.cleanUpUnusedDDAIs(ctx, ddais); e != nil {
112+
return r.updateStatusIfNeededV2(logger, instance, ddaStatusCopy, result, e, now)
113+
}
114+
110115
// Prevent the reconcile loop from stopping by requeueing the DDAI object after a period of time
111116
result.RequeueAfter = defaultRequeuePeriod
112117
return r.updateStatusIfNeededV2(logger, instance, newDDAStatus, result, err, now)

internal/controller/datadogagent/ddai.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@
66
package datadogagent
77

88
import (
9+
"context"
10+
"fmt"
11+
912
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1013
"k8s.io/apimachinery/pkg/runtime"
1114

1215
apicommon "github.com/DataDog/datadog-operator/api/datadoghq/common"
13-
datadoghqv1alpha1 "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
14-
datadoghqv2alpha1 "github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
16+
"github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
17+
"github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
1518
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/global"
1619
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object"
1720
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/override"
1821
"github.com/DataDog/datadog-operator/pkg/constants"
1922
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
2023
)
2124

22-
func (r *Reconciler) generateDDAIFromDDA(dda *datadoghqv2alpha1.DatadogAgent) (*datadoghqv1alpha1.DatadogAgentInternal, error) {
23-
ddai := &datadoghqv1alpha1.DatadogAgentInternal{}
25+
func (r *Reconciler) generateDDAIFromDDA(dda *v2alpha1.DatadogAgent) (*v1alpha1.DatadogAgentInternal, error) {
26+
ddai := &v1alpha1.DatadogAgentInternal{}
2427
// Object meta
2528
if err := generateObjMetaFromDDA(dda, ddai, r.scheme); err != nil {
2629
return nil, err
@@ -38,7 +41,7 @@ func (r *Reconciler) generateDDAIFromDDA(dda *datadoghqv2alpha1.DatadogAgent) (*
3841
return ddai, nil
3942
}
4043

41-
func generateObjMetaFromDDA(dda *datadoghqv2alpha1.DatadogAgent, ddai *datadoghqv1alpha1.DatadogAgentInternal, scheme *runtime.Scheme) error {
44+
func generateObjMetaFromDDA(dda *v2alpha1.DatadogAgent, ddai *v1alpha1.DatadogAgentInternal, scheme *runtime.Scheme) error {
4245
ddai.ObjectMeta = metav1.ObjectMeta{
4346
Name: dda.Name,
4447
Namespace: dda.Namespace,
@@ -51,7 +54,7 @@ func generateObjMetaFromDDA(dda *datadoghqv2alpha1.DatadogAgent, ddai *datadoghq
5154
return nil
5255
}
5356

54-
func generateSpecFromDDA(dda *datadoghqv2alpha1.DatadogAgent, ddai *datadoghqv1alpha1.DatadogAgentInternal) error {
57+
func generateSpecFromDDA(dda *v2alpha1.DatadogAgent, ddai *v1alpha1.DatadogAgentInternal) error {
5558
ddai.Spec = *dda.Spec.DeepCopy()
5659
global.SetGlobalFromDDA(dda, ddai.Spec.Global)
5760
override.SetOverrideFromDDA(dda, &ddai.Spec)
@@ -69,3 +72,24 @@ func getDDAILabels(dda metav1.Object) map[string]string {
6972
labels[apicommon.DatadogAgentNameLabelKey] = dda.GetName()
7073
return labels
7174
}
75+
76+
func (r *Reconciler) cleanUpUnusedDDAIs(ctx context.Context, validDDAIs []*v1alpha1.DatadogAgentInternal) error {
77+
validDDAIMap := make(map[string]struct{}, len(validDDAIs))
78+
for _, ddai := range validDDAIs {
79+
validDDAIMap[fmt.Sprintf("%s/%s", ddai.Namespace, ddai.Name)] = struct{}{}
80+
}
81+
ddaiList := &v1alpha1.DatadogAgentInternalList{}
82+
if err := r.client.List(ctx, ddaiList); err != nil {
83+
return err
84+
}
85+
for _, ddai := range ddaiList.Items {
86+
if _, isValid := validDDAIMap[fmt.Sprintf("%s/%s", ddai.Namespace, ddai.Name)]; !isValid {
87+
r.log.Info("Deleting unused DDAI", "namespace", ddai.Namespace, "name", ddai.Name)
88+
if err := r.client.Delete(ctx, &ddai); err != nil {
89+
return err
90+
}
91+
}
92+
}
93+
94+
return nil
95+
}

internal/controller/datadogagent/ddai_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package datadogagent
22

33
import (
4+
"context"
45
"testing"
56

67
corev1 "k8s.io/api/core/v1"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
"sigs.k8s.io/controller-runtime/pkg/client/fake"
11+
logf "sigs.k8s.io/controller-runtime/pkg/log"
812

913
"github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
1014
"github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
@@ -235,3 +239,158 @@ func Test_generateSpecFromDDA(t *testing.T) {
235239
})
236240
}
237241
}
242+
243+
func Test_cleanUpUnusedDDAIs(t *testing.T) {
244+
sch := agenttestutils.TestScheme()
245+
ctx := context.Background()
246+
logger := logf.Log.WithName("test_cleanUpUnusedDDAIs")
247+
248+
testCases := []struct {
249+
name string
250+
existingDDAIs []client.Object
251+
validDDAIs []*v1alpha1.DatadogAgentInternal
252+
wantDDAIs *v1alpha1.DatadogAgentInternalList
253+
}{
254+
{
255+
name: "empty lists",
256+
existingDDAIs: []client.Object{},
257+
validDDAIs: []*v1alpha1.DatadogAgentInternal{},
258+
wantDDAIs: &v1alpha1.DatadogAgentInternalList{
259+
Items: []v1alpha1.DatadogAgentInternal{},
260+
},
261+
},
262+
{
263+
name: "no ddais to delete",
264+
existingDDAIs: []client.Object{
265+
&v1alpha1.DatadogAgentInternal{
266+
ObjectMeta: metav1.ObjectMeta{
267+
Name: "dda-foo-agent",
268+
Namespace: "default",
269+
},
270+
},
271+
},
272+
validDDAIs: []*v1alpha1.DatadogAgentInternal{
273+
&v1alpha1.DatadogAgentInternal{
274+
ObjectMeta: metav1.ObjectMeta{
275+
Name: "dda-foo-agent",
276+
Namespace: "default",
277+
},
278+
},
279+
},
280+
wantDDAIs: &v1alpha1.DatadogAgentInternalList{
281+
Items: []v1alpha1.DatadogAgentInternal{
282+
{
283+
ObjectMeta: metav1.ObjectMeta{
284+
Name: "dda-foo-agent",
285+
Namespace: "default",
286+
ResourceVersion: "999",
287+
},
288+
},
289+
},
290+
},
291+
},
292+
{
293+
name: "multiple ddais to delete",
294+
existingDDAIs: []client.Object{
295+
&v1alpha1.DatadogAgentInternal{
296+
ObjectMeta: metav1.ObjectMeta{
297+
Name: "dda-foo-agent",
298+
Namespace: "default",
299+
},
300+
},
301+
&v1alpha1.DatadogAgentInternal{
302+
ObjectMeta: metav1.ObjectMeta{
303+
Name: "dda-bar-agent",
304+
Namespace: "default",
305+
},
306+
},
307+
&v1alpha1.DatadogAgentInternal{
308+
ObjectMeta: metav1.ObjectMeta{
309+
Name: "dda-baz-agent",
310+
Namespace: "default",
311+
},
312+
},
313+
},
314+
validDDAIs: []*v1alpha1.DatadogAgentInternal{
315+
&v1alpha1.DatadogAgentInternal{
316+
ObjectMeta: metav1.ObjectMeta{
317+
Name: "dda-foo-agent",
318+
Namespace: "default",
319+
},
320+
},
321+
},
322+
wantDDAIs: &v1alpha1.DatadogAgentInternalList{
323+
Items: []v1alpha1.DatadogAgentInternal{
324+
{
325+
ObjectMeta: metav1.ObjectMeta{
326+
Name: "dda-foo-agent",
327+
Namespace: "default",
328+
ResourceVersion: "999",
329+
},
330+
},
331+
},
332+
},
333+
},
334+
{
335+
name: "multiple ddais to delete with different namespace",
336+
existingDDAIs: []client.Object{
337+
&v1alpha1.DatadogAgentInternal{
338+
ObjectMeta: metav1.ObjectMeta{
339+
Name: "dda-foo-agent",
340+
Namespace: "default",
341+
},
342+
},
343+
&v1alpha1.DatadogAgentInternal{
344+
ObjectMeta: metav1.ObjectMeta{
345+
Name: "dda-foo-agent",
346+
Namespace: "foo",
347+
},
348+
},
349+
&v1alpha1.DatadogAgentInternal{
350+
ObjectMeta: metav1.ObjectMeta{
351+
Name: "dda-foo-agent",
352+
Namespace: "bar",
353+
},
354+
},
355+
},
356+
validDDAIs: []*v1alpha1.DatadogAgentInternal{
357+
&v1alpha1.DatadogAgentInternal{
358+
ObjectMeta: metav1.ObjectMeta{
359+
Name: "dda-foo-agent",
360+
Namespace: "foo",
361+
},
362+
},
363+
},
364+
wantDDAIs: &v1alpha1.DatadogAgentInternalList{
365+
Items: []v1alpha1.DatadogAgentInternal{
366+
{
367+
ObjectMeta: metav1.ObjectMeta{
368+
Name: "dda-foo-agent",
369+
Namespace: "foo",
370+
ResourceVersion: "999",
371+
},
372+
},
373+
},
374+
},
375+
},
376+
}
377+
378+
for _, tt := range testCases {
379+
t.Run(tt.name, func(t *testing.T) {
380+
fakeClient := fake.NewClientBuilder().WithScheme(sch).WithObjects(tt.existingDDAIs...).Build()
381+
382+
r := &Reconciler{
383+
client: fakeClient,
384+
log: logger,
385+
}
386+
387+
err := r.cleanUpUnusedDDAIs(ctx, tt.validDDAIs)
388+
assert.NoError(t, err)
389+
390+
ddaiList := &v1alpha1.DatadogAgentInternalList{}
391+
err = fakeClient.List(ctx, ddaiList)
392+
assert.NoError(t, err)
393+
assert.Equal(t, tt.wantDDAIs, ddaiList)
394+
})
395+
}
396+
}

internal/controller/datadogagent/testutils/client_utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ func TestScheme() *runtime.Scheme {
4242
s.AddKnownTypes(networkingv1.SchemeGroupVersion, &networkingv1.NetworkPolicy{})
4343
s.AddKnownTypes(v2alpha1.GroupVersion, &v2alpha1.DatadogAgent{})
4444
s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.DatadogAgentInternal{})
45-
45+
s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.DatadogAgentInternalList{})
4646
return s
4747
}

0 commit comments

Comments
 (0)