-
-
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.
add support for nuking app runner service(s).
- Loading branch information
Showing
6 changed files
with
236 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,72 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/apprunner" | ||
"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 *AppRunnerService) nukeAll(identifiers []*string) error { | ||
if len(identifiers) == 0 { | ||
logging.Debugf("[App Runner Service] No App Runner Services found in region %s", a.Region) | ||
return nil | ||
} | ||
|
||
logging.Debugf("[App Runner Service] Deleting all App Runner Services in region %s", a.Region) | ||
var deleted []*string | ||
|
||
for _, identifier := range identifiers { | ||
logging.Debugf("[App Runner Service] Deleting App Runner Service %s in region %s", *identifier, a.Region) | ||
|
||
_, err := a.Client.DeleteServiceWithContext(a.Context, &apprunner.DeleteServiceInput{ | ||
ServiceArn: identifier, | ||
}) | ||
if err != nil { | ||
logging.Debugf("[App Runner Service] Error deleting App Runner Service %s in region %s", *identifier, a.Region) | ||
} else { | ||
deleted = append(deleted, identifier) | ||
logging.Debugf("[App Runner Service] Deleted App Runner Service %s in region %s", *identifier, a.Region) | ||
} | ||
|
||
e := report.Entry{ | ||
Identifier: aws.StringValue(identifier), | ||
ResourceType: a.ResourceName(), | ||
Error: err, | ||
} | ||
report.Record(e) | ||
} | ||
|
||
logging.Debugf("[OK] %d App Runner Service(s) nuked in %s", len(deleted), a.Region) | ||
return nil | ||
} | ||
|
||
func (a *AppRunnerService) getAll(c context.Context, configObj config.Config) ([]*string, error) { | ||
var identifiers []*string | ||
paginator := func(output *apprunner.ListServicesOutput, lastPage bool) bool { | ||
for _, service := range output.ServiceSummaryList { | ||
if configObj.AppRunnerService.ShouldInclude(config.ResourceValue{ | ||
Name: service.ServiceName, | ||
Time: service.CreatedAt, | ||
}) { | ||
identifiers = append(identifiers, service.ServiceArn) | ||
} | ||
} | ||
return !lastPage | ||
} | ||
|
||
param := &apprunner.ListServicesInput{ | ||
MaxResults: aws.Int64(19), | ||
} | ||
|
||
if err := a.Client.ListServicesPagesWithContext(c, param, paginator); err != nil { | ||
logging.Debugf("[App Runner Service] Failed to list app runner services: %s", err) | ||
return nil, errors.WithStackTrace(err) | ||
} | ||
|
||
return identifiers, 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,109 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"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/apprunner" | ||
"github.com/aws/aws-sdk-go/service/apprunner/apprunneriface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
type mockedAppRunnerService struct { | ||
apprunneriface.AppRunnerAPI | ||
ListServicesOutput apprunner.ListServicesOutput | ||
DeleteServiceOutput apprunner.DeleteServiceOutput | ||
} | ||
|
||
func (m mockedAppRunnerService) ListServicesPagesWithContext(_ aws.Context, _ *apprunner.ListServicesInput, callback func(*apprunner.ListServicesOutput, bool) bool, _ ...request.Option) error { | ||
callback(&m.ListServicesOutput, true) | ||
return nil | ||
} | ||
|
||
func (m mockedAppRunnerService) DeleteServiceWithContext(aws.Context, *apprunner.DeleteServiceInput, ...request.Option) (*apprunner.DeleteServiceOutput, error) { | ||
return &m.DeleteServiceOutput, nil | ||
} | ||
|
||
func Test_AppRunnerService_GetAll(t *testing.T) { | ||
|
||
t.Parallel() | ||
|
||
testName1 := "test-service-1" | ||
testName2 := "test-service-2" | ||
now := time.Now() | ||
service := AppRunnerService{ | ||
Client: mockedAppRunnerService{ | ||
ListServicesOutput: apprunner.ListServicesOutput{ | ||
ServiceSummaryList: []*apprunner.ServiceSummary{ | ||
{ | ||
ServiceName: &testName1, | ||
ServiceArn: aws.String(fmt.Sprintf("arn::%s", testName1)), | ||
CreatedAt: &now, | ||
}, | ||
{ | ||
ServiceName: &testName2, | ||
ServiceArn: aws.String(fmt.Sprintf("arn::%s", testName2)), | ||
CreatedAt: aws.Time(now.Add(1)), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
tests := map[string]struct { | ||
configObj config.ResourceType | ||
expected []string | ||
}{ | ||
"emptyFilter": { | ||
configObj: config.ResourceType{}, | ||
expected: []string{fmt.Sprintf("arn::%s", testName1), fmt.Sprintf("arn::%s", testName2)}, | ||
}, | ||
"nameExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
NamesRegExp: []config.Expression{{ | ||
RE: *regexp.MustCompile(testName1), | ||
}}, | ||
}}, | ||
expected: []string{fmt.Sprintf("arn::%s", 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 := service.getAll(context.Background(), config.Config{ | ||
AppRunnerService: tc.configObj, | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.expected, aws.StringValueSlice(names)) | ||
}) | ||
} | ||
} | ||
|
||
func TestAppRunnerService_NukeAll(t *testing.T) { | ||
|
||
t.Parallel() | ||
|
||
testName := "test-app-runner-service" | ||
service := AppRunnerService{ | ||
Client: mockedAppRunnerService{ | ||
DeleteServiceOutput: apprunner.DeleteServiceOutput{}, | ||
}, | ||
} | ||
|
||
err := service.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,51 @@ | ||
package resources | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/apprunner" | ||
"github.com/aws/aws-sdk-go/service/apprunner/apprunneriface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/gruntwork-io/go-commons/errors" | ||
) | ||
|
||
type AppRunnerService struct { | ||
BaseAwsResource | ||
Client apprunneriface.AppRunnerAPI | ||
Region string | ||
AppRunners []string | ||
} | ||
|
||
func (a *AppRunnerService) GetAndSetResourceConfig(configObj config.Config) config.ResourceType { | ||
return configObj.AppRunnerService | ||
} | ||
|
||
func (a *AppRunnerService) Init(session *session.Session) { | ||
a.Client = apprunner.New(session) | ||
} | ||
|
||
func (a *AppRunnerService) ResourceName() string { return "app-runner-service" } | ||
|
||
func (a *AppRunnerService) ResourceIdentifiers() []string { return a.AppRunners } | ||
|
||
func (a *AppRunnerService) MaxBatchSize() int { return 19 } | ||
|
||
func (a *AppRunnerService) Nuke(identifiers []string) error { | ||
if err := a.nukeAll(aws.StringSlice(identifiers)); err != nil { | ||
return errors.WithStackTrace(err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *AppRunnerService) GetAndSetIdentifiers(c context.Context, configObj config.Config) ([]string, error) { | ||
identifiers, err := a.getAll(c, configObj) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
a.AppRunners = aws.StringValueSlice(identifiers) | ||
return a.AppRunners, 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