Skip to content

Commit c28a9f4

Browse files
authored
fix: ensure we mark resource as adopted adopt-or-create (#186)
Issue [#2459#issuecomment-2879691276](aws-controllers-k8s/community#2459 (comment)) Description of changes: Currently the `adopted` annotation was getting removed when the resource goes through update path during adopt-or-create adoption. These changes ensure the annotation is persisted in k8s. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 7ec3ad0 commit c28a9f4

File tree

2 files changed

+66
-22
lines changed

2 files changed

+66
-22
lines changed

pkg/runtime/reconciler.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -740,13 +740,13 @@ func (r *resourceReconciler) updateResource(
740740
rm acktypes.AWSResourceManager,
741741
desired acktypes.AWSResource,
742742
latest acktypes.AWSResource,
743-
) (acktypes.AWSResource, error) {
744-
var err error
743+
) (updated acktypes.AWSResource, err error) {
745744
rlog := ackrtlog.FromContext(ctx)
746745
exit := rlog.Trace("r.updateResource")
747746
defer func() {
748747
exit(err)
749748
}()
749+
updated = latest
750750

751751
// Ensure the resource is managed
752752
if err = r.failOnResourceUnmanaged(ctx, latest); err != nil {
@@ -762,21 +762,24 @@ func (r *resourceReconciler) updateResource(
762762
"diff", delta.Differences,
763763
)
764764
rlog.Enter("rm.Update")
765-
latest, err = rm.Update(ctx, desired, latest, delta)
765+
updated, err = rm.Update(ctx, desired, latest, delta)
766766
rlog.Exit("rm.Update", err, "latest", latest)
767767
if err != nil {
768-
return latest, err
768+
return updated, err
769769
}
770770
// Ensure that we are patching any changes to the annotations/metadata and
771771
// the Spec that may have been set by the resource manager's successful
772772
// Update call above.
773-
latest, err = r.patchResourceMetadataAndSpec(ctx, rm, desired, latest)
773+
if IsAdopted(latest) {
774+
r.rd.MarkAdopted(updated)
775+
}
776+
updated, err = r.patchResourceMetadataAndSpec(ctx, rm, desired, updated)
774777
if err != nil {
775-
return latest, err
778+
return updated, err
776779
}
777780
rlog.Info("updated resource")
778781
}
779-
return latest, nil
782+
return updated, nil
780783
}
781784

782785
// lateInitializeResource calls AWSResourceManager.LateInitialize() method and

pkg/runtime/reconciler_test.go

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,6 @@ func TestReconcilerAdoptOrCreateResource_Create(t *testing.T) {
459459
).Once()
460460
rm.On("IsSynced", ctx, latest).Return(true, nil)
461461
rmf, rd := managedResourceManagerFactoryMocks(desired, latest)
462-
rd.On("MarkAdopted", latest).Return()
463462

464463
rm.On("LateInitialize", ctx, latest).Return(latest, nil)
465464
rd.On("IsManaged", desired).Return(false).Once()
@@ -484,31 +483,59 @@ func TestReconcilerAdoptOrCreateResource_Create(t *testing.T) {
484483

485484
func TestReconcilerAdoptOrCreateResource_Adopt(t *testing.T) {
486485
require := require.New(t)
486+
assert := assert.New(t)
487487

488488
ctx := context.TODO()
489+
adoptionFieldsString := "{\"arn\": \"my-adopt-book-arn\"}"
490+
adoptionFields := map[string]string{
491+
"arn": "my-adopt-book-arn",
492+
}
489493

490494
desired, _, metaObj := resourceMocks()
491495
desired.On("ReplaceConditions", []*ackv1alpha1.Condition{}).Return()
492496
metaObj.SetAnnotations(map[string]string{
493497
ackv1alpha1.AnnotationAdoptionPolicy: "adopt-or-create",
494-
ackv1alpha1.AnnotationAdoptionFields: "{\"arn\": \"my-adopt-book-arn\"}",
498+
ackv1alpha1.AnnotationAdoptionFields: adoptionFieldsString,
495499
})
496500

497501
ids := &ackmocks.AWSResourceIdentifiers{}
498502
delta := ackcompare.NewDelta()
499-
delta.Add("Spec.A", "val1", "val2")
503+
delta.Add("Spec", "val1", "val2")
500504

501-
latest, latestRTObj, _ := resourceMocks()
505+
latest, latestRTObj, latestMetaObj := resourceMocks()
502506
latest.On("Identifiers").Return(ids)
503507
latest.On("Conditions").Return([]*ackv1alpha1.Condition{})
504-
latest.On("MetaObject").Return(metav1.ObjectMeta{
508+
latest.On(
509+
"ReplaceConditions",
510+
mock.AnythingOfType("[]*v1alpha1.Condition"),
511+
).Return().Run(func(args mock.Arguments) {
512+
conditions := args.Get(0).([]*ackv1alpha1.Condition)
513+
hasSynced := false
514+
for _, condition := range conditions {
515+
if condition.Type != ackv1alpha1.ConditionTypeResourceSynced {
516+
continue
517+
}
518+
519+
hasSynced = true
520+
assert.Equal(corev1.ConditionTrue, condition.Status)
521+
assert.Equal(ackcondition.SyncedMessage, *condition.Message)
522+
}
523+
assert.True(hasSynced)
524+
})
525+
latestMetaObj.SetAnnotations(map[string]string{
526+
ackv1alpha1.AnnotationAdoptionPolicy: "adopt-or-create",
527+
ackv1alpha1.AnnotationAdoptionFields: adoptionFieldsString,
528+
})
529+
updated, updatedRTObj, _ := resourceMocks()
530+
updated.On("Identifiers").Return(ids)
531+
updated.On("Conditions").Return([]*ackv1alpha1.Condition{})
532+
updated.On("MetaObject").Return(metav1.ObjectMeta{
505533
Annotations: map[string]string{
506534
ackv1alpha1.AnnotationAdoptionPolicy: "adopt-or-create",
507535
ackv1alpha1.AnnotationAdoptionFields: "{\"arn\": \"my-adopt-book-arn\"}",
508536
},
509537
})
510-
latest.On("Conditions").Return([]*ackv1alpha1.Condition{})
511-
latest.On(
538+
updated.On(
512539
"ReplaceConditions",
513540
mock.AnythingOfType("[]*v1alpha1.Condition"),
514541
).Return()
@@ -517,36 +544,50 @@ func TestReconcilerAdoptOrCreateResource_Adopt(t *testing.T) {
517544
rm.On("ResolveReferences", ctx, nil, desired).Return(
518545
desired, false, nil,
519546
).Times(2)
547+
desired.On("PopulateResourceFromAnnotation", adoptionFields).Return(nil)
520548
rm.On("ClearResolvedReferences", desired).Return(desired)
549+
rm.On("ClearResolvedReferences", updated).Return(updated)
521550
rm.On("ClearResolvedReferences", latest).Return(latest)
522551
rm.On("ReadOne", ctx, desired).Return(
523552
latest, nil,
524553
).Once()
525554
rm.On("Update", ctx, desired, latest, delta).Return(
526-
latest, nil,
555+
updated, nil,
527556
).Once()
528557
rm.On("IsSynced", ctx, latest).Return(true, nil)
529558
rmf, rd := managedResourceManagerFactoryMocks(desired, latest)
530559

531-
rm.On("LateInitialize", ctx, latest).Return(latest, nil)
560+
rm.On("LateInitialize", ctx, updated).Return(latest, nil)
561+
rd.On("IsManaged", desired).Return(false).Once()
532562
rd.On("IsManaged", desired).Return(true)
533-
rd.On("Delta", desired, latest).Return(
534-
delta,
535-
).Once()
536-
rd.On("Delta", desired, latest).Return(ackcompare.NewDelta())
537-
rd.On("Delta", latest, latest).Return(ackcompare.NewDelta())
563+
rd.On("MarkAdopted", latest).Return().Once()
564+
latestMetaObj.SetAnnotations(map[string]string{
565+
ackv1alpha1.AnnotationAdoptionPolicy: "adopt-or-create",
566+
ackv1alpha1.AnnotationAdoptionFields: adoptionFieldsString,
567+
ackv1alpha1.AnnotationAdopted: "true",
568+
})
569+
// setManaged
570+
rd.On("Delta", latest, latest).Return(ackcompare.NewDelta()).Once()
571+
// update
572+
rd.On("Delta", desired, latest).Return(delta).Once()
573+
//
574+
rd.On("Delta", desired, updated).Return(ackcompare.NewDelta())
575+
rd.On("Delta", updated, updated).Return(ackcompare.NewDelta())
576+
rd.On("MarkAdopted", updated).Return().Once()
538577

539578
r, kc, scmd := reconcilerMocks(rmf)
540579
rm.On("EnsureTags", ctx, desired, scmd).Return(nil)
541580
statusWriter := &ctrlrtclientmock.SubResourceWriter{}
542581
kc.On("Status").Return(statusWriter)
543582
kc.On("Patch", withoutCancelContextMatcher, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
544-
statusWriter.On("Patch", withoutCancelContextMatcher, latestRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
583+
kc.On("Patch", withoutCancelContextMatcher, updatedRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
584+
statusWriter.On("Patch", withoutCancelContextMatcher, updatedRTObj, mock.AnythingOfType("*client.mergeFromPatch")).Return(nil)
545585
_, err := r.Sync(ctx, rm, desired)
546586
require.Nil(err)
547587
rm.AssertNumberOfCalls(t, "ReadOne", 1)
548588
rm.AssertCalled(t, "Update", ctx, desired, latest, delta)
549589
rd.AssertCalled(t, "Delta", desired, latest)
590+
rd.AssertNumberOfCalls(t, "MarkAdopted", 2)
550591
// Assert that the resource is not created or updated
551592
rm.AssertNumberOfCalls(t, "Create", 0)
552593
}

0 commit comments

Comments
 (0)