Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: general improvements #329

Merged
merged 13 commits into from
Oct 2, 2024
Merged
14 changes: 14 additions & 0 deletions docs/resources/iam-role.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# IAM Role

This will remove all IAM Roles an AWS account.

## Settings

- `IncludeServiceLinkedRoles`

### IncludeServiceLinkedRoles

By default, service linked roles are excluded from the deletion process. This setting allows you to include them in the
deletion process now that AWS allows for them to be removed.

Default is `false`.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ nav:
- Migration Guide: config-migration.md
- Resources:
- Cognito User Pool: resources/cognito-user-pool.md
- IAM Role: resources/iam-role.md
- S3 Bucket: resources/s3-bucket.md
- Development:
- Overview: development.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package resources

import (
"context"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/apigateway"

"github.com/ekristen/libnuke/pkg/registry"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/libnuke/pkg/types"

"github.com/ekristen/aws-nuke/v3/pkg/nuke"
)
Expand Down Expand Up @@ -43,8 +45,11 @@ func (l *APIGatewayAPIKeyLister) List(_ context.Context, o interface{}) ([]resou

for _, item := range output.Items {
resources = append(resources, &APIGatewayAPIKey{
svc: svc,
APIKey: item.Id,
svc: svc,
apiKey: item.Id,
Name: item.Name,
Tags: item.Tags,
CreatedDate: item.CreatedDate,
})
}

Expand All @@ -59,18 +64,25 @@ func (l *APIGatewayAPIKeyLister) List(_ context.Context, o interface{}) ([]resou
}

type APIGatewayAPIKey struct {
svc *apigateway.APIGateway
APIKey *string
svc *apigateway.APIGateway
apiKey *string
Name *string
Tags map[string]*string
CreatedDate *time.Time
}

func (f *APIGatewayAPIKey) Remove(_ context.Context) error {
_, err := f.svc.DeleteApiKey(&apigateway.DeleteApiKeyInput{
ApiKey: f.APIKey,
func (r *APIGatewayAPIKey) Remove(_ context.Context) error {
_, err := r.svc.DeleteApiKey(&apigateway.DeleteApiKeyInput{
ApiKey: r.apiKey,
})

return err
}

func (f *APIGatewayAPIKey) String() string {
return *f.APIKey
func (r *APIGatewayAPIKey) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}

func (r *APIGatewayAPIKey) String() string {
return *r.apiKey
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ func init() {

type APIGatewayUsagePlanLister struct{}

type APIGatewayUsagePlan struct {
svc *apigateway.APIGateway
usagePlanID *string
name *string
tags map[string]*string
}

func (l *APIGatewayUsagePlanLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
opts := o.(*nuke.ListerOpts)
svc := apigateway.New(opts.Session)
Expand All @@ -51,9 +44,9 @@ func (l *APIGatewayUsagePlanLister) List(_ context.Context, o interface{}) ([]re
for _, item := range output.Items {
resources = append(resources, &APIGatewayUsagePlan{
svc: svc,
usagePlanID: item.Id,
name: item.Name,
tags: item.Tags,
UsagePlanID: item.Id,
Name: item.Name,
Tags: item.Tags,
})
}

Expand All @@ -67,27 +60,25 @@ func (l *APIGatewayUsagePlanLister) List(_ context.Context, o interface{}) ([]re
return resources, nil
}

func (f *APIGatewayUsagePlan) Remove(_ context.Context) error {
_, err := f.svc.DeleteUsagePlan(&apigateway.DeleteUsagePlanInput{
UsagePlanId: f.usagePlanID,
type APIGatewayUsagePlan struct {
svc *apigateway.APIGateway
UsagePlanID *string
Name *string
Tags map[string]*string
}

func (r *APIGatewayUsagePlan) Remove(_ context.Context) error {
_, err := r.svc.DeleteUsagePlan(&apigateway.DeleteUsagePlanInput{
UsagePlanId: r.UsagePlanID,
})

return err
}

func (f *APIGatewayUsagePlan) String() string {
return *f.usagePlanID
func (r *APIGatewayUsagePlan) String() string {
return *r.UsagePlanID
}

func (f *APIGatewayUsagePlan) Properties() types.Properties {
properties := types.NewProperties()

for key, tag := range f.tags {
properties.SetTag(&key, tag)
}

properties.
Set("UsagePlanID", f.usagePlanID).
Set("Name", f.name)
return properties
func (r *APIGatewayUsagePlan) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}
41 changes: 26 additions & 15 deletions resources/cloudwatchevents-rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,44 @@ type CloudWatchEventsRuleLister struct{}

func (l *CloudWatchEventsRuleLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
opts := o.(*nuke.ListerOpts)
var resources []resource.Resource

svc := cloudwatchevents.New(opts.Session)

resp, err := svc.ListEventBuses(nil)
if err != nil {
return nil, err
}
params := &cloudwatchevents.ListEventBusesInput{}

resources := make([]resource.Resource, 0)
for _, bus := range resp.EventBuses {
resp, err := svc.ListRules(&cloudwatchevents.ListRulesInput{
EventBusName: bus.Name,
})
for {
resp, err := svc.ListEventBuses(params)
if err != nil {
return nil, err
}

for _, rule := range resp.Rules {
resources = append(resources, &CloudWatchEventsRule{
svc: svc,
Name: rule.Name,
ARN: rule.Arn,
State: rule.State,
for _, bus := range resp.EventBuses {
resp, err := svc.ListRules(&cloudwatchevents.ListRulesInput{
EventBusName: bus.Name,
})
if err != nil {
return nil, err
}

for _, rule := range resp.Rules {
resources = append(resources, &CloudWatchEventsRule{
svc: svc,
Name: rule.Name,
ARN: rule.Arn,
State: rule.State,
EventBusName: bus.Name,
})
}
}

if resp.NextToken == nil {
break
}

params.NextToken = resp.NextToken
}

return resources, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ekristen/libnuke/pkg/registry"
"github.com/ekristen/libnuke/pkg/resource"
"github.com/ekristen/libnuke/pkg/types"

"github.com/ekristen/aws-nuke/v3/pkg/nuke"
)
Expand Down Expand Up @@ -62,14 +63,18 @@ type DatabaseMigrationServiceCertificate struct {
ARN *string
}

func (f *DatabaseMigrationServiceCertificate) Remove(_ context.Context) error {
_, err := f.svc.DeleteEndpoint(&databasemigrationservice.DeleteEndpointInput{
EndpointArn: f.ARN,
func (r *DatabaseMigrationServiceCertificate) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}

func (r *DatabaseMigrationServiceCertificate) Remove(_ context.Context) error {
_, err := r.svc.DeleteCertificate(&databasemigrationservice.DeleteCertificateInput{
CertificateArn: r.ARN,
})

return err
}

func (f *DatabaseMigrationServiceCertificate) String() string {
return *f.ARN
func (r *DatabaseMigrationServiceCertificate) String() string {
return *r.ARN
}
47 changes: 30 additions & 17 deletions resources/eks-fargate.go → resources/eks-fargate-profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package resources

import (
"context"

"fmt"
"time"

"github.com/sirupsen/logrus"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eks"
Expand Down Expand Up @@ -71,10 +73,21 @@ func (l *EKSFargateProfileLister) List(_ context.Context, o interface{}) ([]reso
}

for _, name := range resp.FargateProfileNames {
profResp, err := svc.DescribeFargateProfile(&eks.DescribeFargateProfileInput{
ClusterName: clusterName,
FargateProfileName: name,
})
if err != nil {
logrus.WithError(err).Error("unable to describe fargate profile")
continue
}

resources = append(resources, &EKSFargateProfile{
svc: svc,
name: name,
cluster: clusterName,
svc: svc,
Name: name,
Cluster: clusterName,
CreatedAt: profResp.FargateProfile.CreatedAt,
Tags: profResp.FargateProfile.Tags,
})
}

Expand All @@ -91,25 +104,25 @@ func (l *EKSFargateProfileLister) List(_ context.Context, o interface{}) ([]reso
}

type EKSFargateProfile struct {
svc *eks.EKS
cluster *string
name *string
svc *eks.EKS
Cluster *string
Name *string
CreatedAt *time.Time
Tags map[string]*string
}

func (fp *EKSFargateProfile) Remove(_ context.Context) error {
_, err := fp.svc.DeleteFargateProfile(&eks.DeleteFargateProfileInput{
ClusterName: fp.cluster,
FargateProfileName: fp.name,
func (r *EKSFargateProfile) Remove(_ context.Context) error {
_, err := r.svc.DeleteFargateProfile(&eks.DeleteFargateProfileInput{
ClusterName: r.Cluster,
FargateProfileName: r.Name,
})
return err
}

func (fp *EKSFargateProfile) Properties() types.Properties {
return types.NewProperties().
Set("Cluster", *fp.cluster).
Set("Profile", *fp.name)
func (r *EKSFargateProfile) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}

func (fp *EKSFargateProfile) String() string {
return fmt.Sprintf("%s:%s", *fp.cluster, *fp.name)
func (r *EKSFargateProfile) String() string {
return fmt.Sprintf("%s:%s", *r.Cluster, *r.Name)
}
21 changes: 21 additions & 0 deletions resources/eks-fargate-profile_mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package resources

import (
"testing"

"github.com/gotidy/ptr"
"github.com/stretchr/testify/assert"
)

func TestEKSFargateProperties(t *testing.T) {
resource := &EKSFargateProfile{
Cluster: ptr.String("test-id"),
Name: ptr.String("test-name"),
}

properties := resource.Properties()

assert.Equal(t, "test-id", properties.Get("Cluster"))
assert.Equal(t, "test-name", properties.Get("Name"))
assert.Equal(t, "test-id:test-name", resource.String())
}
4 changes: 3 additions & 1 deletion resources/iam-role-policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package resources

import (
"context"

"fmt"
"strings"

Expand Down Expand Up @@ -41,6 +40,9 @@ func (e *IAMRolePolicy) Filter() error {
if strings.HasPrefix(e.rolePath, "/aws-service-role/") {
return fmt.Errorf("cannot alter service roles")
}
if strings.HasPrefix(e.rolePath, "/aws-reserved/sso.amazonaws.com/") {
return fmt.Errorf("cannot alter sso roles")
}
return nil
}

Expand Down
11 changes: 10 additions & 1 deletion resources/iam-roles.go → resources/iam-role.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/ekristen/libnuke/pkg/registry"
"github.com/ekristen/libnuke/pkg/resource"
libsettings "github.com/ekristen/libnuke/pkg/settings"
"github.com/ekristen/libnuke/pkg/types"

"github.com/ekristen/aws-nuke/v3/pkg/nuke"
Expand All @@ -32,20 +33,28 @@ func init() {
DeprecatedAliases: []string{
"IamRole",
},
Settings: []string{
"IncludeServiceLinkedRoles",
},
})
}

type IAMRole struct {
svc iamiface.IAMAPI
settings *libsettings.Setting
Name *string
Path *string
CreateDate *time.Time
LastUsedDate *time.Time
Tags []*iam.Tag
}

func (r *IAMRole) Settings(settings *libsettings.Setting) {
r.settings = settings
}

func (r *IAMRole) Filter() error {
if strings.HasPrefix(*r.Path, "/aws-service-role/") {
if strings.HasPrefix(*r.Path, "/aws-service-role/") && !r.settings.GetBool("IncludeServiceLinkedRoles") {
return fmt.Errorf("cannot delete service roles")
}
if strings.HasPrefix(*r.Path, "/aws-reserved/sso.amazonaws.com/") {
Expand Down
Loading