From ee06e2ccf68d169f0ee7c70f203146d649ee08e7 Mon Sep 17 00:00:00 2001 From: Sean Stoops Date: Mon, 24 Apr 2023 16:48:07 -0700 Subject: [PATCH 1/2] Added an ECSTasks module to handle standalone fargate tasks which are not auto-removed by the deletion of an ECS Service. --- resources/ecs-tasks.go | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 resources/ecs-tasks.go diff --git a/resources/ecs-tasks.go b/resources/ecs-tasks.go new file mode 100644 index 000000000..a1b9d93b2 --- /dev/null +++ b/resources/ecs-tasks.go @@ -0,0 +1,109 @@ +package resources + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ecs" + "github.com/rebuy-de/aws-nuke/v2/pkg/types" +) + +type ECSTask struct { + svc *ecs.ECS + taskARN *string + clusterARN *string +} + +func init() { + register("ECSTask", ListECSTasks) +} + +func ListECSTasks(sess *session.Session) ([]Resource, error) { + svc := ecs.New(sess) + resources := []Resource{} + clusters := []*string{} + + clusterParams := &ecs.ListClustersInput{ + MaxResults: aws.Int64(100), + } + + // Discover all clusters + for { + output, err := svc.ListClusters(clusterParams) + if err != nil { + return nil, err + } + + for _, clusterArn := range output.ClusterArns { + clusters = append(clusters, clusterArn) + } + + if output.NextToken == nil { + break + } + + clusterParams.NextToken = output.NextToken + } + + // Discover all running tasks from all clusters + for _, clusterArn := range clusters { + taskParams := &ecs.ListTasksInput{ + Cluster: clusterArn, + MaxResults: aws.Int64(10), + DesiredStatus: aws.String("RUNNING"), + } + output, err := svc.ListTasks(taskParams) + if err != nil { + return nil, err + } + + for _, taskArn := range output.TaskArns { + resources = append(resources, &ECSTask{ + svc: svc, + taskARN: taskArn, + clusterARN: clusterArn, + }) + } + + if output.NextToken == nil { + continue + } + + taskParams.NextToken = output.NextToken + } + + return resources, nil +} + +func (t *ECSTask) Filter() error { + return nil +} + +func (t *ECSTask) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("TaskARN", t.taskARN) + properties.Set("ClusterARN", t.clusterARN) + + return properties +} + +func (t *ECSTask) Remove() error { + // When StopTask is called on a task, the equivalent of docker stop is issued to the + // containers running in the task. This results in a SIGTERM value and a default + // 30-second timeout, after which the SIGKILL value is sent and the containers are + // forcibly stopped. If the container handles the SIGTERM value gracefully and exits + // within 30 seconds from receiving it, no SIGKILL value is sent. + + _, err := t.svc.StopTask(&ecs.StopTaskInput{ + Cluster: t.clusterARN, + Task: t.taskARN, + Reason: aws.String("Task stopped via AWS Nuke"), + }) + + return err +} + +func (t *ECSTask) String() string { + return fmt.Sprintf("%s -> %s", *t.taskARN, *t.clusterARN) +} From 51894cea476de4921af6f546f87b4f22ff0d2fc5 Mon Sep 17 00:00:00 2001 From: Sean Stoops Date: Thu, 27 Apr 2023 13:53:41 -0700 Subject: [PATCH 2/2] Removing deprecated String method. Eliminating a for-loop in the cluster query. --- resources/ecs-tasks.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/resources/ecs-tasks.go b/resources/ecs-tasks.go index a1b9d93b2..c492bd2df 100644 --- a/resources/ecs-tasks.go +++ b/resources/ecs-tasks.go @@ -1,8 +1,6 @@ package resources import ( - "fmt" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecs" @@ -35,9 +33,7 @@ func ListECSTasks(sess *session.Session) ([]Resource, error) { return nil, err } - for _, clusterArn := range output.ClusterArns { - clusters = append(clusters, clusterArn) - } + clusters = append(clusters, output.ClusterArns...) if output.NextToken == nil { break @@ -103,7 +99,3 @@ func (t *ECSTask) Remove() error { return err } - -func (t *ECSTask) String() string { - return fmt.Sprintf("%s -> %s", *t.taskARN, *t.clusterARN) -}