Skip to content

Commit

Permalink
sync fork with upstream main
Browse files Browse the repository at this point in the history
  • Loading branch information
ekristen committed Apr 25, 2022
2 parents 710458f + aa877db commit 7ec9486
Show file tree
Hide file tree
Showing 37 changed files with 573 additions and 91 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,51 @@ If an exclude is used, then all its resource types will not be deleted.
aws-nuke resource-types
```

### AWS Cloud Control API Support

> This feature is not yet released and is probably part of `v2.18`.
*aws-nuke* supports removing resources via the AWS Cloud Control API. When
executing *aws-nuke* it will automatically remove a manually managed set of
resources via Cloud Control.

Only a subset of Cloud Control supported resources will be removed
automatically, because there might be resources that were already implemented
and adding them too would bypass existing filters in user configs as Cloud
Control has another naming scheme and a different set of properties. Moreover,
there are some Cloud Control resources that need special handling which is not
yet supported by *aws-nuke*.

Even though the subset of automatically supported Cloud Control resources is
limited, you can can configure *aws-nuke* to make it try any additional
resource. Either via command line flags of via the config file.

For the config file you have to add the resource to
the`resource-types.cloud-control` list:

```yaml
resource-types:
cloud-control:
- AWS::EC2::TransitGateway
- AWS::EC2::VPC
```
If you want to use the command line, you have to add a `--cloud-control` flag
for each resource you want to add:

```sh
aws-nuke \
-c nuke-config.yaml \
--cloud-control AWS::EC2::TransitGateway \
--cloud-control AWS::EC2::VPC
```

**Note:** There are some resources that are supported by Cloud Control and are
already natively implemented by *aws-nuke*. If you configure to use Cloud
Control for those resources, it will not execute the natively implemented code
for this resource. For example with the `--cloud-control AWS::EC2::VPC` it will
not use the `EC2VPC` resource.

### Feature Flags

There are some features, which are quite opinionated. To make those work for
Expand Down
6 changes: 6 additions & 0 deletions cmd/nuke.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func (n *Nuke) Scan() error {

resourceTypes := ResolveResourceTypes(
resources.GetListerNames(),
resources.GetCloudControlMapping(),
[]types.Collection{
n.Parameters.Targets,
n.Config.ResourceTypes.Targets,
Expand All @@ -149,6 +150,11 @@ func (n *Nuke) Scan() error {
n.Config.ResourceTypes.Excludes,
accountConfig.ResourceTypes.Excludes,
},
[]types.Collection{
n.Parameters.CloudControl,
n.Config.ResourceTypes.CloudControl,
accountConfig.ResourceTypes.CloudControl,
},
)

queue := make(Queue, 0)
Expand Down
5 changes: 3 additions & 2 deletions cmd/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
type NukeParameters struct {
ConfigPath string

Targets []string
Excludes []string
Targets []string
Excludes []string
CloudControl []string

NoDryRun bool
Force bool
Expand Down
4 changes: 2 additions & 2 deletions cmd/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ func (i *Item) Print() {

// List gets all resource items of the same resource type like the Item.
func (i *Item) List() ([]resources.Resource, error) {
listers := resources.GetListers()
lister := resources.GetLister(i.Type)
sess, err := i.Region.Session(i.Type)
if err != nil {
return nil, err
}
return listers[i.Type](sess)
return lister(sess)
}

func (i *Item) GetProperty(key string) (string, error) {
Expand Down
6 changes: 6 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ func NewRootCommand() *cobra.Command {
&params.Excludes, "exclude", "e", []string{},
"Prevent nuking of certain resource types (eg IAMServerCertificate). "+
"This flag can be used multiple times.")
command.PersistentFlags().StringSliceVar(
&params.CloudControl, "cloud-control", []string{},
"Nuke given resource via Cloud Control API. "+
"If there is an old-style method for the same resource, the old-style one will not be executed. "+
"Note that old-style and cloud-control filters are not compatible! "+
"This flag can be used multiple times.")
command.PersistentFlags().BoolVar(
&params.NoDryRun, "no-dry-run", false,
"If specified, it actually deletes found resources. "+
Expand Down
18 changes: 17 additions & 1 deletion cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,23 @@ func Prompt(expect string) error {
return nil
}

func ResolveResourceTypes(base types.Collection, include, exclude []types.Collection) types.Collection {
func ResolveResourceTypes(
base types.Collection, mapping map[string]string,
include, exclude, cloudControl []types.Collection) types.Collection {

for _, cl := range cloudControl {
oldStyle := types.Collection{}
for _, c := range cl {
os, found := mapping[c]
if found {
oldStyle = append(oldStyle, os)
}
}

base = base.Union(cl)
base = base.Remove(oldStyle)
}

for _, i := range include {
if len(i) > 0 {
base = base.Intersect(i)
Expand Down
30 changes: 23 additions & 7 deletions cmd/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import (

func TestResolveResourceTypes(t *testing.T) {
cases := []struct {
base types.Collection
include []types.Collection
exclude []types.Collection
result types.Collection
name string
base types.Collection
mapping map[string]string
include []types.Collection
exclude []types.Collection
cloudControl []types.Collection
result types.Collection
}{
{
base: types.Collection{"a", "b", "c", "d"},
Expand Down Expand Up @@ -41,11 +44,24 @@ func TestResolveResourceTypes(t *testing.T) {
exclude: []types.Collection{{"a"}},
result: types.Collection{"b", "c"},
},
{
name: "CloudControlAdd",
base: types.Collection{"a", "b"},
cloudControl: []types.Collection{{"x"}},
result: types.Collection{"a", "b", "x"},
},
{
name: "CloudControlReplaceOldStyle",
base: types.Collection{"a", "b", "c"},
mapping: map[string]string{"z": "b"},
cloudControl: []types.Collection{{"z"}},
result: types.Collection{"a", "z", "c"},
},
}

for i, tc := range cases {
t.Run(fmt.Sprint(i), func(t *testing.T) {
r := ResolveResourceTypes(tc.base, tc.include, tc.exclude)
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
r := ResolveResourceTypes(tc.base, tc.mapping, tc.include, tc.exclude, tc.cloudControl)

sort.Strings(r)
sort.Strings(tc.result)
Expand Down
100 changes: 100 additions & 0 deletions dev/list-cloudcontrol/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package main

import (
"encoding/json"
"fmt"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/fatih/color"
"github.com/rebuy-de/aws-nuke/resources"
"github.com/rebuy-de/rebuy-go-sdk/v3/pkg/cmdutil"
"github.com/sirupsen/logrus"
)

type CFTypeSchema struct {
Handlers map[string]interface{} `json:"handlers"`
}

func main() {
ctx := cmdutil.SignalRootContext()

sess, err := session.NewSession(&aws.Config{
Region: aws.String(endpoints.UsEast1RegionID),
})
if err != nil {
logrus.Fatal(err)
}

cf := cloudformation.New(sess)

mapping := resources.GetCloudControlMapping()

in := &cloudformation.ListTypesInput{
Type: aws.String(cloudformation.RegistryTypeResource),
Visibility: aws.String(cloudformation.VisibilityPublic),
ProvisioningType: aws.String(cloudformation.ProvisioningTypeFullyMutable),
}

err = cf.ListTypesPagesWithContext(ctx, in, func(out *cloudformation.ListTypesOutput, _ bool) bool {
if out == nil {
return true
}

for _, summary := range out.TypeSummaries {
if summary == nil {
continue
}

typeName := aws.StringValue(summary.TypeName)
color.New(color.Bold).Printf("%-55s", typeName)
if !strings.HasPrefix(typeName, "AWS::") {
color.HiBlack("does not have a valid prefix")
continue
}

describe, err := cf.DescribeType(&cloudformation.DescribeTypeInput{
Type: aws.String(cloudformation.RegistryTypeResource),
TypeName: aws.String(typeName),
})
if err != nil {
color.New(color.FgRed).Println(err)
continue
}

var schema CFTypeSchema
err = json.Unmarshal([]byte(aws.StringValue(describe.Schema)), &schema)
if err != nil {
color.New(color.FgRed).Println(err)
continue
}

_, canList := schema.Handlers["list"]
if !canList {
color.New(color.FgHiBlack).Println("does not support list")
continue
}

resourceName, exists := mapping[typeName]
if exists && resourceName == typeName {
fmt.Print("is only covered by ")
color.New(color.FgGreen, color.Bold).Println(resourceName)
continue
} else if exists {
fmt.Print("is also covered by ")
color.New(color.FgBlue, color.Bold).Println(resourceName)
continue
}

color.New(color.FgYellow).Println("is not configured")
}

return true
})
if err != nil {
logrus.Fatal(err)
}
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/pkg/errors v0.9.1
github.com/rebuy-de/rebuy-go-sdk/v3 v3.11.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.3.0
github.com/stretchr/testify v1.7.0
Expand All @@ -25,6 +26,8 @@ require (

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gemnasium/logrus-graylog-hook/v3 v3.0.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
Expand All @@ -35,7 +38,7 @@ require (
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/mod v0.5.0 // indirect
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
golang.org/x/tools v0.1.5 // indirect
golang.org/x/tools v0.1.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
8 changes: 7 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/gemnasium/logrus-graylog-hook/v3 v3.0.3 h1:YQHp/LxUTeZhgnXKbJASRii315h+HWtPd5ctewP4Pms=
github.com/gemnasium/logrus-graylog-hook/v3 v3.0.3/go.mod h1:wi1zWv9tIvyLSMLCAzgRP+YR24oLVQVBHfPPKjtht44=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand Down Expand Up @@ -325,13 +327,16 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/rebuy-de/rebuy-go-sdk/v3 v3.11.0 h1:kjWGsRRl6x0dMjU8PQajgd5woDdCC7dW17B9+JGnBho=
github.com/rebuy-de/rebuy-go-sdk/v3 v3.11.0/go.mod h1:imLjgHMb9XZeZ2Cj6BEOdEuwkdUyOgDN4oBcSZthzro=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
Expand Down Expand Up @@ -628,8 +633,9 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
5 changes: 3 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
)

type ResourceTypes struct {
Targets types.Collection `yaml:"targets"`
Excludes types.Collection `yaml:"excludes"`
Targets types.Collection `yaml:"targets"`
Excludes types.Collection `yaml:"excludes"`
CloudControl types.Collection `yaml:"cloud-control"`
}

type Account struct {
Expand Down
Loading

0 comments on commit 7ec9486

Please sign in to comment.