-
-
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.
elastic bean stalk application implementation (#644)
* elastic bean stalk application implementation * elastic bean stalk application implementation
- Loading branch information
1 parent
250f467
commit e9f66f6
Showing
7 changed files
with
233 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,71 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/elasticbeanstalk" | ||
"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 shouldIncludeEBApplication(app *elasticbeanstalk.ApplicationDescription, configObj config.Config) bool { | ||
return configObj.ElasticBeanstalk.ShouldInclude(config.ResourceValue{ | ||
Name: app.ApplicationName, | ||
Time: app.DateCreated, | ||
}) | ||
} | ||
|
||
// Returns a formatted string of EB application ids | ||
func (eb *EBApplications) getAll(c context.Context, configObj config.Config) ([]*string, error) { | ||
output, err := eb.Client.DescribeApplications(&elasticbeanstalk.DescribeApplicationsInput{}) | ||
if err != nil { | ||
return nil, errors.WithStackTrace(err) | ||
} | ||
var appIds []*string | ||
for _, app := range output.Applications { | ||
if shouldIncludeEBApplication(app, configObj) { | ||
appIds = append(appIds, app.ApplicationName) | ||
} | ||
} | ||
return appIds, nil | ||
} | ||
|
||
// Deletes all EB Applications | ||
func (eb *EBApplications) nukeAll(appIds []*string) error { | ||
if len(appIds) == 0 { | ||
logging.Debugf("No Elastic Beanstalk to nuke in region %s", eb.Region) | ||
return nil | ||
} | ||
|
||
logging.Debugf("Deleting all Elastic Beanstalk applications in region %s", eb.Region) | ||
var deletedApps []*string | ||
|
||
for _, id := range appIds { | ||
_, err := eb.Client.DeleteApplication(&elasticbeanstalk.DeleteApplicationInput{ | ||
ApplicationName: id, | ||
TerminateEnvByForce: aws.Bool(true), | ||
}) | ||
// Record status of this resource | ||
e := report.Entry{ | ||
Identifier: aws.StringValue(id), | ||
ResourceType: "Elastic Beanstalk Application", | ||
Error: err, | ||
} | ||
report.Record(e) | ||
|
||
if err != nil { | ||
logging.Debugf("[Failed] %s", err) | ||
continue | ||
} | ||
|
||
// get the deleted ids | ||
deletedApps = append(deletedApps, id) | ||
logging.Debugf("Deleted Elastic Beanstalk application: %s", *id) | ||
|
||
} | ||
logging.Debugf("[OK] %d Elastic Beanstalk application(s) deleted in %s", len(deletedApps), eb.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,99 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
"regexp" | ||
"testing" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/elasticbeanstalk" | ||
"github.com/aws/aws-sdk-go/service/elasticbeanstalk/elasticbeanstalkiface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
type mockedEBApplication struct { | ||
elasticbeanstalkiface.ElasticBeanstalkAPI | ||
DescribeApplicationsOutput elasticbeanstalk.DescribeApplicationsOutput | ||
} | ||
|
||
func (mock *mockedEBApplication) DescribeApplications(req *elasticbeanstalk.DescribeApplicationsInput) (*elasticbeanstalk.DescribeApplicationsOutput, error) { | ||
return &mock.DescribeApplicationsOutput, nil | ||
} | ||
|
||
func (mock *mockedEBApplication) DeleteApplication(*elasticbeanstalk.DeleteApplicationInput) (*elasticbeanstalk.DeleteApplicationOutput, error) { | ||
return nil, nil | ||
} | ||
|
||
func TestEBApplication_GetAll(t *testing.T) { | ||
t.Parallel() | ||
|
||
app1 := "demo-app-golang-backend" | ||
app2 := "demo-app-golang-frontend" | ||
|
||
now := time.Now() | ||
eb := EBApplications{ | ||
Client: &mockedEBApplication{ | ||
DescribeApplicationsOutput: elasticbeanstalk.DescribeApplicationsOutput{ | ||
Applications: []*elasticbeanstalk.ApplicationDescription{ | ||
{ | ||
ApplicationArn: aws.String("app-arn-01"), | ||
ApplicationName: &app1, | ||
DateCreated: aws.Time(now), | ||
}, | ||
{ | ||
ApplicationArn: aws.String("app-arn-02"), | ||
ApplicationName: &app2, | ||
DateCreated: aws.Time(now.Add(1)), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
tests := map[string]struct { | ||
configObj config.ResourceType | ||
expected []string | ||
}{ | ||
"emptyFilter": { | ||
configObj: config.ResourceType{}, | ||
expected: []string{ | ||
app1, app2, | ||
}, | ||
}, | ||
"nameExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
NamesRegExp: []config.Expression{{ | ||
RE: *regexp.MustCompile(app1), | ||
}}}, | ||
}, | ||
expected: []string{app2}, | ||
}, | ||
"timeAfterExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
TimeAfter: aws.Time(now), | ||
}}, | ||
expected: []string{app1}, | ||
}, | ||
"timeBeforeExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
TimeBefore: aws.Time(now.Add(1)), | ||
}}, | ||
expected: []string{app2}, | ||
}, | ||
} | ||
|
||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
names, err := eb.getAll(context.Background(), config.Config{ | ||
ElasticBeanstalk: tc.configObj, | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.expected, aws.StringValueSlice(names)) | ||
}) | ||
} | ||
} |
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,58 @@ | ||
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/elasticbeanstalk" | ||
"github.com/aws/aws-sdk-go/service/elasticbeanstalk/elasticbeanstalkiface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
// EBApplications - represents all elastic beanstalk applications | ||
type EBApplications struct { | ||
BaseAwsResource | ||
Client elasticbeanstalkiface.ElasticBeanstalkAPI | ||
Region string | ||
appIds []string | ||
} | ||
|
||
func (eb *EBApplications) Init(session *session.Session) { | ||
eb.Client = elasticbeanstalk.New(session) | ||
} | ||
|
||
// ResourceName - the simple name of the aws resource | ||
func (eb *EBApplications) ResourceName() string { | ||
return "elastic-beanstalk" | ||
} | ||
|
||
// ResourceIdentifiers - The application ids of the elastic beanstalk | ||
func (eb *EBApplications) ResourceIdentifiers() []string { | ||
return eb.appIds | ||
} | ||
|
||
func (eb *EBApplications) MaxBatchSize() int { | ||
// Tentative batch size to ensure AWS doesn't throttle | ||
return 49 | ||
} | ||
|
||
func (eb *EBApplications) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) { | ||
identifiers, err := eb.getAll(c, configObj) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
eb.appIds = awsgo.StringValueSlice(identifiers) | ||
return eb.appIds, nil | ||
} | ||
|
||
// Nuke - nuke 'em all!!! | ||
func (eb *EBApplications) Nuke(identifiers []string) error { | ||
if err := eb.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
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