Skip to content

Commit

Permalink
change port ec2 ipam byoasn, ec2 ipam custom allocation, ec2 ipam poo…
Browse files Browse the repository at this point in the history
…l, ec2 ipam resource discovery, ec2 ipam scope, ec2 ipam to awsSDKv2 #770 (#790)
  • Loading branch information
wakeful authored Nov 20, 2024
1 parent 988f95f commit 174aedb
Show file tree
Hide file tree
Showing 21 changed files with 486 additions and 458 deletions.
96 changes: 48 additions & 48 deletions aws/resources/ec2_ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ 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"
"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"
"github.com/gruntwork-io/cloud-nuke/util"
"github.com/gruntwork-io/go-commons/errors"
)

func shouldIncludeIpamID(ipam *ec2.Ipam, firstSeenTime *time.Time, configObj config.Config) bool {
func shouldIncludeIpamID(ipam *types.Ipam, firstSeenTime *time.Time, configObj config.Config) bool {
var ipamName string
// get the tags as map
tagMap := util.ConvertEC2TagsToMap(ipam.Tags)
tagMap := util.ConvertTypesTagsToMap(ipam.Tags)
if name, ok := tagMap["Name"]; ok {
ipamName = name
}
Expand All @@ -32,55 +32,55 @@ func shouldIncludeIpamID(ipam *ec2.Ipam, firstSeenTime *time.Time, configObj con

// Returns a formatted string of IPAM URLs
func (ec2Ipam *EC2IPAMs) getAll(c context.Context, configObj config.Config) ([]*string, error) {
result := []*string{}
var result []*string
var firstSeenTime *time.Time
var err error

paginator := func(output *ec2.DescribeIpamsOutput, lastPage bool) bool {
for _, ipam := range output.Ipams {
firstSeenTime, err = util.GetOrCreateFirstSeen(c, ec2Ipam.Client, ipam.IpamId, util.ConvertEC2TagsToMap(ipam.Tags))
params := &ec2.DescribeIpamsInput{
MaxResults: aws.Int32(10),
}

ipamsPaginator := ec2.NewDescribeIpamsPaginator(ec2Ipam.Client, params)
for ipamsPaginator.HasMorePages() {
page, errPage := ipamsPaginator.NextPage(c)
if errPage != nil {
return nil, errors.WithStackTrace(errPage)
}

for _, ipam := range page.Ipams {
firstSeenTime, err = util.GetOrCreateFirstSeen(c, ec2Ipam.Client, ipam.IpamId, util.ConvertTypesTagsToMap(ipam.Tags))
if err != nil {
logging.Error("Unable to retrieve tags")
continue
}
// Check for include this ipam
if shouldIncludeIpamID(ipam, firstSeenTime, configObj) {
if shouldIncludeIpamID(&ipam, firstSeenTime, configObj) {
result = append(result, ipam.IpamId)
}
}
return !lastPage
}

params := &ec2.DescribeIpamsInput{
MaxResults: awsgo.Int64(10),
}

err = ec2Ipam.Client.DescribeIpamsPagesWithContext(ec2Ipam.Context, params, paginator)
if err != nil {
return nil, errors.WithStackTrace(err)
}

// checking the nukable permissions
ec2Ipam.VerifyNukablePermissions(result, func(id *string) error {
_, err := ec2Ipam.Client.DeleteIpamWithContext(ec2Ipam.Context, &ec2.DeleteIpamInput{
_, err := ec2Ipam.Client.DeleteIpam(ec2Ipam.Context, &ec2.DeleteIpamInput{
IpamId: id,
Cascade: aws.Bool(true),
DryRun: awsgo.Bool(true),
DryRun: aws.Bool(true),
})
return err
})

return result, nil
}

// deProvisionPoolCIDRs : Detach the CIDR provisiond on the pool
// deProvisionPoolCIDRs : Detach the CIDR provisioned on the pool
func (ec2Ipam *EC2IPAMs) deProvisionPoolCIDRs(poolID *string) error {
output, err := ec2Ipam.Client.GetIpamPoolCidrsWithContext(ec2Ipam.Context, &ec2.GetIpamPoolCidrsInput{
output, err := ec2Ipam.Client.GetIpamPoolCidrs(ec2Ipam.Context, &ec2.GetIpamPoolCidrsInput{
IpamPoolId: poolID,
Filters: []*ec2.Filter{
Filters: []types.Filter{
{
Name: awsgo.String("state"),
Values: awsgo.StringSlice([]string{"provisioned"}),
Name: aws.String("state"),
Values: []string{"provisioned"},
},
},
})
Expand All @@ -89,23 +89,23 @@ func (ec2Ipam *EC2IPAMs) deProvisionPoolCIDRs(poolID *string) error {
}

for _, poolCidr := range output.IpamPoolCidrs {
_, err := ec2Ipam.Client.DeprovisionIpamPoolCidrWithContext(ec2Ipam.Context, &ec2.DeprovisionIpamPoolCidrInput{
_, err := ec2Ipam.Client.DeprovisionIpamPoolCidr(ec2Ipam.Context, &ec2.DeprovisionIpamPoolCidrInput{
IpamPoolId: poolID,
Cidr: poolCidr.Cidr,
})

if err != nil {
return errors.WithStackTrace(err)
}
logging.Debugf("De-Provisioned CIDR(s) from IPAM Pool %s", aws.StringValue(poolID))
logging.Debugf("De-Provisioned CIDR(s) from IPAM Pool %s", aws.ToString(poolID))
}

return nil
}

// releaseCustomAllocations : Release the custom allocated CIDR(s) from the pool
func (ec2Ipam *EC2IPAMs) releaseCustomAllocations(poolID *string) error {
output, err := ec2Ipam.Client.GetIpamPoolAllocationsWithContext(ec2Ipam.Context, &ec2.GetIpamPoolAllocationsInput{
output, err := ec2Ipam.Client.GetIpamPoolAllocations(ec2Ipam.Context, &ec2.GetIpamPoolAllocationsInput{
IpamPoolId: poolID,
})
if err != nil {
Expand All @@ -114,10 +114,10 @@ func (ec2Ipam *EC2IPAMs) releaseCustomAllocations(poolID *string) error {

for _, poolAllocation := range output.IpamPoolAllocations {
// we only can release the custom allocations
if *poolAllocation.ResourceType != "custom" {
if poolAllocation.ResourceType != types.IpamPoolAllocationResourceTypeCustom {
continue
}
_, err := ec2Ipam.Client.ReleaseIpamPoolAllocationWithContext(ec2Ipam.Context, &ec2.ReleaseIpamPoolAllocationInput{
_, err := ec2Ipam.Client.ReleaseIpamPoolAllocation(ec2Ipam.Context, &ec2.ReleaseIpamPoolAllocationInput{
IpamPoolId: poolID,
IpamPoolAllocationId: poolAllocation.IpamPoolAllocationId,
Cidr: poolAllocation.Cidr,
Expand All @@ -126,7 +126,7 @@ func (ec2Ipam *EC2IPAMs) releaseCustomAllocations(poolID *string) error {
if err != nil {
return errors.WithStackTrace(err)
}
logging.Debugf("Release custom allocated CIDR(s) from IPAM Pool %s", aws.StringValue(poolID))
logging.Debugf("Release custom allocated CIDR(s) from IPAM Pool %s", aws.ToString(poolID))
}

return nil
Expand All @@ -139,19 +139,19 @@ func (ec2Ipam *EC2IPAMs) releaseCustomAllocations(poolID *string) error {
// We cannot delete an IPAM pool if there are allocations in it or CIDRs provisioned to it. We must first release the allocations and Deprovision CIDRs
// from a pool before we can delete the pool
func (ec2Ipam *EC2IPAMs) nukePublicIPAMPools(ipamID *string) error {
ipam, err := ec2Ipam.Client.DescribeIpamsWithContext(ec2Ipam.Context, &ec2.DescribeIpamsInput{
IpamIds: aws.StringSlice([]string{*ipamID}),
ipam, err := ec2Ipam.Client.DescribeIpams(ec2Ipam.Context, &ec2.DescribeIpamsInput{
IpamIds: []string{*ipamID},
})
if err != nil {
logging.Errorf(fmt.Sprintf("Error describing IPAM %s: %s", *ipamID, err.Error()))
return errors.WithStackTrace(err)
}

// Describe the scope to read the scope arn
scope, err := ec2Ipam.Client.DescribeIpamScopesWithContext(ec2Ipam.Context, &ec2.DescribeIpamScopesInput{
IpamScopeIds: aws.StringSlice([]string{
scope, err := ec2Ipam.Client.DescribeIpamScopes(ec2Ipam.Context, &ec2.DescribeIpamScopesInput{
IpamScopeIds: []string{
*ipam.Ipams[0].PublicDefaultScopeId,
}),
},
})

if err != nil {
Expand All @@ -160,13 +160,13 @@ func (ec2Ipam *EC2IPAMs) nukePublicIPAMPools(ipamID *string) error {
}

// get the pools which is assigned on the public scope of the IPAM
output, err := ec2Ipam.Client.DescribeIpamPoolsWithContext(ec2Ipam.Context, &ec2.DescribeIpamPoolsInput{
Filters: []*ec2.Filter{
output, err := ec2Ipam.Client.DescribeIpamPools(ec2Ipam.Context, &ec2.DescribeIpamPoolsInput{
Filters: []types.Filter{
{
Name: aws.String("ipam-scope-arn"),
Values: aws.StringSlice([]string{
Values: []string{
*scope.IpamScopes[0].IpamScopeArn,
}),
},
},
},
})
Expand All @@ -191,14 +191,14 @@ func (ec2Ipam *EC2IPAMs) nukePublicIPAMPools(ipamID *string) error {
}

// delete ipam pool
_, err = ec2Ipam.Client.DeleteIpamPoolWithContext(ec2Ipam.Context, &ec2.DeleteIpamPoolInput{
_, err = ec2Ipam.Client.DeleteIpamPool(ec2Ipam.Context, &ec2.DeleteIpamPoolInput{
IpamPoolId: pool.IpamPoolId,
})
if err != nil {
logging.Errorf("[Failed] Delete IPAM Pool %s", err)
return errors.WithStackTrace(err)
}
logging.Debugf("Deleted IPAM Pool %s from IPAM %s", aws.StringValue(pool.IpamPoolId), aws.StringValue(ipamID))
logging.Debugf("Deleted IPAM Pool %s from IPAM %s", aws.ToString(pool.IpamPoolId), aws.ToString(ipamID))
}

return nil
Expand All @@ -220,7 +220,7 @@ func (ec2Ipam *EC2IPAMs) deleteIPAM(id *string) error {
Cascade: aws.Bool(true),
}

_, err := ec2Ipam.Client.DeleteIpamWithContext(ec2Ipam.Context, params)
_, err := ec2Ipam.Client.DeleteIpam(ec2Ipam.Context, params)

return err
}
Expand Down Expand Up @@ -256,16 +256,16 @@ func (ec2Ipam *EC2IPAMs) nukeAll(ids []*string) error {

for _, id := range ids {

if nukable, reason := ec2Ipam.IsNukable(awsgo.StringValue(id)); !nukable {
logging.Debugf("[Skipping] %s nuke because %v", awsgo.StringValue(id), reason)
if nukable, reason := ec2Ipam.IsNukable(aws.ToString(id)); !nukable {
logging.Debugf("[Skipping] %s nuke because %v", aws.ToString(id), reason)
continue
}

err := ec2Ipam.nukeIPAM(id)

// Record status of this resource
e := report.Entry{
Identifier: aws.StringValue(id),
Identifier: aws.ToString(id),
ResourceType: "IPAM",
Error: err,
}
Expand Down
21 changes: 10 additions & 11 deletions aws/resources/ec2_ipam_byoasn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package resources
import (
"context"

"github.com/aws/aws-sdk-go/aws"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
Expand All @@ -14,12 +13,12 @@ import (

// Returns a formatted string of IPAM Byoasns
func (byoasn *EC2IPAMByoasn) getAll(c context.Context, configObj config.Config) ([]*string, error) {
result := []*string{}
var result []*string
params := &ec2.DescribeIpamByoasnInput{
MaxResults: &MaxResultCount,
}

output, err := byoasn.Client.DescribeIpamByoasnWithContext(byoasn.Context, params)
output, err := byoasn.Client.DescribeIpamByoasn(byoasn.Context, params)
if err != nil {
return nil, errors.WithStackTrace(err)
}
Expand All @@ -30,9 +29,9 @@ func (byoasn *EC2IPAMByoasn) getAll(c context.Context, configObj config.Config)

// checking the nukable permissions
byoasn.VerifyNukablePermissions(result, func(id *string) error {
_, err := byoasn.Client.DisassociateIpamByoasnWithContext(byoasn.Context, &ec2.DisassociateIpamByoasnInput{
_, err := byoasn.Client.DisassociateIpamByoasn(byoasn.Context, &ec2.DisassociateIpamByoasnInput{
Asn: id,
DryRun: awsgo.Bool(true),
DryRun: aws.Bool(true),
})
return err
})
Expand All @@ -50,18 +49,18 @@ func (byoasn *EC2IPAMByoasn) nukeAll(asns []*string) error {
var list []*string

for _, id := range asns {
if nukable, reason := byoasn.IsNukable(awsgo.StringValue(id)); !nukable {
logging.Debugf("[Skipping] %s nuke because %v", awsgo.StringValue(id), reason)
if nukable, reason := byoasn.IsNukable(aws.ToString(id)); !nukable {
logging.Debugf("[Skipping] %s nuke because %v", aws.ToString(id), reason)
continue
}

_, err := byoasn.Client.DisassociateIpamByoasnWithContext(byoasn.Context, &ec2.DisassociateIpamByoasnInput{
_, err := byoasn.Client.DisassociateIpamByoasn(byoasn.Context, &ec2.DisassociateIpamByoasnInput{
Asn: id,
})

// Record status of this resource
e := report.Entry{
Identifier: aws.StringValue(id),
Identifier: aws.ToString(id),
ResourceType: "IPAM Byoasn",
Error: err,
}
Expand Down
21 changes: 10 additions & 11 deletions aws/resources/ec2_ipam_byoasn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,26 @@ import (
"testing"

"github.com/aws/aws-sdk-go-v2/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/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/stretchr/testify/require"
)

type mockedIPAMByoASN struct {
ec2iface.EC2API
EC2IPAMByoasnAPI
DescribeIpamByoasnOutput ec2.DescribeIpamByoasnOutput
DisassociateIpamByoasnOutput ec2.DisassociateIpamByoasnOutput
}

func (m mockedIPAMByoASN) DescribeIpamByoasnWithContext(_ awsgo.Context, _ *ec2.DescribeIpamByoasnInput, _ ...request.Option) (*ec2.DescribeIpamByoasnOutput, error) {
return &m.DescribeIpamByoasnOutput, nil
}
func (m mockedIPAMByoASN) DisassociateIpamByoasnWithContext(_ awsgo.Context, _ *ec2.DisassociateIpamByoasnInput, _ ...request.Option) (*ec2.DisassociateIpamByoasnOutput, error) {
func (m mockedIPAMByoASN) DisassociateIpamByoasn(ctx context.Context, params *ec2.DisassociateIpamByoasnInput, optFns ...func(*ec2.Options)) (*ec2.DisassociateIpamByoasnOutput, error) {
return &m.DisassociateIpamByoasnOutput, nil
}

func (m mockedIPAMByoASN) DescribeIpamByoasn(ctx context.Context, params *ec2.DescribeIpamByoasnInput, optFns ...func(*ec2.Options)) (*ec2.DescribeIpamByoasnOutput, error) {
return &m.DescribeIpamByoasnOutput, nil
}

func TestIPAMByoASN_GetAll(t *testing.T) {
t.Parallel()

Expand All @@ -39,7 +38,7 @@ func TestIPAMByoASN_GetAll(t *testing.T) {
ipam := EC2IPAMByoasn{
Client: mockedIPAMByoASN{
DescribeIpamByoasnOutput: ec2.DescribeIpamByoasnOutput{
Byoasns: []*ec2.Byoasn{
Byoasns: []types.Byoasn{
{
Asn: aws.String(testId1),
IpamId: aws.String(testName1),
Expand Down Expand Up @@ -68,7 +67,7 @@ func TestIPAMByoASN_GetAll(t *testing.T) {
EC2IPAM: tc.configObj,
})
require.NoError(t, err)
require.Equal(t, tc.expected, awsgo.StringValueSlice(ids))
require.Equal(t, tc.expected, aws.ToStringSlice(ids))
})
}
}
Expand Down
Loading

0 comments on commit 174aedb

Please sign in to comment.