From 43da4fa7a5aa084053c050601936c875c686d146 Mon Sep 17 00:00:00 2001 From: Erik Kristensen Date: Thu, 25 Jan 2024 16:29:30 -0700 Subject: [PATCH] add(resources): MemoryDB from upstream (#35) * feat: MemoryDBACL resource support (#1079) feat: MemoryDBCluster resource support feat: MemoryDBParameterGroup resource support feat: MemoryDBSubnetGroup resource support feat: MemoryDBUser resource support * Filter open-access MemoryDB ACL (#1089) * migrate: memorydb resources to libnuke format --------- Co-authored-by: James Taylor <127947293+JTaylor-myenergi@users.noreply.github.com> Co-authored-by: Philipp Trulson --- resources/memorydb-acl.go | 108 +++++++++++++++++++++++++ resources/memorydb-cluster.go | 99 +++++++++++++++++++++++ resources/memorydb-parametergroups.go | 112 ++++++++++++++++++++++++++ resources/memorydb-subnetgroups.go | 100 +++++++++++++++++++++++ resources/memorydb-user.go | 109 +++++++++++++++++++++++++ 5 files changed, 528 insertions(+) create mode 100644 resources/memorydb-acl.go create mode 100644 resources/memorydb-cluster.go create mode 100644 resources/memorydb-parametergroups.go create mode 100644 resources/memorydb-subnetgroups.go create mode 100644 resources/memorydb-user.go diff --git a/resources/memorydb-acl.go b/resources/memorydb-acl.go new file mode 100644 index 00000000..1541c754 --- /dev/null +++ b/resources/memorydb-acl.go @@ -0,0 +1,108 @@ +package resources + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/memorydb" + + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/pkg/nuke" +) + +type MemoryDBACL struct { + svc *memorydb.MemoryDB + name *string + tags []*memorydb.Tag +} + +const MemoryDBACLResource = "MemoryDBACL" + +func init() { + resource.Register(&resource.Registration{ + Name: MemoryDBACLResource, + Scope: nuke.Account, + Lister: &MemoryDBACLLister{}, + }) +} + +type MemoryDBACLLister struct{} + +func (l *MemoryDBACLLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := memorydb.New(opts.Session) + var resources []resource.Resource + + params := &memorydb.DescribeACLsInput{MaxResults: aws.Int64(50)} + for { + resp, err := svc.DescribeACLs(params) + if err != nil { + return nil, err + } + + for _, acl := range resp.ACLs { + tags, err := svc.ListTags(&memorydb.ListTagsInput{ + ResourceArn: acl.ARN, + }) + + if err != nil { + continue + } + + resources = append(resources, &MemoryDBACL{ + svc: svc, + name: acl.Name, + tags: tags.TagList, + }) + + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +func (i *MemoryDBACL) Filter() error { + if *i.name == "open-access" { + return fmt.Errorf("open-access ACL can't be deleted") + } else { + return nil + } +} + +func (i *MemoryDBACL) Remove(_ context.Context) error { + params := &memorydb.DeleteACLInput{ + ACLName: i.name, + } + + _, err := i.svc.DeleteACL(params) + if err != nil { + return err + } + + return nil +} + +func (i *MemoryDBACL) String() string { + return *i.name +} + +func (i *MemoryDBACL) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("Name", i.name) + + for _, tag := range i.tags { + properties.SetTag(tag.Key, tag.Value) + } + + return properties +} diff --git a/resources/memorydb-cluster.go b/resources/memorydb-cluster.go new file mode 100644 index 00000000..4e0ab9b6 --- /dev/null +++ b/resources/memorydb-cluster.go @@ -0,0 +1,99 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/memorydb" + + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/pkg/nuke" +) + +type MemoryDBCluster struct { + svc *memorydb.MemoryDB + name *string + tags []*memorydb.Tag +} + +const MemoryDBClusterResource = "MemoryDBCluster" + +func init() { + resource.Register(&resource.Registration{ + Name: MemoryDBClusterResource, + Scope: nuke.Account, + Lister: &MemoryDBClusterLister{}, + }) +} + +type MemoryDBClusterLister struct{} + +func (l *MemoryDBClusterLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := memorydb.New(opts.Session) + var resources []resource.Resource + + params := &memorydb.DescribeClustersInput{MaxResults: aws.Int64(100)} + + for { + resp, err := svc.DescribeClusters(params) + if err != nil { + return nil, err + } + + for _, cluster := range resp.Clusters { + tags, err := svc.ListTags(&memorydb.ListTagsInput{ + ResourceArn: cluster.ARN, + }) + + if err != nil { + continue + } + + resources = append(resources, &MemoryDBCluster{ + svc: svc, + name: cluster.Name, + tags: tags.TagList, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +func (c *MemoryDBCluster) Remove(_ context.Context) error { + params := &memorydb.DeleteClusterInput{ + ClusterName: c.name, + } + + _, err := c.svc.DeleteCluster(params) + if err != nil { + return err + } + + return nil +} + +func (i *MemoryDBCluster) String() string { + return *i.name +} + +func (i *MemoryDBCluster) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("Name", i.name) + + for _, tag := range i.tags { + properties.SetTag(tag.Key, tag.Value) + } + + return properties +} diff --git a/resources/memorydb-parametergroups.go b/resources/memorydb-parametergroups.go new file mode 100644 index 00000000..30e7c0a9 --- /dev/null +++ b/resources/memorydb-parametergroups.go @@ -0,0 +1,112 @@ +package resources + +import ( + "context" + "fmt" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/memorydb" + + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/pkg/nuke" +) + +type MemoryDBParameterGroup struct { + svc *memorydb.MemoryDB + name *string + family *string + tags []*memorydb.Tag +} + +const MemoryDBParameterGroupResource = "MemoryDBParameterGroup" + +func init() { + resource.Register(&resource.Registration{ + Name: MemoryDBParameterGroupResource, + Scope: nuke.Account, + Lister: &MemoryDBParameterGroupLister{}, + }) +} + +type MemoryDBParameterGroupLister struct{} + +func (l *MemoryDBParameterGroupLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := memorydb.New(opts.Session) + var resources []resource.Resource + + params := &memorydb.DescribeParameterGroupsInput{MaxResults: aws.Int64(100)} + + for { + resp, err := svc.DescribeParameterGroups(params) + if err != nil { + return nil, err + } + + for _, parameterGroup := range resp.ParameterGroups { + tags, err := svc.ListTags(&memorydb.ListTagsInput{ + ResourceArn: parameterGroup.ARN, + }) + + if err != nil { + continue + } + + resources = append(resources, &MemoryDBParameterGroup{ + svc: svc, + name: parameterGroup.Name, + family: parameterGroup.Family, + tags: tags.TagList, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +func (i *MemoryDBParameterGroup) Filter() error { + if strings.HasPrefix(*i.name, "default.") { + return fmt.Errorf("Cannot delete default parameter group") + } + return nil +} + +func (i *MemoryDBParameterGroup) Remove(_ context.Context) error { + params := &memorydb.DeleteParameterGroupInput{ + ParameterGroupName: i.name, + } + + _, err := i.svc.DeleteParameterGroup(params) + if err != nil { + return err + } + + return nil +} + +func (i *MemoryDBParameterGroup) String() string { + return *i.name +} + +func (i *MemoryDBParameterGroup) Properties() types.Properties { + properties := types.NewProperties() + properties. + Set("Name", i.name). + Set("Family", i.family) + + for _, tag := range i.tags { + properties.SetTag(tag.Key, tag.Value) + } + + return properties +} diff --git a/resources/memorydb-subnetgroups.go b/resources/memorydb-subnetgroups.go new file mode 100644 index 00000000..231efc6a --- /dev/null +++ b/resources/memorydb-subnetgroups.go @@ -0,0 +1,100 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/memorydb" + + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/pkg/nuke" +) + +type MemoryDBSubnetGroup struct { + svc *memorydb.MemoryDB + name *string + tags []*memorydb.Tag +} + +const MemoryDBSubnetGroupResource = "MemoryDBSubnetGroup" + +func init() { + resource.Register(&resource.Registration{ + Name: MemoryDBSubnetGroupResource, + Scope: nuke.Account, + Lister: &MemoryDBSubnetGroupLister{}, + }) +} + +type MemoryDBSubnetGroupLister struct{} + +func (l *MemoryDBSubnetGroupLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := memorydb.New(opts.Session) + var resources []resource.Resource + + params := &memorydb.DescribeSubnetGroupsInput{MaxResults: aws.Int64(100)} + + for { + resp, err := svc.DescribeSubnetGroups(params) + if err != nil { + return nil, err + } + for _, subnetGroup := range resp.SubnetGroups { + tags, err := svc.ListTags(&memorydb.ListTagsInput{ + ResourceArn: subnetGroup.ARN, + }) + + if err != nil { + continue + } + + resources = append(resources, &MemoryDBSubnetGroup{ + svc: svc, + name: subnetGroup.Name, + tags: tags.TagList, + }) + + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +func (i *MemoryDBSubnetGroup) Remove(_ context.Context) error { + params := &memorydb.DeleteSubnetGroupInput{ + SubnetGroupName: i.name, + } + + _, err := i.svc.DeleteSubnetGroup(params) + if err != nil { + return err + } + + return nil +} + +func (i *MemoryDBSubnetGroup) String() string { + return *i.name +} + +func (i *MemoryDBSubnetGroup) Properties() types.Properties { + properties := types.NewProperties() + properties. + Set("Name", i.name) + + for _, tag := range i.tags { + properties.SetTag(tag.Key, tag.Value) + } + + return properties +} diff --git a/resources/memorydb-user.go b/resources/memorydb-user.go new file mode 100644 index 00000000..858c9d2e --- /dev/null +++ b/resources/memorydb-user.go @@ -0,0 +1,109 @@ +package resources + +import ( + "context" + "fmt" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/memorydb" + + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/pkg/nuke" +) + +type MemoryDBUser struct { + svc *memorydb.MemoryDB + name *string + tags []*memorydb.Tag +} + +const MemoryDBUserResource = "MemoryDBUser" + +func init() { + resource.Register(&resource.Registration{ + Name: MemoryDBUserResource, + Scope: nuke.Account, + Lister: &MemoryDBUserLister{}, + }) +} + +type MemoryDBUserLister struct{} + +func (l *MemoryDBUserLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := memorydb.New(opts.Session) + var resources []resource.Resource + + params := &memorydb.DescribeUsersInput{MaxResults: aws.Int64(50)} + for { + resp, err := svc.DescribeUsers(params) + if err != nil { + return nil, err + } + + for _, user := range resp.Users { + tags, err := svc.ListTags(&memorydb.ListTagsInput{ + ResourceArn: user.ARN, + }) + + if err != nil { + continue + } + + resources = append(resources, &MemoryDBUser{ + svc: svc, + name: user.Name, + tags: tags.TagList, + }) + + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +func (i *MemoryDBUser) Filter() error { + if strings.EqualFold(*i.name, "default") { + return fmt.Errorf("Cannot delete default user") + } + return nil +} + +func (i *MemoryDBUser) Remove(_ context.Context) error { + params := &memorydb.DeleteUserInput{ + UserName: i.name, + } + + _, err := i.svc.DeleteUser(params) + if err != nil { + return err + } + + return nil +} + +func (i *MemoryDBUser) String() string { + return *i.name +} + +func (i *MemoryDBUser) Properties() types.Properties { + properties := types.NewProperties() + properties. + Set("Name", i.name) + + for _, tag := range i.tags { + properties.SetTag(tag.Key, tag.Value) + } + + return properties +}