Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit f9a3a63

Browse files
authored
Merge pull request #66 from rebuy-de/refactor-listers
Refactor resource listers
2 parents 07ca11d + 097be85 commit f9a3a63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+838
-504
lines changed

cmd/log.go

+12-7
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,27 @@ var (
1313
ReasonRemoveTriggered = *color.New(color.FgGreen)
1414
ReasonWaitPending = *color.New(color.FgBlue)
1515
ReasonSuccess = *color.New(color.FgGreen)
16-
ColorID = *color.New(color.Bold)
17-
Warning = *color.New(color.FgYellow)
1816
)
1917

20-
func Log(reg string, r resources.Resource, c color.Color, msg string) {
21-
ColorID.Printf("%s", reg)
18+
var (
19+
ColorRegion = *color.New(color.Bold)
20+
ColorResourceType = *color.New()
21+
ColorResourceID = *color.New(color.Bold)
22+
ColorWarning = *color.New(color.FgYellow)
23+
)
24+
25+
func Log(region Region, resourceType string, r resources.Resource, c color.Color, msg string) {
26+
ColorRegion.Printf("%s", region.Name)
2227
fmt.Printf(" - ")
23-
fmt.Print(resources.GetCategory(r))
28+
ColorResourceType.Print(resourceType)
2429
fmt.Printf(" - ")
25-
ColorID.Printf("'%s'", r.String())
30+
ColorResourceID.Printf("'%s'", r.String())
2631
fmt.Printf(" - ")
2732
c.Printf("%s\n", msg)
2833
}
2934

3035
func LogWarn(s string, i ...interface{}) {
31-
Warning.Printf("WARNING: "+s, i...)
36+
ColorWarning.Printf("WARNING: "+s, i...)
3237
}
3338

3439
func LogErrorf(err error) {

cmd/nuke.go

+13-8
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,20 @@ func (n *Nuke) Run() error {
108108
func (n *Nuke) Scan() error {
109109
queue := make(Queue, 0)
110110

111-
for _, region := range n.Config.Regions {
112-
sess, err := n.Account.Session(region)
111+
for _, regionName := range n.Config.Regions {
112+
sess, err := n.Account.Session(regionName)
113113
if err != nil {
114114
return err
115115
}
116116

117-
items := Scan(sess)
117+
region := Region{
118+
Name: regionName,
119+
Session: sess,
120+
}
121+
122+
items := Scan(region)
118123
for item := range items {
119-
if !n.Parameters.WantsTarget(item.Service) {
124+
if !n.Parameters.WantsTarget(item.Type) {
120125
continue
121126
}
122127

@@ -147,7 +152,7 @@ func (n *Nuke) Filter(item *Item) {
147152
}
148153
}
149154

150-
filters, ok := accountConfig.Filters[item.Service]
155+
filters, ok := accountConfig.Filters[item.Type]
151156
if !ok {
152157
return
153158
}
@@ -207,15 +212,15 @@ func (n *Nuke) HandleRemove(item *Item) {
207212
func (n *Nuke) HandleWait(item *Item, cache map[string][]resources.Resource) {
208213
var err error
209214

210-
left, ok := cache[item.Service]
215+
left, ok := cache[item.Type]
211216
if !ok {
212-
left, err = item.Lister()
217+
left, err = item.List()
213218
if err != nil {
214219
item.State = ItemStateFailed
215220
item.Reason = err.Error()
216221
return
217222
}
218-
cache[item.Service] = left
223+
cache[item.Type] = left
219224
}
220225

221226
for _, r := range left {

cmd/queue.go

+18-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import "github.com/rebuy-de/aws-nuke/resources"
44

55
type ItemState int
66

7+
// States of Items based on the latest request to AWS.
78
const (
89
ItemStateNew ItemState = iota
910
ItemStatePending
@@ -13,34 +14,41 @@ const (
1314
ItemStateFinished
1415
)
1516

17+
// An Item describes an actual AWS resource entity with the current state and
18+
// some metadata.
1619
type Item struct {
1720
Resource resources.Resource
1821

19-
Service string
20-
Lister resources.ResourceLister
21-
2222
State ItemState
23-
Region string
2423
Reason string
24+
25+
Region Region
26+
Type string
2527
}
2628

2729
func (i *Item) Print() {
2830
switch i.State {
2931
case ItemStateNew:
30-
Log(i.Region, i.Resource, ReasonWaitPending, "would remove")
32+
Log(i.Region, i.Type, i.Resource, ReasonWaitPending, "would remove")
3133
case ItemStatePending:
32-
Log(i.Region, i.Resource, ReasonWaitPending, "triggered remove")
34+
Log(i.Region, i.Type, i.Resource, ReasonWaitPending, "triggered remove")
3335
case ItemStateWaiting:
34-
Log(i.Region, i.Resource, ReasonWaitPending, "waiting")
36+
Log(i.Region, i.Type, i.Resource, ReasonWaitPending, "waiting")
3537
case ItemStateFailed:
36-
Log(i.Region, i.Resource, ReasonError, i.Reason)
38+
Log(i.Region, i.Type, i.Resource, ReasonError, i.Reason)
3739
case ItemStateFiltered:
38-
Log(i.Region, i.Resource, ReasonSkip, i.Reason)
40+
Log(i.Region, i.Type, i.Resource, ReasonSkip, i.Reason)
3941
case ItemStateFinished:
40-
Log(i.Region, i.Resource, ReasonSuccess, "removed")
42+
Log(i.Region, i.Type, i.Resource, ReasonSuccess, "removed")
4143
}
4244
}
4345

46+
// List gets all resource items of the same resource type like the Item.
47+
func (i *Item) List() ([]resources.Resource, error) {
48+
listers := resources.GetListers()
49+
return listers[i.Type](i.Region.Session)
50+
}
51+
4452
type Queue []*Item
4553

4654
func (q Queue) CountTotal() int {

cmd/region.go

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package cmd
2+
3+
import "github.com/aws/aws-sdk-go/aws/session"
4+
5+
type Region struct {
6+
Name string
7+
Session *session.Session
8+
}

cmd/root.go

+26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package cmd
22

33
import (
4+
"fmt"
5+
"sort"
6+
47
"github.com/rebuy-de/aws-nuke/pkg/awsutil"
8+
"github.com/rebuy-de/aws-nuke/resources"
59
"github.com/spf13/cobra"
610
)
711

@@ -70,6 +74,28 @@ func NewRootCommand() *cobra.Command {
7074
"don't ask for confirmation")
7175

7276
command.AddCommand(NewVersionCommand())
77+
command.AddCommand(NewResourceTypesCommand())
7378

7479
return command
7580
}
81+
82+
func NewResourceTypesCommand() *cobra.Command {
83+
cmd := &cobra.Command{
84+
Use: "resource-types",
85+
Short: "lists all available resource types",
86+
Run: func(cmd *cobra.Command, args []string) {
87+
types := []string{}
88+
for resourceType, _ := range resources.GetListers() {
89+
types = append(types, resourceType)
90+
}
91+
92+
sort.Strings(types)
93+
94+
for _, resourceType := range types {
95+
fmt.Println(resourceType)
96+
}
97+
},
98+
}
99+
100+
return cmd
101+
}

cmd/scan.go

+8-11
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import (
88
"github.com/rebuy-de/aws-nuke/resources"
99
)
1010

11-
func Scan(sess *session.Session) <-chan *Item {
11+
func Scan(region Region) <-chan *Item {
1212
items := make(chan *Item, 100)
1313

1414
go func() {
15-
listers := resources.GetListers(sess)
16-
17-
for _, lister := range listers {
18-
r, err := safeLister(lister)
15+
for resourceType, lister := range resources.GetListers() {
16+
rs, err := safeLister(region.Session, lister)
1917
if err != nil {
2018
LogErrorf(fmt.Errorf("\n=============\n\n"+
2119
"Listing with %T failed:\n\n"+
@@ -26,13 +24,12 @@ func Scan(sess *session.Session) <-chan *Item {
2624
continue
2725
}
2826

29-
for _, r := range r {
27+
for _, r := range rs {
3028
items <- &Item{
31-
Region: *sess.Config.Region,
29+
Region: region,
3230
Resource: r,
33-
Service: resources.GetCategory(r),
34-
Lister: lister,
3531
State: ItemStateNew,
32+
Type: resourceType,
3633
}
3734
}
3835
}
@@ -43,13 +40,13 @@ func Scan(sess *session.Session) <-chan *Item {
4340
return items
4441
}
4542

46-
func safeLister(lister resources.ResourceLister) (r []resources.Resource, err error) {
43+
func safeLister(sess *session.Session, lister resources.ResourceLister) (r []resources.Resource, err error) {
4744
defer func() {
4845
if r := recover(); r != nil {
4946
err = fmt.Errorf("%v\n\n%s", r.(error), string(debug.Stack()))
5047
}
5148
}()
5249

53-
r, err = lister()
50+
r, err = lister(sess)
5451
return
5552
}

cmd/scan_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@ import (
44
"strings"
55
"testing"
66

7+
"github.com/aws/aws-sdk-go/aws/session"
78
"github.com/rebuy-de/aws-nuke/resources"
89
)
910

1011
func TestSafeLister(t *testing.T) {
11-
nilLister := func() ([]resources.Resource, error) {
12+
nilLister := func(s *session.Session) ([]resources.Resource, error) {
13+
// generate nil pointer dereference panic
1214
var ptr *string
1315
_ = *ptr
1416

1517
return nil, nil
1618
}
1719

18-
_, err := safeLister(nilLister)
20+
_, err := safeLister(nil, nilLister)
1921
if !strings.Contains(err.Error(), "runtime error: invalid memory address or nil pointer dereference") {
2022
t.Fatalf("Got unexpected error: %v", err)
2123
}

resources/autoscaling-groups.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,27 @@ package resources
22

33
import (
44
"github.com/aws/aws-sdk-go/aws"
5+
"github.com/aws/aws-sdk-go/aws/session"
56
"github.com/aws/aws-sdk-go/service/autoscaling"
67
)
78

8-
func (n *AutoScalingNuke) ListGroups() ([]Resource, error) {
9+
func init() {
10+
register("AutoScalingGroup", ListAutoscalingGroups)
11+
}
12+
13+
func ListAutoscalingGroups(s *session.Session) ([]Resource, error) {
14+
svc := autoscaling.New(s)
15+
916
params := &autoscaling.DescribeAutoScalingGroupsInput{}
10-
resp, err := n.Service.DescribeAutoScalingGroups(params)
17+
resp, err := svc.DescribeAutoScalingGroups(params)
1118
if err != nil {
1219
return nil, err
1320
}
1421

1522
resources := make([]Resource, 0)
1623
for _, asg := range resp.AutoScalingGroups {
1724
resources = append(resources, &AutoScalingGroup{
18-
svc: n.Service,
25+
svc: svc,
1926
name: asg.AutoScalingGroupName,
2027
})
2128
}

resources/autoscaling-launchconfigurations.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
package resources
22

3-
import "github.com/aws/aws-sdk-go/service/autoscaling"
3+
import (
4+
"github.com/aws/aws-sdk-go/aws/session"
5+
"github.com/aws/aws-sdk-go/service/autoscaling"
6+
)
7+
8+
func init() {
9+
register("LaunchConfiguration", ListLaunchConfigurations)
10+
}
11+
12+
func ListLaunchConfigurations(s *session.Session) ([]Resource, error) {
13+
svc := autoscaling.New(s)
414

5-
func (n *AutoScalingNuke) ListLaunchConfigurations() ([]Resource, error) {
615
params := &autoscaling.DescribeLaunchConfigurationsInput{}
7-
resp, err := n.Service.DescribeLaunchConfigurations(params)
16+
resp, err := svc.DescribeLaunchConfigurations(params)
817
if err != nil {
918
return nil, err
1019
}
1120

1221
resources := make([]Resource, 0)
1322
for _, launchconfig := range resp.LaunchConfigurations {
1423
resources = append(resources, &LaunchConfiguration{
15-
svc: n.Service,
24+
svc: svc,
1625
name: launchconfig.LaunchConfigurationName,
1726
})
1827
}

resources/cloudformation-stack.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
package resources
22

3-
import "github.com/aws/aws-sdk-go/service/cloudformation"
3+
import (
4+
"github.com/aws/aws-sdk-go/aws/session"
5+
"github.com/aws/aws-sdk-go/service/cloudformation"
6+
)
47

5-
func (n *CloudFormationNuke) ListStacks() ([]Resource, error) {
6-
resp, err := n.Service.DescribeStacks(nil)
8+
func init() {
9+
register("CloudFormationStack", ListCloudFormationStacks)
10+
}
11+
12+
func ListCloudFormationStacks(sess *session.Session) ([]Resource, error) {
13+
svc := cloudformation.New(sess)
14+
15+
resp, err := svc.DescribeStacks(nil)
716
if err != nil {
817
return nil, err
918
}
1019

1120
resources := make([]Resource, 0)
1221
for _, stack := range resp.Stacks {
1322
resources = append(resources, &CloudFormationStack{
14-
svc: n.Service,
23+
svc: svc,
1524
name: stack.StackName,
1625
})
1726
}

resources/cloudtrail-trails.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package resources
22

3-
import "github.com/aws/aws-sdk-go/service/cloudtrail"
3+
import (
4+
"github.com/aws/aws-sdk-go/aws/session"
5+
"github.com/aws/aws-sdk-go/service/cloudtrail"
6+
)
47

5-
func (n *CloudTrailNuke) ListTrails() ([]Resource, error) {
6-
resp, err := n.Service.DescribeTrails(nil)
8+
func init() {
9+
register("CloudTrailTrail", ListCloudTrailTrails)
10+
}
11+
12+
func ListCloudTrailTrails(sess *session.Session) ([]Resource, error) {
13+
svc := cloudtrail.New(sess)
14+
15+
resp, err := svc.DescribeTrails(nil)
716
if err != nil {
817
return nil, err
918
}
1019
resources := make([]Resource, 0)
1120
for _, trail := range resp.TrailList {
1221
resources = append(resources, &CloudTrailTrail{
13-
svc: n.Service,
22+
svc: svc,
1423
name: trail.Name,
1524
})
1625

0 commit comments

Comments
 (0)