Skip to content

Commit

Permalink
wait for ASO tags to converge before updating
Browse files Browse the repository at this point in the history
  • Loading branch information
nojnhuh committed Oct 17, 2023
1 parent 5c6f04d commit 5b35816
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
2 changes: 1 addition & 1 deletion azure/services/aso/aso_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ func TestCreateOrUpdateResource(t *testing.T) {

specMock.MockTagsGetterSetter.EXPECT().GetActualTags(gomock.Any()).Return(nil)
specMock.MockTagsGetterSetter.EXPECT().GetAdditionalTags().Return(nil)
specMock.MockTagsGetterSetter.EXPECT().GetDesiredTags(gomock.Any()).Return(nil)
specMock.MockTagsGetterSetter.EXPECT().GetDesiredTags(gomock.Any()).Return(nil).Times(2)
specMock.MockTagsGetterSetter.EXPECT().SetTags(gomock.Any(), gomock.Any())

ctx := context.Background()
Expand Down
13 changes: 13 additions & 0 deletions azure/services/aso/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ package aso

import (
"encoding/json"
"reflect"

asoannotations "github.com/Azure/azure-service-operator/v2/pkg/common/annotations"
"github.com/Azure/azure-service-operator/v2/pkg/genruntime"
"github.com/pkg/errors"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
"sigs.k8s.io/cluster-api-provider-azure/azure/converters"
"sigs.k8s.io/cluster-api-provider-azure/azure/services/tags"
"sigs.k8s.io/cluster-api-provider-azure/util/maps"
Expand All @@ -47,6 +50,16 @@ func reconcileTags[T genruntime.MetaObject](t TagsGetterSetter[T], existing T, r
}

existingTags = t.GetActualTags(existing)
// Wait for tags to converge so we know for sure which ones are deleted from additionalTags (and
// should be deleted) and which were added manually (and should be kept).
if !reflect.DeepEqual(t.GetDesiredTags(existing), existingTags) &&
existing.GetAnnotations()[asoannotations.ReconcilePolicy] == string(asoannotations.ReconcilePolicyManage) {
return azure.WithTransientError(azure.NewOperationNotDoneError(&infrav1.Future{
Type: createOrUpdateFutureType,
ResourceGroup: existing.GetNamespace(),
Name: existing.GetName(),
}), requeueInterval)
}
}

existingTagsMap := converters.TagsToMap(existingTags)
Expand Down
28 changes: 28 additions & 0 deletions azure/services/aso/tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ package aso

import (
"encoding/json"
"errors"
"testing"

asoresourcesv1 "github.com/Azure/azure-service-operator/v2/api/resources/v1api20200601"
asoannotations "github.com/Azure/azure-service-operator/v2/pkg/common/annotations"
. "github.com/onsi/gomega"
"go.uber.org/mock/gomock"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
"sigs.k8s.io/cluster-api-provider-azure/azure/services/aso/mock_aso"
)

Expand All @@ -43,6 +46,7 @@ func TestReconcileTags(t *testing.T) {
"oldAdditionalTag": "oldAdditionalVal",
},
existingTags: infrav1.Tags{
"oldAdditionalTag": "oldAdditionalVal",
"nonAdditionalTag": "nonAdditionalVal",
},
additionalTagsSpec: infrav1.Tags{
Expand Down Expand Up @@ -94,6 +98,7 @@ func TestReconcileTags(t *testing.T) {
})
}
tag.EXPECT().GetActualTags(existing).Return(test.existingTags)
tag.EXPECT().GetDesiredTags(existing).Return(test.existingTags)
tag.EXPECT().GetAdditionalTags().Return(test.additionalTagsSpec)

parameters := &asoresourcesv1.ResourceGroup{}
Expand Down Expand Up @@ -123,4 +128,27 @@ func TestReconcileTags(t *testing.T) {
err := reconcileTags[*asoresourcesv1.ResourceGroup](tag, existing, existing != nil, nil)
g.Expect(err).To(HaveOccurred())
})

t.Run("existing tags not up to date", func(t *testing.T) {
g := NewWithT(t)

mockCtrl := gomock.NewController(t)
tag := mock_aso.NewMockTagsGetterSetter[*asoresourcesv1.ResourceGroup](mockCtrl)

existing := &asoresourcesv1.ResourceGroup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
asoannotations.ReconcilePolicy: string(asoannotations.ReconcilePolicyManage),
},
},
}
tag.EXPECT().GetActualTags(existing).Return(infrav1.Tags{"new": "value"})
tag.EXPECT().GetDesiredTags(existing).Return(infrav1.Tags{"old": "tag"})

err := reconcileTags[*asoresourcesv1.ResourceGroup](tag, existing, existing != nil, nil)
g.Expect(azure.IsOperationNotDoneError(err)).To(BeTrue())
var recerr azure.ReconcileError
g.Expect(errors.As(err, &recerr)).To(BeTrue())
g.Expect(recerr.IsTransient()).To(BeTrue())
})
}

0 comments on commit 5b35816

Please sign in to comment.