Skip to content

Commit

Permalink
Move ecs policies and terminator classes into paas files
Browse files Browse the repository at this point in the history
Signed-off-by: Alina Buzachis <[email protected]>
  • Loading branch information
alinabuzachis committed Jun 7, 2022
1 parent f1af250 commit ba35199
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 124 deletions.
6 changes: 0 additions & 6 deletions aws/policy/compute.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@ Statement:
- t3.micro
- m1.large # lowest cost instance type with EBS optimization supported

- Sid: AllowGlobalUnrestrictedResourceActionsWhichIncurFees
Effect: Allow
Action:
- ecs:CreateCluster
Resource: "*"

# ASG and ELB don't like being region restricted.
- Sid: AllowGlobalUnrestrictedResourceActionsWhichIncurNoFees
Effect: Allow
Expand Down
33 changes: 33 additions & 0 deletions aws/policy/paas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,36 @@ Statement:
StringLike:
lambda:FunctionArn:
- arn:aws:lambda:{{ aws_region }}:{{ aws_account_id }}:function:*

- Sid: AllowGlobalUnrestrictedResourceActionsWhichIncurFees
Effect: Allow
Action:
- ecs:CreateCluster
Resource: "*"

- Sid: AllowGlobalUnrestrictedResourceActionsWhichIncurNoFees
Effect: Allow
Action:
- ecs:Describe*
- ecs:List*
- ecs:TagResource
- ecs:UntagResource
- ecs:PutAccountSetting
- ecs:RegisterTaskDefinition
- ecs:DeregisterTaskDefinition
Resource:
- "*"

- Sid: AllowGlobalRestrictedResourceActionsWhichIncurFees
Effect: Allow
Action:
- ecs:RunTask
- ecs:StartTask
- ecs:StopTask
- ecs:DeleteCluster
- ecs:CreateService
- ecs:DeleteService
- ecs:UpdateService
- ecs:UpdateCluster
Resource:
- 'arn:aws:ecs:{{ aws_region }}:{{ aws_account_id }}:*'
118 changes: 0 additions & 118 deletions aws/terminator/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,121 +618,3 @@ def created_time(self):

def terminate(self):
self.client.cancel_spot_instance_requests(SpotInstanceRequestIds=[self.id])


class Ecs(DbTerminator):
@property
def age_limit(self):
return datetime.timedelta(minutes=20)

@property
def name(self):
return self.instance['clusterName']

@staticmethod
def create(credentials):
def _paginate_cluster_results(client):
names = client.get_paginator('list_clusters').paginate(
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['clusterArns']

if not names:
return []

return client.describe_clusters(name=names)['clusters']

return Terminator._create(credentials, Ecs, 'ecs', _paginate_cluster_results)

def terminate(self):
def _paginate_task_results(container_instance):
names = self.client.get_paginator('list_tasks').paginate(
cluster=self.name,
containerInstance=container_instance,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['taskArns']

if not names:
return []

return self.client.describe_taks(cluster=self.name, tasks=names)['tasks']

def _paginate_container_instance_results():
names = self.client.get_paginator('list_container_instances').paginate(
cluster=self.name,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['containerInstanceArns']

if not names:
return []

return self.client.describe_container_instances(cluster=self.name, containerInstances=names)['containerInstances']

def _paginate_service_results():
names = self.client.get_paginator('list_services').paginate(
cluster=self.name,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['serviceArns']

if not names:
return []

return self.client.describe_services(cluster=self.name, services=names)['services']

container_instances = _paginate_container_instance_results()
for name in container_instances:
# If there are tasks running on a container instance, stop them first
tasks = _paginate_task_results(name['containerInstanceArn'])
for task in tasks:
self.client.stop_task(cluster=self.name, task=task['taskArn'])

# If there are running services, delete them first
services = _paginate_service_results()
for name in services:
self.client.delete_service(cluster=self.name, service=name['serviceName'], force=True)

# Deregister container instances
for name in container_instances:
self.client.deregister_container_instance(containerInstance=name['containerInstanceArn'])

# Delete cluster
try:
self.client.delete_cluster(cluster=self.name)
except (self.client.exceptions.ClusterContainsServicesException, self.client.exceptions.ClusterContainsTasksException):
pass


class EcsCluster(DbTerminator):
@property
def age_limit(self):
return datetime.timedelta(minutes=30)

@property
def name(self):
return self.instance['clusterName']

@staticmethod
def create(credentials):
def _paginate_cluster_results(client):
names = client.get_paginator('list_clusters').paginate(
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['clusterArns']

if not names:
return []

return client.describe_clusters(name=names)['clusters']

return Terminator._create(credentials, EcsCluster, 'ecs', _paginate_cluster_results)

def terminate(self):
self.client.delete_cluster(cluster=self.name)
120 changes: 120 additions & 0 deletions aws/terminator/paas.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import datetime

from . import DbTerminator, Terminator


Expand All @@ -20,3 +22,121 @@ def ignore(self) -> bool:

def terminate(self):
self.client.delete_event_source_mapping(UUID=self.id)


class Ecs(DbTerminator):
@property
def age_limit(self):
return datetime.timedelta(minutes=20)

@property
def name(self):
return self.instance['clusterName']

@staticmethod
def create(credentials):
def _paginate_cluster_results(client):
names = client.get_paginator('list_clusters').paginate(
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['clusterArns']

if not names:
return []

return client.describe_clusters(name=names)['clusters']

return Terminator._create(credentials, Ecs, 'ecs', _paginate_cluster_results)

def terminate(self):
def _paginate_task_results(container_instance):
names = self.client.get_paginator('list_tasks').paginate(
cluster=self.name,
containerInstance=container_instance,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['taskArns']

if not names:
return []

return self.client.describe_taks(cluster=self.name, tasks=names)['tasks']

def _paginate_container_instance_results():
names = self.client.get_paginator('list_container_instances').paginate(
cluster=self.name,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['containerInstanceArns']

if not names:
return []

return self.client.describe_container_instances(cluster=self.name, containerInstances=names)['containerInstances']

def _paginate_service_results():
names = self.client.get_paginator('list_services').paginate(
cluster=self.name,
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['serviceArns']

if not names:
return []

return self.client.describe_services(cluster=self.name, services=names)['services']

container_instances = _paginate_container_instance_results()
for name in container_instances:
# If there are tasks running on a container instance, stop them first
tasks = _paginate_task_results(name['containerInstanceArn'])
for task in tasks:
self.client.stop_task(cluster=self.name, task=task['taskArn'])

# If there are running services, delete them first
services = _paginate_service_results()
for name in services:
self.client.delete_service(cluster=self.name, service=name['serviceName'], force=True)

# Deregister container instances
for name in container_instances:
self.client.deregister_container_instance(containerInstance=name['containerInstanceArn'])

# Delete cluster
try:
self.client.delete_cluster(cluster=self.name)
except (self.client.exceptions.ClusterContainsServicesException, self.client.exceptions.ClusterContainsTasksException):
pass


class EcsCluster(DbTerminator):
@property
def age_limit(self):
return datetime.timedelta(minutes=30)

@property
def name(self):
return self.instance['clusterName']

@staticmethod
def create(credentials):
def _paginate_cluster_results(client):
names = client.get_paginator('list_clusters').paginate(
PaginationConfig={
'PageSize': 100,
}
).build_full_result()['clusterArns']

if not names:
return []

return client.describe_clusters(name=names)['clusters']

return Terminator._create(credentials, EcsCluster, 'ecs', _paginate_cluster_results)

def terminate(self):
self.client.delete_cluster(cluster=self.name)

0 comments on commit ba35199

Please sign in to comment.