-
-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nuke implementation rds-proxy (#720)
- Loading branch information
1 parent
a111ffb
commit b2ce0a4
Showing
6 changed files
with
243 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
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 resources | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/rds" | ||
"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 (rdp *RdsProxy) getAll(_ context.Context, configObj config.Config) ([]*string, error) { | ||
var names []*string | ||
err := rdp.Client.DescribeDBProxiesPagesWithContext( | ||
rdp.Context, | ||
&rds.DescribeDBProxiesInput{}, | ||
func(page *rds.DescribeDBProxiesOutput, lastPage bool) bool { | ||
for _, proxy := range page.DBProxies { | ||
if configObj.RdsProxy.ShouldInclude(config.ResourceValue{ | ||
Name: proxy.DBProxyName, | ||
Time: proxy.CreatedDate, | ||
}) { | ||
names = append(names, proxy.DBProxyName) | ||
} | ||
} | ||
|
||
return !lastPage | ||
}) | ||
if err != nil { | ||
return nil, errors.WithStackTrace(err) | ||
} | ||
|
||
return names, nil | ||
} | ||
|
||
func (rdp *RdsProxy) nukeAll(identifiers []*string) error { | ||
if len(identifiers) == 0 { | ||
logging.Debugf("No RDS proxy in region %s", rdp.Region) | ||
return nil | ||
} | ||
|
||
logging.Debugf("Deleting all DB Proxies in region %s", rdp.Region) | ||
var deleted []*string | ||
|
||
for _, identifier := range identifiers { | ||
logging.Debugf("[RDS Proxy] Deleting %s in region %s", *identifier, rdp.Region) | ||
|
||
_, err := rdp.Client.DeleteDBProxyWithContext( | ||
rdp.Context, | ||
&rds.DeleteDBProxyInput{ | ||
DBProxyName: identifier, | ||
}) | ||
if err != nil { | ||
logging.Errorf("[RDS Proxy] Error deleting RDS Proxy %s: %s", *identifier, err) | ||
} else { | ||
deleted = append(deleted, identifier) | ||
logging.Debugf("[RDS Proxy] Deleted RDS Proxy %s", *identifier) | ||
} | ||
|
||
// Record status of this resource | ||
e := report.Entry{ | ||
Identifier: aws.StringValue(identifier), | ||
ResourceType: rdp.ResourceName(), | ||
Error: err, | ||
} | ||
report.Record(e) | ||
} | ||
|
||
logging.Debugf("[OK] %d RDS DB proxi(s) nuked in %s", len(deleted), rdp.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,106 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
"regexp" | ||
"testing" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/request" | ||
"github.com/aws/aws-sdk-go/service/rds" | ||
"github.com/aws/aws-sdk-go/service/rds/rdsiface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
type mockedRdsProxy struct { | ||
rdsiface.RDSAPI | ||
DescribeDBProxiesOutput rds.DescribeDBProxiesOutput | ||
DeleteDBProxyOutput rds.DeleteDBProxyOutput | ||
} | ||
|
||
func (m mockedRdsProxy) DescribeDBProxiesPagesWithContext(_ aws.Context, _ *rds.DescribeDBProxiesInput, callback func(*rds.DescribeDBProxiesOutput, bool) bool, _ ...request.Option) error { | ||
callback(&m.DescribeDBProxiesOutput, true) | ||
return nil | ||
} | ||
|
||
func (m mockedRdsProxy) DeleteDBProxyWithContext(aws.Context, *rds.DeleteDBProxyInput, ...request.Option) (*rds.DeleteDBProxyOutput, error) { | ||
return &m.DeleteDBProxyOutput, nil | ||
} | ||
|
||
func TestRdsProxy_GetAll(t *testing.T) { | ||
|
||
t.Parallel() | ||
|
||
testName1 := "test-name1" | ||
testName2 := "test-name2" | ||
now := time.Now() | ||
snapshot := RdsProxy{ | ||
Client: mockedRdsProxy{ | ||
DescribeDBProxiesOutput: rds.DescribeDBProxiesOutput{ | ||
DBProxies: []*rds.DBProxy{ | ||
{ | ||
DBProxyName: &testName1, | ||
CreatedDate: &now, | ||
}, | ||
{ | ||
DBProxyName: &testName2, | ||
CreatedDate: aws.Time(now.Add(1)), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
tests := map[string]struct { | ||
configObj config.ResourceType | ||
expected []string | ||
}{ | ||
"emptyFilter": { | ||
configObj: config.ResourceType{}, | ||
expected: []string{testName1, testName2}, | ||
}, | ||
"nameExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
NamesRegExp: []config.Expression{{ | ||
RE: *regexp.MustCompile(testName1), | ||
}}}, | ||
}, | ||
expected: []string{testName2}, | ||
}, | ||
"timeAfterExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
TimeAfter: aws.Time(now.Add(-1 * time.Hour)), | ||
}}, | ||
expected: []string{}, | ||
}, | ||
} | ||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
names, err := snapshot.getAll(context.Background(), config.Config{ | ||
RdsProxy: tc.configObj, | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.expected, aws.StringValueSlice(names)) | ||
}) | ||
} | ||
} | ||
|
||
func TestRdsProxy_NukeAll(t *testing.T) { | ||
|
||
t.Parallel() | ||
|
||
testName := "test-db-proxy" | ||
snapshot := RdsProxy{ | ||
Client: mockedRdsProxy{ | ||
DeleteDBProxyOutput: rds.DeleteDBProxyOutput{}, | ||
}, | ||
} | ||
|
||
err := snapshot.nukeAll([]*string{&testName}) | ||
assert.NoError(t, err) | ||
} |
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,60 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
|
||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/rds" | ||
"github.com/aws/aws-sdk-go/service/rds/rdsiface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
type RdsProxy struct { | ||
BaseAwsResource | ||
Client rdsiface.RDSAPI | ||
Region string | ||
GroupNames []string | ||
} | ||
|
||
func (pg *RdsProxy) Init(session *session.Session) { | ||
pg.Client = rds.New(session) | ||
} | ||
|
||
func (pg *RdsProxy) ResourceName() string { | ||
return "rds-proxy" | ||
} | ||
|
||
// ResourceIdentifiers - The names of the rds parameter group | ||
func (pg *RdsProxy) ResourceIdentifiers() []string { | ||
return pg.GroupNames | ||
} | ||
|
||
func (pg *RdsProxy) MaxBatchSize() int { | ||
// Tentative batch size to ensure AWS doesn't throttle | ||
return 49 | ||
} | ||
|
||
func (pg *RdsProxy) GetAndSetResourceConfig(configObj config.Config) config.ResourceType { | ||
return configObj.RdsProxy | ||
} | ||
|
||
func (pg *RdsProxy) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) { | ||
identifiers, err := pg.getAll(c, configObj) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
pg.GroupNames = awsgo.StringValueSlice(identifiers) | ||
return pg.GroupNames, nil | ||
} | ||
|
||
// Nuke - nuke 'em all!!! | ||
func (pg *RdsProxy) Nuke(identifiers []string) error { | ||
if err := pg.nukeAll(awsgo.StringSlice(identifiers)); 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