Skip to content

Commit

Permalink
migrate: aws v2 transit-gateway (gruntwork-io#773)
Browse files Browse the repository at this point in the history
Co-authored-by: James Kwon <[email protected]>
  • Loading branch information
james03160927 and james03160927 authored Oct 26, 2024
1 parent 546ea3f commit ef74d82
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 77 deletions.
74 changes: 37 additions & 37 deletions aws/resources/transit_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"fmt"
"time"

"github.com/aws/aws-sdk-go/aws"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awsgo "github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
Expand All @@ -30,7 +30,7 @@ const (
// Returns a formatted string of TransitGateway IDs
func (tgw *TransitGateways) getAll(c context.Context, configObj config.Config) ([]*string, error) {

result, err := tgw.Client.DescribeTransitGatewaysWithContext(tgw.Context, &ec2.DescribeTransitGatewaysInput{})
result, err := tgw.Client.DescribeTransitGateways(tgw.Context, &ec2.DescribeTransitGatewaysInput{})
if err != nil {
logging.Debugf("[DescribeTransitGateways Failed] %s", err)
return nil, errors.WithStackTrace(err)
Expand All @@ -45,11 +45,11 @@ func (tgw *TransitGateways) getAll(c context.Context, configObj config.Config) (
Time: transitGateway.CreationTime,
Name: hostNameTagValue,
}) &&
awsgo.StringValue(transitGateway.State) != "deleted" && awsgo.StringValue(transitGateway.State) != "deleting" {
transitGateway.State != types.TransitGatewayStateDeleted && transitGateway.State != types.TransitGatewayStateDeleting {
ids = append(ids, transitGateway.TransitGatewayId)
}

if currentOwner != nil && transitGateway.OwnerId != nil && currentOwner != awsgo.StringValue(transitGateway.OwnerId) {
if currentOwner != nil && transitGateway.OwnerId != nil && currentOwner != awsgo.ToString(transitGateway.OwnerId) {
tgw.SetNukableStatus(*transitGateway.TransitGatewayId, util.ErrDifferentOwner)
continue
}
Expand All @@ -62,9 +62,9 @@ func (tgw *TransitGateways) getAll(c context.Context, configObj config.Config) (
tgw.VerifyNukablePermissions(ids, func(id *string) error {
params := &ec2.DeleteTransitGatewayInput{
TransitGatewayId: id,
DryRun: aws.Bool(true), // dry run set as true , checks permission without actualy making the request
DryRun: awsgo.Bool(true), // dry run set as true , checks permission without actualy making the request
}
_, err := tgw.Client.DeleteTransitGatewayWithContext(tgw.Context, params)
_, err := tgw.Client.DeleteTransitGateway(tgw.Context, params)
return err
})

Expand All @@ -77,7 +77,7 @@ func (tgw *TransitGateways) nuke(id *string) error {
return errors.WithStackTrace(err)
}

if _, err := tgw.Client.DeleteTransitGatewayWithContext(tgw.Context, &ec2.DeleteTransitGatewayInput{
if _, err := tgw.Client.DeleteTransitGateway(tgw.Context, &ec2.DeleteTransitGatewayInput{
TransitGatewayId: id,
}); err != nil {
return errors.WithStackTrace(err)
Expand All @@ -87,76 +87,76 @@ func (tgw *TransitGateways) nuke(id *string) error {
}

func (tgw *TransitGateways) nukeAttachments(id *string) error {
logging.Debugf("nuking transit gateway attachments for %v", awsgo.StringValue(id))
output, err := tgw.Client.DescribeTransitGatewayAttachmentsWithContext(tgw.Context, &ec2.DescribeTransitGatewayAttachmentsInput{
Filters: []*ec2.Filter{
logging.Debugf("nuking transit gateway attachments for %v", awsgo.ToString(id))
output, err := tgw.Client.DescribeTransitGatewayAttachments(tgw.Context, &ec2.DescribeTransitGatewayAttachmentsInput{
Filters: []types.Filter{
{
Name: awsgo.String("transit-gateway-id"),
Values: []*string{
id,
Values: []string{
awsgo.ToString(id),
},
},
{
Name: awsgo.String("state"),
Values: []*string{
awsgo.String("available"),
Values: []string{
"available",
},
},
},
})
if err != nil {
logging.Errorf("[Failed] unable to describe the transit gateway attachments for %v : %s", awsgo.StringValue(id), err)
logging.Errorf("[Failed] unable to describe the transit gateway attachments for %v : %s", awsgo.ToString(id), err)
return errors.WithStackTrace(err)
}

logging.Debugf("%v attachment(s) found with %v", len(output.TransitGatewayAttachments), awsgo.StringValue(id))
logging.Debugf("%v attachment(s) found with %v", len(output.TransitGatewayAttachments), awsgo.ToString(id))

for _, attachments := range output.TransitGatewayAttachments {
var (
err error
attachmentType = awsgo.StringValue(attachments.ResourceType)
attachmentType = attachments.ResourceType
now = time.Now()
)

switch attachmentType {
case TransitGatewayAttachmentTypePeering:
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.StringValue(id))
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.ToString(id))
// Delete the Transit Gateway Peering Attachment
_, err = tgw.Client.DeleteTransitGatewayPeeringAttachmentWithContext(tgw.Context, &ec2.DeleteTransitGatewayPeeringAttachmentInput{
_, err = tgw.Client.DeleteTransitGatewayPeeringAttachment(tgw.Context, &ec2.DeleteTransitGatewayPeeringAttachmentInput{
TransitGatewayAttachmentId: attachments.TransitGatewayAttachmentId,
})
case TransitGatewayAttachmentTypeVPC:
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.StringValue(id))
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.ToString(id))
// Delete the Transit Gateway VPC Attachment
_, err = tgw.Client.DeleteTransitGatewayVpcAttachmentWithContext(tgw.Context, &ec2.DeleteTransitGatewayVpcAttachmentInput{
_, err = tgw.Client.DeleteTransitGatewayVpcAttachment(tgw.Context, &ec2.DeleteTransitGatewayVpcAttachmentInput{
TransitGatewayAttachmentId: attachments.TransitGatewayAttachmentId,
})
case TransitGatewayAttachmentTypeConnect:
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.StringValue(id))
logging.Debugf("[Execution] deleting the attachments of type %v for %v ", attachmentType, awsgo.ToString(id))
// Delete the Transit Gateway Connect Attachment
_, err = tgw.Client.DeleteTransitGatewayConnectWithContext(tgw.Context, &ec2.DeleteTransitGatewayConnectInput{
_, err = tgw.Client.DeleteTransitGatewayConnect(tgw.Context, &ec2.DeleteTransitGatewayConnectInput{
TransitGatewayAttachmentId: attachments.TransitGatewayAttachmentId,
})
default:
err = fmt.Errorf("%v typed transit gateway attachment nuking not handled", attachmentType)
}
if err != nil {
logging.Errorf("[Failed] unable to delete the transit gateway peernig attachment for %v : %s", awsgo.StringValue(id), err)
logging.Errorf("[Failed] unable to delete the transit gateway peernig attachment for %v : %s", awsgo.ToString(id), err)
return err
}
if err := tgw.WaitUntilTransitGatewayAttachmentDeleted(id, attachmentType); err != nil {
logging.Errorf("[Failed] unable to wait until nuking the transit gateway attachment with type %v for %v : %s", attachmentType,awsgo.StringValue(id), err)
logging.Errorf("[Failed] unable to wait until nuking the transit gateway attachment with type %v for %v : %s", attachmentType, awsgo.ToString(id), err)
return errors.WithStackTrace(err)
}

logging.Debugf("waited %v to nuke the attachment", time.Since(now))
}

logging.Debugf("[Ok] successfully nuked all the attachments on %v", awsgo.StringValue(id))
logging.Debugf("[Ok] successfully nuked all the attachments on %v", awsgo.ToString(id))
return nil
}

func (tgw *TransitGateways) WaitUntilTransitGatewayAttachmentDeleted(id *string, attachmentType string) error {
func (tgw *TransitGateways) WaitUntilTransitGatewayAttachmentDeleted(id *string, attachmentType types.TransitGatewayAttachmentResourceType) error {
timeoutCtx, cancel := context.WithTimeout(tgw.Context, 5*time.Minute)
defer cancel()

Expand All @@ -168,19 +168,19 @@ func (tgw *TransitGateways) WaitUntilTransitGatewayAttachmentDeleted(id *string,
case <-timeoutCtx.Done():
return fmt.Errorf("transit gateway attachments deletion check timed out after 5 minute")
case <-ticker.C:
output, err := tgw.Client.DescribeTransitGatewayAttachmentsWithContext(tgw.Context, &ec2.DescribeTransitGatewayAttachmentsInput{
Filters: []*ec2.Filter{
output, err := tgw.Client.DescribeTransitGatewayAttachments(tgw.Context, &ec2.DescribeTransitGatewayAttachmentsInput{
Filters: []types.Filter{
{
Name: awsgo.String("transit-gateway-id"),
Values: []*string{
id,
Values: []string{
awsgo.ToString(id),
},
},
{
Name: awsgo.String("state"),
Values: []*string{
awsgo.String("available"),
awsgo.String("deleting"),
Values: []string{
"available",
"deleting",
},
},
},
Expand Down Expand Up @@ -220,7 +220,7 @@ func (tgw *TransitGateways) nukeAll(ids []*string) error {

// Record status of this resource
e := report.Entry{
Identifier: aws.StringValue(id),
Identifier: awsgo.ToString(id),
ResourceType: "Transit Gateway",
Error: err,
}
Expand Down
31 changes: 13 additions & 18 deletions aws/resources/transit_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,47 @@ import (
"testing"
"time"

"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/aws/aws-sdk-go/aws"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/stretchr/testify/require"
)

type mockedTransitGateway struct {
ec2iface.EC2API
TransitGatewayAPI
DescribeTransitGatewaysOutput ec2.DescribeTransitGatewaysOutput
DeleteTransitGatewayOutput ec2.DeleteTransitGatewayOutput
DescribeTransitGatewayAttachmentsOutput ec2.DescribeTransitGatewayAttachmentsOutput
DeleteTransitGatewayPeeringAttachmentOutput ec2.DeleteTransitGatewayPeeringAttachmentOutput
DeleteTransitGatewayVpcAttachmentOutput ec2.DeleteTransitGatewayVpcAttachmentOutput
DeleteVpnConnectionOutput ec2.DeleteVpnConnectionOutput
DeleteTransitGatewayConnectOutput ec2.DeleteTransitGatewayConnectOutput

}

func (m mockedTransitGateway) DescribeTransitGatewaysWithContext(_ awsgo.Context, _ *ec2.DescribeTransitGatewaysInput, _ ...request.Option) (*ec2.DescribeTransitGatewaysOutput, error) {
func (m mockedTransitGateway) DescribeTransitGateways(ctx context.Context, params *ec2.DescribeTransitGatewaysInput, optFns ...func(*ec2.Options)) (*ec2.DescribeTransitGatewaysOutput, error) {
return &m.DescribeTransitGatewaysOutput, nil
}

func (m mockedTransitGateway) DeleteTransitGatewayWithContext(_ awsgo.Context, _ *ec2.DeleteTransitGatewayInput, _ ...request.Option) (*ec2.DeleteTransitGatewayOutput, error) {
func (m mockedTransitGateway) DeleteTransitGateway(ctx context.Context, params *ec2.DeleteTransitGatewayInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayOutput, error) {
return &m.DeleteTransitGatewayOutput, nil
}

func (m mockedTransitGateway) DescribeTransitGatewayAttachmentsWithContext(awsgo.Context, *ec2.DescribeTransitGatewayAttachmentsInput, ...request.Option) (*ec2.DescribeTransitGatewayAttachmentsOutput, error) {
func (m mockedTransitGateway) DescribeTransitGatewayAttachments(ctx context.Context, params *ec2.DescribeTransitGatewayAttachmentsInput, optFns ...func(*ec2.Options)) (*ec2.DescribeTransitGatewayAttachmentsOutput, error) {
return &m.DescribeTransitGatewayAttachmentsOutput, nil
}

func (m mockedTransitGateway) DeleteTransitGatewayPeeringAttachmentWithContext(aws.Context, *ec2.DeleteTransitGatewayPeeringAttachmentInput, ...request.Option) (*ec2.DeleteTransitGatewayPeeringAttachmentOutput, error) {
func (m mockedTransitGateway) DeleteTransitGatewayPeeringAttachment(ctx context.Context, params *ec2.DeleteTransitGatewayPeeringAttachmentInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayPeeringAttachmentOutput, error) {
return &m.DeleteTransitGatewayPeeringAttachmentOutput, nil
}
func (m mockedTransitGateway) DeleteTransitGatewayVpcAttachmentWithContext(_ awsgo.Context, _ *ec2.DeleteTransitGatewayVpcAttachmentInput, _ ...request.Option) (*ec2.DeleteTransitGatewayVpcAttachmentOutput, error) {

func (m mockedTransitGateway) DeleteTransitGatewayVpcAttachment(ctx context.Context, params *ec2.DeleteTransitGatewayVpcAttachmentInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayVpcAttachmentOutput, error) {
return &m.DeleteTransitGatewayVpcAttachmentOutput, nil
}

func (m mockedTransitGateway) DeleteTransitGatewayConnectWithContext(_ awsgo.Context, _ *ec2.DeleteTransitGatewayConnectInput, _ ...request.Option) (*ec2.DeleteTransitGatewayConnectOutput, error) {
func (m mockedTransitGateway) DeleteTransitGatewayConnect(ctx context.Context, params *ec2.DeleteTransitGatewayConnectInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayConnectOutput, error) {
return &m.DeleteTransitGatewayConnectOutput, nil
}
func (m mockedTransitGateway) WaitUntilTransitGatewayAttachmentDeleted(*string, string) error {
return nil
}

func TestTransitGateways_GetAll(t *testing.T) {

Expand All @@ -62,16 +57,16 @@ func TestTransitGateways_GetAll(t *testing.T) {
tgw := TransitGateways{
Client: mockedTransitGateway{
DescribeTransitGatewaysOutput: ec2.DescribeTransitGatewaysOutput{
TransitGateways: []*ec2.TransitGateway{
TransitGateways: []types.TransitGateway{
{
TransitGatewayId: aws.String(gatewayId1),
CreationTime: aws.Time(now),
State: aws.String("available"),
State: "available",
},
{
TransitGatewayId: aws.String(gatewayId2),
CreationTime: aws.Time(now.Add(1)),
State: aws.String("deleting"),
State: "deleting",
},
},
},
Expand Down
25 changes: 15 additions & 10 deletions aws/resources/transit_gateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,34 @@ package resources
import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/go-commons/errors"
)

type TransitGatewayAPI interface {
DescribeTransitGateways(ctx context.Context, params *ec2.DescribeTransitGatewaysInput, optFns ...func(*ec2.Options)) (*ec2.DescribeTransitGatewaysOutput, error)
DeleteTransitGateway(ctx context.Context, params *ec2.DeleteTransitGatewayInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayOutput, error)
DescribeTransitGatewayAttachments(ctx context.Context, params *ec2.DescribeTransitGatewayAttachmentsInput, optFns ...func(*ec2.Options)) (*ec2.DescribeTransitGatewayAttachmentsOutput, error)
DeleteTransitGatewayPeeringAttachment(ctx context.Context, params *ec2.DeleteTransitGatewayPeeringAttachmentInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayPeeringAttachmentOutput, error)
DeleteTransitGatewayVpcAttachment(ctx context.Context, params *ec2.DeleteTransitGatewayVpcAttachmentInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayVpcAttachmentOutput, error)
DeleteTransitGatewayConnect(ctx context.Context, params *ec2.DeleteTransitGatewayConnectInput, optFns ...func(*ec2.Options)) (*ec2.DeleteTransitGatewayConnectOutput, error)
}

// TransitGateways - represents all transit gateways
type TransitGateways struct {
BaseAwsResource
Client ec2iface.EC2API
Client TransitGatewayAPI
Region string
Ids []string
}

func (tgw *TransitGateways) Init(session *session.Session) {
// to initialize base resource
// NOTE : This is madatory to initialize the nukables map
tgw.BaseAwsResource.Init(session)
tgw.Client = ec2.New(session)

func (tgw *TransitGateways) InitV2(cfg aws.Config) {
tgw.Client = ec2.NewFromConfig(cfg)
}
func (tgw *TransitGateways) IsUsingV2() bool { return true }

// ResourceName - the simple name of the aws resource
func (tgw *TransitGateways) ResourceName() string {
Expand Down
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ go 1.21

require (
github.com/aws/aws-sdk-go v1.49.13
github.com/aws/aws-sdk-go-v2 v1.31.0
github.com/aws/aws-sdk-go-v2 v1.32.2
github.com/aws/aws-sdk-go-v2/config v1.27.24
github.com/aws/aws-sdk-go-v2/credentials v1.17.24
github.com/aws/aws-sdk-go-v2/service/amp v1.27.1
github.com/aws/aws-sdk-go-v2/service/ec2 v1.184.0
github.com/aws/aws-sdk-go-v2/service/eventbridge v1.33.7
github.com/aws/aws-sdk-go-v2/service/scheduler v1.10.7
github.com/aws/aws-sdk-go-v2/service/sns v1.32.3
Expand All @@ -28,16 +29,16 @@ require (
atomicgo.dev/cursor v0.1.1 // indirect
atomicgo.dev/keyboard v0.2.8 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect
github.com/aws/smithy-go v1.21.0 // indirect
github.com/aws/smithy-go v1.22.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
Loading

0 comments on commit ef74d82

Please sign in to comment.