-
-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement support for configservice recorders and rules (#405)
- Loading branch information
1 parent
f8f53d0
commit 50592c3
Showing
13 changed files
with
664 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package aws | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/configservice" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/gruntwork-io/cloud-nuke/logging" | ||
"github.com/gruntwork-io/cloud-nuke/report" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
func getAllConfigRecorders(session *session.Session, excludeAfter time.Time, configObj config.Config) ([]string, error) { | ||
svc := configservice.New(session) | ||
|
||
configRecorderNames := []string{} | ||
|
||
param := &configservice.DescribeConfigurationRecordersInput{} | ||
|
||
output, err := svc.DescribeConfigurationRecorders(param) | ||
if err != nil { | ||
return []string{}, errors.WithStackTrace(err) | ||
} | ||
|
||
for _, configRecorder := range output.ConfigurationRecorders { | ||
if shouldIncludeConfigRecorder(configRecorder, excludeAfter, configObj) { | ||
configRecorderNames = append(configRecorderNames, aws.StringValue(configRecorder.Name)) | ||
} | ||
} | ||
|
||
return configRecorderNames, nil | ||
} | ||
|
||
func shouldIncludeConfigRecorder(configRecorder *configservice.ConfigurationRecorder, excludeAfter time.Time, configObj config.Config) bool { | ||
if configRecorder == nil { | ||
return false | ||
} | ||
|
||
return config.ShouldInclude( | ||
aws.StringValue(configRecorder.Name), | ||
configObj.ConfigServiceRecorder.IncludeRule.NamesRegExp, | ||
configObj.ConfigServiceRecorder.ExcludeRule.NamesRegExp, | ||
) | ||
} | ||
|
||
func nukeAllConfigRecorders(session *session.Session, configRecorderNames []string) error { | ||
svc := configservice.New(session) | ||
|
||
if len(configRecorderNames) == 0 { | ||
logging.Logger.Debugf("No Config recorders to nuke in region %s", *session.Config.Region) | ||
return nil | ||
} | ||
|
||
var deletedNames []*string | ||
|
||
for _, configRecorderName := range configRecorderNames { | ||
params := &configservice.DeleteConfigurationRecorderInput{ | ||
ConfigurationRecorderName: aws.String(configRecorderName), | ||
} | ||
|
||
_, err := svc.DeleteConfigurationRecorder(params) | ||
|
||
// Record status of this resource | ||
e := report.Entry{ | ||
Identifier: configRecorderName, | ||
ResourceType: "Config Recorder", | ||
Error: err, | ||
} | ||
report.Record(e) | ||
|
||
if err != nil { | ||
logging.Logger.Debugf("[Failed] %s", err) | ||
} else { | ||
deletedNames = append(deletedNames, aws.String(configRecorderName)) | ||
logging.Logger.Debugf("Deleted Config Recorder: %s", configRecorderName) | ||
} | ||
} | ||
|
||
logging.Logger.Debugf("[OK] %d Config Recorders deleted in %s", len(deletedNames), *session.Config.Region) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package aws | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/configservice" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestListConfigRecorders(t *testing.T) { | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
require.NoError(t, err) | ||
|
||
session, err := session.NewSession(&aws.Config{Region: aws.String(region)}) | ||
require.NoError(t, err) | ||
|
||
// You can only have one configuration recorder per region, so instead of our usual | ||
// create and list pattern, we'll just ensure there is a recorder in our target region, | ||
// creating one if necessary, and then that we can see that config recorder returned by | ||
// getAllConfigRecorders | ||
configRecorderName := ensureConfigurationRecorderExistsInRegion(t, region) | ||
|
||
configRecorderNames, lookupErr := getAllConfigRecorders(session, time.Now(), config.Config{}) | ||
require.NoError(t, lookupErr) | ||
require.NotEmpty(t, configRecorderNames) | ||
|
||
// Sanity check that we got back a recorder | ||
assert.Equal(t, configRecorderNames[0], configRecorderName) | ||
} | ||
|
||
func TestNukeConfigRecorderOne(t *testing.T) { | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
require.NoError(t, err) | ||
|
||
session, err := session.NewSession(&aws.Config{Region: aws.String(region)}) | ||
require.NoError(t, err) | ||
|
||
configRecorderName := ensureConfigurationRecorderExistsInRegion(t, region) | ||
|
||
defer deleteConfigRecorder(t, region, configRecorderName, false) | ||
|
||
require.NoError( | ||
t, | ||
nukeAllConfigRecorders(session, []string{configRecorderName}), | ||
) | ||
|
||
assertConfigRecordersDeleted(t, region) | ||
} | ||
|
||
// Test helpers | ||
|
||
func deleteConfigRecorder(t *testing.T, region string, configRecorderName string, checkErr bool) { | ||
session, err := session.NewSession(&aws.Config{Region: aws.String(region)}) | ||
require.NoError(t, err) | ||
|
||
configService := configservice.New(session) | ||
|
||
param := &configservice.DeleteConfigurationRecorderInput{ | ||
ConfigurationRecorderName: aws.String(configRecorderName), | ||
} | ||
|
||
_, deleteErr := configService.DeleteConfigurationRecorder(param) | ||
if checkErr { | ||
require.NoError(t, deleteErr) | ||
} | ||
} | ||
|
||
func assertConfigRecordersDeleted(t *testing.T, region string) { | ||
session, err := session.NewSession(&aws.Config{Region: aws.String(region)}) | ||
require.NoError(t, err) | ||
|
||
svc := configservice.New(session) | ||
|
||
param := &configservice.DescribeConfigurationRecordersInput{} | ||
|
||
resp, err := svc.DescribeConfigurationRecorders(param) | ||
require.NoError(t, err) | ||
|
||
require.Empty(t, resp.ConfigurationRecorders) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package aws | ||
|
||
import ( | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
type ConfigServiceRecorders struct { | ||
RecorderNames []string | ||
} | ||
|
||
func (u ConfigServiceRecorders) ResourceName() string { | ||
return "config-recorders" | ||
} | ||
|
||
func (u ConfigServiceRecorders) ResourceIdentifiers() []string { | ||
return u.RecorderNames | ||
} | ||
|
||
func (u ConfigServiceRecorders) MaxBatchSize() int { | ||
return 50 | ||
} | ||
|
||
func (u ConfigServiceRecorders) Nuke(session *session.Session, configServiceRecorderNames []string) error { | ||
if err := nukeAllConfigRecorders(session, configServiceRecorderNames); err != nil { | ||
return errors.WithStackTrace(err) | ||
} | ||
return nil | ||
} |
Oops, something went wrong.