2015-12-17 17:13:00 +00:00
|
|
|
from __future__ import unicode_literals
|
2019-08-03 11:56:07 +00:00
|
|
|
from datetime import datetime
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
from copy import deepcopy
|
|
|
|
|
2018-06-25 00:13:39 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2015-12-17 17:13:00 +00:00
|
|
|
import boto3
|
|
|
|
import sure # noqa
|
2016-06-11 10:52:53 +00:00
|
|
|
import json
|
|
|
|
from moto.ec2 import utils as ec2_utils
|
|
|
|
from uuid import UUID
|
2015-12-17 17:13:00 +00:00
|
|
|
|
2018-06-04 13:35:22 +00:00
|
|
|
from moto import mock_cloudformation, mock_elbv2
|
2015-12-17 17:13:00 +00:00
|
|
|
from moto import mock_ecs
|
2016-06-11 10:52:53 +00:00
|
|
|
from moto import mock_ec2
|
2017-04-13 16:46:15 +00:00
|
|
|
from nose.tools import assert_raises
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_create_cluster():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
response = client.create_cluster(clusterName="test_ecs_cluster")
|
|
|
|
response["cluster"]["clusterName"].should.equal("test_ecs_cluster")
|
|
|
|
response["cluster"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["cluster"]["status"].should.equal("ACTIVE")
|
|
|
|
response["cluster"]["registeredContainerInstancesCount"].should.equal(0)
|
|
|
|
response["cluster"]["runningTasksCount"].should.equal(0)
|
|
|
|
response["cluster"]["pendingTasksCount"].should.equal(0)
|
|
|
|
response["cluster"]["activeServicesCount"].should.equal(0)
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_clusters():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-2")
|
|
|
|
_ = client.create_cluster(clusterName="test_cluster0")
|
|
|
|
_ = client.create_cluster(clusterName="test_cluster1")
|
|
|
|
response = client.list_clusters()
|
|
|
|
response["clusterArns"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-2:012345678910:cluster/test_cluster0"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["clusterArns"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-2:012345678910:cluster/test_cluster1"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-03-22 16:08:02 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_describe_clusters():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2019-03-22 16:08:02 +00:00
|
|
|
response = client.describe_clusters(clusters=["some-cluster"])
|
2019-10-31 15:44:26 +00:00
|
|
|
response["failures"].should.contain(
|
|
|
|
{
|
|
|
|
"arn": "arn:aws:ecs:us-east-1:012345678910:cluster/some-cluster",
|
|
|
|
"reason": "MISSING",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2019-03-22 16:08:02 +00:00
|
|
|
|
2015-12-17 17:13:00 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_delete_cluster():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
|
|
|
response = client.delete_cluster(cluster="test_ecs_cluster")
|
|
|
|
response["cluster"]["clusterName"].should.equal("test_ecs_cluster")
|
|
|
|
response["cluster"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["cluster"]["status"].should.equal("ACTIVE")
|
|
|
|
response["cluster"]["registeredContainerInstancesCount"].should.equal(0)
|
|
|
|
response["cluster"]["runningTasksCount"].should.equal(0)
|
|
|
|
response["cluster"]["pendingTasksCount"].should.equal(0)
|
|
|
|
response["cluster"]["activeServicesCount"].should.equal(0)
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
response = client.list_clusters()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["clusterArns"]).should.equal(0)
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_register_task_definition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2015-12-17 17:13:00 +00:00
|
|
|
response = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-07-26 13:11:25 +00:00
|
|
|
],
|
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "bar"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
type(response["taskDefinition"]).should.be(dict)
|
|
|
|
response["taskDefinition"]["revision"].should.equal(1)
|
|
|
|
response["taskDefinition"]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["name"].should.equal(
|
|
|
|
"hello_world"
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["image"].should.equal(
|
|
|
|
"docker/hello-world:latest"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["cpu"].should.equal(1024)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["memory"].should.equal(400)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["essential"].should.equal(
|
|
|
|
True
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["environment"][0][
|
|
|
|
"name"
|
|
|
|
].should.equal("AWS_ACCESS_KEY_ID")
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["environment"][0][
|
|
|
|
"value"
|
|
|
|
].should.equal("SOME_ACCESS_KEY")
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["logConfiguration"][
|
|
|
|
"logDriver"
|
|
|
|
].should.equal("json-file")
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_task_definitions():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world2",
|
|
|
|
"image": "docker/hello-world2:latest",
|
|
|
|
"cpu": 1024,
|
|
|
|
"memory": 400,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY2"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
response = client.list_task_definitions()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["taskDefinitionArns"]).should.equal(2)
|
|
|
|
response["taskDefinitionArns"][0].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["taskDefinitionArns"][1].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:2"
|
|
|
|
)
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
2019-11-26 14:17:54 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_list_task_definitions_with_family_prefix():
|
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.register_task_definition(
|
|
|
|
family="test_ecs_task_a",
|
|
|
|
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"},
|
|
|
|
}
|
|
|
|
],
|
|
|
|
)
|
|
|
|
_ = client.register_task_definition(
|
|
|
|
family="test_ecs_task_a",
|
|
|
|
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"},
|
|
|
|
}
|
|
|
|
],
|
|
|
|
)
|
|
|
|
_ = client.register_task_definition(
|
|
|
|
family="test_ecs_task_b",
|
|
|
|
containerDefinitions=[
|
|
|
|
{
|
|
|
|
"name": "hello_world2",
|
|
|
|
"image": "docker/hello-world2:latest",
|
|
|
|
"cpu": 1024,
|
|
|
|
"memory": 400,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY2"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
|
|
|
}
|
|
|
|
],
|
|
|
|
)
|
|
|
|
empty_response = client.list_task_definitions(familyPrefix="test_ecs_task")
|
|
|
|
len(empty_response["taskDefinitionArns"]).should.equal(0)
|
|
|
|
filtered_response = client.list_task_definitions(familyPrefix="test_ecs_task_a")
|
|
|
|
len(filtered_response["taskDefinitionArns"]).should.equal(2)
|
|
|
|
filtered_response["taskDefinitionArns"][0].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task_a:1"
|
|
|
|
)
|
|
|
|
filtered_response["taskDefinitionArns"][1].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task_a:2"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2016-11-24 00:56:12 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_describe_task_definition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2016-11-24 00:56:12 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-11-24 00:56:12 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-11-24 00:56:12 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-11-24 00:56:12 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world2",
|
|
|
|
"image": "docker/hello-world2:latest",
|
|
|
|
"cpu": 1024,
|
|
|
|
"memory": 400,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY2"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
2016-11-24 00:56:12 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-11-24 00:56:12 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world3",
|
|
|
|
"image": "docker/hello-world3:latest",
|
|
|
|
"cpu": 1024,
|
|
|
|
"memory": 400,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY3"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
2016-11-24 00:56:12 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
|
|
|
)
|
|
|
|
response = client.describe_task_definition(taskDefinition="test_ecs_task")
|
|
|
|
response["taskDefinition"]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:3"
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.describe_task_definition(taskDefinition="test_ecs_task:2")
|
|
|
|
response["taskDefinition"]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:2"
|
|
|
|
)
|
2016-11-24 00:56:12 +00:00
|
|
|
|
|
|
|
|
2015-12-17 17:13:00 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_deregister_task_definition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
|
|
|
)
|
|
|
|
response = client.deregister_task_definition(taskDefinition="test_ecs_task:1")
|
|
|
|
type(response["taskDefinition"]).should.be(dict)
|
|
|
|
response["taskDefinition"]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["name"].should.equal(
|
|
|
|
"hello_world"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["image"].should.equal(
|
|
|
|
"docker/hello-world:latest"
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["cpu"].should.equal(1024)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["memory"].should.equal(400)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["essential"].should.equal(
|
|
|
|
True
|
|
|
|
)
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["environment"][0][
|
|
|
|
"name"
|
|
|
|
].should.equal("AWS_ACCESS_KEY_ID")
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["environment"][0][
|
|
|
|
"value"
|
|
|
|
].should.equal("SOME_ACCESS_KEY")
|
|
|
|
response["taskDefinition"]["containerDefinitions"][0]["logConfiguration"][
|
|
|
|
"logDriver"
|
|
|
|
].should.equal("json-file")
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_create_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
|
|
|
)
|
|
|
|
response["service"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["service"]["desiredCount"].should.equal(2)
|
|
|
|
len(response["service"]["events"]).should.equal(0)
|
|
|
|
len(response["service"]["loadBalancers"]).should.equal(0)
|
|
|
|
response["service"]["pendingCount"].should.equal(0)
|
|
|
|
response["service"]["runningCount"].should.equal(0)
|
|
|
|
response["service"]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service"
|
|
|
|
)
|
|
|
|
response["service"]["serviceName"].should.equal("test_ecs_service")
|
|
|
|
response["service"]["status"].should.equal("ACTIVE")
|
|
|
|
response["service"]["taskDefinition"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["service"]["schedulingStrategy"].should.equal("REPLICA")
|
|
|
|
|
2018-08-13 15:09:39 +00:00
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_create_service_scheduling_strategy():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2018-08-13 15:09:39 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2018-08-13 15:09:39 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2018-08-13 15:09:39 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2018-08-13 15:09:39 +00:00
|
|
|
desiredCount=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
schedulingStrategy="DAEMON",
|
|
|
|
)
|
|
|
|
response["service"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["service"]["desiredCount"].should.equal(2)
|
|
|
|
len(response["service"]["events"]).should.equal(0)
|
|
|
|
len(response["service"]["loadBalancers"]).should.equal(0)
|
|
|
|
response["service"]["pendingCount"].should.equal(0)
|
|
|
|
response["service"]["runningCount"].should.equal(0)
|
|
|
|
response["service"]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service"
|
|
|
|
)
|
|
|
|
response["service"]["serviceName"].should.equal("test_ecs_service")
|
|
|
|
response["service"]["status"].should.equal("ACTIVE")
|
|
|
|
response["service"]["taskDefinition"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["service"]["schedulingStrategy"].should.equal("DAEMON")
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_services():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service1",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
schedulingStrategy="REPLICA",
|
|
|
|
desiredCount=2,
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service2",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
schedulingStrategy="DAEMON",
|
|
|
|
desiredCount=2,
|
|
|
|
)
|
|
|
|
unfiltered_response = client.list_services(cluster="test_ecs_cluster")
|
|
|
|
len(unfiltered_response["serviceArns"]).should.equal(2)
|
|
|
|
unfiltered_response["serviceArns"][0].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
unfiltered_response["serviceArns"][1].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2"
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
|
2019-05-02 18:00:28 +00:00
|
|
|
filtered_response = client.list_services(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", schedulingStrategy="REPLICA"
|
2019-05-02 18:00:28 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(filtered_response["serviceArns"]).should.equal(1)
|
|
|
|
filtered_response["serviceArns"][0].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1"
|
|
|
|
)
|
|
|
|
|
2015-12-17 17:13:00 +00:00
|
|
|
|
2016-11-24 00:56:12 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_describe_services():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2016-11-24 00:56:12 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-11-24 00:56:12 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-11-24 00:56:12 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service1",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service2",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service3",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2016-11-24 00:56:12 +00:00
|
|
|
)
|
|
|
|
response = client.describe_services(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
services=[
|
|
|
|
"test_ecs_service1",
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
len(response["services"]).should.equal(2)
|
|
|
|
response["services"][0]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1"
|
|
|
|
)
|
|
|
|
response["services"][0]["serviceName"].should.equal("test_ecs_service1")
|
|
|
|
response["services"][1]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2"
|
|
|
|
)
|
|
|
|
response["services"][1]["serviceName"].should.equal("test_ecs_service2")
|
|
|
|
|
|
|
|
response["services"][0]["deployments"][0]["desiredCount"].should.equal(2)
|
|
|
|
response["services"][0]["deployments"][0]["pendingCount"].should.equal(2)
|
|
|
|
response["services"][0]["deployments"][0]["runningCount"].should.equal(0)
|
|
|
|
response["services"][0]["deployments"][0]["status"].should.equal("PRIMARY")
|
|
|
|
(
|
|
|
|
datetime.now()
|
|
|
|
- response["services"][0]["deployments"][0]["createdAt"].replace(tzinfo=None)
|
|
|
|
).seconds.should.be.within(0, 10)
|
|
|
|
(
|
|
|
|
datetime.now()
|
|
|
|
- response["services"][0]["deployments"][0]["updatedAt"].replace(tzinfo=None)
|
|
|
|
).seconds.should.be.within(0, 10)
|
2017-04-14 16:40:47 +00:00
|
|
|
|
2016-11-24 00:56:12 +00:00
|
|
|
|
2018-08-13 15:09:39 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_describe_services_scheduling_strategy():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2018-08-13 15:09:39 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2018-08-13 15:09:39 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2018-08-13 15:09:39 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service1",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service2",
|
|
|
|
taskDefinition="test_ecs_task",
|
2018-08-13 15:09:39 +00:00
|
|
|
desiredCount=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
schedulingStrategy="DAEMON",
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service3",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
|
|
|
response = client.describe_services(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
services=[
|
|
|
|
"test_ecs_service1",
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2",
|
|
|
|
"test_ecs_service3",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
len(response["services"]).should.equal(3)
|
|
|
|
response["services"][0]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1"
|
2018-08-13 15:09:39 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["services"][0]["serviceName"].should.equal("test_ecs_service1")
|
|
|
|
response["services"][1]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2"
|
|
|
|
)
|
|
|
|
response["services"][1]["serviceName"].should.equal("test_ecs_service2")
|
2018-08-13 15:09:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["services"][0]["deployments"][0]["desiredCount"].should.equal(2)
|
|
|
|
response["services"][0]["deployments"][0]["pendingCount"].should.equal(2)
|
|
|
|
response["services"][0]["deployments"][0]["runningCount"].should.equal(0)
|
|
|
|
response["services"][0]["deployments"][0]["status"].should.equal("PRIMARY")
|
2018-08-13 15:09:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["services"][0]["schedulingStrategy"].should.equal("REPLICA")
|
|
|
|
response["services"][1]["schedulingStrategy"].should.equal("DAEMON")
|
|
|
|
response["services"][2]["schedulingStrategy"].should.equal("REPLICA")
|
2018-08-13 15:09:39 +00:00
|
|
|
|
|
|
|
|
2015-12-17 17:13:00 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_update_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["service"]["desiredCount"].should.equal(2)
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
response = client.update_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
service="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=0,
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["service"]["desiredCount"].should.equal(0)
|
|
|
|
response["service"]["schedulingStrategy"].should.equal("REPLICA")
|
2015-12-17 17:13:00 +00:00
|
|
|
|
|
|
|
|
2018-06-25 00:13:39 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_update_missing_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2018-06-25 00:13:39 +00:00
|
|
|
|
|
|
|
client.update_service.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
service="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=0,
|
2018-06-25 00:13:39 +00:00
|
|
|
).should.throw(ClientError)
|
|
|
|
|
|
|
|
|
2015-12-17 17:13:00 +00:00
|
|
|
@mock_ecs
|
|
|
|
def test_delete_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2015-12-17 17:13:00 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2015-12-17 17:13:00 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2015-12-17 17:13:00 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
_ = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
_ = client.update_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", service="test_ecs_service", desiredCount=0
|
2015-12-17 17:13:00 +00:00
|
|
|
)
|
|
|
|
response = client.delete_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", service="test_ecs_service"
|
|
|
|
)
|
|
|
|
response["service"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["service"]["desiredCount"].should.equal(0)
|
|
|
|
len(response["service"]["events"]).should.equal(0)
|
|
|
|
len(response["service"]["loadBalancers"]).should.equal(0)
|
|
|
|
response["service"]["pendingCount"].should.equal(0)
|
|
|
|
response["service"]["runningCount"].should.equal(0)
|
|
|
|
response["service"]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service"
|
|
|
|
)
|
|
|
|
response["service"]["serviceName"].should.equal("test_ecs_service")
|
|
|
|
response["service"]["status"].should.equal("ACTIVE")
|
|
|
|
response["service"]["schedulingStrategy"].should.equal("REPLICA")
|
|
|
|
response["service"]["taskDefinition"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
2018-10-31 02:03:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_update_non_existant_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2018-10-31 02:03:09 +00:00
|
|
|
try:
|
|
|
|
client.update_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="my-clustet", service="my-service", desiredCount=0
|
2018-10-31 02:03:09 +00:00
|
|
|
)
|
|
|
|
except ClientError as exc:
|
2019-10-31 15:44:26 +00:00
|
|
|
error_code = exc.response["Error"]["Code"]
|
|
|
|
error_code.should.equal("ServiceNotFoundException")
|
2018-10-31 02:03:09 +00:00
|
|
|
else:
|
|
|
|
raise Exception("Didn't raise ClientError")
|
2017-02-24 02:37:43 +00:00
|
|
|
|
2016-06-11 10:52:53 +00:00
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_register_container_instance():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-06-11 10:52:53 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-06-11 10:52:53 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2016-06-11 10:52:53 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-06-11 10:52:53 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-06-11 10:52:53 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["ec2InstanceId"].should.equal(test_instance.id)
|
|
|
|
full_arn = response["containerInstance"]["containerInstanceArn"]
|
|
|
|
arn_part = full_arn.split("/")
|
|
|
|
arn_part[0].should.equal("arn:aws:ecs:us-east-1:012345678910:container-instance")
|
2016-06-11 10:52:53 +00:00
|
|
|
arn_part[1].should.equal(str(UUID(arn_part[1])))
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["status"].should.equal("ACTIVE")
|
|
|
|
len(response["containerInstance"]["registeredResources"]).should.equal(4)
|
|
|
|
len(response["containerInstance"]["remainingResources"]).should.equal(4)
|
|
|
|
response["containerInstance"]["agentConnected"].should.equal(True)
|
|
|
|
response["containerInstance"]["versionInfo"]["agentVersion"].should.equal("1.0.0")
|
|
|
|
response["containerInstance"]["versionInfo"]["agentHash"].should.equal("4023248")
|
|
|
|
response["containerInstance"]["versionInfo"]["dockerVersion"].should.equal(
|
|
|
|
"DockerVersion: 1.5.0"
|
|
|
|
)
|
2016-06-11 10:52:53 +00:00
|
|
|
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2017-04-13 16:46:15 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_deregister_container_instance():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-04-13 16:46:15 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-04-13 16:46:15 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2017-04-13 16:46:15 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-04-13 16:46:15 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_id = response["containerInstance"]["containerInstanceArn"]
|
2017-04-13 16:46:15 +00:00
|
|
|
response = ecs_client.deregister_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, containerInstance=container_instance_id
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
|
|
|
container_instances_response = ecs_client.list_container_instances(
|
|
|
|
cluster=test_cluster_name
|
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(container_instances_response["containerInstanceArns"]).should.equal(0)
|
2017-04-13 16:46:15 +00:00
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_id = response["containerInstance"]["containerInstanceArn"]
|
2017-04-13 16:46:15 +00:00
|
|
|
_ = ecs_client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2017-04-13 16:46:15 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2017-04-13 16:46:15 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.start_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
taskDefinition="test_ecs_task",
|
2017-04-13 16:46:15 +00:00
|
|
|
overrides={},
|
|
|
|
containerInstances=[container_instance_id],
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
|
|
|
with assert_raises(Exception) as e:
|
|
|
|
ecs_client.deregister_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, containerInstance=container_instance_id
|
2017-04-13 16:46:15 +00:00
|
|
|
).should.have.raised(Exception)
|
|
|
|
container_instances_response = ecs_client.list_container_instances(
|
|
|
|
cluster=test_cluster_name
|
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(container_instances_response["containerInstanceArns"]).should.equal(1)
|
2017-04-13 16:46:15 +00:00
|
|
|
ecs_client.deregister_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, containerInstance=container_instance_id, force=True
|
2017-04-13 16:46:15 +00:00
|
|
|
)
|
|
|
|
container_instances_response = ecs_client.list_container_instances(
|
|
|
|
cluster=test_cluster_name
|
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(container_instances_response["containerInstanceArns"]).should.equal(0)
|
2017-04-13 16:46:15 +00:00
|
|
|
|
|
|
|
|
2016-06-11 10:52:53 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_container_instances():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-06-11 10:52:53 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2016-06-11 10:52:53 +00:00
|
|
|
|
|
|
|
instance_to_create = 3
|
|
|
|
test_instance_arns = []
|
|
|
|
for i in range(0, instance_to_create):
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-06-11 10:52:53 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
|
|
|
)
|
2016-06-11 10:52:53 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_instance_arns.append(response["containerInstance"]["containerInstanceArn"])
|
2016-06-11 10:52:53 +00:00
|
|
|
|
|
|
|
response = ecs_client.list_container_instances(cluster=test_cluster_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["containerInstanceArns"]).should.equal(instance_to_create)
|
2016-06-11 10:52:53 +00:00
|
|
|
for arn in test_instance_arns:
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstanceArns"].should.contain(arn)
|
2016-06-14 15:58:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_describe_container_instances():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-06-14 15:58:11 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2016-06-14 15:58:11 +00:00
|
|
|
|
|
|
|
instance_to_create = 3
|
|
|
|
test_instance_arns = []
|
|
|
|
for i in range(0, instance_to_create):
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-06-14 15:58:11 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
|
|
|
)
|
2016-06-14 15:58:11 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_instance_arns.append(response["containerInstance"]["containerInstanceArn"])
|
2016-06-14 15:58:11 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_instance_ids = list(map((lambda x: x.split("/")[1]), test_instance_arns))
|
2017-02-24 02:37:43 +00:00
|
|
|
response = ecs_client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, containerInstances=test_instance_ids
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_arns = [
|
|
|
|
ci["containerInstanceArn"] for ci in response["containerInstances"]
|
|
|
|
]
|
2016-06-14 15:58:11 +00:00
|
|
|
for arn in test_instance_arns:
|
|
|
|
response_arns.should.contain(arn)
|
2019-10-31 15:44:26 +00:00
|
|
|
for instance in response["containerInstances"]:
|
|
|
|
instance.keys().should.contain("runningTasksCount")
|
|
|
|
instance.keys().should.contain("pendingTasksCount")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-12 05:13:55 +00:00
|
|
|
with assert_raises(ClientError) as e:
|
|
|
|
ecs_client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, containerInstances=[]
|
2019-10-12 05:13:55 +00:00
|
|
|
)
|
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2017-03-05 03:30:36 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_update_container_instances_state():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-03-05 03:30:36 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2017-03-05 03:30:36 +00:00
|
|
|
|
|
|
|
instance_to_create = 3
|
|
|
|
test_instance_arns = []
|
|
|
|
for i in range(0, instance_to_create):
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-03-05 03:30:36 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
|
|
|
)
|
|
|
|
|
|
|
|
test_instance_arns.append(response["containerInstance"]["containerInstanceArn"])
|
|
|
|
|
|
|
|
test_instance_ids = list(map((lambda x: x.split("/")[1]), test_instance_arns))
|
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_ids,
|
|
|
|
status="DRAINING",
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2017-03-05 03:30:36 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("DRAINING")
|
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_ids,
|
|
|
|
status="DRAINING",
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2017-03-05 03:30:36 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("DRAINING")
|
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name, containerInstances=test_instance_ids, status="ACTIVE"
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2017-03-05 03:30:36 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("ACTIVE")
|
|
|
|
ecs_client.update_container_instances_state.when.called_with(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_ids,
|
|
|
|
status="test_status",
|
|
|
|
).should.throw(Exception)
|
2017-03-05 03:30:36 +00:00
|
|
|
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2018-10-27 04:54:01 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_update_container_instances_state_by_arn():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2018-10-27 04:54:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2018-10-27 04:54:01 +00:00
|
|
|
|
|
|
|
instance_to_create = 3
|
|
|
|
test_instance_arns = []
|
|
|
|
for i in range(0, instance_to_create):
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2018-10-27 04:54:01 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
|
|
|
)
|
2018-10-27 04:54:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_instance_arns.append(response["containerInstance"]["containerInstanceArn"])
|
2018-10-27 04:54:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_arns,
|
|
|
|
status="DRAINING",
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2018-10-27 04:54:01 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("DRAINING")
|
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_arns,
|
|
|
|
status="DRAINING",
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2018-10-27 04:54:01 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("DRAINING")
|
|
|
|
response = ecs_client.update_container_instances_state(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_arns,
|
|
|
|
status="ACTIVE",
|
|
|
|
)
|
|
|
|
len(response["failures"]).should.equal(0)
|
|
|
|
len(response["containerInstances"]).should.equal(instance_to_create)
|
|
|
|
response_statuses = [ci["status"] for ci in response["containerInstances"]]
|
2018-10-27 04:54:01 +00:00
|
|
|
for status in response_statuses:
|
2019-10-31 15:44:26 +00:00
|
|
|
status.should.equal("ACTIVE")
|
|
|
|
ecs_client.update_container_instances_state.when.called_with(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
containerInstances=test_instance_arns,
|
|
|
|
status="test_status",
|
|
|
|
).should.throw(Exception)
|
2018-10-27 04:54:01 +00:00
|
|
|
|
|
|
|
|
2016-08-29 23:26:13 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_run_task():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-08-29 23:26:13 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-08-29 23:26:13 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
count=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
|
|
|
)
|
|
|
|
len(response["tasks"]).should.equal(2)
|
|
|
|
response["tasks"][0]["taskArn"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task/"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["containerInstanceArn"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:container-instance/"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["overrides"].should.equal({})
|
|
|
|
response["tasks"][0]["lastStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["desiredStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["startedBy"].should.equal("moto")
|
|
|
|
response["tasks"][0]["stoppedReason"].should.equal("")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_start_task():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-08-29 23:26:13 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instances = client.list_container_instances(cluster=test_cluster_name)
|
|
|
|
container_instance_id = container_instances["containerInstanceArns"][0].split("/")[
|
|
|
|
-1
|
|
|
|
]
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-08-29 23:26:13 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = client.start_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
|
|
|
containerInstances=[container_instance_id],
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["tasks"]).should.equal(1)
|
|
|
|
response["tasks"][0]["taskArn"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task/"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["containerInstanceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:container-instance/{0}".format(
|
|
|
|
container_instance_id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
response["tasks"][0]["overrides"].should.equal({})
|
|
|
|
response["tasks"][0]["lastStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["desiredStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["startedBy"].should.equal("moto")
|
|
|
|
response["tasks"][0]["stoppedReason"].should.equal("")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_tasks():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-08-29 23:26:13 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
_ = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instances = client.list_container_instances(cluster=test_cluster_name)
|
|
|
|
container_instance_id = container_instances["containerInstanceArns"][0].split("/")[
|
|
|
|
-1
|
|
|
|
]
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-08-29 23:26:13 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.start_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
|
|
|
containerInstances=[container_instance_id],
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="foo",
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.start_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
|
|
|
containerInstances=[container_instance_id],
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="bar",
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert len(client.list_tasks()["taskArns"]).should.equal(2)
|
|
|
|
assert len(client.list_tasks(cluster="test_ecs_cluster")["taskArns"]).should.equal(
|
|
|
|
2
|
|
|
|
)
|
|
|
|
assert len(client.list_tasks(startedBy="foo")["taskArns"]).should.equal(1)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_describe_tasks():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-08-29 23:26:13 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-08-29 23:26:13 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
tasks_arns = [
|
2019-10-31 15:44:26 +00:00
|
|
|
task["taskArn"]
|
|
|
|
for task in client.run_task(
|
|
|
|
cluster="test_ecs_cluster",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
count=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
|
|
|
)["tasks"]
|
2016-08-29 23:26:13 +00:00
|
|
|
]
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.describe_tasks(cluster="test_ecs_cluster", tasks=tasks_arns)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["tasks"]).should.equal(2)
|
|
|
|
set(
|
|
|
|
[response["tasks"][0]["taskArn"], response["tasks"][1]["taskArn"]]
|
|
|
|
).should.equal(set(tasks_arns))
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2018-06-25 00:13:39 +00:00
|
|
|
# Test we can pass task ids instead of ARNs
|
|
|
|
response = client.describe_tasks(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", tasks=[tasks_arns[0].split("/")[-1]]
|
2018-06-25 00:13:39 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["tasks"]).should.equal(1)
|
2018-06-25 00:13:39 +00:00
|
|
|
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2016-12-03 23:12:22 +00:00
|
|
|
@mock_ecs
|
|
|
|
def describe_task_definition():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2016-12-03 23:12:22 +00:00
|
|
|
container_definition = {
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-12-03 23:12:22 +00:00
|
|
|
}
|
|
|
|
task_definition = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task", containerDefinitions=[container_definition]
|
2016-12-03 23:12:22 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
family = task_definition["family"]
|
2016-12-03 23:12:22 +00:00
|
|
|
task = client.describe_task_definition(taskDefinition=family)
|
2019-10-31 15:44:26 +00:00
|
|
|
task["containerDefinitions"][0].should.equal(container_definition)
|
|
|
|
task["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task2:1"
|
|
|
|
)
|
|
|
|
task["volumes"].should.equal([])
|
2016-12-03 23:12:22 +00:00
|
|
|
|
2017-02-24 02:37:43 +00:00
|
|
|
|
2016-08-29 23:26:13 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_stop_task():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2016-08-29 23:26:13 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2016-08-29 23:26:13 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2016-08-29 23:26:13 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2016-08-29 23:26:13 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
run_response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2016-08-29 23:26:13 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2016-08-29 23:26:13 +00:00
|
|
|
count=1,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
stop_response = client.stop_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
task=run_response["tasks"][0].get("taskArn"),
|
|
|
|
reason="moto testing",
|
2016-08-29 23:26:13 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
stop_response["task"]["taskArn"].should.equal(
|
|
|
|
run_response["tasks"][0].get("taskArn")
|
|
|
|
)
|
|
|
|
stop_response["task"]["lastStatus"].should.equal("STOPPED")
|
|
|
|
stop_response["task"]["desiredStatus"].should.equal("STOPPED")
|
|
|
|
stop_response["task"]["stoppedReason"].should.equal("moto testing")
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_resource_reservation_and_release():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-04-12 12:30:32 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
|
|
|
"portMappings": [{"hostPort": 80, "containerPort": 8080}],
|
2017-04-12 12:30:32 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
run_response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2017-04-12 12:30:32 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
count=1,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_arn = run_response["tasks"][0].get("containerInstanceArn")
|
2017-04-12 12:30:32 +00:00
|
|
|
container_instance_description = client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", containerInstances=[container_instance_arn]
|
|
|
|
)["containerInstances"][0]
|
2018-03-26 18:11:12 +00:00
|
|
|
remaining_resources, registered_resources = _fetch_container_instance_resources(
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_description
|
|
|
|
)
|
|
|
|
remaining_resources["CPU"].should.equal(registered_resources["CPU"] - 1024)
|
|
|
|
remaining_resources["MEMORY"].should.equal(registered_resources["MEMORY"] - 400)
|
|
|
|
registered_resources["PORTS"].append("80")
|
|
|
|
remaining_resources["PORTS"].should.equal(registered_resources["PORTS"])
|
|
|
|
container_instance_description["runningTasksCount"].should.equal(1)
|
2017-04-12 12:30:32 +00:00
|
|
|
client.stop_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
task=run_response["tasks"][0].get("taskArn"),
|
|
|
|
reason="moto testing",
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
container_instance_description = client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", containerInstances=[container_instance_arn]
|
|
|
|
)["containerInstances"][0]
|
2018-03-26 18:11:12 +00:00
|
|
|
remaining_resources, registered_resources = _fetch_container_instance_resources(
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_description
|
|
|
|
)
|
|
|
|
remaining_resources["CPU"].should.equal(registered_resources["CPU"])
|
|
|
|
remaining_resources["MEMORY"].should.equal(registered_resources["MEMORY"])
|
|
|
|
remaining_resources["PORTS"].should.equal(registered_resources["PORTS"])
|
|
|
|
container_instance_description["runningTasksCount"].should.equal(0)
|
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2018-04-04 20:01:01 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_resource_reservation_and_release_memory_reservation():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2018-04-04 20:01:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2018-04-04 20:01:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2018-04-04 20:01:01 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2018-04-04 20:01:01 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2018-04-04 20:01:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2018-04-04 20:01:01 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world",
|
|
|
|
"image": "docker/hello-world:latest",
|
|
|
|
"memoryReservation": 400,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
|
|
|
"portMappings": [{"containerPort": 8080}],
|
2018-04-04 20:01:01 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2018-04-04 20:01:01 +00:00
|
|
|
)
|
|
|
|
run_response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2018-04-04 20:01:01 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2018-04-04 20:01:01 +00:00
|
|
|
count=1,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2018-04-04 20:01:01 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
container_instance_arn = run_response["tasks"][0].get("containerInstanceArn")
|
2018-04-04 20:01:01 +00:00
|
|
|
container_instance_description = client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", containerInstances=[container_instance_arn]
|
|
|
|
)["containerInstances"][0]
|
|
|
|
remaining_resources, registered_resources = _fetch_container_instance_resources(
|
|
|
|
container_instance_description
|
|
|
|
)
|
|
|
|
remaining_resources["CPU"].should.equal(registered_resources["CPU"])
|
|
|
|
remaining_resources["MEMORY"].should.equal(registered_resources["MEMORY"] - 400)
|
|
|
|
remaining_resources["PORTS"].should.equal(registered_resources["PORTS"])
|
|
|
|
container_instance_description["runningTasksCount"].should.equal(1)
|
2018-04-04 20:01:01 +00:00
|
|
|
client.stop_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
task=run_response["tasks"][0].get("taskArn"),
|
|
|
|
reason="moto testing",
|
2018-04-04 20:01:01 +00:00
|
|
|
)
|
|
|
|
container_instance_description = client.describe_container_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster", containerInstances=[container_instance_arn]
|
|
|
|
)["containerInstances"][0]
|
|
|
|
remaining_resources, registered_resources = _fetch_container_instance_resources(
|
|
|
|
container_instance_description
|
|
|
|
)
|
|
|
|
remaining_resources["CPU"].should.equal(registered_resources["CPU"])
|
|
|
|
remaining_resources["MEMORY"].should.equal(registered_resources["MEMORY"])
|
|
|
|
remaining_resources["PORTS"].should.equal(registered_resources["PORTS"])
|
|
|
|
container_instance_description["runningTasksCount"].should.equal(0)
|
2018-04-04 20:01:01 +00:00
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2016-12-20 15:37:18 +00:00
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_create_cluster_through_cloudformation():
|
|
|
|
template = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testCluster": {
|
|
|
|
"Type": "AWS::ECS::Cluster",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Properties": {"ClusterName": "testcluster"},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template_json = json.dumps(template)
|
2018-03-26 18:11:12 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
2018-03-26 18:11:12 +00:00
|
|
|
resp = ecs_conn.list_clusters()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["clusterArns"]).should.equal(0)
|
2018-03-26 18:11:12 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
cfn_conn.create_stack(StackName="test_stack", TemplateBody=template_json)
|
2018-03-26 18:11:12 +00:00
|
|
|
|
|
|
|
resp = ecs_conn.list_clusters()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["clusterArns"]).should.equal(1)
|
2018-03-26 18:11:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
@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",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Resources": {"testCluster": {"Type": "AWS::ECS::Cluster"}},
|
2018-03-26 18:11:12 +00:00
|
|
|
}
|
|
|
|
template_json = json.dumps(template)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
cfn_conn.create_stack(StackName="test_stack", TemplateBody=template_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
2016-12-20 15:37:18 +00:00
|
|
|
resp = ecs_conn.list_clusters()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["clusterArns"]).should.equal(1)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_update_cluster_name_through_cloudformation_should_trigger_a_replacement():
|
|
|
|
template1 = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testCluster": {
|
|
|
|
"Type": "AWS::ECS::Cluster",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Properties": {"ClusterName": "testcluster1"},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template2 = deepcopy(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
template2["Resources"]["testCluster"]["Properties"]["ClusterName"] = "testcluster2"
|
2016-12-20 15:37:18 +00:00
|
|
|
template1_json = json.dumps(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
2016-12-20 15:37:18 +00:00
|
|
|
stack_resp = cfn_conn.create_stack(
|
2019-10-31 15:44:26 +00:00
|
|
|
StackName="test_stack", TemplateBody=template1_json
|
2016-12-20 15:37:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
template2_json = json.dumps(template2)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn.update_stack(StackName=stack_resp["StackId"], TemplateBody=template2_json)
|
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
2016-12-20 15:37:18 +00:00
|
|
|
resp = ecs_conn.list_clusters()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["clusterArns"]).should.equal(1)
|
|
|
|
resp["clusterArns"][0].endswith("testcluster2").should.be.true
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_create_task_definition_through_cloudformation():
|
|
|
|
template = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testTaskDefinition": {
|
2017-02-24 02:37:43 +00:00
|
|
|
"Type": "AWS::ECS::TaskDefinition",
|
|
|
|
"Properties": {
|
|
|
|
"ContainerDefinitions": [
|
2016-12-20 15:37:18 +00:00
|
|
|
{
|
|
|
|
"Name": "ecs-sample",
|
2017-02-24 02:37:43 +00:00
|
|
|
"Image": "amazon/amazon-ecs-sample",
|
2016-12-20 15:37:18 +00:00
|
|
|
"Cpu": "200",
|
|
|
|
"Memory": "500",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Essential": "true",
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
],
|
2017-02-24 02:37:43 +00:00
|
|
|
"Volumes": [],
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template_json = json.dumps(template)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
stack_name = "test_stack"
|
|
|
|
cfn_conn.create_stack(StackName=stack_name, TemplateBody=template_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
2016-12-20 15:37:18 +00:00
|
|
|
resp = ecs_conn.list_task_definitions()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["taskDefinitionArns"]).should.equal(1)
|
|
|
|
task_definition_arn = resp["taskDefinitionArns"][0]
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2018-04-04 19:05:51 +00:00
|
|
|
task_definition_details = cfn_conn.describe_stack_resource(
|
2019-10-31 15:44:26 +00:00
|
|
|
StackName=stack_name, LogicalResourceId="testTaskDefinition"
|
|
|
|
)["StackResourceDetail"]
|
|
|
|
task_definition_details["PhysicalResourceId"].should.equal(task_definition_arn)
|
|
|
|
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_task_definitions_unable_to_be_placed():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-04-12 12:30:32 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world",
|
|
|
|
"image": "docker/hello-world:latest",
|
|
|
|
"cpu": 5000,
|
|
|
|
"memory": 40000,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
2017-04-12 12:30:32 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2017-04-12 12:30:32 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
count=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["tasks"]).should.equal(0)
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_task_definitions_with_port_clash():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-04-12 12:30:32 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = client.create_cluster(clusterName=test_cluster_name)
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-04-12 12:30:32 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"name": "hello_world",
|
|
|
|
"image": "docker/hello-world:latest",
|
|
|
|
"cpu": 256,
|
|
|
|
"memory": 512,
|
|
|
|
"essential": True,
|
|
|
|
"environment": [
|
|
|
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
|
|
|
],
|
|
|
|
"logConfiguration": {"logDriver": "json-file"},
|
|
|
|
"portMappings": [{"hostPort": 80, "containerPort": 8080}],
|
2017-04-12 12:30:32 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-04-12 12:30:32 +00:00
|
|
|
)
|
|
|
|
response = client.run_task(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
2017-04-12 12:30:32 +00:00
|
|
|
overrides={},
|
2019-10-31 15:44:26 +00:00
|
|
|
taskDefinition="test_ecs_task",
|
2017-04-12 12:30:32 +00:00
|
|
|
count=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
startedBy="moto",
|
|
|
|
)
|
|
|
|
len(response["tasks"]).should.equal(1)
|
|
|
|
response["tasks"][0]["taskArn"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task/"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["containerInstanceArn"].should.contain(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:container-instance/"
|
|
|
|
)
|
|
|
|
response["tasks"][0]["overrides"].should.equal({})
|
|
|
|
response["tasks"][0]["lastStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["desiredStatus"].should.equal("RUNNING")
|
|
|
|
response["tasks"][0]["startedBy"].should.equal("moto")
|
|
|
|
response["tasks"][0]["stoppedReason"].should.equal("")
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
|
2016-12-20 15:37:18 +00:00
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_update_task_definition_family_through_cloudformation_should_trigger_a_replacement():
|
|
|
|
template1 = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testTaskDefinition": {
|
2017-02-24 02:37:43 +00:00
|
|
|
"Type": "AWS::ECS::TaskDefinition",
|
|
|
|
"Properties": {
|
2016-12-20 15:37:18 +00:00
|
|
|
"Family": "testTaskDefinition1",
|
2017-02-24 02:37:43 +00:00
|
|
|
"ContainerDefinitions": [
|
2016-12-20 15:37:18 +00:00
|
|
|
{
|
|
|
|
"Name": "ecs-sample",
|
2017-02-24 02:37:43 +00:00
|
|
|
"Image": "amazon/amazon-ecs-sample",
|
2016-12-20 15:37:18 +00:00
|
|
|
"Cpu": "200",
|
|
|
|
"Memory": "500",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Essential": "true",
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
],
|
2017-02-24 02:37:43 +00:00
|
|
|
"Volumes": [],
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template1_json = json.dumps(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
cfn_conn.create_stack(StackName="test_stack", TemplateBody=template1_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
template2 = deepcopy(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
template2["Resources"]["testTaskDefinition"]["Properties"][
|
|
|
|
"Family"
|
|
|
|
] = "testTaskDefinition2"
|
2016-12-20 15:37:18 +00:00
|
|
|
template2_json = json.dumps(template2)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn.update_stack(StackName="test_stack", TemplateBody=template2_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
2019-11-26 14:17:54 +00:00
|
|
|
resp = ecs_conn.list_task_definitions(familyPrefix="testTaskDefinition2")
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp["taskDefinitionArns"]).should.equal(1)
|
|
|
|
resp["taskDefinitionArns"][0].endswith("testTaskDefinition2:1").should.be.true
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_create_service_through_cloudformation():
|
|
|
|
template = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testCluster": {
|
|
|
|
"Type": "AWS::ECS::Cluster",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Properties": {"ClusterName": "testcluster"},
|
2016-12-20 15:37:18 +00:00
|
|
|
},
|
|
|
|
"testTaskDefinition": {
|
2017-02-24 02:37:43 +00:00
|
|
|
"Type": "AWS::ECS::TaskDefinition",
|
|
|
|
"Properties": {
|
|
|
|
"ContainerDefinitions": [
|
2016-12-20 15:37:18 +00:00
|
|
|
{
|
|
|
|
"Name": "ecs-sample",
|
2017-02-24 02:37:43 +00:00
|
|
|
"Image": "amazon/amazon-ecs-sample",
|
2016-12-20 15:37:18 +00:00
|
|
|
"Cpu": "200",
|
|
|
|
"Memory": "500",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Essential": "true",
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
],
|
2017-02-24 02:37:43 +00:00
|
|
|
"Volumes": [],
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
},
|
|
|
|
"testService": {
|
|
|
|
"Type": "AWS::ECS::Service",
|
|
|
|
"Properties": {
|
|
|
|
"Cluster": {"Ref": "testCluster"},
|
|
|
|
"DesiredCount": 10,
|
|
|
|
"TaskDefinition": {"Ref": "testTaskDefinition"},
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template_json = json.dumps(template)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
cfn_conn.create_stack(StackName="test_stack", TemplateBody=template_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
|
|
|
resp = ecs_conn.list_services(cluster="testcluster")
|
|
|
|
len(resp["serviceArns"]).should.equal(1)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_update_service_through_cloudformation_should_trigger_replacement():
|
|
|
|
template1 = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "ECS Cluster Test CloudFormation",
|
|
|
|
"Resources": {
|
|
|
|
"testCluster": {
|
|
|
|
"Type": "AWS::ECS::Cluster",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Properties": {"ClusterName": "testcluster"},
|
2016-12-20 15:37:18 +00:00
|
|
|
},
|
|
|
|
"testTaskDefinition": {
|
2017-02-24 02:37:43 +00:00
|
|
|
"Type": "AWS::ECS::TaskDefinition",
|
|
|
|
"Properties": {
|
|
|
|
"ContainerDefinitions": [
|
2016-12-20 15:37:18 +00:00
|
|
|
{
|
|
|
|
"Name": "ecs-sample",
|
2017-02-24 02:37:43 +00:00
|
|
|
"Image": "amazon/amazon-ecs-sample",
|
2016-12-20 15:37:18 +00:00
|
|
|
"Cpu": "200",
|
|
|
|
"Memory": "500",
|
2019-10-31 15:44:26 +00:00
|
|
|
"Essential": "true",
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
],
|
2017-02-24 02:37:43 +00:00
|
|
|
"Volumes": [],
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
},
|
|
|
|
"testService": {
|
|
|
|
"Type": "AWS::ECS::Service",
|
|
|
|
"Properties": {
|
|
|
|
"Cluster": {"Ref": "testCluster"},
|
|
|
|
"TaskDefinition": {"Ref": "testTaskDefinition"},
|
|
|
|
"DesiredCount": 10,
|
2019-10-31 15:44:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2016-12-20 15:37:18 +00:00
|
|
|
}
|
|
|
|
template_json1 = json.dumps(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn = boto3.client("cloudformation", region_name="us-west-1")
|
|
|
|
cfn_conn.create_stack(StackName="test_stack", TemplateBody=template_json1)
|
2016-12-20 15:37:18 +00:00
|
|
|
template2 = deepcopy(template1)
|
2019-10-31 15:44:26 +00:00
|
|
|
template2["Resources"]["testService"]["Properties"]["DesiredCount"] = 5
|
2016-12-20 15:37:18 +00:00
|
|
|
template2_json = json.dumps(template2)
|
2019-10-31 15:44:26 +00:00
|
|
|
cfn_conn.update_stack(StackName="test_stack", TemplateBody=template2_json)
|
2016-12-20 15:37:18 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_conn = boto3.client("ecs", region_name="us-west-1")
|
|
|
|
resp = ecs_conn.list_services(cluster="testcluster")
|
|
|
|
len(resp["serviceArns"]).should.equal(1)
|
2017-04-12 12:30:32 +00:00
|
|
|
|
|
|
|
|
2017-10-28 18:18:39 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_attributes():
|
|
|
|
# Combined put, list delete attributes into the same test due to the amount of setup
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-10-28 18:18:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-10-28 18:18:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
2017-11-17 18:25:08 +00:00
|
|
|
instances = []
|
2017-10-28 18:18:39 +00:00
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-10-28 18:18:39 +00:00
|
|
|
)[0]
|
2017-11-17 18:25:08 +00:00
|
|
|
instances.append(test_instance)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["ec2InstanceId"].should.equal(test_instance.id)
|
|
|
|
full_arn1 = response["containerInstance"]["containerInstanceArn"]
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-10-28 18:18:39 +00:00
|
|
|
)[0]
|
2017-11-17 18:25:08 +00:00
|
|
|
instances.append(test_instance)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["ec2InstanceId"].should.equal(test_instance.id)
|
|
|
|
full_arn2 = response["containerInstance"]["containerInstanceArn"]
|
|
|
|
partial_arn2 = full_arn2.rsplit("/", 1)[-1]
|
2017-10-28 18:18:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
full_arn2.should_not.equal(
|
|
|
|
full_arn1
|
|
|
|
) # uuid1 isnt unique enough when the pc is fast ;-)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
# Ok set instance 1 with 1 attribute, instance 2 with another, and all of them with a 3rd.
|
|
|
|
ecs_client.put_attributes(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
attributes=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"name": "env", "value": "prod"},
|
|
|
|
{"name": "attr1", "value": "instance1", "targetId": full_arn1},
|
|
|
|
{
|
|
|
|
"name": "attr1",
|
|
|
|
"value": "instance2",
|
|
|
|
"targetId": partial_arn2,
|
|
|
|
"targetType": "container-instance",
|
|
|
|
},
|
|
|
|
],
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
resp = ecs_client.list_attributes(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, targetType="container-instance"
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
attrs = resp["attributes"]
|
2017-11-17 18:25:08 +00:00
|
|
|
|
2019-11-22 14:39:07 +00:00
|
|
|
NUM_CUSTOM_ATTRIBUTES = 4 # 2 specific to individual machines and 1 global, going to both machines (2 + 1*2)
|
2017-11-17 18:25:08 +00:00
|
|
|
NUM_DEFAULT_ATTRIBUTES = 4
|
2019-10-31 15:44:26 +00:00
|
|
|
len(attrs).should.equal(
|
|
|
|
NUM_CUSTOM_ATTRIBUTES + (NUM_DEFAULT_ATTRIBUTES * len(instances))
|
|
|
|
)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
# Tests that the attrs have been set properly
|
2019-10-31 15:44:26 +00:00
|
|
|
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)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
ecs_client.delete_attributes(
|
|
|
|
cluster=test_cluster_name,
|
|
|
|
attributes=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{
|
|
|
|
"name": "attr1",
|
|
|
|
"value": "instance2",
|
|
|
|
"targetId": partial_arn2,
|
|
|
|
"targetType": "container-instance",
|
|
|
|
}
|
|
|
|
],
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
2017-11-17 18:25:08 +00:00
|
|
|
NUM_CUSTOM_ATTRIBUTES -= 1
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
resp = ecs_client.list_attributes(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, targetType="container-instance"
|
|
|
|
)
|
|
|
|
attrs = resp["attributes"]
|
|
|
|
len(attrs).should.equal(
|
|
|
|
NUM_CUSTOM_ATTRIBUTES + (NUM_DEFAULT_ATTRIBUTES * len(instances))
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_poll_endpoint():
|
|
|
|
# Combined put, list delete attributes into the same test due to the amount of setup
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
# Just a placeholder until someone actually wants useless data, just testing it doesnt raise an exception
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = ecs_client.discover_poll_endpoint(cluster="blah", containerInstance="blah")
|
|
|
|
resp.should.contain("endpoint")
|
|
|
|
resp.should.contain("telemetryEndpoint")
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_task_definition_families():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2017-10-28 18:18:39 +00:00
|
|
|
client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2017-10-28 18:18:39 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2017-10-28 18:18:39 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="alt_test_ecs_task",
|
2017-10-28 18:18:39 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2017-10-28 18:18:39 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2017-10-28 18:18:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
resp1 = client.list_task_definition_families()
|
2019-10-31 15:44:26 +00:00
|
|
|
resp2 = client.list_task_definition_families(familyPrefix="alt")
|
2017-10-28 18:18:39 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
len(resp1["families"]).should.equal(2)
|
|
|
|
len(resp2["families"]).should.equal(1)
|
2017-10-28 18:18:39 +00:00
|
|
|
|
|
|
|
|
2017-11-17 18:25:08 +00:00
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_default_container_instance_attributes():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-11-17 18:25:08 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
# Create cluster and EC2 instance
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-11-17 18:25:08 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Register container instance
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-11-17 18:25:08 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["ec2InstanceId"].should.equal(test_instance.id)
|
|
|
|
full_arn = response["containerInstance"]["containerInstanceArn"]
|
|
|
|
container_instance_id = full_arn.rsplit("/", 1)[-1]
|
2017-11-17 18:25:08 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
default_attributes = response["containerInstance"]["attributes"]
|
2017-11-17 18:25:08 +00:00
|
|
|
assert len(default_attributes) == 4
|
|
|
|
expected_result = [
|
2019-10-31 15:44:26 +00:00
|
|
|
{
|
|
|
|
"name": "ecs.availability-zone",
|
|
|
|
"value": test_instance.placement["AvailabilityZone"],
|
|
|
|
},
|
|
|
|
{"name": "ecs.ami-id", "value": test_instance.image_id},
|
|
|
|
{"name": "ecs.instance-type", "value": test_instance.instance_type},
|
|
|
|
{"name": "ecs.os-type", "value": test_instance.platform or "linux"},
|
2017-11-17 18:25:08 +00:00
|
|
|
]
|
2019-10-31 15:44:26 +00:00
|
|
|
assert sorted(default_attributes, key=lambda item: item["name"]) == sorted(
|
|
|
|
expected_result, key=lambda item: item["name"]
|
|
|
|
)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ec2
|
|
|
|
@mock_ecs
|
|
|
|
def test_describe_container_instances_with_attributes():
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
2017-11-17 18:25:08 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
test_cluster_name = "test_ecs_cluster"
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
# Create cluster and EC2 instance
|
2019-10-31 15:44:26 +00:00
|
|
|
_ = ecs_client.create_cluster(clusterName=test_cluster_name)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
test_instance = ec2.create_instances(
|
2019-10-31 15:44:26 +00:00
|
|
|
ImageId="ami-1234abcd", MinCount=1, MaxCount=1
|
2017-11-17 18:25:08 +00:00
|
|
|
)[0]
|
|
|
|
|
|
|
|
instance_id_document = json.dumps(
|
|
|
|
ec2_utils.generate_instance_identity_document(test_instance)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Register container instance
|
|
|
|
response = ecs_client.register_container_instance(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
2017-11-17 18:25:08 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["containerInstance"]["ec2InstanceId"].should.equal(test_instance.id)
|
|
|
|
full_arn = response["containerInstance"]["containerInstanceArn"]
|
|
|
|
container_instance_id = full_arn.rsplit("/", 1)[-1]
|
|
|
|
default_attributes = response["containerInstance"]["attributes"]
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
# Set attributes on container instance, one without a value
|
|
|
|
attributes = [
|
2019-10-31 15:44:26 +00:00
|
|
|
{"name": "env", "value": "prod"},
|
|
|
|
{
|
|
|
|
"name": "attr1",
|
|
|
|
"value": "instance1",
|
|
|
|
"targetId": container_instance_id,
|
|
|
|
"targetType": "container-instance",
|
|
|
|
},
|
|
|
|
{"name": "attr_without_value"},
|
2018-03-26 18:11:12 +00:00
|
|
|
]
|
2019-10-31 15:44:26 +00:00
|
|
|
ecs_client.put_attributes(cluster=test_cluster_name, attributes=attributes)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
# Describe container instance, should have attributes previously set
|
2019-10-31 15:44:26 +00:00
|
|
|
described_instance = ecs_client.describe_container_instances(
|
|
|
|
cluster=test_cluster_name, containerInstances=[container_instance_id]
|
|
|
|
)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert len(described_instance["containerInstances"]) == 1
|
|
|
|
assert isinstance(described_instance["containerInstances"][0]["attributes"], list)
|
2017-11-17 18:25:08 +00:00
|
|
|
|
|
|
|
# Remove additional info passed to put_attributes
|
|
|
|
cleaned_attributes = []
|
|
|
|
for attribute in attributes:
|
2019-10-31 15:44:26 +00:00
|
|
|
attribute.pop("targetId", None)
|
|
|
|
attribute.pop("targetType", None)
|
2017-11-17 18:25:08 +00:00
|
|
|
cleaned_attributes.append(attribute)
|
2019-10-31 15:44:26 +00:00
|
|
|
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"]
|
|
|
|
)
|
2017-11-17 18:25:08 +00:00
|
|
|
assert described_attributes == expected_attributes
|
|
|
|
|
|
|
|
|
2017-04-12 12:30:32 +00:00
|
|
|
def _fetch_container_instance_resources(container_instance_description):
|
|
|
|
remaining_resources = {}
|
|
|
|
registered_resources = {}
|
2019-10-31 15:44:26 +00:00
|
|
|
remaining_resources_list = container_instance_description["remainingResources"]
|
|
|
|
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["MEMORY"] = [
|
|
|
|
x["integerValue"] for x in remaining_resources_list if x["name"] == "MEMORY"
|
|
|
|
][0]
|
|
|
|
remaining_resources["PORTS"] = [
|
|
|
|
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]
|
2017-04-12 12:30:32 +00:00
|
|
|
return remaining_resources, registered_resources
|
2018-06-04 13:35:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_create_service_load_balancing():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
client.create_cluster(clusterName="test_ecs_cluster")
|
2018-06-04 13:35:22 +00:00
|
|
|
client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2018-06-04 13:35:22 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2018-06-04 13:35:22 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2018-06-04 13:35:22 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2018-06-04 13:35:22 +00:00
|
|
|
desiredCount=2,
|
|
|
|
loadBalancers=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"targetGroupArn": "test_target_group_arn",
|
|
|
|
"loadBalancerName": "test_load_balancer_name",
|
|
|
|
"containerName": "test_container_name",
|
|
|
|
"containerPort": 123,
|
2018-06-04 13:35:22 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
|
|
|
)
|
|
|
|
response["service"]["clusterArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster"
|
|
|
|
)
|
|
|
|
response["service"]["desiredCount"].should.equal(2)
|
|
|
|
len(response["service"]["events"]).should.equal(0)
|
|
|
|
len(response["service"]["loadBalancers"]).should.equal(1)
|
|
|
|
response["service"]["loadBalancers"][0]["targetGroupArn"].should.equal(
|
|
|
|
"test_target_group_arn"
|
|
|
|
)
|
|
|
|
response["service"]["loadBalancers"][0]["loadBalancerName"].should.equal(
|
|
|
|
"test_load_balancer_name"
|
|
|
|
)
|
|
|
|
response["service"]["loadBalancers"][0]["containerName"].should.equal(
|
|
|
|
"test_container_name"
|
|
|
|
)
|
|
|
|
response["service"]["loadBalancers"][0]["containerPort"].should.equal(123)
|
|
|
|
response["service"]["pendingCount"].should.equal(0)
|
|
|
|
response["service"]["runningCount"].should.equal(0)
|
|
|
|
response["service"]["serviceArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service"
|
|
|
|
)
|
|
|
|
response["service"]["serviceName"].should.equal("test_ecs_service")
|
|
|
|
response["service"]["status"].should.equal("ACTIVE")
|
|
|
|
response["service"]["taskDefinition"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
2018-06-04 13:35:22 +00:00
|
|
|
)
|
2019-07-26 13:11:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_tags_for_resource():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
2019-07-26 13:11:25 +00:00
|
|
|
response = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-07-26 13:11:25 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-07-26 13:11:25 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "bar"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
type(response["taskDefinition"]).should.be(dict)
|
|
|
|
response["taskDefinition"]["revision"].should.equal(1)
|
|
|
|
response["taskDefinition"]["taskDefinitionArn"].should.equal(
|
|
|
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
2019-07-26 13:11:25 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
task_definition_arn = response["taskDefinition"]["taskDefinitionArn"]
|
2019-07-26 13:11:25 +00:00
|
|
|
response = client.list_tags_for_resource(resourceArn=task_definition_arn)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
type(response["tags"]).should.be(list)
|
|
|
|
response["tags"].should.equal(
|
|
|
|
[{"key": "createdBy", "value": "moto-unittest"}, {"key": "foo", "value": "bar"}]
|
|
|
|
)
|
2019-07-26 13:11:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_tags_for_resource_unknown():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
task_definition_arn = "arn:aws:ecs:us-east-1:012345678910:task-definition/unknown:1"
|
2019-07-26 13:11:25 +00:00
|
|
|
try:
|
|
|
|
client.list_tags_for_resource(resourceArn=task_definition_arn)
|
|
|
|
except ClientError as err:
|
2019-10-31 15:44:26 +00:00
|
|
|
err.response["Error"]["Code"].should.equal("ClientException")
|
2019-10-03 18:30:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_tags_for_resource_ecs_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2019-10-03 18:30:08 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-10-03 18:30:08 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-10-03 18:30:08 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2019-10-03 18:30:08 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2019-10-03 18:30:08 +00:00
|
|
|
desiredCount=2,
|
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "bar"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
resourceArn=response["service"]["serviceArn"]
|
|
|
|
)
|
|
|
|
type(response["tags"]).should.be(list)
|
|
|
|
response["tags"].should.equal(
|
|
|
|
[{"key": "createdBy", "value": "moto-unittest"}, {"key": "foo", "value": "bar"}]
|
2019-10-03 18:30:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_list_tags_for_resource_unknown_service():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
service_arn = "arn:aws:ecs:us-east-1:012345678910:service/unknown:1"
|
2019-10-03 18:30:08 +00:00
|
|
|
try:
|
|
|
|
client.list_tags_for_resource(resourceArn=service_arn)
|
|
|
|
except ClientError as err:
|
2019-10-31 15:44:26 +00:00
|
|
|
err.response["Error"]["Code"].should.equal("ServiceNotFoundException")
|
2019-10-03 19:16:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_ecs_service_tag_resource():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2019-10-03 19:16:07 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-10-03 19:16:07 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
|
|
|
desiredCount=2,
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
client.tag_resource(
|
2019-10-31 15:44:26 +00:00
|
|
|
resourceArn=response["service"]["serviceArn"],
|
2019-10-03 19:16:07 +00:00
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "bar"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
resourceArn=response["service"]["serviceArn"]
|
|
|
|
)
|
|
|
|
type(response["tags"]).should.be(list)
|
|
|
|
response["tags"].should.equal(
|
|
|
|
[{"key": "createdBy", "value": "moto-unittest"}, {"key": "foo", "value": "bar"}]
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_ecs_service_tag_resource_overwrites_tag():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2019-10-03 19:16:07 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-10-03 19:16:07 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
desiredCount=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
tags=[{"key": "foo", "value": "bar"}],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
client.tag_resource(
|
2019-10-31 15:44:26 +00:00
|
|
|
resourceArn=response["service"]["serviceArn"],
|
2019-10-03 19:16:07 +00:00
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "hello world"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
resourceArn=response["service"]["serviceArn"]
|
|
|
|
)
|
|
|
|
type(response["tags"]).should.be(list)
|
|
|
|
response["tags"].should.equal(
|
|
|
|
[
|
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "foo", "value": "hello world"},
|
2019-10-03 19:16:07 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_ecs_service_untag_resource():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2019-10-03 19:16:07 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-10-03 19:16:07 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
desiredCount=2,
|
2019-10-31 15:44:26 +00:00
|
|
|
tags=[{"key": "foo", "value": "bar"}],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
client.untag_resource(
|
2019-10-31 15:44:26 +00:00
|
|
|
resourceArn=response["service"]["serviceArn"], tagKeys=["foo"]
|
|
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
resourceArn=response["service"]["serviceArn"]
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["tags"].should.equal([])
|
2019-10-03 19:16:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ecs
|
|
|
|
def test_ecs_service_untag_resource_multiple_tags():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("ecs", region_name="us-east-1")
|
|
|
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
2019-10-03 19:16:07 +00:00
|
|
|
_ = client.register_task_definition(
|
2019-10-31 15:44:26 +00:00
|
|
|
family="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
containerDefinitions=[
|
|
|
|
{
|
2019-10-31 15:44:26 +00:00
|
|
|
"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"},
|
2019-10-03 19:16:07 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
response = client.create_service(
|
2019-10-31 15:44:26 +00:00
|
|
|
cluster="test_ecs_cluster",
|
|
|
|
serviceName="test_ecs_service",
|
|
|
|
taskDefinition="test_ecs_task",
|
2019-10-03 19:16:07 +00:00
|
|
|
desiredCount=2,
|
|
|
|
tags=[
|
2019-10-31 15:44:26 +00:00
|
|
|
{"key": "foo", "value": "bar"},
|
|
|
|
{"key": "createdBy", "value": "moto-unittest"},
|
|
|
|
{"key": "hello", "value": "world"},
|
|
|
|
],
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
|
|
|
client.untag_resource(
|
2019-10-31 15:44:26 +00:00
|
|
|
resourceArn=response["service"]["serviceArn"], tagKeys=["foo", "createdBy"]
|
|
|
|
)
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
resourceArn=response["service"]["serviceArn"]
|
2019-10-03 19:16:07 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["tags"].should.equal([{"key": "hello", "value": "world"}])
|