Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Eip #545

Merged
merged 2 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
}
if IsNukeable(eipAddresses.ResourceName(), resourceTypes) {
start := time.Now()
allocationIds, err := getAllEIPAddresses(cloudNukeSession, region, excludeAfter, configObj)
allocationIds, err := eipAddresses.getAll(configObj)
if err != nil {
ge := report.GeneralError{
Error: err,
Expand Down
67 changes: 26 additions & 41 deletions aws/eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ package aws

import (
"github.com/gruntwork-io/cloud-nuke/telemetry"
"github.com/gruntwork-io/cloud-nuke/util"
commonTelemetry "github.com/gruntwork-io/go-commons/telemetry"
"time"

"github.com/aws/aws-sdk-go/aws"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"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/go-commons/errors"
)

func setFirstSeenTag(svc *ec2.EC2, address ec2.Address, key string, value time.Time, layout string) error {
func (ea EIPAddresses) setFirstSeenTag(address ec2.Address, value time.Time) error {
// We set a first seen tag because an Elastic IP doesn't contain an attribute that gives us it's creation time
_, err := svc.CreateTags(&ec2.CreateTagsInput{
_, err := ea.Client.CreateTags(&ec2.CreateTagsInput{
Resources: []*string{address.AllocationId},
Tags: []*ec2.Tag{
{
Key: awsgo.String(key),
Value: awsgo.String(value.Format(layout)),
Key: awsgo.String(util.FirstSeenTagKey),
Value: awsgo.String(util.FormatTimestampTag(value)),
},
},
})
Expand All @@ -34,92 +34,77 @@ func setFirstSeenTag(svc *ec2.EC2, address ec2.Address, key string, value time.T
return nil
}

func getFirstSeenTag(svc *ec2.EC2, address ec2.Address, key string, layout string) (*time.Time, error) {
func (ea EIPAddresses) getFirstSeenTag(address ec2.Address) (*time.Time, error) {
tags := address.Tags
for _, tag := range tags {
if *tag.Key == key {
firstSeenTime, err := time.Parse(layout, *tag.Value)
if util.IsFirstSeenTag(tag.Key) {
firstSeenTime, err := util.ParseTimestampTag(tag.Value)
if err != nil {
return nil, errors.WithStackTrace(err)
}

return &firstSeenTime, nil
return firstSeenTime, nil
}
}

return nil, nil
}

// Returns a formatted string of EIP allocation ids
func getAllEIPAddresses(session *session.Session, region string, excludeAfter time.Time, configObj config.Config) ([]*string, error) {
svc := ec2.New(session)
const layout = "2006-01-02 15:04:05"

result, err := svc.DescribeAddresses(&ec2.DescribeAddressesInput{})
func (ea EIPAddresses) getAll(configObj config.Config) ([]*string, error) {
result, err := ea.Client.DescribeAddresses(&ec2.DescribeAddressesInput{})
if err != nil {
return nil, errors.WithStackTrace(err)
}

var allocationIds []*string
for _, address := range result.Addresses {
firstSeenTime, err := getFirstSeenTag(svc, *address, firstSeenTagKey, layout)
firstSeenTime, err := ea.getFirstSeenTag(*address)
if err != nil {
return nil, errors.WithStackTrace(err)
}

if firstSeenTime == nil {
now := time.Now().UTC()
firstSeenTime = &now
if err := setFirstSeenTag(svc, *address, firstSeenTagKey, *firstSeenTime, layout); err != nil {
if err := ea.setFirstSeenTag(*address, *firstSeenTime); err != nil {
return nil, err
}
}
if shouldIncludeAllocationId(address, excludeAfter, *firstSeenTime, configObj) {
if ea.shouldInclude(address, *firstSeenTime, configObj) {
allocationIds = append(allocationIds, address.AllocationId)
}
}

return allocationIds, nil
}

func shouldIncludeAllocationId(address *ec2.Address, excludeAfter time.Time, firstSeenTime time.Time, configObj config.Config) bool {
if address == nil {
return false
}

if excludeAfter.Before(firstSeenTime) {
return false
}

func (ea EIPAddresses) shouldInclude(address *ec2.Address, firstSeenTime time.Time, configObj config.Config) bool {
// If Name is unset, GetEC2ResourceNameTagValue returns error and zero value string
// Ignore this error and pass empty string to config.ShouldInclude
allocationName := GetEC2ResourceNameTagValue(address.Tags)

return config.ShouldInclude(
*allocationName,
configObj.ElasticIP.IncludeRule.NamesRegExp,
configObj.ElasticIP.ExcludeRule.NamesRegExp,
)
return configObj.ElasticIP.ShouldInclude(config.ResourceValue{
Time: &firstSeenTime,
Name: allocationName,
})
}

// Deletes all EIP allocation ids
func nukeAllEIPAddresses(session *session.Session, allocationIds []*string) error {
svc := ec2.New(session)

func (ea EIPAddresses) nukeAll(allocationIds []*string) error {
if len(allocationIds) == 0 {
logging.Logger.Debugf("No Elastic IPs to nuke in region %s", *session.Config.Region)
logging.Logger.Debugf("No Elastic IPs to nuke in region %s", ea.Region)
return nil
}

logging.Logger.Debugf("Deleting all Elastic IPs in region %s", *session.Config.Region)
logging.Logger.Debugf("Deleting all Elastic IPs in region %s", ea.Region)
var deletedAllocationIDs []*string

for _, allocationID := range allocationIds {
params := &ec2.ReleaseAddressInput{
AllocationId: allocationID,
}

_, err := svc.ReleaseAddress(params)
_, err := ea.Client.ReleaseAddress(params)

// Record status of this resource
e := report.Entry{
Expand All @@ -136,15 +121,15 @@ func nukeAllEIPAddresses(session *session.Session, allocationIds []*string) erro
telemetry.TrackEvent(commonTelemetry.EventContext{
EventName: "Error Nuking EIP",
}, map[string]interface{}{
"region": *session.Config.Region,
"region": ea.Region,
"reason": "Still Attached to an Active Resource",
})
} else {
logging.Logger.Debugf("[Failed] %s", err)
telemetry.TrackEvent(commonTelemetry.EventContext{
EventName: "Error Nuking EIP",
}, map[string]interface{}{
"region": *session.Config.Region,
"region": ea.Region,
})
}
} else {
Expand All @@ -153,6 +138,6 @@ func nukeAllEIPAddresses(session *session.Session, allocationIds []*string) erro
}
}

logging.Logger.Debugf("[OK] %d Elastic IP(s) deleted in %s", len(deletedAllocationIDs), *session.Config.Region)
logging.Logger.Debugf("[OK] %d Elastic IP(s) deleted in %s", len(deletedAllocationIDs), ea.Region)
return nil
}
Loading