Add launchType parameter to ECS (#3578)

This commit is contained in:
Anton Grübel 2021-01-08 18:14:40 +01:00 committed by GitHub
parent d712a98ce1
commit f4418185d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 22 deletions

View File

@ -256,6 +256,7 @@ class Service(BaseObject, CloudFormationModel):
scheduling_strategy=None,
tags=None,
deployment_controller=None,
launch_type=None,
):
self.cluster_arn = cluster.arn
self.arn = "arn:aws:ecs:{0}:012345678910:service/{1}".format(
@ -272,12 +273,14 @@ class Service(BaseObject, CloudFormationModel):
self.task_sets = []
self.deployment_controller = deployment_controller or {"type": "ECS"}
self.events = []
self.launch_type = launch_type
if self.deployment_controller["type"] == "ECS":
self.deployments = [
{
"createdAt": datetime.now(pytz.utc),
"desiredCount": self.desired_count,
"id": "ecs-svc/{}".format(randint(0, 32 ** 12)),
"launchType": self.launch_type,
"pendingCount": self.desired_count,
"runningCount": 0,
"status": "PRIMARY",
@ -1011,6 +1014,7 @@ class EC2ContainerServiceBackend(BaseBackend):
scheduling_strategy=None,
tags=None,
deployment_controller=None,
launch_type=None,
):
cluster_name = cluster_str.split("/")[-1]
if cluster_name in self.clusters:
@ -1023,6 +1027,12 @@ class EC2ContainerServiceBackend(BaseBackend):
task_definition = None
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(
cluster,
service_name,
@ -1032,6 +1042,7 @@ class EC2ContainerServiceBackend(BaseBackend):
scheduling_strategy,
tags,
deployment_controller,
launch_type,
)
cluster_service_pair = "{0}:{1}".format(cluster_name, service_name)
self.services[cluster_service_pair] = service
@ -1478,6 +1489,12 @@ class EC2ContainerServiceBackend(BaseBackend):
client_token=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(
service,
cluster,

View File

@ -166,6 +166,7 @@ class EC2ContainerServiceResponse(BaseResponse):
scheduling_strategy = self._get_param("schedulingStrategy")
tags = self._get_param("tags")
deployment_controller = self._get_param("deploymentController")
launch_type = self._get_param("launchType")
service = self.ecs_backend.create_service(
cluster_str,
service_name,
@ -175,6 +176,7 @@ class EC2ContainerServiceResponse(BaseResponse):
scheduling_strategy,
tags,
deployment_controller,
launch_type,
)
return json.dumps({"service": service.response_object})

View File

@ -422,6 +422,50 @@ def test_create_service():
"arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1"
)
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
@ -582,6 +626,7 @@ def test_describe_services():
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")
response["services"][0]["deployments"][0]["launchType"].should.equal("EC2")
(
datetime.now()
- response["services"][0]["deployments"][0]["createdAt"].replace(tzinfo=None)
@ -602,6 +647,8 @@ def test_describe_services():
[{"key": "Name", "value": "test_ecs_service1"}]
)
response["services"][1]["tags"].should.equal([])
response["services"][0]["launchType"].should.equal("EC2")
response["services"][1]["launchType"].should.equal("EC2")
@mock_ecs
@ -2617,16 +2664,70 @@ def test_create_task_set():
service_arn = client.describe_services(
cluster=cluster_name, services=[service_name]
)["services"][0]["serviceArn"]
assert task_set["clusterArn"] == cluster_arn
assert task_set["serviceArn"] == service_arn
assert task_set["taskDefinition"].endswith("{0}:1".format(task_def_name))
assert task_set["scale"] == {"value": 100.0, "unit": "PERCENT"}
assert (
task_set["loadBalancers"][0]["targetGroupArn"]
== "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
task_set["clusterArn"].should.equal(cluster_arn)
task_set["serviceArn"].should.equal(service_arn)
task_set["taskDefinition"].should.match("{0}:1$".format(task_def_name))
task_set["scale"].should.equal({"value": 100.0, "unit": "PERCENT"})
task_set["loadBalancers"][0]["targetGroupArn"].should.equal(
"arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/"
"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
@ -2692,20 +2793,21 @@ def test_describe_task_sets():
cluster=cluster_name, services=[service_name]
)["services"][0]["serviceArn"]
assert "tags" in task_sets[0]
assert len(task_sets) == 1
assert task_sets[0]["taskDefinition"].endswith("{0}:1".format(task_def_name))
assert task_sets[0]["clusterArn"] == cluster_arn
assert task_sets[0]["serviceArn"] == service_arn
assert task_sets[0]["serviceArn"].endswith(service_name)
assert task_sets[0]["scale"] == {"value": 100.0, "unit": "PERCENT"}
assert task_sets[0]["taskSetArn"].endswith(task_sets[0]["id"])
assert (
task_sets[0]["loadBalancers"][0]["targetGroupArn"]
== "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
task_sets[0].should.have.key("tags")
task_sets.should.have.length_of(1)
task_sets[0]["taskDefinition"].should.match("{0}:1$".format(task_def_name))
task_sets[0]["clusterArn"].should.equal(cluster_arn)
task_sets[0]["serviceArn"].should.equal(service_arn)
task_sets[0]["serviceArn"].should.match("{0}$".format(service_name))
task_sets[0]["scale"].should.equal({"value": 100.0, "unit": "PERCENT"})
task_sets[0]["taskSetArn"].should.match("{0}$".format(task_sets[0]["id"]))
task_sets[0]["loadBalancers"][0]["targetGroupArn"].should.equal(
"arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/"
"c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a"
)
assert task_sets[0]["loadBalancers"][0]["containerPort"] == 8080
assert task_sets[0]["loadBalancers"][0]["containerName"] == "hello_world"
task_sets[0]["loadBalancers"][0]["containerPort"].should.equal(8080)
task_sets[0]["loadBalancers"][0]["containerName"].should.equal("hello_world")
task_sets[0]["launchType"].should.equal("EC2")
@mock_ecs