Skip to content

Commit

Permalink
Add config support for nuking NAT gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
yorinasub17 committed Jun 25, 2021
1 parent 1d8840c commit 21f3ef3
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 47 deletions.
10 changes: 10 additions & 0 deletions .circleci/nuke_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ SecretsManager:
- "^RDSDBConfig[a-zA-Z0-9]{6}$"
- "ECRDeployRunnerTestSSHKey-[a-zA-Z0-9]{6}$"
- "ECRDeployRunnerTestGitPAT-[a-zA-Z0-9]{6}$"

NatGateway:
# There is a bug in the cloud-nuke config where exclude does not work by itself, so we add a null include rule that
# includes everything.
include:
names_regex:
- ".*"
exclude:
names_regex:
- "^ecs-deploy-runner-v2-nat-gateway-0$"
52 changes: 13 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ The following resources support the Config file:
- Secrets Manager Secrets
- Resource type: `secretsmanager`
- Config key: `SecretsManager`
- NAT Gateways
- Resource type: `nat-gateway`
- Config key: `NATGateway`


#### Example
Expand Down Expand Up @@ -234,45 +237,16 @@ Be careful when nuking and append the `--dry-run` option if you're unsure. Even

To find out what we options are supported in the config file today, consult this table. Resource types at the top level of the file that are supported are listed here.

| resource type | support |
|----------------|---------|
| s3 | partial |
| iam | partial |
| secretsmanager | partial |
| ec2 instance | none |
| iam role | none |
| ... (more to come) | none |


##### s3 resource type:
_Note: the fields without `_regex` suffixes refer to support for plain-text matching against those fields._

| field | include | exclude |
|-------------|---------|---------|
| names | none | none |
| names_regex |||
| tags | none | none |
| tags_regex | none | none |

##### iam resource type:
_Note: the fields without `_regex` suffixes refer to support for plain-text matching against those fields._

| field | include | exclude |
|-------------|---------|---------|
| names | none | none |
| names_regex |||
| tags | none | none |
| tags_regex | none | none |

##### secretsmanager resource type:
_Note: the fields without `_regex` suffixes refer to support for plain-text matching against those fields._

| field | include | exclude |
|-------------|---------|---------|
| names | none | none |
| names_regex |||
| tags | none | none |
| tags_regex | none | none |
| resource type | names | names_regex | tags | tags_regex |
|--------------------|-------|-------------|------|------------|
| s3 | none || none | none |
| iam | none || none | none |
| secretsmanager | none || none | none |
| nat-gateway | none || none | none |
| ec2 instance | none | none | none | none |
| iam role | none | none | none | none |
| ... (more to come) | none | none | none | none |



### Log level
Expand Down
2 changes: 1 addition & 1 deletion aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func GetAllResources(targetRegions []string, excludeAfter time.Time, resourceTyp
// NATGateway
natGateways := NatGateways{}
if IsNukeable(natGateways.ResourceName(), resourceTypes) {
ngwIDs, err := getAllNatGateways(session, excludeAfter)
ngwIDs, err := getAllNatGateways(session, excludeAfter, configObj)
if err != nil {
return nil, errors.WithStackTrace(err)
}
Expand Down
23 changes: 19 additions & 4 deletions aws/nat_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
"github.com/gruntwork-io/go-commons/retry"
multierror "github.com/hashicorp/go-multierror"

"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/logging"
)

func getAllNatGateways(session *session.Session, excludeAfter time.Time) ([]*string, error) {
func getAllNatGateways(session *session.Session, excludeAfter time.Time, configObj config.Config) ([]*string, error) {
svc := ec2.New(session)

allNatGateways := []*string{}
Expand All @@ -24,7 +25,7 @@ func getAllNatGateways(session *session.Session, excludeAfter time.Time) ([]*str
input,
func(page *ec2.DescribeNatGatewaysOutput, lastPage bool) bool {
for _, ngw := range page.NatGateways {
if shouldIncludeNatGateway(ngw, excludeAfter) {
if shouldIncludeNatGateway(ngw, excludeAfter, configObj) {
allNatGateways = append(allNatGateways, ngw.NatGatewayId)
}
}
Expand All @@ -34,15 +35,29 @@ func getAllNatGateways(session *session.Session, excludeAfter time.Time) ([]*str
return allNatGateways, errors.WithStackTrace(err)
}

func shouldIncludeNatGateway(ngw *ec2.NatGateway, excludeAfter time.Time) bool {
func shouldIncludeNatGateway(ngw *ec2.NatGateway, excludeAfter time.Time, configObj config.Config) bool {
if ngw == nil {
return false
}

if ngw.CreateTime != nil && excludeAfter.Before(*ngw.CreateTime) {
return false
}
return true

return config.ShouldInclude(
getNatGatewayName(ngw),
configObj.NatGateway.IncludeRule.NamesRegExp,
configObj.NatGateway.ExcludeRule.NamesRegExp,
)
}

func getNatGatewayName(ngw *ec2.NatGateway) string {
for _, tag := range ngw.Tags {
if aws.StringValue(tag.Key) == "Name" {
return aws.StringValue(tag.Value)
}
}
return ""
}

func nukeAllNatGateways(session *session.Session, identifiers []*string) error {
Expand Down
7 changes: 4 additions & 3 deletions aws/nat_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"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/gruntwork-io/cloud-nuke/config"
terraws "github.com/gruntwork-io/terratest/modules/aws"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -25,7 +26,7 @@ func TestListNatGateways(t *testing.T) {
ngwID := createNatGateway(t, svc, region)
defer deleteNatGateway(t, svc, ngwID, true)

natGatewayIDs, err := getAllNatGateways(session, time.Now())
natGatewayIDs, err := getAllNatGateways(session, time.Now(), config.Config{})
require.NoError(t, err)
assert.Contains(t, aws.StringValueSlice(natGatewayIDs), aws.StringValue(ngwID))
}
Expand All @@ -45,13 +46,13 @@ func TestTimeFilterExclusionNewlyCreatedNatGateway(t *testing.T) {
defer deleteNatGateway(t, svc, ngwID, true)

// Assert NGW is picked up without filters
natGatewayIDsNewer, err := getAllNatGateways(session, time.Now())
natGatewayIDsNewer, err := getAllNatGateways(session, time.Now(), config.Config{})
require.NoError(t, err)
assert.Contains(t, aws.StringValueSlice(natGatewayIDsNewer), aws.StringValue(ngwID))

// Assert user doesn't appear when we look at users older than 1 Hour
olderThan := time.Now().Add(-1 * time.Hour)
natGatewayIDsOlder, err := getAllNatGateways(session, olderThan)
natGatewayIDsOlder, err := getAllNatGateways(session, olderThan, config.Config{})
require.NoError(t, err)
assert.NotContains(t, aws.StringValueSlice(natGatewayIDsOlder), aws.StringValue(ngwID))
}
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Config struct {
S3 ResourceType `yaml:"s3"`
IAMUsers ResourceType `yaml:"IAMUsers"`
SecretsManagerSecrets ResourceType `yaml:"SecretsManager"`
NatGateway ResourceType `yaml:"NatGateway"`
}

type ResourceType struct {
Expand Down

0 comments on commit 21f3ef3

Please sign in to comment.