-
-
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.
Merge pull request #19 from gruntwork-io/snapshot-nuking
Snapshot nuking
- Loading branch information
Showing
6 changed files
with
219 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package aws | ||
|
||
import ( | ||
"time" | ||
|
||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/gruntwork-io/aws-nuke/logging" | ||
"github.com/gruntwork-io/gruntwork-cli/errors" | ||
) | ||
|
||
// Returns a formatted string of Snapshot snapshot ids | ||
func getAllSnapshots(session *session.Session, region string, excludeAfter time.Time) ([]*string, error) { | ||
svc := ec2.New(session) | ||
|
||
params := &ec2.DescribeSnapshotsInput{ | ||
OwnerIds: []*string{awsgo.String("self")}, | ||
} | ||
|
||
output, err := svc.DescribeSnapshots(params) | ||
if err != nil { | ||
return nil, errors.WithStackTrace(err) | ||
} | ||
|
||
var snapshotIds []*string | ||
for _, snapshot := range output.Snapshots { | ||
if excludeAfter.After(*snapshot.StartTime) { | ||
snapshotIds = append(snapshotIds, snapshot.SnapshotId) | ||
} | ||
} | ||
|
||
return snapshotIds, nil | ||
} | ||
|
||
// Deletes all Snapshots | ||
func nukeAllSnapshots(session *session.Session, snapshotIds []*string) error { | ||
svc := ec2.New(session) | ||
|
||
if len(snapshotIds) == 0 { | ||
logging.Logger.Infof("No Snapshots to nuke in region %s", *session.Config.Region) | ||
return nil | ||
} | ||
|
||
logging.Logger.Infof("Terminating all Snapshots in region %s", *session.Config.Region) | ||
|
||
for _, snapshotID := range snapshotIds { | ||
params := &ec2.DeleteSnapshotInput{ | ||
SnapshotId: snapshotID, | ||
} | ||
|
||
_, err := svc.DeleteSnapshot(params) | ||
if err != nil { | ||
logging.Logger.Errorf("[Failed] %s", err) | ||
return errors.WithStackTrace(err) | ||
} | ||
|
||
logging.Logger.Infof("Deleted Snapshot: %s", *snapshotID) | ||
} | ||
|
||
logging.Logger.Infof("[OK] %d Snapshot(s) terminated in %s", len(snapshotIds), *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,111 @@ | ||
package aws | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/gruntwork-io/aws-nuke/util" | ||
"github.com/gruntwork-io/gruntwork-cli/errors" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func createTestSnapshot(t *testing.T, session *session.Session, name string) ec2.Snapshot { | ||
svc := ec2.New(session) | ||
|
||
az := awsgo.StringValue(session.Config.Region) + "a" | ||
volume := createTestEBSVolume(t, session, name, az) | ||
snapshot, err := svc.CreateSnapshot(&ec2.CreateSnapshotInput{ | ||
VolumeId: volume.VolumeId, | ||
}) | ||
|
||
if err != nil { | ||
assert.Failf(t, "Could not create test Snapshot", errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
err = svc.WaitUntilSnapshotCompleted(&ec2.DescribeSnapshotsInput{ | ||
OwnerIds: []*string{awsgo.String("self")}, | ||
SnapshotIds: []*string{snapshot.SnapshotId}, | ||
}) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
return *snapshot | ||
} | ||
|
||
func TestListSnapshots(t *testing.T) { | ||
t.Parallel() | ||
|
||
region := getRandomRegion() | ||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
uniqueTestID := "aws-nuke-test-" + util.UniqueID() | ||
snapshot := createTestSnapshot(t, session, uniqueTestID) | ||
|
||
// clean up after this test | ||
defer nukeAllSnapshots(session, []*string{snapshot.SnapshotId}) | ||
defer nukeAllEbsVolumes(session, findEBSVolumesByNameTag(t, session, uniqueTestID)) | ||
|
||
snapshots, err := getAllSnapshots(session, region, time.Now().Add(1*time.Hour*-1)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of Snapshots") | ||
} | ||
|
||
assert.NotContains(t, awsgo.StringValueSlice(snapshots), *snapshot.SnapshotId) | ||
|
||
snapshots, err = getAllSnapshots(session, region, time.Now().Add(1*time.Hour)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of Snapshots") | ||
} | ||
|
||
assert.Contains(t, awsgo.StringValueSlice(snapshots), *snapshot.SnapshotId) | ||
} | ||
|
||
func TestNukeSnapshots(t *testing.T) { | ||
t.Parallel() | ||
|
||
region := getRandomRegion() | ||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
svc := ec2.New(session) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
uniqueTestID := "aws-nuke-test-" + util.UniqueID() | ||
snapshot := createTestSnapshot(t, session, uniqueTestID) | ||
|
||
// clean up ec2 instance created by the above call | ||
defer nukeAllEbsVolumes(session, findEBSVolumesByNameTag(t, session, uniqueTestID)) | ||
|
||
_, err = svc.DescribeSnapshots(&ec2.DescribeSnapshotsInput{ | ||
SnapshotIds: []*string{snapshot.SnapshotId}, | ||
}) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
if err := nukeAllSnapshots(session, []*string{snapshot.SnapshotId}); err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
snapshots, err := getAllSnapshots(session, region, time.Now().Add(1*time.Hour)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of Snapshots") | ||
} | ||
|
||
assert.NotContains(t, awsgo.StringValueSlice(snapshots), *snapshot.SnapshotId) | ||
} |
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,30 @@ | ||
package aws | ||
|
||
import ( | ||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/gruntwork-io/gruntwork-cli/errors" | ||
) | ||
|
||
// Snapshots - represents all user owned Snapshots | ||
type Snapshots struct { | ||
SnapshotIds []string | ||
} | ||
|
||
// ResourceName - the simple name of the aws resource | ||
func (snapshot Snapshots) ResourceName() string { | ||
return "snap" | ||
} | ||
|
||
// ResourceIdentifiers - The Snapshot snapshot ids | ||
func (snapshot Snapshots) ResourceIdentifiers() []string { | ||
return snapshot.SnapshotIds | ||
} | ||
|
||
// Nuke - nuke 'em all!!! | ||
func (snapshot Snapshots) Nuke(session *session.Session) error { | ||
if err := nukeAllSnapshots(session, awsgo.StringSlice(snapshot.SnapshotIds)); err != nil { | ||
return errors.WithStackTrace(err) | ||
} | ||
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