Skip to content

Commit f3dbc85

Browse files
committed
Merge branch 'main' into oreilly-main
2 parents cfa9c9e + 1ebde32 commit f3dbc85

15 files changed

+393
-64
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,10 +612,10 @@ The easiest way of installing it, is to download the latest
612612
#### Example for Linux Intel/AMD
613613

614614
Download and extract
615-
`$ wget -c https://github.com/rebuy-de/aws-nuke/releases/download/v2.22.1/aws-nuke-v2.22.1-linux-amd64.tar.gz -O - | tar -xz -C $HOME/bin`
615+
`$ wget -c https://github.com/rebuy-de/aws-nuke/releases/download/v2.23.0/aws-nuke-v2.23.0-linux-amd64.tar.gz -O - | tar -xz -C $HOME/bin`
616616

617617
Run
618-
`$ aws-nuke-v2.22.1-linux-amd64`
618+
`$ aws-nuke-v2.23.0-linux-amd64`
619619

620620
### Compile from Source
621621

@@ -639,7 +639,7 @@ $ docker run \
639639
--rm -it \
640640
-v /full-path/to/nuke-config.yml:/home/aws-nuke/config.yml \
641641
-v /home/user/.aws:/home/aws-nuke/.aws \
642-
quay.io/rebuy/aws-nuke:v2.22.1 \
642+
quay.io/rebuy/aws-nuke:v2.23.0 \
643643
--profile default \
644644
--config /home/aws-nuke/config.yml
645645
```

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ module github.com/rebuy-de/aws-nuke/v2
33
go 1.19
44

55
require (
6-
github.com/aws/aws-sdk-go v1.44.251
6+
github.com/aws/aws-sdk-go v1.44.295
77
github.com/fatih/color v1.15.0
88
github.com/golang/mock v1.6.0
99
github.com/google/uuid v1.3.0
1010
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4
1111
github.com/pkg/errors v0.9.1
1212
github.com/rebuy-de/rebuy-go-sdk/v4 v4.5.1
13-
github.com/sirupsen/logrus v1.9.0
13+
github.com/sirupsen/logrus v1.9.3
1414
github.com/spf13/cobra v1.7.0
15-
github.com/stretchr/testify v1.8.2
16-
golang.org/x/sync v0.1.0
15+
github.com/stretchr/testify v1.8.4
16+
golang.org/x/sync v0.3.0
1717
gopkg.in/yaml.v3 v3.0.1
1818
)
1919

go.sum

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/aws/aws-sdk-go v1.44.251 h1:unCIT7a/BkYvJ/43D0Ts/0aRbWDMQM0SUzBtdsKPwCg=
2-
github.com/aws/aws-sdk-go v1.44.251/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
1+
github.com/aws/aws-sdk-go v1.44.295 h1:SGjU1+MqttXfRiWHD6WU0DRhaanJgAFY+xIhEaugV8Y=
2+
github.com/aws/aws-sdk-go v1.44.295/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
33
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
44
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
55
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -42,22 +42,18 @@ github.com/rebuy-de/rebuy-go-sdk/v4 v4.5.1 h1:7QWjC0uku9pIqTXS664clCMjqhZLjO/sUV
4242
github.com/rebuy-de/rebuy-go-sdk/v4 v4.5.1/go.mod h1:ZSfnIcE8RFKz7IO6AFZjETDbPyMdUjtxCea9R7Q6pQE=
4343
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
4444
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
45-
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
46-
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
45+
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
46+
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
4747
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
4848
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
4949
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
5050
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
5151
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5252
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
53-
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
54-
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
5553
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
5654
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
57-
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
58-
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
59-
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
60-
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
55+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
56+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
6157
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
6258
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
6359
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -78,8 +74,8 @@ golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
7874
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7975
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8076
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
81-
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
82-
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
77+
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
78+
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
8379
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8480
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8581
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pkg/config/config.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ type Nuke struct {
3737
}
3838

3939
type FeatureFlags struct {
40-
DisableDeletionProtection DisableDeletionProtection `yaml:"disable-deletion-protection"`
41-
ForceDeleteLightsailAddOns bool `yaml:"force-delete-lightsail-addons"`
40+
DisableDeletionProtection DisableDeletionProtection `yaml:"disable-deletion-protection"`
41+
DisableEC2InstanceStopProtection bool `yaml:"disable-ec2-instance-stop-protection"`
42+
ForceDeleteLightsailAddOns bool `yaml:"force-delete-lightsail-addons"`
4243
}
4344

4445
type DisableDeletionProtection struct {

resources/cloudcontrol.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ func init() {
2626
registerCloudControl("AWS::AppRunner::Service")
2727
registerCloudControl("AWS::ApplicationInsights::Application")
2828
registerCloudControl("AWS::Backup::Framework")
29+
registerCloudControl("AWS::ECR::PublicRepository")
30+
registerCloudControl("AWS::ECR::PullThroughCacheRule")
31+
registerCloudControl("AWS::ECR::RegistryPolicy")
32+
registerCloudControl("AWS::ECR::ReplicationConfiguration")
2933
registerCloudControl("AWS::MWAA::Environment")
3034
registerCloudControl("AWS::Synthetics::Canary")
3135
registerCloudControl("AWS::Timestream::Database")

resources/cloudfront-function.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package resources
2+
3+
import (
4+
"github.com/aws/aws-sdk-go/aws/session"
5+
"github.com/aws/aws-sdk-go/service/cloudfront"
6+
"github.com/rebuy-de/aws-nuke/v2/pkg/types"
7+
)
8+
9+
type CloudFrontFunction struct {
10+
svc *cloudfront.CloudFront
11+
name *string
12+
stage *string
13+
}
14+
15+
func init() {
16+
register("CloudFrontFunction", ListCloudFrontFunctions)
17+
}
18+
19+
func ListCloudFrontFunctions(sess *session.Session) ([]Resource, error) {
20+
svc := cloudfront.New(sess)
21+
resources := []Resource{}
22+
params := &cloudfront.ListFunctionsInput{}
23+
24+
for {
25+
resp, err := svc.ListFunctions(params)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
for _, item := range resp.FunctionList.Items {
31+
resources = append(resources, &CloudFrontFunction{
32+
svc: svc,
33+
name: item.Name,
34+
stage: item.FunctionMetadata.Stage,
35+
})
36+
}
37+
38+
if resp.FunctionList.NextMarker == nil {
39+
break
40+
}
41+
42+
params.Marker = resp.FunctionList.NextMarker
43+
44+
}
45+
return resources, nil
46+
}
47+
48+
func (f *CloudFrontFunction) Remove() error {
49+
resp, err := f.svc.GetFunction(&cloudfront.GetFunctionInput{
50+
Name: f.name,
51+
Stage: f.stage,
52+
})
53+
if err != nil {
54+
return err
55+
}
56+
57+
_, err = f.svc.DeleteFunction(&cloudfront.DeleteFunctionInput{
58+
Name: f.name,
59+
IfMatch: resp.ETag,
60+
})
61+
62+
return err
63+
}
64+
65+
func (f *CloudFrontFunction) Properties() types.Properties {
66+
properties := types.NewProperties()
67+
properties.Set("name", f.name)
68+
properties.Set("stage", f.stage)
69+
return properties
70+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package resources
2+
3+
import (
4+
"github.com/aws/aws-sdk-go/aws/session"
5+
"github.com/aws/aws-sdk-go/service/cloudfront"
6+
"github.com/rebuy-de/aws-nuke/v2/pkg/types"
7+
)
8+
9+
type CloudFrontOriginAccessControl struct {
10+
svc *cloudfront.CloudFront
11+
ID *string
12+
}
13+
14+
func init() {
15+
register("CloudFrontOriginAccessControl", ListCloudFrontOriginAccessControls)
16+
}
17+
18+
func ListCloudFrontOriginAccessControls(sess *session.Session) ([]Resource, error) {
19+
svc := cloudfront.New(sess)
20+
resources := []Resource{}
21+
params := &cloudfront.ListOriginAccessControlsInput{}
22+
23+
for {
24+
resp, err := svc.ListOriginAccessControls(params)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
for _, item := range resp.OriginAccessControlList.Items {
30+
resources = append(resources, &CloudFrontOriginAccessControl{
31+
svc: svc,
32+
ID: item.Id,
33+
})
34+
}
35+
36+
if !*resp.OriginAccessControlList.IsTruncated {
37+
break
38+
}
39+
40+
params.Marker = resp.OriginAccessControlList.NextMarker
41+
}
42+
43+
return resources, nil
44+
}
45+
46+
func (f *CloudFrontOriginAccessControl) Remove() error {
47+
resp, err := f.svc.GetOriginAccessControl(&cloudfront.GetOriginAccessControlInput{
48+
Id: f.ID,
49+
})
50+
if err != nil {
51+
return err
52+
}
53+
54+
_, err = f.svc.DeleteOriginAccessControl(&cloudfront.DeleteOriginAccessControlInput{
55+
Id: f.ID,
56+
IfMatch: resp.ETag,
57+
})
58+
59+
return err
60+
}
61+
62+
func (f *CloudFrontOriginAccessControl) Properties() types.Properties {
63+
properties := types.NewProperties()
64+
properties.Set("ID", f.ID)
65+
return properties
66+
}

resources/ec2-instances.go

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,59 @@ func (i *EC2Instance) Remove() error {
7272

7373
_, err := i.svc.TerminateInstances(params)
7474
if err != nil {
75-
if i.featureFlags.DisableDeletionProtection.EC2Instance {
76-
awsErr, ok := err.(awserr.Error)
77-
if ok && awsErr.Code() == "OperationNotPermitted" &&
78-
awsErr.Message() == "The instance '"+*i.instance.InstanceId+"' may not be terminated. "+
79-
"Modify its 'disableApiTermination' instance attribute and try again." {
80-
err = i.DisableProtection()
81-
if err != nil {
82-
return err
83-
}
84-
_, err := i.svc.TerminateInstances(params)
85-
if err != nil {
86-
return err
87-
}
88-
return nil
75+
awsErr, ok := err.(awserr.Error)
76+
// Check for Termination Protection, disable it, and try termination again.
77+
if ok && awsErr.Code() == "OperationNotPermitted" &&
78+
awsErr.Message() == "The instance '"+*i.instance.InstanceId+"' may not be "+
79+
"terminated. Modify its 'disableApiTermination' instance attribute and "+
80+
"try again." && i.featureFlags.DisableDeletionProtection.EC2Instance {
81+
termErr := i.DisableTerminationProtection()
82+
if termErr != nil {
83+
return termErr
84+
}
85+
_, err = i.svc.TerminateInstances(params)
86+
// If we still get an error, we'll check for type and let the next routine
87+
// handle it.
88+
if err != nil {
89+
awsErr, ok = err.(awserr.Error)
8990
}
9091
}
92+
93+
// Check for Stop Protection, disable it, and try termination again.
94+
if ok && awsErr.Code() == "OperationNotPermitted" &&
95+
awsErr.Message() == "The instance '"+*i.instance.InstanceId+"' may not be "+
96+
"terminated. Modify its 'disableApiStop' instance attribute and try "+
97+
"again." && i.featureFlags.DisableEC2InstanceStopProtection {
98+
stopErr := i.DisableStopProtection()
99+
if stopErr != nil {
100+
return stopErr
101+
}
102+
_, err = i.svc.TerminateInstances(params)
103+
}
104+
105+
// If we still have an error at this point, we'll return it.
106+
if err != nil {
107+
return err
108+
}
109+
}
110+
return nil
111+
}
112+
113+
func (i *EC2Instance) DisableStopProtection() error {
114+
params := &ec2.ModifyInstanceAttributeInput{
115+
InstanceId: i.instance.InstanceId,
116+
DisableApiStop: &ec2.AttributeBooleanValue{
117+
Value: aws.Bool(false),
118+
},
119+
}
120+
_, err := i.svc.ModifyInstanceAttribute(params)
121+
if err != nil {
91122
return err
92123
}
93124
return nil
94125
}
95126

96-
func (i *EC2Instance) DisableProtection() error {
127+
func (i *EC2Instance) DisableTerminationProtection() error {
97128
params := &ec2.ModifyInstanceAttributeInput{
98129
InstanceId: i.instance.InstanceId,
99130
DisableApiTermination: &ec2.AttributeBooleanValue{

resources/ecr-repository.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ type ECRRepository struct {
1818
}
1919

2020
func init() {
21-
register("ECRRepository", ListECRRepositories)
21+
register("ECRRepository", ListECRRepositories,
22+
mapCloudControl("AWS::ECR::Repository"))
2223
}
2324

2425
func ListECRRepositories(sess *session.Session) ([]Resource, error) {

resources/iam-groups.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,23 @@ func init() {
1919

2020
func ListIAMGroups(sess *session.Session) ([]Resource, error) {
2121
svc := iam.New(sess)
22-
23-
resp, err := svc.ListGroups(nil)
22+
resources := []Resource{}
23+
24+
err := svc.ListGroupsPages(nil, func(page *iam.ListGroupsOutput, lastPage bool) bool {
25+
for _, out := range page.Groups {
26+
resources = append(resources, &IAMGroup{
27+
svc: svc,
28+
id: *out.GroupId,
29+
name: *out.GroupName,
30+
path: *out.Path,
31+
})
32+
}
33+
return true
34+
})
2435
if err != nil {
2536
return nil, err
2637
}
2738

28-
resources := make([]Resource, 0)
29-
for _, out := range resp.Groups {
30-
resources = append(resources, &IAMGroup{
31-
svc: svc,
32-
id: *out.GroupId,
33-
name: *out.GroupName,
34-
path: *out.Path,
35-
})
36-
}
37-
3839
return resources, nil
3940
}
4041

0 commit comments

Comments
 (0)