Skip to content

Commit

Permalink
add aws v2 sdk to support newer resources (gruntwork-io#745)
Browse files Browse the repository at this point in the history
add support for Managed Prometheus
  • Loading branch information
wakeful committed Jul 15, 2024
1 parent 663cde4 commit f11a027
Show file tree
Hide file tree
Showing 11 changed files with 346 additions and 113 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Cloud-nuke suppports 🔎 inspecting and 🔥💀 deleting the following AWS res
| CloudWatch | Alarms |
| OpenSearch | Domains |
| KMS | Custgomer managed keys (and associated key aliases) |
| Managed Prometheus | Prometheus Workspace |
| GuardDuty | Detectors |
| Macie | Member accounts |
| SageMaker | Notebook instances |
Expand Down Expand Up @@ -606,6 +607,7 @@ of the file that are supported are listed here.
| lt | LaunchTemplate | ✅ (Launch Template Name) | ✅ (Created Time) | ❌ | ✅ |
| macie-member | MacieMember | ❌ | ✅ (Creation Time) | ❌ | ✅ |
| msk-cluster | MSKCluster | ✅ (Cluster Name) | ✅ (Creation Time) | ❌ | ✅ |
| managed-prometheus | ManagedPrometheus | ✅ (Workspace Alias) | ✅ (Creation Time) | ✅ | ✅ |
| nat-gateway | NatGateway | ✅ (EC2 Name Tag) | ✅ (Creation Time) | ✅ | ✅ |
| network-acl | NetworkACL | ✅ (ACL Name Tag) | ✅ (Creation Time) | ✅ | ✅ |
| network-interface | NetworkInterface | ✅ (Interface Name Tag) | ✅ (Creation Time) | ✅ | ✅ |
Expand Down
27 changes: 27 additions & 0 deletions aws/region.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package aws

import (
"context"
"fmt"

awsgoV2 "github.com/aws/aws-sdk-go-v2/aws"
awsgoV2cfg "github.com/aws/aws-sdk-go-v2/config"
awsgoV2cred "github.com/aws/aws-sdk-go-v2/credentials"
awsgo "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
Expand Down Expand Up @@ -146,3 +151,25 @@ func GetTargetRegions(enabledRegions []string, selectedRegions []string, exclude
}
return targetRegions, nil
}

func Session2cfg(ctx context.Context, session *session.Session) (awsgoV2.Config, error) {
cfgV1 := session.Config
cred, err := cfgV1.Credentials.Get()
if err != nil {
return awsgoV2.Config{}, errors.WithStackTrace(err)
}

cfgV2, err := awsgoV2cfg.LoadDefaultConfig(ctx,
awsgoV2cfg.WithRegion(*cfgV1.Region),
awsgoV2cfg.WithCredentialsProvider(awsgoV2cred.NewStaticCredentialsProvider(
cred.AccessKeyID,
cred.SecretAccessKey,
cred.SessionToken,
)),
)
if err != nil {
return awsgoV2.Config{}, errors.WithStackTrace(err)
}

return cfgV2, nil
}
3 changes: 3 additions & 0 deletions aws/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ import (
"context"
"strings"

awsgoV2 "github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/gruntwork-io/cloud-nuke/config"
)

// AwsResource is an interface that represents a single AWS resource
type AwsResource interface {
Init(session *session.Session)
InitV2(cfg awsgoV2.Config)
ResourceName() string
ResourceIdentifiers() []string
MaxBatchSize() int
Nuke(identifiers []string) error
GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error)
IsNukable(string) (bool, error)
IsUsingV2() bool

PrepareContext(context.Context, config.ResourceType) error
GetAndSetResourceConfig(config.Config) config.ResourceType
Expand Down
27 changes: 26 additions & 1 deletion aws/resource_registry.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package aws

import (
"context"
"fmt"
"reflect"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/gruntwork-io/cloud-nuke/aws/resources"
"github.com/gruntwork-io/cloud-nuke/logging"
)

const Global = "global"
Expand Down Expand Up @@ -60,6 +63,7 @@ func getRegisteredRegionalResources() []AwsResource {
&resources.ASGroups{},
&resources.AppRunnerService{},
&resources.BackupVault{},
&resources.ManagedPrometheus{},
&resources.CloudtrailTrail{},
&resources.CloudWatchAlarms{},
&resources.CloudWatchDashboards{},
Expand Down Expand Up @@ -163,7 +167,28 @@ func toAwsResourcesPointer(resources []AwsResource) []*AwsResource {

func initRegisteredResources(resources []*AwsResource, session *session.Session, region string) []*AwsResource {
for _, resource := range resources {
(*resource).Init(session)
if (*resource).IsUsingV2() {
v2Config, err := Session2cfg(context.Background(), session)
if err != nil {
logging.Debug(fmt.Sprintf(
"[aws sdk cfg] failed to convert v1 session into aws v2 config for resource %s: %v",
(*resource).ResourceName(),
err,
))
}

logging.Debug(fmt.Sprintf(
"[aws sdk cfg] using aws sdk v2 for resource %s",
(*resource).ResourceName(),
))
(*resource).InitV2(v2Config)
} else {
logging.Debug(fmt.Sprintf(
"[aws sdk cfg] using deprecated aws sdk v1 for resource %s",
(*resource).ResourceName(),
))
(*resource).Init(session)
}

// Note: only regional resources have the field `Region`, which is used for logging purposes only
setRegionForRegionalResource(resource, region)
Expand Down
10 changes: 10 additions & 0 deletions aws/resources/base_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"time"

awsgoV2 "github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/cloud-nuke/util"
Expand All @@ -25,6 +26,11 @@ type BaseAwsResource struct {
func (br *BaseAwsResource) Init(_ *session.Session) {
br.Nukables = make(map[string]error)
}

func (br *BaseAwsResource) InitV2(cfg awsgoV2.Config) {
br.Nukables = make(map[string]error)
}

func (br *BaseAwsResource) ResourceName() string {
return "not implemented: ResourceName"
}
Expand Down Expand Up @@ -101,3 +107,7 @@ func (br *BaseAwsResource) IsNukable(identifier string) (bool, error) {

return true, nil
}

func (br *BaseAwsResource) IsUsingV2() bool {
return false
}
77 changes: 77 additions & 0 deletions aws/resources/managed_prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package resources

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/amp"
"github.com/aws/aws-sdk-go-v2/service/amp/types"
"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 (a *ManagedPrometheus) nukeAll(identifiers []*string) error {
if len(identifiers) == 0 {
logging.Debugf("[Managed Prometheus] No Prometheus Workspaces found in region %s", a.Region)
return nil
}

logging.Debugf("[Managed Prometheus] Deleting all Prometheus Workspaces in %s", a.Region)
var deleted []*string

for _, identifier := range identifiers {
logging.Debugf("[Managed Prometheus] Deleting Prometheus Workspace %s in region %s", *identifier, a.Region)

_, err := a.Client.DeleteWorkspace(a.Context, &amp.DeleteWorkspaceInput{
WorkspaceId: identifier,
ClientToken: nil,
})
if err != nil {
logging.Debugf("[Managed Prometheus] Error deleting Workspace %s in region %s", *identifier, a.Region)
} else {
deleted = append(deleted, identifier)
logging.Debugf("[Managed Prometheus] Deleted Workspace %s in region %s", *identifier, a.Region)
}

e := report.Entry{
Identifier: aws.ToString(identifier),
ResourceType: a.ResourceName(),
Error: err,
}
report.Record(e)
}

logging.Debugf("[OK] %d Prometheus Workspace(s) deleted in %s", len(deleted), a.Region)
return nil
}

func (a *ManagedPrometheus) getAll(ctx context.Context, cnfObj config.Config) ([]*string, error) {
paginator := amp.NewListWorkspacesPaginator(a.Client, &amp.ListWorkspacesInput{})

var identifiers []*string
for paginator.HasMorePages() {
workspaces, err := paginator.NextPage(ctx)
if err != nil {
logging.Debugf("[Managed Prometheus] Failed to list workspaces: %s", err)
return nil, errors.WithStackTrace(err)
}

for _, workspace := range workspaces.Workspaces {
if workspace.Status.StatusCode != types.WorkspaceStatusCodeActive {
continue
}

if cnfObj.ManagedPrometheus.ShouldInclude(config.ResourceValue{
Name: workspace.Alias,
Time: workspace.CreatedAt,
Tags: workspace.Tags,
}) {
identifiers = append(identifiers, workspace.WorkspaceId)
}
}
}

return identifiers, nil
}
53 changes: 53 additions & 0 deletions aws/resources/managed_prometheus_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package resources

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/amp"
"github.com/gruntwork-io/cloud-nuke/config"
"github.com/gruntwork-io/go-commons/errors"
)

type ManagedPrometheus struct {
BaseAwsResource
Client *amp.Client
Region string
WorkSpaces []string
}

func (a *ManagedPrometheus) GetAndSetResourceConfig(configObj config.Config) config.ResourceType {
return configObj.ManagedPrometheus
}

func (a *ManagedPrometheus) InitV2(cfg aws.Config) {
a.Client = amp.NewFromConfig(cfg)
}

func (a *ManagedPrometheus) IsUsingV2() bool { return true }

func (a *ManagedPrometheus) ResourceName() string { return "managed-prometheus" }

func (a *ManagedPrometheus) ResourceIdentifiers() []string { return a.WorkSpaces }

func (a *ManagedPrometheus) MaxBatchSize() int {
return 100
}

func (a *ManagedPrometheus) Nuke(identifiers []string) error {
if err := a.nukeAll(aws.StringSlice(identifiers)); err != nil {
return errors.WithStackTrace(err)
}

return nil
}

func (a *ManagedPrometheus) GetAndSetIdentifiers(ctx context.Context, cnfObj config.Config) ([]string, error) {
identifiers, err := a.getAll(ctx, cnfObj)
if err != nil {
return nil, err
}

a.WorkSpaces = aws.ToStringSlice(identifiers)
return a.WorkSpaces, nil
}
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Config struct {
AutoScalingGroup ResourceType `yaml:"AutoScalingGroup"`
AppRunnerService ResourceType `yaml:"AppRunnerService"`
BackupVault ResourceType `yaml:"BackupVault"`
ManagedPrometheus ResourceType `yaml:"ManagedPrometheus"`
CloudWatchAlarm ResourceType `yaml:"CloudWatchAlarm"`
CloudWatchDashboard ResourceType `yaml:"CloudWatchDashboard"`
CloudWatchLogGroup ResourceType `yaml:"CloudWatchLogGroup"`
Expand Down
Loading

0 comments on commit f11a027

Please sign in to comment.