diff --git a/pkg/conversions/tags_conversion.go b/pkg/conversions/tags_conversion.go new file mode 100644 index 00000000..4636c8a5 --- /dev/null +++ b/pkg/conversions/tags_conversion.go @@ -0,0 +1,59 @@ +package conversions + +import ( + "github.com/aws/aws-sdk-go/aws" + appmeshsdk "github.com/aws/aws-sdk-go/service/appmesh" +) + +func Convert_CRD_Labls_To_SDK_TagChangeSet(crdLabels map[string]string, sdkTags []*appmeshsdk.TagRef) (map[string][]*appmeshsdk.TagRef, error) { + add := make(map[string]string) + remove := make(map[string]string) + existing := make(map[string]string) + + for _, tag := range sdkTags { + k := *tag.Key + v := *tag.Value + existing[k] = v + + if _, found := crdLabels[k]; !found { + remove[k] = v + } + } + + for k, v := range crdLabels { + if current, found := existing[k]; found { + if v != current { + add[k] = v + } + } else { + add[k] = v + } + } + + sdkAdd, err := Convert_CRD_Labels_To_SDK_Tags(add) + if err != nil { + return nil, err + } + + sdkRemove, err := Convert_CRD_Labels_To_SDK_Tags(remove) + if err != nil { + return nil, err + } + + sdkChangeset := make(map[string][]*appmeshsdk.TagRef) + sdkChangeset["add"] = sdkAdd + sdkChangeset["remove"] = sdkRemove + + return sdkChangeset, nil +} + +func Convert_CRD_Labels_To_SDK_Tags(crdObj map[string]string) ([]*appmeshsdk.TagRef, error) { + sdkObj := []*appmeshsdk.TagRef{} + for k, v := range crdObj { + sdkObj = append(sdkObj, &appmeshsdk.TagRef{ + Key: aws.String(k), + Value: aws.String(v), + }) + } + return sdkObj, nil +} diff --git a/pkg/mesh/resource_manager.go b/pkg/mesh/resource_manager.go index 8b030325..ac2edd88 100644 --- a/pkg/mesh/resource_manager.go +++ b/pkg/mesh/resource_manager.go @@ -111,6 +111,11 @@ func (m *defaultResourceManager) createSDKMesh(ctx context.Context, ms *appmesh. if err != nil { return nil, err } + + if err = m.tagSDKMesh(ctx, ms, resp.Mesh); err != nil { + return nil, err + } + return resp.Mesh, nil } @@ -120,6 +125,12 @@ func (m *defaultResourceManager) updateSDKMesh(ctx context.Context, sdkMS *appme if err != nil { return nil, err } + + // Update tags before checking spec + if err = m.tagSDKMesh(ctx, ms, sdkMS); err != nil { + return nil, err + } + opts := cmpopts.EquateEmpty() if cmp.Equal(desiredSDKMSSpec, actualSDKMSSpec, opts) { return sdkMS, nil @@ -149,6 +160,51 @@ func (m *defaultResourceManager) updateSDKMesh(ctx context.Context, sdkMS *appme return resp.Mesh, nil } +func (m *defaultResourceManager) tagSDKMesh(ctx context.Context, ms *appmesh.Mesh, sdkMS *appmeshsdk.MeshData) error { + resp, err := m.appMeshSDK.ListTagsForResource(&appmeshsdk.ListTagsForResourceInput{ + ResourceArn: sdkMS.Metadata.Arn, + }) + if err != nil { + return err + } + + changeset, err := conversions.Convert_CRD_Labls_To_SDK_TagChangeSet(ms.Labels, resp.Tags) + if err != nil { + return err + } + + // Nothing to do, up to date + if len(changeset["add"]) == 0 && len(changeset["remove"]) == 0 { + return nil + } + + // Add missing tags + if len(changeset["add"]) > 0 { + if _, err = m.appMeshSDK.TagResource(&appmeshsdk.TagResourceInput{ + ResourceArn: sdkMS.Metadata.Arn, + Tags: changeset["add"], + }); err != nil { + return err + } + } + + // Remove tags that are no longer labels + if len(changeset["remove"]) > 0 { + tagkeys := []*string{} + for _, tag := range changeset["remove"] { + tagkeys = append(tagkeys, tag.Key) + } + if _, err = m.appMeshSDK.UntagResource(&appmeshsdk.UntagResourceInput{ + ResourceArn: sdkMS.Metadata.Arn, + TagKeys: tagkeys, + }); err != nil { + return err + } + } + + return nil +} + func (m *defaultResourceManager) deleteSDKMesh(ctx context.Context, sdkMS *appmeshsdk.MeshData, ms *appmesh.Mesh) error { if !m.isSDKMeshOwnedByCRDMesh(ctx, sdkMS, ms) { m.log.V(1).Info("skip mesh deletion since its not owned",