Skip to content

Commit c4f0a7a

Browse files
committed
Use the correct private and public zone clients.
Set a Destroy User Agent. Cleanup pointer references to use the aws sdk.
1 parent 4fcea32 commit c4f0a7a

File tree

4 files changed

+61
-27
lines changed

4 files changed

+61
-27
lines changed

pkg/destroy/aws/aws.go

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
1010
"github.com/aws/aws-sdk-go-v2/aws/arn"
11-
"github.com/aws/aws-sdk-go-v2/aws/middleware"
11+
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
1212
configv2 "github.com/aws/aws-sdk-go-v2/config"
1313
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
1414
ec2v2 "github.com/aws/aws-sdk-go-v2/service/ec2"
@@ -23,6 +23,7 @@ import (
2323
"github.com/aws/aws-sdk-go-v2/service/s3"
2424
s3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
2525
"github.com/aws/aws-sdk-go-v2/service/sts"
26+
"github.com/aws/smithy-go/middleware"
2627
"github.com/pkg/errors"
2728
"github.com/sirupsen/logrus"
2829
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -87,6 +88,9 @@ const (
8788
endpointISOBEast1 = "us-isob-east-1"
8889
endpointUSGovEast1 = "us-gov-east-1"
8990
endpointUSGovWest1 = "us-gov-west-1"
91+
92+
// OpenShiftInstallerDestroyerUserAgent is the User Agent key to add to the AWS Destroy API request header.
93+
OpenShiftInstallerDestroyerUserAgent = "OpenShift/4.x Destroyer"
9094
)
9195

9296
// New returns an AWS destroyer from ClusterMetadata.
@@ -101,49 +105,58 @@ func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.
101105
ec2Client, err := awssession.NewEC2Client(ctx, awssession.EndpointOptions{
102106
Region: region,
103107
Endpoints: metadata.AWS.ServiceEndpoints,
104-
})
108+
}, ec2v2.WithAPIOptions(awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw)))
105109
if err != nil {
106110
return nil, fmt.Errorf("failed to create EC2 client: %w", err)
107111
}
108112

109113
iamClient, err := awssession.NewIAMClient(ctx, awssession.EndpointOptions{
110114
Region: region,
111115
Endpoints: metadata.AWS.ServiceEndpoints,
112-
})
116+
}, iamv2.WithAPIOptions(awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw)))
113117
if err != nil {
114118
return nil, fmt.Errorf("failed to create IAM client: %w", err)
115119
}
116120

117121
// FIXME: remove this code when the elb and elbv2 clients are "fixed" or figured out
118-
elbCfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region))
122+
elbCfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region),
123+
configv2.WithAPIOptions([]func(*middleware.Stack) error{
124+
awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw),
125+
}))
119126
if err != nil {
120127
return nil, fmt.Errorf("failed to create AWS config for elb client: %w", err)
121128
}
122129
elbclient := elb.NewFromConfig(elbCfg, func(options *elb.Options) {
123130
options.Region = region
124131
for _, endpoint := range metadata.AWS.ServiceEndpoints {
125-
if strings.EqualFold(endpoint.Name, "elb") {
132+
if strings.EqualFold(endpoint.Name, "elb") || strings.EqualFold(endpoint.Name, "elasticloadbalancing") {
126133
options.BaseEndpoint = awsv2.String(endpoint.URL)
127134
}
128135
}
129136
})
130137

131138
// FIXME: remove this code when the elb and elbv2 clients are "fixed" or figured out
132-
elbv2Cfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region))
139+
elbv2Cfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region),
140+
configv2.WithAPIOptions([]func(*middleware.Stack) error{
141+
awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw),
142+
}))
133143
if err != nil {
134144
return nil, fmt.Errorf("failed to create AWS config for elbv2 client: %w", err)
135145
}
136146
elbv2client := elbv2.NewFromConfig(elbv2Cfg, func(options *elbv2.Options) {
137147
options.Region = region
138148
for _, endpoint := range metadata.AWS.ServiceEndpoints {
139-
if strings.EqualFold(endpoint.Name, "elbv2") {
149+
if strings.EqualFold(endpoint.Name, "elbv2") || strings.EqualFold(endpoint.Name, "elasticloadbalancingv2") {
140150
options.BaseEndpoint = awsv2.String(endpoint.URL)
141151
}
142152
}
143153
})
144154

145155
// FIXME: remove this code when the s3client is made
146-
s3Cfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region))
156+
s3Cfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region),
157+
configv2.WithAPIOptions([]func(*middleware.Stack) error{
158+
awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw),
159+
}))
147160
if err != nil {
148161
return nil, fmt.Errorf("failed to create AWS config for S3 client: %w", err)
149162
}
@@ -157,14 +170,17 @@ func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.
157170
})
158171

159172
// FIXME: remove this code when the EFS client is made
160-
efsCfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region))
173+
efsCfg, err := awssession.GetConfigWithOptions(ctx, configv2.WithRegion(region),
174+
configv2.WithAPIOptions([]func(*middleware.Stack) error{
175+
awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw),
176+
}))
161177
if err != nil {
162178
return nil, fmt.Errorf("failed to create AWS config for EFS client: %w", err)
163179
}
164180
efsClient := efs.NewFromConfig(efsCfg, func(options *efs.Options) {
165181
options.Region = region
166182
for _, endpoint := range metadata.AWS.ServiceEndpoints {
167-
if strings.EqualFold(endpoint.Name, "efs") {
183+
if strings.EqualFold(endpoint.Name, "elasticfilesystem") {
168184
options.BaseEndpoint = awsv2.String(endpoint.URL)
169185
}
170186
}
@@ -173,7 +189,7 @@ func New(logger logrus.FieldLogger, metadata *types.ClusterMetadata) (providers.
173189
route53Client, err := awssession.NewRoute53Client(ctx, awssession.EndpointOptions{
174190
Region: region,
175191
Endpoints: metadata.AWS.ServiceEndpoints,
176-
}, "") // FIXME: Do we need an ARN here?
192+
}, "", route53.WithAPIOptions(awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw)))
177193
if err != nil {
178194
return nil, fmt.Errorf("failed to create Route53 client: %w", err)
179195
}
@@ -213,15 +229,18 @@ func createResourceTaggingClientWithConfig(cfg awsv2.Config, region string, endp
213229
return resourcegroupstaggingapi.NewFromConfig(cfg, func(options *resourcegroupstaggingapi.Options) {
214230
options.Region = region
215231
for _, endpoint := range endpoints {
216-
if strings.EqualFold(endpoint.Name, "resourcegroupstaggingapi") {
232+
if strings.EqualFold(endpoint.Name, "tagging") {
217233
options.BaseEndpoint = awsv2.String(endpoint.URL)
218234
}
219235
}
220236
})
221237
}
222238

223239
func createResourceTaggingClient(region string, endpoints []awstypes.ServiceEndpoint) (*resourcegroupstaggingapi.Client, error) {
224-
cfg, err := awssession.GetConfigWithOptions(context.Background(), configv2.WithRegion(region))
240+
cfg, err := awssession.GetConfigWithOptions(context.Background(), configv2.WithRegion(region),
241+
configv2.WithAPIOptions([]func(*middleware.Stack) error{
242+
awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw),
243+
}))
225244
if err != nil {
226245
return nil, fmt.Errorf("failed to create AWS config for resource tagging client: %w", err)
227246
}
@@ -250,7 +269,7 @@ func (o *ClusterUninstaller) RunWithContext(ctx context.Context) ([]string, erro
250269
stsSvc, err := awssession.NewSTSClient(ctx, awssession.EndpointOptions{
251270
Region: endpointUSEast1,
252271
Endpoints: o.endpoints,
253-
}, sts.WithAPIOptions(middleware.AddUserAgentKeyValue("OpenShift/4.x Destroyer", version.Raw)))
272+
}, sts.WithAPIOptions(awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw)))
254273
if err != nil {
255274
return nil, fmt.Errorf("failed to create STS client: %w", err)
256275
}
@@ -691,7 +710,7 @@ func deleteRoute53(ctx context.Context, client *route53.Client, arn arn.ARN, log
691710
for paginator.HasMorePages() {
692711
page, err := paginator.NextPage(ctx)
693712
if err != nil {
694-
return fmt.Errorf("listing record sets for public zone: %w", err)
713+
return fmt.Errorf("listing record sets for public zone %s: %w", publicZoneID, err)
695714
}
696715
for _, recordSet := range page.ResourceRecordSets {
697716
key := recordSetKey(recordSet)
@@ -707,7 +726,7 @@ func deleteRoute53(ctx context.Context, client *route53.Client, arn arn.ARN, log
707726
for paginator.HasMorePages() {
708727
page, err := paginator.NextPage(ctx)
709728
if err != nil {
710-
return fmt.Errorf("listing record sets: %w", err)
729+
return fmt.Errorf("listing record sets for zone %s: %w", id, err)
711730
}
712731

713732
for _, recordSet := range page.ResourceRecordSets {

pkg/destroy/aws/elbhelpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func deleteElasticLoadBalancerClassicByVPC(ctx context.Context, client *elbapi.C
6565
for paginator.HasMorePages() {
6666
page, err := paginator.NextPage(ctx)
6767
if err != nil {
68-
return fmt.Errorf("describing load balacers by vpc %s: %w", vpc, err)
68+
return fmt.Errorf("describing load balancers by vpc %s: %w", vpc, err)
6969
}
7070

7171
logger.Debugf("iterating over a page of %d v1 load balancers", len(page.LoadBalancerDescriptions))

pkg/destroy/aws/iamhelpers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (search *IamRoleSearch) find(ctx context.Context) (arns []string, names []s
6363
lastError = fmt.Errorf("get tags for %s: %w", *role.Arn, err)
6464
}
6565
} else {
66-
tags := make(map[string]string, len(role.Tags))
66+
tags := make(map[string]string, len(response.Tags))
6767
for _, tag := range response.Tags {
6868
tags[*tag.Key] = *tag.Value
6969
}
@@ -111,7 +111,7 @@ func (search *IamUserSearch) arns(ctx context.Context) ([]string, error) {
111111
}
112112

113113
// Unfortunately user.Tags is empty from ListUsers, so we need to query each one
114-
response, err := search.client.ListUserTags(ctx, &iamv2.ListUserTagsInput{UserName: aws.String(*user.UserName)})
114+
response, err := search.client.ListUserTags(ctx, &iamv2.ListUserTagsInput{UserName: user.UserName})
115115
if err != nil {
116116
switch {
117117
case strings.Contains(HandleErrorCode(err), "NoSuchEntity"):

pkg/destroy/aws/shared.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/aws/aws-sdk-go-v2/aws"
1010
"github.com/aws/aws-sdk-go-v2/aws/arn"
11+
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
1112
"github.com/aws/aws-sdk-go-v2/service/iam"
1213
"github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
1314
tagtypes "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi/types"
@@ -16,6 +17,9 @@ import (
1617
"github.com/pkg/errors"
1718
"github.com/sirupsen/logrus"
1819
"k8s.io/apimachinery/pkg/util/wait"
20+
21+
awssession "github.com/openshift/installer/pkg/asset/installconfig/aws"
22+
"github.com/openshift/installer/pkg/version"
1923
)
2024

2125
func (o *ClusterUninstaller) removeSharedTags(
@@ -76,7 +80,7 @@ func (o *ClusterUninstaller) removeSharedTag(ctx context.Context, tagClients []*
7680
}
7781

7882
for _, resource := range page.ResourceTagMappingList {
79-
arnString := *resource.ResourceARN
83+
arnString := aws.ToString(resource.ResourceARN)
8084
logger := o.Logger.WithField("arn", arnString)
8185
parsedARN, err := arn.Parse(arnString)
8286
if err != nil {
@@ -98,7 +102,7 @@ func (o *ClusterUninstaller) removeSharedTag(ctx context.Context, tagClients []*
98102

99103
if lastErr != nil {
100104
o.Logger.Infof("failed to get tagged resources: %v", lastErr)
101-
var invalidParameter tagtypes.InvalidParameterException
105+
var invalidParameter *tagtypes.InvalidParameterException
102106
if errors.As(lastErr, &invalidParameter) {
103107
continue
104108
}
@@ -107,7 +111,7 @@ func (o *ClusterUninstaller) removeSharedTag(ctx context.Context, tagClients []*
107111
}
108112

109113
if len(arns) == 0 {
110-
o.Logger.Debugf("No matches in %s for %s: shared, removing client", o.Region, key)
114+
o.Logger.Debugf("No matches in %s for %s: shared, removing client", tagClient.Options().Region, key)
111115
continue
112116
}
113117
// appending the tag client here but it needs to be removed if there is a InvalidParameterException when trying to
@@ -204,6 +208,17 @@ func (o *ClusterUninstaller) cleanSharedRoute53(ctx context.Context, arn arn.ARN
204208
}
205209

206210
func (o *ClusterUninstaller) cleanSharedHostedZone(ctx context.Context, id string, logger logrus.FieldLogger) error {
211+
// The private hosted zone (phz) may belong to a different account,
212+
// in which case we need a separate client.
213+
// Note: the ClusterUninstaller has a basic Route53 client used for public zone resources.
214+
privateZoneClient, err := awssession.NewRoute53Client(ctx, awssession.EndpointOptions{
215+
Region: o.Region,
216+
Endpoints: o.endpoints,
217+
}, o.HostedZoneRole, route53.WithAPIOptions(awsmiddleware.AddUserAgentKeyValue(OpenShiftInstallerDestroyerUserAgent, version.Raw)))
218+
if err != nil {
219+
return fmt.Errorf("failed to create Route53 private zone client: %w", err)
220+
}
221+
207222
if o.ClusterDomain == "" {
208223
logger.Debug("No cluster domain specified in metadata; cannot clean the shared hosted zone")
209224
return nil
@@ -216,7 +231,7 @@ func (o *ClusterUninstaller) cleanSharedHostedZone(ctx context.Context, id strin
216231
}
217232

218233
var lastError error
219-
paginator := route53.NewListResourceRecordSetsPaginator(o.Route53Client, &route53.ListResourceRecordSetsInput{HostedZoneId: aws.String(id)})
234+
paginator := route53.NewListResourceRecordSetsPaginator(privateZoneClient, &route53.ListResourceRecordSetsInput{HostedZoneId: aws.String(id)})
220235
for paginator.HasMorePages() {
221236
page, err := paginator.NextPage(ctx)
222237
if err != nil {
@@ -225,14 +240,14 @@ func (o *ClusterUninstaller) cleanSharedHostedZone(ctx context.Context, id strin
225240

226241
for _, recordSet := range page.ResourceRecordSets {
227242
// skip record sets that are not part of the cluster
228-
name := *recordSet.Name
243+
name := aws.ToString(recordSet.Name)
229244
if !strings.HasSuffix(name, dottedClusterDomain) {
230245
continue
231246
}
232247
if len(name) == len(dottedClusterDomain) {
233248
continue
234249
}
235-
recordsetFields := logrus.Fields{"recordset": fmt.Sprintf("%s (%s)", *recordSet.Name, recordSet.Type)}
250+
recordsetFields := logrus.Fields{"recordset": fmt.Sprintf("%s (%s)", aws.ToString(recordSet.Name), recordSet.Type)}
236251
// delete any matching record sets in the public hosted zone
237252
if publicZoneID != "" {
238253
publicZoneLogger := logger.WithField("id", publicZoneID)
@@ -248,7 +263,7 @@ func (o *ClusterUninstaller) cleanSharedHostedZone(ctx context.Context, id strin
248263
publicZoneLogger.WithFields(recordsetFields).Debug("Deleted from public zone")
249264
}
250265
// delete the record set
251-
if err := deleteRoute53RecordSet(ctx, o.Route53Client, id, &recordSet, logger); err != nil {
266+
if err := deleteRoute53RecordSet(ctx, privateZoneClient, id, &recordSet, logger); err != nil {
252267
if lastError != nil {
253268
logger.Debug(lastError)
254269
}
@@ -280,7 +295,7 @@ func deleteMatchingRecordSetInPublicZone(ctx context.Context, client *route53.Cl
280295
return nil
281296
}
282297
matchingRecordSet := out.ResourceRecordSets[0]
283-
if *matchingRecordSet.Name != *recordSet.Name || matchingRecordSet.Type != recordSet.Type {
298+
if aws.ToString(matchingRecordSet.Name) != aws.ToString(recordSet.Name) || matchingRecordSet.Type != recordSet.Type {
284299
return nil
285300
}
286301
return deleteRoute53RecordSet(ctx, client, zoneID, &matchingRecordSet, logger)

0 commit comments

Comments
 (0)