Add launchType parameter to ECS (#3578)
This commit is contained in:
parent
d712a98ce1
commit
f4418185d1
@ -256,6 +256,7 @@ class Service(BaseObject, CloudFormationModel):
|
|||||||
scheduling_strategy=None,
|
scheduling_strategy=None,
|
||||||
tags=None,
|
tags=None,
|
||||||
deployment_controller=None,
|
deployment_controller=None,
|
||||||
|
launch_type=None,
|
||||||
):
|
):
|
||||||
self.cluster_arn = cluster.arn
|
self.cluster_arn = cluster.arn
|
||||||
self.arn = "arn:aws:ecs:{0}:012345678910:service/{1}".format(
|
self.arn = "arn:aws:ecs:{0}:012345678910:service/{1}".format(
|
||||||
@ -272,12 +273,14 @@ class Service(BaseObject, CloudFormationModel):
|
|||||||
self.task_sets = []
|
self.task_sets = []
|
||||||
self.deployment_controller = deployment_controller or {"type": "ECS"}
|
self.deployment_controller = deployment_controller or {"type": "ECS"}
|
||||||
self.events = []
|
self.events = []
|
||||||
|
self.launch_type = launch_type
|
||||||
if self.deployment_controller["type"] == "ECS":
|
if self.deployment_controller["type"] == "ECS":
|
||||||
self.deployments = [
|
self.deployments = [
|
||||||
{
|
{
|
||||||
"createdAt": datetime.now(pytz.utc),
|
"createdAt": datetime.now(pytz.utc),
|
||||||
"desiredCount": self.desired_count,
|
"desiredCount": self.desired_count,
|
||||||
"id": "ecs-svc/{}".format(randint(0, 32 ** 12)),
|
"id": "ecs-svc/{}".format(randint(0, 32 ** 12)),
|
||||||
|
"launchType": self.launch_type,
|
||||||
"pendingCount": self.desired_count,
|
"pendingCount": self.desired_count,
|
||||||
"runningCount": 0,
|
"runningCount": 0,
|
||||||
"status": "PRIMARY",
|
"status": "PRIMARY",
|
||||||
@ -1011,6 +1014,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
scheduling_strategy=None,
|
scheduling_strategy=None,
|
||||||
tags=None,
|
tags=None,
|
||||||
deployment_controller=None,
|
deployment_controller=None,
|
||||||
|
launch_type=None,
|
||||||
):
|
):
|
||||||
cluster_name = cluster_str.split("/")[-1]
|
cluster_name = cluster_str.split("/")[-1]
|
||||||
if cluster_name in self.clusters:
|
if cluster_name in self.clusters:
|
||||||
@ -1023,6 +1027,12 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
task_definition = None
|
task_definition = None
|
||||||
desired_count = desired_count if desired_count is not None else 0
|
desired_count = desired_count if desired_count is not None else 0
|
||||||
|
|
||||||
|
launch_type = launch_type if launch_type is not None else "EC2"
|
||||||
|
if launch_type not in ["EC2", "FARGATE"]:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
"launch type should be one of [EC2,FARGATE]"
|
||||||
|
)
|
||||||
|
|
||||||
service = Service(
|
service = Service(
|
||||||
cluster,
|
cluster,
|
||||||
service_name,
|
service_name,
|
||||||
@ -1032,6 +1042,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
scheduling_strategy,
|
scheduling_strategy,
|
||||||
tags,
|
tags,
|
||||||
deployment_controller,
|
deployment_controller,
|
||||||
|
launch_type,
|
||||||
)
|
)
|
||||||
cluster_service_pair = "{0}:{1}".format(cluster_name, service_name)
|
cluster_service_pair = "{0}:{1}".format(cluster_name, service_name)
|
||||||
self.services[cluster_service_pair] = service
|
self.services[cluster_service_pair] = service
|
||||||
@ -1478,6 +1489,12 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
client_token=None,
|
client_token=None,
|
||||||
tags=None,
|
tags=None,
|
||||||
):
|
):
|
||||||
|
launch_type = launch_type if launch_type is not None else "EC2"
|
||||||
|
if launch_type not in ["EC2", "FARGATE"]:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
"launch type should be one of [EC2,FARGATE]"
|
||||||
|
)
|
||||||
|
|
||||||
task_set = TaskSet(
|
task_set = TaskSet(
|
||||||
service,
|
service,
|
||||||
cluster,
|
cluster,
|
||||||
|
@ -166,6 +166,7 @@ class EC2ContainerServiceResponse(BaseResponse):
|
|||||||
scheduling_strategy = self._get_param("schedulingStrategy")
|
scheduling_strategy = self._get_param("schedulingStrategy")
|
||||||
tags = self._get_param("tags")
|
tags = self._get_param("tags")
|
||||||
deployment_controller = self._get_param("deploymentController")
|
deployment_controller = self._get_param("deploymentController")
|
||||||
|
launch_type = self._get_param("launchType")
|
||||||
service = self.ecs_backend.create_service(
|
service = self.ecs_backend.create_service(
|
||||||
cluster_str,
|
cluster_str,
|
||||||
service_name,
|
service_name,
|
||||||
@ -175,6 +176,7 @@ class EC2ContainerServiceResponse(BaseResponse):
|
|||||||
scheduling_strategy,
|
scheduling_strategy,
|
||||||
tags,
|
tags,
|
||||||
deployment_controller,
|
deployment_controller,
|
||||||
|
launch_type,
|
||||||
)
|
)
|
||||||
return json.dumps({"service": service.response_object})
|
return json.dumps({"service": service.response_object})
|
||||||
|
|
||||||
|
@ -422,6 +422,50 @@ def test_create_service():
|
|||||||
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
|
||||||
)
|
)
|
||||||
response["service"]["schedulingStrategy"].should.equal("REPLICA")
|
response["service"]["schedulingStrategy"].should.equal("REPLICA")
|
||||||
|
response["service"]["launchType"].should.equal("EC2")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_create_service_errors():
|
||||||
|
# given
|
||||||
|
client = boto3.client("ecs", region_name="us-east-1")
|
||||||
|
_ = client.create_cluster(clusterName="test_ecs_cluster")
|
||||||
|
_ = client.register_task_definition(
|
||||||
|
family="test_ecs_task",
|
||||||
|
containerDefinitions=[
|
||||||
|
{
|
||||||
|
"name": "hello_world",
|
||||||
|
"image": "docker/hello-world:latest",
|
||||||
|
"cpu": 1024,
|
||||||
|
"memory": 400,
|
||||||
|
"essential": True,
|
||||||
|
"environment": [
|
||||||
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
||||||
|
],
|
||||||
|
"logConfiguration": {"logDriver": "json-file"},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# not existing launch type
|
||||||
|
# when
|
||||||
|
with pytest.raises(ClientError) as e:
|
||||||
|
client.create_service(
|
||||||
|
cluster="test_ecs_cluster",
|
||||||
|
serviceName="test_ecs_service",
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
desiredCount=2,
|
||||||
|
launchType="SOMETHING",
|
||||||
|
)
|
||||||
|
|
||||||
|
# then
|
||||||
|
ex = e.value
|
||||||
|
ex.operation_name.should.equal("CreateService")
|
||||||
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
|
ex.response["Error"]["Code"].should.contain("ClientException")
|
||||||
|
ex.response["Error"]["Message"].should.equal(
|
||||||
|
"launch type should be one of [EC2,FARGATE]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_ecs
|
@mock_ecs
|
||||||
@ -582,6 +626,7 @@ def test_describe_services():
|
|||||||
response["services"][0]["deployments"][0]["pendingCount"].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]["runningCount"].should.equal(0)
|
||||||
response["services"][0]["deployments"][0]["status"].should.equal("PRIMARY")
|
response["services"][0]["deployments"][0]["status"].should.equal("PRIMARY")
|
||||||
|
response["services"][0]["deployments"][0]["launchType"].should.equal("EC2")
|
||||||
(
|
(
|
||||||
datetime.now()
|
datetime.now()
|
||||||
- response["services"][0]["deployments"][0]["createdAt"].replace(tzinfo=None)
|
- response["services"][0]["deployments"][0]["createdAt"].replace(tzinfo=None)
|
||||||
@ -602,6 +647,8 @@ def test_describe_services():
|
|||||||
[{"key": "Name", "value": "test_ecs_service1"}]
|
[{"key": "Name", "value": "test_ecs_service1"}]
|
||||||
)
|
)
|
||||||
response["services"][1]["tags"].should.equal([])
|
response["services"][1]["tags"].should.equal([])
|
||||||
|
response["services"][0]["launchType"].should.equal("EC2")
|
||||||
|
response["services"][1]["launchType"].should.equal("EC2")
|
||||||
|
|
||||||
|
|
||||||
@mock_ecs
|
@mock_ecs
|
||||||
@ -2617,16 +2664,70 @@ def test_create_task_set():
|
|||||||
service_arn = client.describe_services(
|
service_arn = client.describe_services(
|
||||||
cluster=cluster_name, services=[service_name]
|
cluster=cluster_name, services=[service_name]
|
||||||
)["services"][0]["serviceArn"]
|
)["services"][0]["serviceArn"]
|
||||||
assert task_set["clusterArn"] == cluster_arn
|
task_set["clusterArn"].should.equal(cluster_arn)
|
||||||
assert task_set["serviceArn"] == service_arn
|
task_set["serviceArn"].should.equal(service_arn)
|
||||||
assert task_set["taskDefinition"].endswith("{0}:1".format(task_def_name))
|
task_set["taskDefinition"].should.match("{0}:1$".format(task_def_name))
|
||||||
assert task_set["scale"] == {"value": 100.0, "unit": "PERCENT"}
|
task_set["scale"].should.equal({"value": 100.0, "unit": "PERCENT"})
|
||||||
assert (
|
task_set["loadBalancers"][0]["targetGroupArn"].should.equal(
|
||||||
task_set["loadBalancers"][0]["targetGroupArn"]
|
"arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/"
|
||||||
== "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
|
"c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
|
||||||
|
)
|
||||||
|
task_set["loadBalancers"][0]["containerPort"].should.equal(8080)
|
||||||
|
task_set["loadBalancers"][0]["containerName"].should.equal("hello_world")
|
||||||
|
task_set["launchType"].should.equal("EC2")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_create_task_set_errors():
|
||||||
|
# given
|
||||||
|
cluster_name = "test_ecs_cluster"
|
||||||
|
service_name = "test_ecs_service"
|
||||||
|
task_def_name = "test_ecs_task"
|
||||||
|
|
||||||
|
client = boto3.client("ecs", region_name="us-east-1")
|
||||||
|
_ = client.create_cluster(clusterName=cluster_name)
|
||||||
|
_ = client.register_task_definition(
|
||||||
|
family="test_ecs_task",
|
||||||
|
containerDefinitions=[
|
||||||
|
{
|
||||||
|
"name": "hello_world",
|
||||||
|
"image": "docker/hello-world:latest",
|
||||||
|
"cpu": 1024,
|
||||||
|
"memory": 400,
|
||||||
|
"essential": True,
|
||||||
|
"environment": [
|
||||||
|
{"name": "AWS_ACCESS_KEY_ID", "value": "SOME_ACCESS_KEY"}
|
||||||
|
],
|
||||||
|
"logConfiguration": {"logDriver": "json-file"},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
_ = client.create_service(
|
||||||
|
cluster=cluster_name,
|
||||||
|
serviceName=service_name,
|
||||||
|
taskDefinition=task_def_name,
|
||||||
|
desiredCount=2,
|
||||||
|
deploymentController={"type": "EXTERNAL"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# not existing launch type
|
||||||
|
# when
|
||||||
|
with pytest.raises(ClientError) as e:
|
||||||
|
client.create_task_set(
|
||||||
|
cluster=cluster_name,
|
||||||
|
service=service_name,
|
||||||
|
taskDefinition=task_def_name,
|
||||||
|
launchType="SOMETHING",
|
||||||
|
)
|
||||||
|
|
||||||
|
# then
|
||||||
|
ex = e.value
|
||||||
|
ex.operation_name.should.equal("CreateTaskSet")
|
||||||
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
|
ex.response["Error"]["Code"].should.contain("ClientException")
|
||||||
|
ex.response["Error"]["Message"].should.equal(
|
||||||
|
"launch type should be one of [EC2,FARGATE]"
|
||||||
)
|
)
|
||||||
assert task_set["loadBalancers"][0]["containerPort"] == 8080
|
|
||||||
assert task_set["loadBalancers"][0]["containerName"] == "hello_world"
|
|
||||||
|
|
||||||
|
|
||||||
@mock_ecs
|
@mock_ecs
|
||||||
@ -2692,20 +2793,21 @@ def test_describe_task_sets():
|
|||||||
cluster=cluster_name, services=[service_name]
|
cluster=cluster_name, services=[service_name]
|
||||||
)["services"][0]["serviceArn"]
|
)["services"][0]["serviceArn"]
|
||||||
|
|
||||||
assert "tags" in task_sets[0]
|
task_sets[0].should.have.key("tags")
|
||||||
assert len(task_sets) == 1
|
task_sets.should.have.length_of(1)
|
||||||
assert task_sets[0]["taskDefinition"].endswith("{0}:1".format(task_def_name))
|
task_sets[0]["taskDefinition"].should.match("{0}:1$".format(task_def_name))
|
||||||
assert task_sets[0]["clusterArn"] == cluster_arn
|
task_sets[0]["clusterArn"].should.equal(cluster_arn)
|
||||||
assert task_sets[0]["serviceArn"] == service_arn
|
task_sets[0]["serviceArn"].should.equal(service_arn)
|
||||||
assert task_sets[0]["serviceArn"].endswith(service_name)
|
task_sets[0]["serviceArn"].should.match("{0}$".format(service_name))
|
||||||
assert task_sets[0]["scale"] == {"value": 100.0, "unit": "PERCENT"}
|
task_sets[0]["scale"].should.equal({"value": 100.0, "unit": "PERCENT"})
|
||||||
assert task_sets[0]["taskSetArn"].endswith(task_sets[0]["id"])
|
task_sets[0]["taskSetArn"].should.match("{0}$".format(task_sets[0]["id"]))
|
||||||
assert (
|
task_sets[0]["loadBalancers"][0]["targetGroupArn"].should.equal(
|
||||||
task_sets[0]["loadBalancers"][0]["targetGroupArn"]
|
"arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/"
|
||||||
== "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
|
"c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
|
||||||
)
|
)
|
||||||
assert task_sets[0]["loadBalancers"][0]["containerPort"] == 8080
|
task_sets[0]["loadBalancers"][0]["containerPort"].should.equal(8080)
|
||||||
assert task_sets[0]["loadBalancers"][0]["containerName"] == "hello_world"
|
task_sets[0]["loadBalancers"][0]["containerName"].should.equal("hello_world")
|
||||||
|
task_sets[0]["launchType"].should.equal("EC2")
|
||||||
|
|
||||||
|
|
||||||
@mock_ecs
|
@mock_ecs
|
||||||
|
Loading…
Reference in New Issue
Block a user