-
-
Notifications
You must be signed in to change notification settings - Fork 353
/
macie.go
145 lines (128 loc) · 4.75 KB
/
macie.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package resources
import (
"context"
"github.com/gruntwork-io/cloud-nuke/config"
"strings"
"github.com/aws/aws-sdk-go/aws"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/macie2"
"github.com/gruntwork-io/cloud-nuke/logging"
"github.com/gruntwork-io/cloud-nuke/report"
"github.com/gruntwork-io/go-commons/errors"
)
// getAll will find and return any Macie accounts that were created via accepting an invite from another AWS Account
// Unfortunately, the Macie API doesn't provide the metadata information we'd need to implement the configObj pattern, so we
// currently can only accept a session and excludeAfter
func (mm *MacieMember) getAll(c context.Context, configObj config.Config) ([]*string, error) {
var macieStatus []*string
output, err := mm.Client.GetMacieSession(&macie2.GetMacieSessionInput{})
if err != nil {
// If Macie is not enabled when we call GetMacieSession, we get back an error
// so we should ignore the error if it's just telling us the account/region is not
// enabled and return nil to indicate there are no resources to nuke
if strings.Contains(err.Error(), "Macie is not enabled") {
return nil, nil
}
return nil, errors.WithStackTrace(err)
}
// Note: there's no identifier for the Macie resource, so we just insert random elements to the return array
// to follow the similar framework as other resources.
if configObj.MacieMember.ShouldInclude(config.ResourceValue{
Time: output.CreatedAt,
}) {
macieStatus = append(macieStatus, output.Status)
}
return macieStatus, nil
}
func (mm *MacieMember) getAllMacieMembers() ([]*string, error) {
var memberAccountIds []*string
// OnlyAssociated=false input parameter includes "pending" invite members
members, err := mm.Client.ListMembers(&macie2.ListMembersInput{OnlyAssociated: aws.String("false")})
if err != nil {
return nil, errors.WithStackTrace(err)
}
for _, member := range members.Members {
memberAccountIds = append(memberAccountIds, member.AccountId)
}
for awsgo.StringValue(members.NextToken) != "" {
members, err = mm.Client.ListMembers(&macie2.ListMembersInput{NextToken: members.NextToken})
if err != nil {
return nil, errors.WithStackTrace(err)
}
for _, member := range members.Members {
memberAccountIds = append(memberAccountIds, member.AccountId)
}
}
logging.Debugf("Found %d member accounts attached to macie", len(memberAccountIds))
return memberAccountIds, nil
}
func (mm *MacieMember) removeMacieMembers(memberAccountIds []*string) error {
// Member accounts must first be disassociated
for _, accountId := range memberAccountIds {
_, err := mm.Client.DisassociateMember(&macie2.DisassociateMemberInput{Id: accountId})
if err != nil {
return err
}
logging.Debugf("%s member account disassociated", *accountId)
// Once disassociated, member accounts can be deleted
_, err = mm.Client.DeleteMember(&macie2.DeleteMemberInput{Id: accountId})
if err != nil {
return err
}
logging.Debugf("%s member account deleted", *accountId)
}
return nil
}
func (mm *MacieMember) nukeAll(identifier []string) error {
if len(identifier) == 0 {
logging.Debugf("No Macie member accounts to nuke in region %s", mm.Region)
return nil
}
// Check for and remove any member accounts in Macie
// Macie cannot be disabled with active member accounts
memberAccountIds, err := mm.getAllMacieMembers()
if err != nil {
}
if err == nil && len(memberAccountIds) > 0 {
err = mm.removeMacieMembers(memberAccountIds)
if err != nil {
logging.Errorf("[Failed] Failed to remove members from macie")
}
}
// Check for an administrator account
// Macie cannot be disabled with an active administrator account
adminAccount, err := mm.Client.GetAdministratorAccount(&macie2.GetAdministratorAccountInput{})
if err != nil {
if strings.Contains(err.Error(), "there isn't a delegated Macie administrator") {
logging.Debugf("No delegated Macie administrator found to remove.")
} else {
logging.Errorf("[Failed] Failed to check for administrator account")
}
}
// Disassociate administrator account if it exists
if adminAccount.Administrator != nil {
_, err := mm.Client.DisassociateFromAdministratorAccount(&macie2.DisassociateFromAdministratorAccountInput{})
if err != nil {
logging.Errorf("[Failed] Failed to disassociate from administrator account")
}
}
// Disable Macie
_, err = mm.Client.DisableMacie(&macie2.DisableMacieInput{})
if err != nil {
logging.Errorf("[Failed] Failed to disable macie.")
e := report.Entry{
Identifier: aws.StringValue(&identifier[0]),
ResourceType: "Macie",
Error: err,
}
report.Record(e)
} else {
logging.Debugf("[OK] Macie disabled in %s", mm.Region)
e := report.Entry{
Identifier: mm.Region,
ResourceType: "Macie",
}
report.Record(e)
}
return nil
}