Add ECS CloudFormation support (#795)
* Add cloudformation support to AWS::ECS::Cluster * Add CloudFormation support to AWS::ECS::TaskDefinition * Add CloudFormation support to AWS::ECS::Service * Add support to update AWS::ECS::Cluster through CloudFormation * Fix Cluster.update_from_cloudformation_json to return original_resource if nothing changed * Implement TaskDefinition.update_from_cloudformation_json * Implement Service.update_from_cloudformation_json
This commit is contained in:
parent
a20906ff15
commit
0115267f2a
3 changed files with 366 additions and 2 deletions
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
import uuid
|
||||
from random import randint
|
||||
from random import randint, random
|
||||
|
||||
from moto.core import BaseBackend
|
||||
from moto.ec2 import ec2_backends
|
||||
|
|
@ -48,13 +48,39 @@ class Cluster(BaseObject):
|
|||
del response_object['arn'], response_object['name']
|
||||
return response_object
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
return ecs_backend.create_cluster(
|
||||
# ClusterName is optional in CloudFormation, thus create a random name if necessary
|
||||
cluster_name=properties.get('ClusterName', 'ecscluster{0}'.format(int(random() * 10 ** 6))),
|
||||
)
|
||||
@classmethod
|
||||
def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
|
||||
if original_resource.name != properties['ClusterName']:
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
ecs_backend.delete_cluster(original_resource.arn)
|
||||
return ecs_backend.create_cluster(
|
||||
# ClusterName is optional in CloudFormation, thus create a random name if necessary
|
||||
cluster_name=properties.get('ClusterName', 'ecscluster{0}'.format(int(random() * 10 ** 6))),
|
||||
)
|
||||
else:
|
||||
# no-op when nothing changed between old and new resources
|
||||
return original_resource
|
||||
|
||||
|
||||
class TaskDefinition(BaseObject):
|
||||
def __init__(self, family, revision, container_definitions, volumes=None):
|
||||
self.family = family
|
||||
self.arn = 'arn:aws:ecs:us-east-1:012345678910:task-definition/{0}:{1}'.format(family, revision)
|
||||
self.container_definitions = container_definitions
|
||||
if volumes is not None:
|
||||
if volumes is None:
|
||||
self.volumes = []
|
||||
else:
|
||||
self.volumes = volumes
|
||||
|
||||
@property
|
||||
|
|
@ -64,6 +90,37 @@ class TaskDefinition(BaseObject):
|
|||
del response_object['arn']
|
||||
return response_object
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
|
||||
family = properties.get('Family', 'task-definition-{0}'.format(int(random() * 10 ** 6)))
|
||||
container_definitions = properties['ContainerDefinitions']
|
||||
volumes = properties['Volumes']
|
||||
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
return ecs_backend.register_task_definition(
|
||||
family=family, container_definitions=container_definitions, volumes=volumes)
|
||||
|
||||
@classmethod
|
||||
def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
|
||||
family = properties.get('Family', 'task-definition-{0}'.format(int(random() * 10 ** 6)))
|
||||
container_definitions = properties['ContainerDefinitions']
|
||||
volumes = properties['Volumes']
|
||||
if (original_resource.family != family or
|
||||
original_resource.container_definitions != container_definitions or
|
||||
original_resource.volumes != volumes
|
||||
# currently TaskRoleArn isn't stored at TaskDefinition instances
|
||||
):
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
ecs_backend.deregister_task_definition(original_resource.arn)
|
||||
return ecs_backend.register_task_definition(
|
||||
family=family, container_definitions=container_definitions, volumes=volumes)
|
||||
else:
|
||||
# no-op when nothing changed between old and new resources
|
||||
return original_resource
|
||||
|
||||
class Task(BaseObject):
|
||||
def __init__(self, cluster, task_definition, container_instance_arn, overrides={}, started_by=''):
|
||||
|
|
@ -105,6 +162,51 @@ class Service(BaseObject):
|
|||
response_object['serviceArn'] = self.arn
|
||||
return response_object
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
if isinstance(properties['Cluster'], Cluster):
|
||||
cluster = properties['Cluster'].name
|
||||
else:
|
||||
cluster = properties['Cluster']
|
||||
if isinstance(properties['TaskDefinition'], TaskDefinition):
|
||||
task_definition = properties['TaskDefinition'].family
|
||||
else:
|
||||
task_definition = properties['TaskDefinition']
|
||||
service_name = '{0}Service{1}'.format(cluster, int(random() * 10 ** 6))
|
||||
desired_count = properties['DesiredCount']
|
||||
# TODO: LoadBalancers
|
||||
# TODO: Role
|
||||
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
return ecs_backend.create_service(
|
||||
cluster, service_name, task_definition, desired_count)
|
||||
|
||||
@classmethod
|
||||
def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):
|
||||
properties = cloudformation_json['Properties']
|
||||
if isinstance(properties['Cluster'], Cluster):
|
||||
cluster_name = properties['Cluster'].name
|
||||
else:
|
||||
cluster_name = properties['Cluster']
|
||||
if isinstance(properties['TaskDefinition'], TaskDefinition):
|
||||
task_definition = properties['TaskDefinition'].family
|
||||
else:
|
||||
task_definition = properties['TaskDefinition']
|
||||
desired_count = properties['DesiredCount']
|
||||
|
||||
ecs_backend = ecs_backends[region_name]
|
||||
service_name = original_resource.name
|
||||
if original_resource.cluster_arn != Cluster(cluster_name).arn:
|
||||
# TODO: LoadBalancers
|
||||
# TODO: Role
|
||||
ecs_backend.delete_service(cluster_name, service_name)
|
||||
new_service_name = '{0}Service{1}'.format(cluster_name, int(random() * 10 ** 6))
|
||||
return ecs_backend.create_service(
|
||||
cluster_name, new_service_name, task_definition, desired_count)
|
||||
else:
|
||||
return ecs_backend.update_service(cluster_name, service_name, task_definition, desired_count)
|
||||
|
||||
|
||||
class ContainerInstance(BaseObject):
|
||||
def __init__(self, ec2_instance_id):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue