Skip to content

Commit b54dea6

Browse files
committed
bug fixes, codeclimate, and featureflags (#32)
* chore(codeclimate): disable return-statements * [email protected] to fix scanner registration, add dependency for snapshot, add feature-flag support * docs: add cli documentation, improve filtering docs around dateOlderThan
1 parent bd40150 commit b54dea6

File tree

11 files changed

+202
-14
lines changed

11 files changed

+202
-14
lines changed

.codeclimate.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
checks:
2+
return-statements:
3+
enabled: false
14
plugins:
25
duplication:
36
enabled: true

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ jobs:
2222
go mod download
2323
- name: run go tests
2424
run: |
25-
go test -timeout 60s -race -coverprofile=coverage.txt -covermode=atomic ./...
25+
go test -timeout 60s -race -coverprofile=coverage.txt -covermode=atomic ./...

docs/cli-feature-flags.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Feature Flags
2+
3+
## Overview
4+
5+
These are the feature flags that are currently available in aws-nuke. They are all disabled by default. These are
6+
switches that changes the actual behavior of the tool itself. Changing the behavior of a resource is done via resource
7+
settings.
8+
9+
!!! note
10+
The original tool had configuration options called `feature-flags` which were used to enable/disable certain
11+
behaviors with resources, those are now called settings and `feature-flags` have been deprecated in the config.
12+
13+
## Usage
14+
15+
```console
16+
aws-nuke run --feature-flag "wait-on-dependencies"
17+
```
18+
19+
**Note:** other CLI arguments are omitted for brevity.
20+
21+
## Available Feature Flags
22+
23+
- `wait-on-dependencies` - This feature flag will cause aws-nuke to wait for all resource type dependencies to be
24+
deleted before deleting the next resource type.
25+
26+
### wait-on-dependencies
27+
28+
This feature flag will cause aws-nuke to wait for all resource type dependencies to be deleted before deleting the next
29+
resource type. This is useful for resources that have dependencies on other resources. For example, an IAM Role that has
30+
an attached policy.
31+
32+
The problem is that if you delete the IAM Role first, it will fail because it has a dependency on the policy.
33+
34+
This feature flag will cause aws-nuke to wait for all resources of a given type to be deleted before deleting the next
35+
resource type. This will reduce the number of errors and unnecessary API calls.

docs/cli-usage.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Usage
2+
3+
## aws-nuke
4+
5+
```console
6+
NAME:
7+
aws-nuke - remove everything from an aws account
8+
9+
USAGE:
10+
aws-nuke [global options] command [command options]
11+
12+
VERSION:
13+
3.0.0-beta.2
14+
15+
AUTHOR:
16+
Erik Kristensen <[email protected]>
17+
18+
COMMANDS:
19+
run, nuke run nuke against an aws account and remove everything from it
20+
resource-types, list-resources list available resources to nuke
21+
help, h Shows a list of commands or help for one command
22+
23+
GLOBAL OPTIONS:
24+
--help, -h show help
25+
--version, -v print the version
26+
```
27+
28+
## aws-nuke run
29+
30+
```console
31+
NAME:
32+
aws-nuke run - run nuke against an aws account and remove everything from it
33+
34+
USAGE:
35+
aws-nuke run [command options] [arguments...]
36+
37+
OPTIONS:
38+
--config value path to config file (default: "config.yaml")
39+
--force disable prompting for verification to run (default: false)
40+
--force-sleep value seconds to sleep (default: 10)
41+
--quiet hide filtered messages (default: false)
42+
--no-dry-run actually run the removal of the resources after discovery (default: false)
43+
--only-resource value, --target value, --include value, --include-resource value [ --only-resource value, --target value, --include value, --include-resource value ] only run against these resource types
44+
--exclude-resource value, --exclude value [ --exclude-resource value, --exclude value ] exclude these resource types
45+
--cloud-control value [ --cloud-control value ] use these resource types with the Cloud Control API instead of the default
46+
--feature-flag value [ --feature-flag value ] enable experimental behaviors that may not be fully tested or supported
47+
--log-level value, -l value Log Level (default: "info") [$LOGLEVEL]
48+
--log-caller log the caller (aka line number and file) (default: false)
49+
--log-disable-color disable log coloring (default: false)
50+
--log-full-timestamp force log output to always show full timestamp (default: false)
51+
--help, -h show help
52+
```

docs/config-filtering.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,32 @@ IAMUser:
7373

7474
### DateOlderThan
7575

76-
The identifier is parsed as a timestamp. After the offset is added to it (specified in the `value` field), the resulting
77-
timestamp must be AFTER the current time. Details on offset syntax can be found in the [library documentation](https://golang.org/pkg/time/#ParseDuration).
78-
Supported date formats are epoch time:
76+
This works by parsing the specified property into a timestamp and comparing it to the current time minus the specified
77+
duration. The duration is specified in the `value` field. The duration syntax is based on golang's duration syntax.
78+
79+
> ParseDuration parses a duration string. A duration string is a possibly signed sequence of decimal numbers, each with
80+
> optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"),
81+
> "ms", "s", "m", "h".
82+
83+
Full details on duration syntax can be found in the [time library documentation](https://golang.org/pkg/time/#ParseDuration).
84+
85+
The value from the property is parsed as a timestamp and the following are the supported formats:
7986

8087
- `2006-01-02`
8188
- `2006/01/02`
8289
- `2006-01-02T15:04:05Z`
8390
- `2006-01-02T15:04:05.999999999Z07:00`
8491
- `2006-01-02T15:04:05Z07:00`
8592

93+
In the follow example we are filtering EC2 Images that have a `CreationDate` older than 1 hour.
94+
95+
```yaml
96+
EC2Image:
97+
- type: dateOlderThan
98+
property: CreationDate
99+
value: 1h
100+
```
101+
86102
## Properties
87103

88104
By default, when writing a filter if you do not specify a property, it will use the `Name` property. However, resources

docs/resources.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ The anatomy of a resource is fairly simple, it's broken down into a few parts:
1313
- `Resource` - This is the base resource type that is used to define the resource.
1414
- `Lister` - This is the type that is used to list the resources.
1515

16+
### Resource
17+
1618
The resource must have the `func Remove() error` method defined on it, this is what is used to remove the resource.
1719

1820
It can optionally have the following methods defined:
@@ -21,6 +23,70 @@ It can optionally have the following methods defined:
2123
- `func String() string` - This is used to print the resource in a human-readable format.
2224
- `func Properties() types.Properties` - This is used to print the resource in a human-readable format.
2325

26+
```go
27+
package resources
28+
29+
import (
30+
"context"
31+
32+
"github.com/ekristen/libnuke/pkg/resource"
33+
"github.com/ekristen/libnuke/pkg/types"
34+
35+
"github.com/ekristen/aws-nuke/pkg/nuke"
36+
)
37+
38+
type ExampleResource struct {
39+
ID *string
40+
}
41+
42+
func (r *ExampleResource) Remove(_ context.Context) error {
43+
// remove the resource, an error will put the resource in failed state
44+
// resources in failed state are retried a number of times
45+
return nil
46+
}
47+
48+
func (r *ExampleResource) Filter() error {
49+
// filter the resource, this is useful for built-in resources that cannot
50+
// be removed, like an AWS managed resource, return an error here to filter
51+
// it before it even gets to the user supplied filters.
52+
return nil
53+
}
54+
55+
func (r *ExampleResource) String() string {
56+
// return a string representation of the resource, this is legacy, but still
57+
// used for a number of reasons.
58+
return *r.ID
59+
}
60+
```
61+
62+
## Lister
63+
64+
The lister must have the `func List(ctx context.Context, o interface{}) ([]resource.Resource, error)` method defined on it.
65+
66+
```go
67+
package resources
68+
69+
import (
70+
"context"
71+
72+
"github.com/ekristen/libnuke/pkg/resource"
73+
74+
"github.com/ekristen/aws-nuke/pkg/nuke"
75+
)
76+
77+
type ExampleResourceLister struct{}
78+
79+
func (l *ExampleResourceLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
80+
opts := o.(*nuke.ListerOpts)
81+
82+
var resources []resource.Resource
83+
84+
// list the resources and add to resources slice
85+
86+
return resources, nil
87+
}
88+
```
89+
2490
### Example
2591

2692
```go

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.21.6
44

55
require (
66
github.com/aws/aws-sdk-go v1.49.21
7-
github.com/ekristen/libnuke v0.0.0-20240122232527-922a9af6ba13
7+
github.com/ekristen/libnuke v0.0.0-20240123221700-d8899f33f580
88
github.com/fatih/color v1.16.0
99
github.com/golang/mock v1.6.0
1010
github.com/google/uuid v1.5.0
@@ -24,7 +24,6 @@ require (
2424
github.com/mattn/go-colorable v0.1.13 // indirect
2525
github.com/mattn/go-isatty v0.0.20 // indirect
2626
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect
27-
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
2827
github.com/pmezard/go-difflib v1.0.0 // indirect
2928
github.com/russross/blackfriday/v2 v2.1.0 // indirect
3029
github.com/stevenle/topsort v0.2.0 // indirect

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
66
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
77
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
88
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9-
github.com/ekristen/libnuke v0.0.0-20240122232527-922a9af6ba13 h1:d8d42BTmJkuO+cS8c+xitkNFC0ik9xAbqbZ+pJ76j3M=
10-
github.com/ekristen/libnuke v0.0.0-20240122232527-922a9af6ba13/go.mod h1:GgNcRFHihQza4zWLoun9hEXzVfGTk+nKTwCwo6xAyDg=
9+
github.com/ekristen/libnuke v0.0.0-20240123221700-d8899f33f580 h1:7F4+KkJLtwDC5STusCTGIcnIjBmOOP7mUOpCzS2KoCU=
10+
github.com/ekristen/libnuke v0.0.0-20240123221700-d8899f33f580/go.mod h1:BqHpyOLHEgCwAi82WbM+1fjGRgdDDG4a8W4ivjfHMP8=
1111
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
1212
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
1313
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
@@ -34,8 +34,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
3434
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
3535
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk=
3636
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY=
37-
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
38-
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
3937
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
4038
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
4139
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

mkdocs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ nav:
7070
- Install: installation.md
7171
- Authentication: auth.md
7272
- Quick Start: quick-start.md
73+
- CLI:
74+
- Usage: cli-usage.md
75+
- Feature Flags: cli-feature-flags.md
7376
- Config:
7477
- Overview: config.md
7578
- Filtering: config-filtering.md

pkg/commands/nuke/command.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"slices"
78

89
"github.com/sirupsen/logrus"
910
"github.com/urfave/cli/v2"
@@ -52,6 +53,12 @@ func execute(c *cli.Context) error {
5253
Alternatives: c.StringSlice("cloud-control"),
5354
}
5455

56+
if len(c.StringSlice("feature-flag")) > 0 {
57+
if slices.Contains(c.StringSlice("feature-flag"), "wait-on-dependencies") {
58+
params.WaitOnDependencies = true
59+
}
60+
}
61+
5562
// Parse the user supplied configuration file to pass in part to configure the nuke process.
5663
parsedConfig, err := config.New(libconfig.Options{
5764
Path: c.Path("config"),
@@ -94,6 +101,8 @@ func execute(c *cli.Context) error {
94101
// Instantiate libnuke
95102
n := libnuke.New(params, filters, parsedConfig.Settings)
96103

104+
n.RegisterVersion(common.AppVersion.Summary)
105+
97106
// Register our custom validate handler that validates the account and AWS nuke unique alias checks
98107
n.RegisterValidateHandler(func() error {
99108
return parsedConfig.ValidateAccount(account.ID(), account.Aliases())
@@ -112,8 +121,8 @@ func execute(c *cli.Context) error {
112121
resource.GetNames(),
113122
[]types.Collection{
114123
n.Parameters.Includes,
115-
parsedConfig.ResourceTypes.Targets,
116-
accountConfig.ResourceTypes.Targets,
124+
parsedConfig.ResourceTypes.GetIncludes(),
125+
accountConfig.ResourceTypes.GetIncludes(),
117126
},
118127
[]types.Collection{
119128
n.Parameters.Excludes,
@@ -122,8 +131,8 @@ func execute(c *cli.Context) error {
122131
},
123132
[]types.Collection{
124133
n.Parameters.Alternatives,
125-
parsedConfig.ResourceTypes.CloudControl,
126-
accountConfig.ResourceTypes.CloudControl,
134+
parsedConfig.ResourceTypes.GetAlternatives(),
135+
accountConfig.ResourceTypes.GetAlternatives(),
127136
},
128137
resource.GetAlternativeResourceTypeMapping(),
129138
)
@@ -194,6 +203,10 @@ func init() {
194203
Name: "cloud-control",
195204
Usage: "use these resource types with the Cloud Control API instead of the default",
196205
},
206+
&cli.StringSliceFlag{
207+
Name: "feature-flag",
208+
Usage: "enable experimental behaviors that may not be fully tested or supported",
209+
},
197210
}
198211

199212
cmd := &cli.Command{

0 commit comments

Comments
 (0)