/
leftovers.go
123 lines (100 loc) · 3.44 KB
/
leftovers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package azure
import (
"errors"
"fmt"
"github.com/Azure/azure-sdk-for-go/arm/resources/resources"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/adal"
azurelib "github.com/Azure/go-autorest/autorest/azure"
"github.com/fatih/color"
"github.com/genevieve/leftovers/common"
multierror "github.com/hashicorp/go-multierror"
)
type resource interface {
List(filter string) ([]common.Deletable, error)
Type() string
}
type Leftovers struct {
logger logger
resource resource
}
// List will print all of the resources that match the provided filter.
func (l Leftovers) List(filter string) {
l.logger.NoConfirm()
list, err := l.resource.List(filter)
if err != nil {
l.logger.Println(color.YellowString(err.Error()))
}
for _, r := range list {
l.logger.Println(fmt.Sprintf("[%s: %s]", r.Type(), r.Name()))
}
}
// Types will print all the resource types that can
// be deleted on this IaaS.
func (l Leftovers) Types() {
l.logger.Println(l.resource.Type())
}
// Delete will collect all resources that contain
// the provided filter in the resource's identifier, prompt
// you to confirm deletion (if enabled), and delete those
// that are selected.
func (l Leftovers) Delete(filter string) error {
var (
deletables []common.Deletable
result *multierror.Error
)
deletables, err := l.resource.List(filter)
if err != nil {
l.logger.Println(color.YellowString(err.Error()))
}
for _, d := range deletables {
l.logger.Println(fmt.Sprintf("[%s: %s] Deleting...", d.Type(), d.Name()))
err := d.Delete()
if err != nil {
err = fmt.Errorf("[%s: %s] %s", d.Type(), d.Name(), color.YellowString(err.Error()))
result = multierror.Append(result, err)
l.logger.Println(err.Error())
} else {
l.logger.Println(fmt.Sprintf("[%s: %s] %s", d.Type(), d.Name(), color.GreenString("Deleted!")))
}
}
return result.ErrorOrNil()
}
// DeleteType will collect all resources of the provied type that contain
// the provided filter in the resource's identifier, prompt
// you to confirm deletion (if enabled), and delete those
// that are selected.
func (l Leftovers) DeleteType(filter, rType string) error {
return l.Delete(filter)
}
// NewLeftovers returns a new Leftovers for Azure that can be used to list resources,
// list types, or delete resources for the provided account. It returns an error
// if the credentials provided are invalid.
func NewLeftovers(logger logger, clientId, clientSecret, subscriptionId, tenantId string) (Leftovers, error) {
if clientId == "" {
return Leftovers{}, errors.New("Missing client id.")
}
if clientSecret == "" {
return Leftovers{}, errors.New("Missing client secret.")
}
if subscriptionId == "" {
return Leftovers{}, errors.New("Missing subscription id.")
}
if tenantId == "" {
return Leftovers{}, errors.New("Missing tenant id.")
}
oauthConfig, err := adal.NewOAuthConfig(azurelib.PublicCloud.ActiveDirectoryEndpoint, tenantId)
if err != nil {
return Leftovers{}, fmt.Errorf("Creating oauth config: %s\n", err)
}
servicePrincipalToken, err := adal.NewServicePrincipalToken(*oauthConfig, clientId, clientSecret, azurelib.PublicCloud.ResourceManagerEndpoint)
if err != nil {
return Leftovers{}, fmt.Errorf("Creating service principal token: %s\n", err)
}
gc := resources.NewGroupsClient(subscriptionId)
gc.ManagementClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken)
return Leftovers{
logger: logger,
resource: NewGroups(gc, logger),
}, nil
}