diff --git a/AUTHORS.md b/AUTHORS.md index 08757d2bb..5d5b99a06 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -45,3 +45,4 @@ Moto is written by Steve Pulec with contributions from: * [Tom Viner](https://github.com/tomviner) * [Justin Wiley](https://github.com/SectorNine50) * [Adam Stauffer](https://github.com/adamstauffer) +* [Guy Templeton](https://github.com/gjtempleton) diff --git a/moto/ecs/models.py b/moto/ecs/models.py index e4258cee1..22835ecbb 100644 --- a/moto/ecs/models.py +++ b/moto/ecs/models.py @@ -652,6 +652,7 @@ class EC2ContainerServiceBackend(BaseBackend): '/')[-1] self.container_instances[cluster_name][ container_instance_id] = container_instance + self.clusters[cluster_name].registered_container_instances_count += 1 return container_instance def list_container_instances(self, cluster_str): @@ -715,8 +716,10 @@ class EC2ContainerServiceBackend(BaseBackend): resource["stringSetValue"].remove(str(port)) else: resource["stringSetValue"].append(str(port)) + container_instance.runningTaskCount += resource_multiplier * 1 def deregister_container_instance(self, cluster_str, container_instance_str, force): + failures = [] cluster_name = cluster_str.split('/')[-1] if cluster_name not in self.clusters: raise Exception("{0} is not a cluster".format(cluster_name)) @@ -724,18 +727,18 @@ class EC2ContainerServiceBackend(BaseBackend): container_instance = self.container_instances[cluster_name].get(container_instance_id) if container_instance is None: raise Exception("{0} is not a container id in the cluster") - if not force and container_instance.running_tasks_count > 0: + if not force and container_instance.runningTaskCount > 0: raise Exception("Found running tasks on the instance.") # Currently assume that people might want to do something based around deregistered instances # with tasks left running on them - but nothing if deregistration is forced or no tasks were # running already - elif force and container_instance.running_tasks_count > 0: + elif force and container_instance.runningTaskCount > 0: if not self.container_instances.get('orphaned'): self.container_instances['orphaned'] = {} self.container_instances['orphaned'][container_instance_id] = container_instance del(self.container_instances[cluster_name][container_instance_id]) self._respond_to_cluster_state_update(cluster_str) - pass + return container_instance, failures def _respond_to_cluster_state_update(self, cluster_str): cluster_name = cluster_str.split('/')[-1] diff --git a/moto/ecs/responses.py b/moto/ecs/responses.py index 6c8fd8e2d..50d9e3cd4 100644 --- a/moto/ecs/responses.py +++ b/moto/ecs/responses.py @@ -204,10 +204,12 @@ class EC2ContainerServiceResponse(BaseResponse): }) def deregister_container_instance(self): - cluster_str = self._get_param('cluster', 'default'), + cluster_str = self._get_param('cluster') + if not cluster_str: + cluster_str = 'default' container_instance_str = self._get_param('containerInstance') - force = self._get_param('force', False) - container_instance = self.ecs_backend.deregister_container_instance( + force = self._get_param('force') + container_instance, failures = self.ecs_backend.deregister_container_instance( cluster_str, container_instance_str, force ) return json.dumps({ diff --git a/tests/test_ecs/test_ecs_boto3.py b/tests/test_ecs/test_ecs_boto3.py index e76be8cbe..7be782740 100644 --- a/tests/test_ecs/test_ecs_boto3.py +++ b/tests/test_ecs/test_ecs_boto3.py @@ -11,6 +11,7 @@ from uuid import UUID from moto import mock_cloudformation from moto import mock_ecs from moto import mock_ec2 +from nose.tools import assert_raises @mock_ecs @@ -542,6 +543,92 @@ def test_register_container_instance(): 'dockerVersion'].should.equal('DockerVersion: 1.5.0') +@mock_ec2 +@mock_ecs +def test_deregister_container_instance(): + ecs_client = boto3.client('ecs', region_name='us-east-1') + ec2 = boto3.resource('ec2', region_name='us-east-1') + + test_cluster_name = 'test_ecs_cluster' + + _ = ecs_client.create_cluster( + clusterName=test_cluster_name + ) + + test_instance = ec2.create_instances( + ImageId="ami-1234abcd", + MinCount=1, + MaxCount=1, + )[0] + + instance_id_document = json.dumps( + ec2_utils.generate_instance_identity_document(test_instance) + ) + + response = ecs_client.register_container_instance( + cluster=test_cluster_name, + instanceIdentityDocument=instance_id_document + ) + container_instance_id = response['containerInstance']['containerInstanceArn'] + response = ecs_client.deregister_container_instance( + cluster=test_cluster_name, + containerInstance=container_instance_id + ) + container_instances_response = ecs_client.list_container_instances( + cluster=test_cluster_name + ) + len(container_instances_response['containerInstanceArns']).should.equal(0) + + response = ecs_client.register_container_instance( + cluster=test_cluster_name, + instanceIdentityDocument=instance_id_document + ) + container_instance_id = response['containerInstance']['containerInstanceArn'] + _ = ecs_client.register_task_definition( + family='test_ecs_task', + containerDefinitions=[ + { + 'name': 'hello_world', + 'image': 'docker/hello-world:latest', + 'cpu': 1024, + 'memory': 400, + 'essential': True, + 'environment': [{ + 'name': 'AWS_ACCESS_KEY_ID', + 'value': 'SOME_ACCESS_KEY' + }], + 'logConfiguration': {'logDriver': 'json-file'} + } + ] + ) + + response = ecs_client.start_task( + cluster='test_ecs_cluster', + taskDefinition='test_ecs_task', + overrides={}, + containerInstances=[container_instance_id], + startedBy='moto' + ) + with assert_raises(Exception) as e: + ecs_client.deregister_container_instance( + cluster=test_cluster_name, + containerInstance=container_instance_id + ).should.have.raised(Exception) + container_instances_response = ecs_client.list_container_instances( + cluster=test_cluster_name + ) + len(container_instances_response['containerInstanceArns']).should.equal(1) + ecs_client.deregister_container_instance( + cluster=test_cluster_name, + containerInstance=container_instance_id, + force=True + ) + container_instances_response = ecs_client.list_container_instances( + cluster=test_cluster_name + ) + len(container_instances_response['containerInstanceArns']).should.equal(0) + + @mock_ec2 @mock_ecs def test_list_container_instances():