Skip to content

Commit 29feb19

Browse files
committed
** Migrate the use of resource tagging api to the sdk V2.
pkg/destroy/aws: ** Alter the function name from HandleErrorCode to handleErrorCode. The initial thought was that this function could be used in other areas of the code, but it will remain in destroy for now. pkg/destroy/aws/shared.go: ** Remove the session import and uses in the file.
1 parent f562ed8 commit 29feb19

File tree

6 files changed

+177
-138
lines changed

6 files changed

+177
-138
lines changed

pkg/destroy/aws/aws.go

Lines changed: 90 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,24 @@ import (
99
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
1010
"github.com/aws/aws-sdk-go-v2/aws/arn"
1111
configv2 "github.com/aws/aws-sdk-go-v2/config"
12+
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
1213
ec2v2 "github.com/aws/aws-sdk-go-v2/service/ec2"
1314
"github.com/aws/aws-sdk-go-v2/service/efs"
1415
elb "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
1516
elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
1617
iamv2 "github.com/aws/aws-sdk-go-v2/service/iam"
18+
"github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
19+
tagtypes "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi/types"
1720
"github.com/aws/aws-sdk-go-v2/service/route53"
1821
route53types "github.com/aws/aws-sdk-go-v2/service/route53/types"
1922
"github.com/aws/aws-sdk-go-v2/service/s3"
2023
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
24+
"github.com/aws/aws-sdk-go-v2/service/sts"
2125
"github.com/aws/aws-sdk-go/aws"
2226
"github.com/aws/aws-sdk-go/aws/awserr"
2327
"github.com/aws/aws-sdk-go/aws/endpoints"
2428
"github.com/aws/aws-sdk-go/aws/request"
2529
"github.com/aws/aws-sdk-go/aws/session"
26-
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
2730
"github.com/aws/aws-sdk-go/service/s3/s3manager"
2831
"github.com/pkg/errors"
2932
"github.com/sirupsen/logrus"
@@ -34,6 +37,7 @@ import (
3437
awssession "github.com/openshift/installer/pkg/asset/installconfig/aws"
3538
"github.com/openshift/installer/pkg/destroy/providers"
3639
"github.com/openshift/installer/pkg/types"
40+
awstypes "github.com/openshift/installer/pkg/types/aws"
3741
"github.com/openshift/installer/pkg/version"
3842
)
3943

@@ -67,6 +71,7 @@ type ClusterUninstaller struct {
6771
ClusterID string
6872
ClusterDomain string
6973
HostedZoneRole string
74+
endpoints []awstypes.ServiceEndpoint
7075

7176
// Session is the AWS session to be used for deletion. If nil, a
7277
// new session will be created based on the usual credential
@@ -175,6 +180,7 @@ func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.
175180
ClusterDomain: metadata.AWS.ClusterDomain,
176181
Session: session,
177182
HostedZoneRole: metadata.AWS.HostedZoneRole,
183+
endpoints: metadata.AWS.ServiceEndpoints,
178184
EC2Client: ec2Client,
179185
IAMClient: iamClient,
180186
ELBClient: elbclient,
@@ -198,6 +204,25 @@ func (o *ClusterUninstaller) Run() (*types.ClusterQuota, error) {
198204
return nil, err
199205
}
200206

207+
func createResourceTaggingClientWithConfig(cfg awsv2.Config, region string, endpoints []awstypes.ServiceEndpoint) *resourcegroupstaggingapi.Client {
208+
return resourcegroupstaggingapi.NewFromConfig(cfg, func(options *resourcegroupstaggingapi.Options) {
209+
options.Region = region
210+
for _, endpoint := range endpoints {
211+
if strings.EqualFold(endpoint.Name, "resourcegroupstaggingapi") {
212+
options.BaseEndpoint = awsv2.String(endpoint.URL)
213+
}
214+
}
215+
})
216+
}
217+
218+
func createResourceTaggingClient(region string, endpoints []awstypes.ServiceEndpoint) (*resourcegroupstaggingapi.Client, error) {
219+
cfg, err := awssession.GetConfigWithOptions(context.Background(), configv2.WithRegion(region))
220+
if err != nil {
221+
return nil, fmt.Errorf("failed to create AWS config for resource tagging client: %w", err)
222+
}
223+
return createResourceTaggingClientWithConfig(cfg, region, endpoints), nil
224+
}
225+
201226
// RunWithContext runs the uninstall process with a context.
202227
// The first return is the list of ARNs for resources that could not be destroyed.
203228
func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, error) {
@@ -219,16 +244,31 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
219244
Fn: request.MakeAddToUserAgentHandler("OpenShift/4.x Destroyer", version.Raw),
220245
})
221246

222-
tagClients := []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI{
223-
resourcegroupstaggingapi.New(awsSession),
247+
baseTaggingClient, err := createResourceTaggingClient(o.Region, o.endpoints)
248+
if err != nil {
249+
return nil, err
224250
}
251+
tagClients := []*resourcegroupstaggingapi.Client{baseTaggingClient}
225252

226253
if o.HostedZoneRole != "" {
227-
cfg := awssession.GetR53ClientCfg(awsSession, o.HostedZoneRole)
254+
cfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(endpointUSEast1))
255+
if err != nil {
256+
return nil, fmt.Errorf("failed to create AWS config for resource tagging client: %w", err)
257+
}
258+
stsSvc, err := awssession.NewSTSClient(ctx, awssession.EndpointOptions{
259+
Region: endpointUSEast1,
260+
Endpoints: o.endpoints,
261+
}, sts.WithAPIOptions(middleware.AddUserAgentKeyValue("OpenShift/4.x Destroyer", version.Raw)))
262+
if err != nil {
263+
return nil, fmt.Errorf("failed to create STS client: %w", err)
264+
}
265+
266+
creds := stscreds.NewAssumeRoleProvider(stsSvc, o.HostedZoneRole)
267+
cfg.Credentials = awsv2.NewCredentialsCache(creds)
228268
// This client is specifically for finding route53 zones,
229269
// so it needs to use the global us-east-1 region.
230-
cfg.Region = aws.String(endpoints.UsEast1RegionID)
231-
tagClients = append(tagClients, resourcegroupstaggingapi.New(awsSession, cfg))
270+
271+
tagClients = append(tagClients, createResourceTaggingClientWithConfig(cfg, endpointUSEast1, o.endpoints))
232272
}
233273

234274
switch o.Region {
@@ -238,13 +278,19 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
238278
break
239279
case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID:
240280
if o.Region != endpoints.UsGovWest1RegionID {
241-
tagClients = append(tagClients,
242-
resourcegroupstaggingapi.New(awsSession, aws.NewConfig().WithRegion(endpoints.UsGovWest1RegionID)))
281+
tagClient, err := createResourceTaggingClient(endpoints.UsGovWest1RegionID, o.endpoints)
282+
if err != nil {
283+
return nil, fmt.Errorf("failed to create resource tagging client for usgov-west-1: %w", err)
284+
}
285+
tagClients = append(tagClients, tagClient)
243286
}
244287
default:
245288
if o.Region != endpoints.UsEast1RegionID {
246-
tagClients = append(tagClients,
247-
resourcegroupstaggingapi.New(awsSession, aws.NewConfig().WithRegion(endpoints.UsEast1RegionID)))
289+
tagClient, err := createResourceTaggingClientWithConfig(endpoints.UsEast1RegionID, o.endpoints)
290+
if err != nil {
291+
return nil, fmt.Errorf("failed to create resource tagging client for default us-east-1: %w", err)
292+
}
293+
tagClients = append(tagClients, tagClient)
248294
}
249295
}
250296

@@ -275,7 +321,7 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
275321
// Terminate EC2 instances. The instances need to be terminated first so that we can ensure that there is nothing
276322
// running on the cluster creating new resources while we are attempting to delete resources, which could leak
277323
// the new resources.
278-
err = o.DeleteEC2Instances(ctx, awsSession, resourcesToDelete, deleted, tracker)
324+
err = o.DeleteEC2Instances(ctx, resourcesToDelete, deleted, tracker)
279325
if err != nil {
280326
return resourcesToDelete.UnsortedList(), err
281327
}
@@ -284,7 +330,7 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
284330
err = wait.PollImmediateUntil(
285331
time.Second*10,
286332
func() (done bool, err error) {
287-
newlyDeleted, loopError := o.DeleteResources(ctx, awsSession, resourcesToDelete.UnsortedList(), tracker)
333+
newlyDeleted, loopError := o.DeleteResources(ctx, resourcesToDelete.UnsortedList(), tracker)
288334
// Delete from the resources-to-delete set so that the current state of the resources to delete can be
289335
// returned if the context is completed.
290336
resourcesToDelete = resourcesToDelete.Difference(newlyDeleted)
@@ -314,7 +360,7 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
314360
return resourcesToDelete.UnsortedList(), err
315361
}
316362

317-
err = o.removeSharedTags(ctx, awsSession, tagClients, tracker)
363+
err = o.removeSharedTags(ctx, tagClients, tracker)
318364
if err != nil {
319365
return nil, err
320366
}
@@ -333,7 +379,7 @@ func (o *ClusterUninstaller) findUntaggableResources(ctx context.Context, delete
333379
profile := fmt.Sprintf("%s-%s-profile", o.ClusterID, profileType)
334380
response, err := o.IAMClient.GetInstanceProfile(ctx, &iamv2.GetInstanceProfileInput{InstanceProfileName: &profile})
335381
if err != nil {
336-
if strings.Contains(HandleErrorCode(err), "NoSuchEntity") {
382+
if strings.Contains(handleErrorCode(err), "NoSuchEntity") {
337383
continue
338384
}
339385
return resources, fmt.Errorf("failed to get IAM instance profile: %w", err)
@@ -352,11 +398,11 @@ func (o *ClusterUninstaller) findUntaggableResources(ctx context.Context, delete
352398
// deleted - the resources that have already been deleted. Any resources specified in this set will be ignored.
353399
func (o *ClusterUninstaller) findResourcesToDelete(
354400
ctx context.Context,
355-
tagClients []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI,
401+
tagClients []*resourcegroupstaggingapi.Client,
356402
iamRoleSearch *IamRoleSearch,
357403
iamUserSearch *IamUserSearch,
358404
deleted sets.Set[string],
359-
) (sets.Set[string], []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI, error) {
405+
) (sets.Set[string], []*resourcegroupstaggingapi.Client, error) {
360406
var errs []error
361407
resources, tagClients, err := FindTaggedResourcesToDelete(ctx, o.Logger, tagClients, o.Filters, iamRoleSearch, iamUserSearch, deleted)
362408
if err != nil {
@@ -380,14 +426,14 @@ func (o *ClusterUninstaller) findResourcesToDelete(
380426
func FindTaggedResourcesToDelete(
381427
ctx context.Context,
382428
logger logrus.FieldLogger,
383-
tagClients []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI,
429+
tagClients []*resourcegroupstaggingapi.Client,
384430
filters []Filter,
385431
iamRoleSearch *IamRoleSearch,
386432
iamUserSearch *IamUserSearch,
387433
deleted sets.Set[string],
388-
) (sets.Set[string], []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI, error) {
434+
) (sets.Set[string], []*resourcegroupstaggingapi.Client, error) {
389435
resources := sets.New[string]()
390-
var tagClientsWithResources []*resourcegroupstaggingapi.ResourceGroupsTaggingAPI
436+
var tagClientsWithResources []*resourcegroupstaggingapi.Client
391437
var errs []error
392438

393439
// Find resources by tag
@@ -402,7 +448,7 @@ func FindTaggedResourcesToDelete(
402448
if len(resourcesInTagClient) > 0 || err != nil {
403449
tagClientsWithResources = append(tagClientsWithResources, tagClient)
404450
} else {
405-
logger.Debugf("no deletions from %s, removing client", *tagClient.Config.Region)
451+
logger.Debugf("no deletions from %s, removing client", tagClient.Options().Region)
406452
}
407453
}
408454

@@ -434,39 +480,37 @@ func FindTaggedResourcesToDelete(
434480
func findResourcesByTag(
435481
ctx context.Context,
436482
logger logrus.FieldLogger,
437-
tagClient *resourcegroupstaggingapi.ResourceGroupsTaggingAPI,
483+
tagClient *resourcegroupstaggingapi.Client,
438484
filters []Filter,
439485
deleted sets.Set[string],
440486
) (sets.Set[string], error) {
441487
resources := sets.New[string]()
442488
for _, filter := range filters {
443-
logger.Debugf("search for matching resources by tag in %s matching %#+v", *tagClient.Config.Region, filter)
444-
tagFilters := make([]*resourcegroupstaggingapi.TagFilter, 0, len(filter))
489+
logger.Debugf("search for matching resources by tag in %s matching %#+v", tagClient.Options().Region, filter)
490+
tagFilters := make([]tagtypes.TagFilter, 0, len(filter))
445491
for key, value := range filter {
446-
tagFilters = append(tagFilters, &resourcegroupstaggingapi.TagFilter{
492+
tagFilters = append(tagFilters, tagtypes.TagFilter{
447493
Key: aws.String(key),
448-
Values: []*string{aws.String(value)},
494+
Values: []string{value},
449495
})
450496
}
451-
err := tagClient.GetResourcesPagesWithContext(
452-
ctx,
453-
&resourcegroupstaggingapi.GetResourcesInput{TagFilters: tagFilters},
454-
func(results *resourcegroupstaggingapi.GetResourcesOutput, lastPage bool) bool {
455-
for _, resource := range results.ResourceTagMappingList {
456-
arnString := *resource.ResourceARN
457-
if !deleted.Has(arnString) {
458-
resources.Insert(arnString)
459-
}
497+
498+
paginator := resourcegroupstaggingapi.NewGetResourcesPaginator(tagClient, &resourcegroupstaggingapi.GetResourcesInput{TagFilters: tagFilters})
499+
for paginator.HasMorePages() {
500+
page, err := paginator.NextPage(ctx)
501+
if err != nil {
502+
return resources, fmt.Errorf("failed to fetch resources by tag: %w", err)
503+
}
504+
505+
for _, resource := range page.ResourceTagMappingList {
506+
arnString := *resource.ResourceARN
507+
if !deleted.Has(arnString) {
508+
resources.Insert(arnString)
460509
}
461-
return !lastPage
462-
},
463-
)
464-
if err != nil {
465-
err = errors.Wrap(err, "get tagged resources")
466-
logger.Info(err)
467-
return resources, err
510+
}
468511
}
469512
}
513+
470514
return resources, nil
471515
}
472516

@@ -475,7 +519,7 @@ func findResourcesByTag(
475519
// resources - the resources to be deleted.
476520
//
477521
// The first return is the ARNs of the resources that were successfully deleted.
478-
func (o *ClusterUninstaller) DeleteResources(ctx context.Context, awsSession *session.Session, resources []string, tracker *ErrorTracker) (sets.Set[string], error) {
522+
func (o *ClusterUninstaller) DeleteResources(ctx context.Context, resources []string, tracker *ErrorTracker) (sets.Set[string], error) {
479523
deleted := sets.New[string]()
480524
for _, arnString := range resources {
481525
l := o.Logger.WithField("arn", arnString)
@@ -638,7 +682,7 @@ func deleteRoute53(ctx context.Context, client *route53.Client, arn arn.ARN, log
638682
if err != nil {
639683
// In some cases AWS may return the zone in the list of tagged resources despite the fact
640684
// it no longer exists.
641-
if strings.Contains(HandleErrorCode(err), "NoSuchHostedZone") {
685+
if strings.Contains(handleErrorCode(err), "NoSuchHostedZone") {
642686
return nil
643687
}
644688
return err
@@ -850,7 +894,7 @@ func deleteFileSystem(ctx context.Context, client *efs.Client, fsid string, logg
850894

851895
_, err = client.DeleteFileSystem(ctx, &efs.DeleteFileSystemInput{FileSystemId: aws.String(fsid)})
852896
if err != nil {
853-
if strings.Contains(HandleErrorCode(err), "FileSystemNotFound") {
897+
if strings.Contains(handleErrorCode(err), "FileSystemNotFound") {
854898
return nil
855899
}
856900
return err
@@ -909,7 +953,7 @@ func deleteAccessPoint(ctx context.Context, client *efs.Client, id string, logge
909953
logger = logger.WithField("AccessPoint ID", id)
910954
_, err := client.DeleteAccessPoint(ctx, &efs.DeleteAccessPointInput{AccessPointId: aws.String(id)})
911955
if err != nil {
912-
if strings.Contains(HandleErrorCode(err), "AccessPointNotFound") {
956+
if strings.Contains(handleErrorCode(err), "AccessPointNotFound") {
913957
return nil
914958
}
915959
return err
@@ -923,7 +967,7 @@ func deleteMountTarget(ctx context.Context, client *efs.Client, id string, logge
923967
logger = logger.WithField("Mount Target ID", id)
924968
_, err := client.DeleteMountTarget(ctx, &efs.DeleteMountTargetInput{MountTargetId: aws.String(id)})
925969
if err != nil {
926-
if strings.Contains(HandleErrorCode(err), "MountTargetNotFound") {
970+
if strings.Contains(handleErrorCode(err), "MountTargetNotFound") {
927971
return nil
928972
}
929973
return err

0 commit comments

Comments
 (0)