Merge pull request #1537 from william-richard/cloudformation-ecs-cluster-name-optional
If Properies isn't set, cloudformation will just use default values
This commit is contained in:
		
						commit
						080e3c5f5d
					
				@ -51,3 +51,4 @@ Moto is written by Steve Pulec with contributions from:
 | 
				
			|||||||
* [Alex Morken](https://github.com/alexmorken)
 | 
					* [Alex Morken](https://github.com/alexmorken)
 | 
				
			||||||
* [Clive Li](https://github.com/cliveli)
 | 
					* [Clive Li](https://github.com/cliveli)
 | 
				
			||||||
* [Jim Shields](https://github.com/jimjshields)
 | 
					* [Jim Shields](https://github.com/jimjshields)
 | 
				
			||||||
 | 
					* [William Richard](https://github.com/william-richard)
 | 
				
			||||||
 | 
				
			|||||||
@ -61,7 +61,11 @@ class Cluster(BaseObject):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
 | 
					    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
 | 
				
			||||||
        properties = cloudformation_json['Properties']
 | 
					        # if properties is not provided, cloudformation will use the default values for all properties
 | 
				
			||||||
 | 
					        if 'Properties' in cloudformation_json:
 | 
				
			||||||
 | 
					            properties = cloudformation_json['Properties']
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            properties = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ecs_backend = ecs_backends[region_name]
 | 
					        ecs_backend = ecs_backends[region_name]
 | 
				
			||||||
        return ecs_backend.create_cluster(
 | 
					        return ecs_backend.create_cluster(
 | 
				
			||||||
 | 
				
			|||||||
@ -664,7 +664,7 @@ def test_list_container_instances():
 | 
				
			|||||||
            instanceIdentityDocument=instance_id_document)
 | 
					            instanceIdentityDocument=instance_id_document)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_instance_arns.append(response['containerInstance'][
 | 
					        test_instance_arns.append(response['containerInstance'][
 | 
				
			||||||
                                  'containerInstanceArn'])
 | 
					                                      'containerInstanceArn'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = ecs_client.list_container_instances(cluster=test_cluster_name)
 | 
					    response = ecs_client.list_container_instances(cluster=test_cluster_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -702,7 +702,7 @@ def test_describe_container_instances():
 | 
				
			|||||||
            instanceIdentityDocument=instance_id_document)
 | 
					            instanceIdentityDocument=instance_id_document)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_instance_arns.append(response['containerInstance'][
 | 
					        test_instance_arns.append(response['containerInstance'][
 | 
				
			||||||
                                  'containerInstanceArn'])
 | 
					                                      'containerInstanceArn'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test_instance_ids = list(
 | 
					    test_instance_ids = list(
 | 
				
			||||||
        map((lambda x: x.split('/')[1]), test_instance_arns))
 | 
					        map((lambda x: x.split('/')[1]), test_instance_arns))
 | 
				
			||||||
@ -1052,7 +1052,7 @@ def test_describe_tasks():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    len(response['tasks']).should.equal(2)
 | 
					    len(response['tasks']).should.equal(2)
 | 
				
			||||||
    set([response['tasks'][0]['taskArn'], response['tasks']
 | 
					    set([response['tasks'][0]['taskArn'], response['tasks']
 | 
				
			||||||
         [1]['taskArn']]).should.equal(set(tasks_arns))
 | 
					    [1]['taskArn']]).should.equal(set(tasks_arns))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_ecs
 | 
					@mock_ecs
 | 
				
			||||||
@ -1208,7 +1208,8 @@ def test_resource_reservation_and_release():
 | 
				
			|||||||
        cluster='test_ecs_cluster',
 | 
					        cluster='test_ecs_cluster',
 | 
				
			||||||
        containerInstances=[container_instance_arn]
 | 
					        containerInstances=[container_instance_arn]
 | 
				
			||||||
    )['containerInstances'][0]
 | 
					    )['containerInstances'][0]
 | 
				
			||||||
    remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
 | 
					    remaining_resources, registered_resources = _fetch_container_instance_resources(
 | 
				
			||||||
 | 
					        container_instance_description)
 | 
				
			||||||
    remaining_resources['CPU'].should.equal(registered_resources['CPU'] - 1024)
 | 
					    remaining_resources['CPU'].should.equal(registered_resources['CPU'] - 1024)
 | 
				
			||||||
    remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'] - 400)
 | 
					    remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'] - 400)
 | 
				
			||||||
    registered_resources['PORTS'].append('80')
 | 
					    registered_resources['PORTS'].append('80')
 | 
				
			||||||
@ -1223,7 +1224,8 @@ def test_resource_reservation_and_release():
 | 
				
			|||||||
        cluster='test_ecs_cluster',
 | 
					        cluster='test_ecs_cluster',
 | 
				
			||||||
        containerInstances=[container_instance_arn]
 | 
					        containerInstances=[container_instance_arn]
 | 
				
			||||||
    )['containerInstances'][0]
 | 
					    )['containerInstances'][0]
 | 
				
			||||||
    remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
 | 
					    remaining_resources, registered_resources = _fetch_container_instance_resources(
 | 
				
			||||||
 | 
					        container_instance_description)
 | 
				
			||||||
    remaining_resources['CPU'].should.equal(registered_resources['CPU'])
 | 
					    remaining_resources['CPU'].should.equal(registered_resources['CPU'])
 | 
				
			||||||
    remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'])
 | 
					    remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'])
 | 
				
			||||||
    remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
 | 
					    remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
 | 
				
			||||||
@ -1327,6 +1329,36 @@ def test_create_cluster_through_cloudformation():
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    template_json = json.dumps(template)
 | 
					    template_json = json.dumps(template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ecs_conn = boto3.client('ecs', region_name='us-west-1')
 | 
				
			||||||
 | 
					    resp = ecs_conn.list_clusters()
 | 
				
			||||||
 | 
					    len(resp['clusterArns']).should.equal(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
 | 
				
			||||||
 | 
					    cfn_conn.create_stack(
 | 
				
			||||||
 | 
					        StackName="test_stack",
 | 
				
			||||||
 | 
					        TemplateBody=template_json,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = ecs_conn.list_clusters()
 | 
				
			||||||
 | 
					    len(resp['clusterArns']).should.equal(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@mock_ecs
 | 
				
			||||||
 | 
					@mock_cloudformation
 | 
				
			||||||
 | 
					def test_create_cluster_through_cloudformation_no_name():
 | 
				
			||||||
 | 
					    # cloudformation should create a cluster name for you if you do not provide it
 | 
				
			||||||
 | 
					    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-clustername
 | 
				
			||||||
 | 
					    template = {
 | 
				
			||||||
 | 
					        "AWSTemplateFormatVersion": "2010-09-09",
 | 
				
			||||||
 | 
					        "Description": "ECS Cluster Test CloudFormation",
 | 
				
			||||||
 | 
					        "Resources": {
 | 
				
			||||||
 | 
					            "testCluster": {
 | 
				
			||||||
 | 
					                "Type": "AWS::ECS::Cluster",
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    template_json = json.dumps(template)
 | 
				
			||||||
    cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
 | 
					    cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
 | 
				
			||||||
    cfn_conn.create_stack(
 | 
					    cfn_conn.create_stack(
 | 
				
			||||||
        StackName="test_stack",
 | 
					        StackName="test_stack",
 | 
				
			||||||
@ -1760,7 +1792,8 @@ def test_attributes():
 | 
				
			|||||||
        attributes=[
 | 
					        attributes=[
 | 
				
			||||||
            {'name': 'env', 'value': 'prod'},
 | 
					            {'name': 'env', 'value': 'prod'},
 | 
				
			||||||
            {'name': 'attr1', 'value': 'instance1', 'targetId': full_arn1},
 | 
					            {'name': 'attr1', 'value': 'instance1', 'targetId': full_arn1},
 | 
				
			||||||
            {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2, 'targetType': 'container-instance'}
 | 
					            {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2,
 | 
				
			||||||
 | 
					             'targetType': 'container-instance'}
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1776,12 +1809,14 @@ def test_attributes():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Tests that the attrs have been set properly
 | 
					    # Tests that the attrs have been set properly
 | 
				
			||||||
    len(list(filter(lambda item: item['name'] == 'env', attrs))).should.equal(2)
 | 
					    len(list(filter(lambda item: item['name'] == 'env', attrs))).should.equal(2)
 | 
				
			||||||
    len(list(filter(lambda item: item['name'] == 'attr1' and item['value'] == 'instance1', attrs))).should.equal(1)
 | 
					    len(list(
 | 
				
			||||||
 | 
					        filter(lambda item: item['name'] == 'attr1' and item['value'] == 'instance1', attrs))).should.equal(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ecs_client.delete_attributes(
 | 
					    ecs_client.delete_attributes(
 | 
				
			||||||
        cluster=test_cluster_name,
 | 
					        cluster=test_cluster_name,
 | 
				
			||||||
        attributes=[
 | 
					        attributes=[
 | 
				
			||||||
            {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2, 'targetType': 'container-instance'}
 | 
					            {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2,
 | 
				
			||||||
 | 
					             'targetType': 'container-instance'}
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    NUM_CUSTOM_ATTRIBUTES -= 1
 | 
					    NUM_CUSTOM_ATTRIBUTES -= 1
 | 
				
			||||||
@ -1892,7 +1927,8 @@ def test_default_container_instance_attributes():
 | 
				
			|||||||
        {'name': 'ecs.instance-type', 'value': test_instance.instance_type},
 | 
					        {'name': 'ecs.instance-type', 'value': test_instance.instance_type},
 | 
				
			||||||
        {'name': 'ecs.os-type', 'value': test_instance.platform or 'linux'}
 | 
					        {'name': 'ecs.os-type', 'value': test_instance.platform or 'linux'}
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    assert sorted(default_attributes, key=lambda item: item['name']) == sorted(expected_result, key=lambda item: item['name'])
 | 
					    assert sorted(default_attributes, key=lambda item: item['name']) == sorted(expected_result,
 | 
				
			||||||
 | 
					                                                                               key=lambda item: item['name'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_ec2
 | 
					@mock_ec2
 | 
				
			||||||
@ -1932,17 +1968,19 @@ def test_describe_container_instances_with_attributes():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Set attributes on container instance, one without a value
 | 
					    # Set attributes on container instance, one without a value
 | 
				
			||||||
    attributes = [
 | 
					    attributes = [
 | 
				
			||||||
            {'name': 'env', 'value': 'prod'},
 | 
					        {'name': 'env', 'value': 'prod'},
 | 
				
			||||||
            {'name': 'attr1', 'value': 'instance1', 'targetId': container_instance_id, 'targetType': 'container-instance'},
 | 
					        {'name': 'attr1', 'value': 'instance1', 'targetId': container_instance_id,
 | 
				
			||||||
            {'name': 'attr_without_value'}
 | 
					         'targetType': 'container-instance'},
 | 
				
			||||||
        ]
 | 
					        {'name': 'attr_without_value'}
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
    ecs_client.put_attributes(
 | 
					    ecs_client.put_attributes(
 | 
				
			||||||
        cluster=test_cluster_name,
 | 
					        cluster=test_cluster_name,
 | 
				
			||||||
        attributes=attributes
 | 
					        attributes=attributes
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Describe container instance, should have attributes previously set
 | 
					    # Describe container instance, should have attributes previously set
 | 
				
			||||||
    described_instance = ecs_client.describe_container_instances(cluster=test_cluster_name, containerInstances=[container_instance_id])
 | 
					    described_instance = ecs_client.describe_container_instances(cluster=test_cluster_name,
 | 
				
			||||||
 | 
					                                                                 containerInstances=[container_instance_id])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert len(described_instance['containerInstances']) == 1
 | 
					    assert len(described_instance['containerInstances']) == 1
 | 
				
			||||||
    assert isinstance(described_instance['containerInstances'][0]['attributes'], list)
 | 
					    assert isinstance(described_instance['containerInstances'][0]['attributes'], list)
 | 
				
			||||||
@ -1953,7 +1991,8 @@ def test_describe_container_instances_with_attributes():
 | 
				
			|||||||
        attribute.pop('targetId', None)
 | 
					        attribute.pop('targetId', None)
 | 
				
			||||||
        attribute.pop('targetType', None)
 | 
					        attribute.pop('targetType', None)
 | 
				
			||||||
        cleaned_attributes.append(attribute)
 | 
					        cleaned_attributes.append(attribute)
 | 
				
			||||||
    described_attributes = sorted(described_instance['containerInstances'][0]['attributes'], key=lambda item: item['name'])
 | 
					    described_attributes = sorted(described_instance['containerInstances'][0]['attributes'],
 | 
				
			||||||
 | 
					                                  key=lambda item: item['name'])
 | 
				
			||||||
    expected_attributes = sorted(default_attributes + cleaned_attributes, key=lambda item: item['name'])
 | 
					    expected_attributes = sorted(default_attributes + cleaned_attributes, key=lambda item: item['name'])
 | 
				
			||||||
    assert described_attributes == expected_attributes
 | 
					    assert described_attributes == expected_attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1963,10 +2002,16 @@ def _fetch_container_instance_resources(container_instance_description):
 | 
				
			|||||||
    registered_resources = {}
 | 
					    registered_resources = {}
 | 
				
			||||||
    remaining_resources_list = container_instance_description['remainingResources']
 | 
					    remaining_resources_list = container_instance_description['remainingResources']
 | 
				
			||||||
    registered_resources_list = container_instance_description['registeredResources']
 | 
					    registered_resources_list = container_instance_description['registeredResources']
 | 
				
			||||||
    remaining_resources['CPU'] = [x['integerValue'] for x in remaining_resources_list if x['name'] == 'CPU'][0]
 | 
					    remaining_resources['CPU'] = [x['integerValue'] for x in remaining_resources_list if x['name'] == 'CPU'][
 | 
				
			||||||
    remaining_resources['MEMORY'] = [x['integerValue'] for x in remaining_resources_list if x['name'] == 'MEMORY'][0]
 | 
					        0]
 | 
				
			||||||
    remaining_resources['PORTS'] = [x['stringSetValue'] for x in remaining_resources_list if x['name'] == 'PORTS'][0]
 | 
					    remaining_resources['MEMORY'] = \
 | 
				
			||||||
    registered_resources['CPU'] = [x['integerValue'] for x in registered_resources_list if x['name'] == 'CPU'][0]
 | 
					    [x['integerValue'] for x in remaining_resources_list if x['name'] == 'MEMORY'][0]
 | 
				
			||||||
    registered_resources['MEMORY'] = [x['integerValue'] for x in registered_resources_list if x['name'] == 'MEMORY'][0]
 | 
					    remaining_resources['PORTS'] = \
 | 
				
			||||||
    registered_resources['PORTS'] = [x['stringSetValue'] for x in registered_resources_list if x['name'] == 'PORTS'][0]
 | 
					    [x['stringSetValue'] for x in remaining_resources_list if x['name'] == 'PORTS'][0]
 | 
				
			||||||
 | 
					    registered_resources['CPU'] = \
 | 
				
			||||||
 | 
					    [x['integerValue'] for x in registered_resources_list if x['name'] == 'CPU'][0]
 | 
				
			||||||
 | 
					    registered_resources['MEMORY'] = \
 | 
				
			||||||
 | 
					    [x['integerValue'] for x in registered_resources_list if x['name'] == 'MEMORY'][0]
 | 
				
			||||||
 | 
					    registered_resources['PORTS'] = \
 | 
				
			||||||
 | 
					    [x['stringSetValue'] for x in registered_resources_list if x['name'] == 'PORTS'][0]
 | 
				
			||||||
    return remaining_resources, registered_resources
 | 
					    return remaining_resources, registered_resources
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user