-
-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds support to delete AWS ACM Private CAs. Fixes #200
- Loading branch information
1 parent
922a488
commit d9566af
Showing
15 changed files
with
364 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
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/acmpca" | ||
"github.com/gruntwork-io/cloud-nuke/logging" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
// getAllACMPCA returns a list of all arns of ACMPCA, which can be deleted. | ||
func getAllACMPCA(session *session.Session, region string, excludeAfter time.Time) ([]*string, error) { | ||
svc := acmpca.New(session) | ||
|
||
result, err := svc.ListCertificateAuthorities(&acmpca.ListCertificateAuthoritiesInput{}) | ||
if err != nil { | ||
return nil, errors.WithStackTrace(err) | ||
} | ||
|
||
var arns []*string | ||
for _, ca := range result.CertificateAuthorities { | ||
// one can only delete CAs if they are 'ACTIVE' or 'DISABLED' | ||
isCandidateForDeletion := *ca.Status == acmpca.CertificateAuthorityStatusActive || *ca.Status == acmpca.CertificateAuthorityStatusDisabled | ||
if !isCandidateForDeletion { | ||
continue | ||
} | ||
if excludeAfter.After(*ca.CreatedAt) { | ||
arns = append(arns, ca.Arn) | ||
} | ||
} | ||
return arns, nil | ||
} | ||
|
||
// nukeAllACMPCA will delete all ACMPCA, which are given by a list of arns. | ||
func nukeAllACMPCA(session *session.Session, arns []*string) error { | ||
if len(arns) == 0 { | ||
logging.Logger.Infof("No ACMPCA to nuke in region %s", *session.Config.Region) | ||
return nil | ||
} | ||
svc := acmpca.New(session) | ||
|
||
logging.Logger.Infof("Deleting all ACMPCA in region %s", *session.Config.Region) | ||
var deletedARNs []*string | ||
|
||
for _, arn := range arns { | ||
logging.Logger.Infof("Setting status to 'DISABLED' for ACMPCA %s in region %s", *arn, *session.Config.Region) | ||
if _, updateStatusErr := svc.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ | ||
CertificateAuthorityArn: arn, | ||
Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), | ||
}); updateStatusErr != nil { | ||
logging.Logger.Errorf("[Failed] %s", updateStatusErr) | ||
continue | ||
} | ||
logging.Logger.Infof("Did set status to 'DISABLED' for ACMPCA: %s in region %s", *arn, *session.Config.Region) | ||
|
||
if _, deleteErr := svc.DeleteCertificateAuthority(&acmpca.DeleteCertificateAuthorityInput{ | ||
CertificateAuthorityArn: arn, | ||
// the range is 7 to 30 days. | ||
// since cloud-nuke should not be used in production, | ||
// we assume that the minimum (7 days) is fine. | ||
PermanentDeletionTimeInDays: aws.Int64(7), | ||
}); deleteErr != nil { | ||
logging.Logger.Errorf("[Failed] %s", deleteErr) | ||
continue | ||
} | ||
deletedARNs = append(deletedARNs, arn) | ||
logging.Logger.Infof("Deleted ACMPCA: %s", *arn) | ||
} | ||
logging.Logger.Infof("[OK] %d ACMPCA(s) deleted in %s", len(arns), *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,103 @@ | ||
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/acmpca" | ||
"github.com/gruntwork-io/cloud-nuke/util" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// createTestACMPCA will create am ACMPCA and return its ARN. | ||
func createTestACMPCA(t *testing.T, session *session.Session, name string) *string { | ||
svc := acmpca.New(session) | ||
ca, err := svc.CreateCertificateAuthority(&acmpca.CreateCertificateAuthorityInput{ | ||
CertificateAuthorityConfiguration: &acmpca.CertificateAuthorityConfiguration{ | ||
KeyAlgorithm: awsgo.String(acmpca.KeyAlgorithmRsa2048), | ||
SigningAlgorithm: awsgo.String(acmpca.SigningAlgorithmSha256withrsa), | ||
Subject: &acmpca.ASN1Subject{ | ||
CommonName: awsgo.String(name), | ||
}, | ||
}, | ||
CertificateAuthorityType: awsgo.String("ROOT"), | ||
Tags: []*acmpca.Tag{ | ||
{ | ||
Key: awsgo.String("Name"), | ||
Value: awsgo.String(name), | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
assert.Failf(t, "Could not create ACMPCA", errors.WithStackTrace(err).Error()) | ||
} | ||
return ca.CertificateAuthorityArn | ||
} | ||
|
||
func TestListACMPCA(t *testing.T) { | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
uniqueTestID := "cloud-nuke-test-" + util.UniqueID() | ||
arn := createTestACMPCA(t, session, uniqueTestID) | ||
// clean up after this test | ||
defer nukeAllACMPCA(session, []*string{arn}) | ||
|
||
newARNs, err := getAllACMPCA(session, region, time.Now().Add(1*time.Hour*-1)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of ACMPCA arns") | ||
} | ||
assert.NotContains(t, awsgo.StringValueSlice(newARNs), awsgo.StringValue(arn)) | ||
|
||
allARNs, err := getAllACMPCA(session, region, time.Now().Add(1*time.Hour)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of ACMPCA arns") | ||
} | ||
|
||
assert.Contains(t, awsgo.StringValueSlice(allARNs), awsgo.StringValue(arn)) | ||
} | ||
|
||
func TestNukeACMPCA(t *testing.T) { | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
|
||
if err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
uniqueTestID := "cloud-nuke-test-" + util.UniqueID() | ||
arn := createTestACMPCA(t, session, uniqueTestID) | ||
|
||
if err := nukeAllACMPCA(session, []*string{arn}); err != nil { | ||
assert.Fail(t, errors.WithStackTrace(err).Error()) | ||
} | ||
|
||
arns, err := getAllACMPCA(session, region, time.Now().Add(1*time.Hour)) | ||
if err != nil { | ||
assert.Fail(t, "Unable to fetch list of ACMPCA arns") | ||
} | ||
|
||
assert.NotContains(t, awsgo.StringValueSlice(arns), awsgo.StringValue(arn)) | ||
} |
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,36 @@ | ||
package aws | ||
|
||
import ( | ||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
// ACMPA - represents all ACMPA | ||
type ACMPCA struct { | ||
ARNs []string | ||
} | ||
|
||
// ResourceName - the simple name of the aws resource | ||
func (ca ACMPCA) ResourceName() string { | ||
return "acmpca" | ||
} | ||
|
||
// ResourceIdentifiers - The volume ids of the ebs volumes | ||
func (ca ACMPCA) ResourceIdentifiers() []string { | ||
return ca.ARNs | ||
} | ||
|
||
func (ca ACMPCA) MaxBatchSize() int { | ||
// Tentative batch size to ensure AWS doesn't throttle | ||
return 10 | ||
} | ||
|
||
// Nuke - nuke 'em all!!! | ||
func (ca ACMPCA) Nuke(session *session.Session, arns []string) error { | ||
if err := nukeAllACMPCA(session, awsgo.StringSlice(arns)); 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
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,4 @@ | ||
acmpca: | ||
include: | ||
names_regex: | ||
- .* |
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,5 @@ | ||
acmpca: | ||
include: | ||
names_regex: | ||
- ^cloud-nuke-test- | ||
- -cloud-nuke-test- |
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 @@ | ||
acmpca: |
Oops, something went wrong.