ECS: delete/list/put_account_setting (#4456)
This commit is contained in:
parent
64e16d970a
commit
3d6ffcc74d
@ -48,10 +48,26 @@ class ClusterNotFoundException(JsonRESTError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EcsClientException(JsonRESTError):
|
||||||
|
code = 400
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(EcsClientException, self).__init__(
|
||||||
|
error_type="ClientException", message=message,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidParameterException(JsonRESTError):
|
class InvalidParameterException(JsonRESTError):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
super(InvalidParameterException, self).__init__(
|
super(InvalidParameterException, self).__init__(
|
||||||
error_type="ClientException", message=message,
|
error_type="InvalidParameterException", message=message,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownAccountSettingException(InvalidParameterException):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
"unknown should be one of [serviceLongArnFormat,taskLongArnFormat,containerInstanceLongArnFormat,containerLongArnFormat,awsvpcTrunking,containerInsights,dualStackIPv6]"
|
||||||
)
|
)
|
||||||
|
@ -13,12 +13,14 @@ from moto.core.exceptions import JsonRESTError
|
|||||||
from moto.core.utils import unix_time, pascal_to_camelcase, remap_nested_keys
|
from moto.core.utils import unix_time, pascal_to_camelcase, remap_nested_keys
|
||||||
from moto.ec2 import ec2_backends
|
from moto.ec2 import ec2_backends
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
|
EcsClientException,
|
||||||
ServiceNotFoundException,
|
ServiceNotFoundException,
|
||||||
TaskDefinitionNotFoundException,
|
TaskDefinitionNotFoundException,
|
||||||
TaskSetNotFoundException,
|
TaskSetNotFoundException,
|
||||||
ClusterNotFoundException,
|
ClusterNotFoundException,
|
||||||
InvalidParameterException,
|
InvalidParameterException,
|
||||||
RevisionNotFoundException,
|
RevisionNotFoundException,
|
||||||
|
UnknownAccountSettingException,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +37,9 @@ class BaseObject(BaseModel):
|
|||||||
def gen_response_object(self):
|
def gen_response_object(self):
|
||||||
response_object = copy(self.__dict__)
|
response_object = copy(self.__dict__)
|
||||||
for key, value in self.__dict__.items():
|
for key, value in self.__dict__.items():
|
||||||
if "_" in key:
|
if key.startswith("_"):
|
||||||
|
del response_object[key]
|
||||||
|
elif "_" in key:
|
||||||
response_object[self.camelCase(key)] = value
|
response_object[self.camelCase(key)] = value
|
||||||
del response_object[key]
|
del response_object[key]
|
||||||
return response_object
|
return response_object
|
||||||
@ -45,6 +49,12 @@ class BaseObject(BaseModel):
|
|||||||
return self.gen_response_object()
|
return self.gen_response_object()
|
||||||
|
|
||||||
|
|
||||||
|
class AccountSetting(BaseObject):
|
||||||
|
def __init__(self, name, value):
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
class Cluster(BaseObject, CloudFormationModel):
|
class Cluster(BaseObject, CloudFormationModel):
|
||||||
def __init__(self, cluster_name, region_name):
|
def __init__(self, cluster_name, region_name):
|
||||||
self.active_services_count = 0
|
self.active_services_count = 0
|
||||||
@ -269,6 +279,7 @@ class Task(BaseObject):
|
|||||||
task_definition,
|
task_definition,
|
||||||
container_instance_arn,
|
container_instance_arn,
|
||||||
resource_requirements,
|
resource_requirements,
|
||||||
|
backend,
|
||||||
overrides={},
|
overrides={},
|
||||||
started_by="",
|
started_by="",
|
||||||
tags=[],
|
tags=[],
|
||||||
@ -287,10 +298,11 @@ class Task(BaseObject):
|
|||||||
self.stopped_reason = ""
|
self.stopped_reason = ""
|
||||||
self.resource_requirements = resource_requirements
|
self.resource_requirements = resource_requirements
|
||||||
self.region_name = cluster.region_name
|
self.region_name = cluster.region_name
|
||||||
|
self._backend = backend
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def task_arn(self):
|
def task_arn(self):
|
||||||
if settings.ecs_new_arn_format():
|
if self._backend.enable_long_arn_for_name(name="taskLongArnFormat"):
|
||||||
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:task/{self.cluster_name}/{self.id}"
|
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:task/{self.cluster_name}/{self.id}"
|
||||||
return "arn:aws:ecs:{0}:{1}:task/{2}".format(
|
return "arn:aws:ecs:{0}:{1}:task/{2}".format(
|
||||||
self.region_name, ACCOUNT_ID, self.id
|
self.region_name, ACCOUNT_ID, self.id
|
||||||
@ -315,6 +327,7 @@ class Service(BaseObject, CloudFormationModel):
|
|||||||
tags=None,
|
tags=None,
|
||||||
deployment_controller=None,
|
deployment_controller=None,
|
||||||
launch_type=None,
|
launch_type=None,
|
||||||
|
backend=None,
|
||||||
service_registries=None,
|
service_registries=None,
|
||||||
):
|
):
|
||||||
self.cluster_name = cluster.name
|
self.cluster_name = cluster.name
|
||||||
@ -355,10 +368,11 @@ class Service(BaseObject, CloudFormationModel):
|
|||||||
self.tags = tags if tags is not None else []
|
self.tags = tags if tags is not None else []
|
||||||
self.pending_count = 0
|
self.pending_count = 0
|
||||||
self.region_name = cluster.region_name
|
self.region_name = cluster.region_name
|
||||||
|
self._backend = backend
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def arn(self):
|
def arn(self):
|
||||||
if settings.ecs_new_arn_format():
|
if self._backend.enable_long_arn_for_name(name="serviceLongArnFormat"):
|
||||||
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:service/{self.cluster_name}/{self.name}"
|
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:service/{self.cluster_name}/{self.name}"
|
||||||
return "arn:aws:ecs:{0}:{1}:service/{2}".format(
|
return "arn:aws:ecs:{0}:{1}:service/{2}".format(
|
||||||
self.region_name, ACCOUNT_ID, self.name
|
self.region_name, ACCOUNT_ID, self.name
|
||||||
@ -467,7 +481,7 @@ class Service(BaseObject, CloudFormationModel):
|
|||||||
|
|
||||||
|
|
||||||
class ContainerInstance(BaseObject):
|
class ContainerInstance(BaseObject):
|
||||||
def __init__(self, ec2_instance_id, region_name, cluster_name):
|
def __init__(self, ec2_instance_id, region_name, cluster_name, backend):
|
||||||
self.ec2_instance_id = ec2_instance_id
|
self.ec2_instance_id = ec2_instance_id
|
||||||
self.agent_connected = True
|
self.agent_connected = True
|
||||||
self.status = "ACTIVE"
|
self.status = "ACTIVE"
|
||||||
@ -556,10 +570,13 @@ class ContainerInstance(BaseObject):
|
|||||||
self.region_name = region_name
|
self.region_name = region_name
|
||||||
self.id = str(uuid.uuid4())
|
self.id = str(uuid.uuid4())
|
||||||
self.cluster_name = cluster_name
|
self.cluster_name = cluster_name
|
||||||
|
self._backend = backend
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def container_instance_arn(self):
|
def container_instance_arn(self):
|
||||||
if settings.ecs_new_arn_format():
|
if self._backend.enable_long_arn_for_name(
|
||||||
|
name="containerInstanceLongArnFormat"
|
||||||
|
):
|
||||||
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:container-instance/{self.cluster_name}/{self.id}"
|
return f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:container-instance/{self.cluster_name}/{self.id}"
|
||||||
return (
|
return (
|
||||||
f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:container-instance/{self.id}"
|
f"arn:aws:ecs:{self.region_name}:{ACCOUNT_ID}:container-instance/{self.id}"
|
||||||
@ -686,6 +703,7 @@ class TaskSet(BaseObject):
|
|||||||
class EC2ContainerServiceBackend(BaseBackend):
|
class EC2ContainerServiceBackend(BaseBackend):
|
||||||
def __init__(self, region_name):
|
def __init__(self, region_name):
|
||||||
super(EC2ContainerServiceBackend, self).__init__()
|
super(EC2ContainerServiceBackend, self).__init__()
|
||||||
|
self.account_settings = dict()
|
||||||
self.clusters = {}
|
self.clusters = {}
|
||||||
self.task_definitions = {}
|
self.task_definitions = {}
|
||||||
self.tasks = {}
|
self.tasks = {}
|
||||||
@ -879,9 +897,10 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
task_definition,
|
task_definition,
|
||||||
container_instance_arn,
|
container_instance_arn,
|
||||||
resource_requirements,
|
resource_requirements,
|
||||||
overrides or {},
|
backend=self,
|
||||||
started_by or "",
|
overrides=overrides or {},
|
||||||
tags or [],
|
started_by=started_by or "",
|
||||||
|
tags=tags or [],
|
||||||
)
|
)
|
||||||
self.update_container_instance_resources(
|
self.update_container_instance_resources(
|
||||||
container_instance, resource_requirements
|
container_instance, resource_requirements
|
||||||
@ -978,7 +997,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
self.tasks[cluster.name] = {}
|
self.tasks[cluster.name] = {}
|
||||||
tasks = []
|
tasks = []
|
||||||
if not container_instances:
|
if not container_instances:
|
||||||
raise InvalidParameterException("Container Instances cannot be empty.")
|
raise EcsClientException("Container Instances cannot be empty.")
|
||||||
|
|
||||||
container_instance_ids = [x.split("/")[-1] for x in container_instances]
|
container_instance_ids = [x.split("/")[-1] for x in container_instances]
|
||||||
resource_requirements = self._calculate_task_resource_requirements(
|
resource_requirements = self._calculate_task_resource_requirements(
|
||||||
@ -993,8 +1012,9 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
task_definition,
|
task_definition,
|
||||||
container_instance.container_instance_arn,
|
container_instance.container_instance_arn,
|
||||||
resource_requirements,
|
resource_requirements,
|
||||||
overrides or {},
|
backend=self,
|
||||||
started_by or "",
|
overrides=overrides or {},
|
||||||
|
started_by=started_by or "",
|
||||||
)
|
)
|
||||||
tasks.append(task)
|
tasks.append(task)
|
||||||
self.update_container_instance_resources(
|
self.update_container_instance_resources(
|
||||||
@ -1121,9 +1141,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
|
|
||||||
launch_type = launch_type if launch_type is not None else "EC2"
|
launch_type = launch_type if launch_type is not None else "EC2"
|
||||||
if launch_type not in ["EC2", "FARGATE"]:
|
if launch_type not in ["EC2", "FARGATE"]:
|
||||||
raise InvalidParameterException(
|
raise EcsClientException("launch type should be one of [EC2,FARGATE]")
|
||||||
"launch type should be one of [EC2,FARGATE]"
|
|
||||||
)
|
|
||||||
|
|
||||||
service = Service(
|
service = Service(
|
||||||
cluster,
|
cluster,
|
||||||
@ -1135,6 +1153,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
tags,
|
tags,
|
||||||
deployment_controller,
|
deployment_controller,
|
||||||
launch_type,
|
launch_type,
|
||||||
|
backend=self,
|
||||||
service_registries=service_registries,
|
service_registries=service_registries,
|
||||||
)
|
)
|
||||||
cluster_service_pair = "{0}:{1}".format(cluster.name, service_name)
|
cluster_service_pair = "{0}:{1}".format(cluster.name, service_name)
|
||||||
@ -1225,7 +1244,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
if cluster_name not in self.clusters:
|
if cluster_name not in self.clusters:
|
||||||
raise Exception("{0} is not a cluster".format(cluster_name))
|
raise Exception("{0} is not a cluster".format(cluster_name))
|
||||||
container_instance = ContainerInstance(
|
container_instance = ContainerInstance(
|
||||||
ec2_instance_id, self.region_name, cluster_name
|
ec2_instance_id, self.region_name, cluster_name, backend=self
|
||||||
)
|
)
|
||||||
if not self.container_instances.get(cluster_name):
|
if not self.container_instances.get(cluster_name):
|
||||||
self.container_instances[cluster_name] = {}
|
self.container_instances[cluster_name] = {}
|
||||||
@ -1250,7 +1269,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
cluster = self._get_cluster(cluster_str)
|
cluster = self._get_cluster(cluster_str)
|
||||||
|
|
||||||
if not list_container_instance_ids:
|
if not list_container_instance_ids:
|
||||||
raise InvalidParameterException("Container Instances cannot be empty.")
|
raise EcsClientException("Container Instances cannot be empty.")
|
||||||
failures = []
|
failures = []
|
||||||
container_instance_objects = []
|
container_instance_objects = []
|
||||||
for container_instance_id in list_container_instance_ids:
|
for container_instance_id in list_container_instance_ids:
|
||||||
@ -1590,9 +1609,7 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
launch_type = launch_type if launch_type is not None else "EC2"
|
launch_type = launch_type if launch_type is not None else "EC2"
|
||||||
if launch_type not in ["EC2", "FARGATE"]:
|
if launch_type not in ["EC2", "FARGATE"]:
|
||||||
raise InvalidParameterException(
|
raise EcsClientException("launch type should be one of [EC2,FARGATE]")
|
||||||
"launch type should be one of [EC2,FARGATE]"
|
|
||||||
)
|
|
||||||
|
|
||||||
task_set = TaskSet(
|
task_set = TaskSet(
|
||||||
service,
|
service,
|
||||||
@ -1702,6 +1719,41 @@ class EC2ContainerServiceBackend(BaseBackend):
|
|||||||
task_set.status = "ACTIVE"
|
task_set.status = "ACTIVE"
|
||||||
return task_set_obj
|
return task_set_obj
|
||||||
|
|
||||||
|
def list_account_settings(self, name=None, value=None):
|
||||||
|
expected_names = [
|
||||||
|
"serviceLongArnFormat",
|
||||||
|
"taskLongArnFormat",
|
||||||
|
"containerInstanceLongArnFormat",
|
||||||
|
"containerLongArnFormat",
|
||||||
|
"awsvpcTrunking",
|
||||||
|
"containerInsights",
|
||||||
|
"dualStackIPv6",
|
||||||
|
]
|
||||||
|
if name and name not in expected_names:
|
||||||
|
raise UnknownAccountSettingException()
|
||||||
|
all_settings = self.account_settings.values()
|
||||||
|
return [
|
||||||
|
s
|
||||||
|
for s in all_settings
|
||||||
|
if (not name or s.name == name) and (not value or s.value == value)
|
||||||
|
]
|
||||||
|
|
||||||
|
def put_account_setting(self, name, value):
|
||||||
|
account_setting = AccountSetting(name, value)
|
||||||
|
self.account_settings[name] = account_setting
|
||||||
|
return account_setting
|
||||||
|
|
||||||
|
def delete_account_setting(self, name):
|
||||||
|
self.account_settings.pop(name, None)
|
||||||
|
|
||||||
|
def enable_long_arn_for_name(self, name):
|
||||||
|
if settings.ecs_new_arn_format():
|
||||||
|
return True
|
||||||
|
account = self.account_settings.get(name, None)
|
||||||
|
if account and account.value == "enabled":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
ecs_backends = {}
|
ecs_backends = {}
|
||||||
for region in Session().get_available_regions("ecs"):
|
for region in Session().get_available_regions("ecs"):
|
||||||
|
@ -449,3 +449,20 @@ class EC2ContainerServiceResponse(BaseResponse):
|
|||||||
cluster_str, service_str, primary_task_set
|
cluster_str, service_str, primary_task_set
|
||||||
)
|
)
|
||||||
return json.dumps({"taskSet": task_set.response_object})
|
return json.dumps({"taskSet": task_set.response_object})
|
||||||
|
|
||||||
|
def put_account_setting(self):
|
||||||
|
name = self._get_param("name")
|
||||||
|
value = self._get_param("value")
|
||||||
|
account_setting = self.ecs_backend.put_account_setting(name, value)
|
||||||
|
return json.dumps({"setting": account_setting.response_object})
|
||||||
|
|
||||||
|
def list_account_settings(self):
|
||||||
|
name = self._get_param("name")
|
||||||
|
value = self._get_param("value")
|
||||||
|
account_settings = self.ecs_backend.list_account_settings(name, value)
|
||||||
|
return json.dumps({"settings": [s.response_object for s in account_settings]})
|
||||||
|
|
||||||
|
def delete_account_setting(self):
|
||||||
|
name = self._get_param("name")
|
||||||
|
self.ecs_backend.delete_account_setting(name)
|
||||||
|
return "{}"
|
||||||
|
244
tests/test_ecs/test_ecs_account_settings.py
Normal file
244
tests/test_ecs/test_ecs_account_settings.py
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
from botocore.exceptions import ClientError
|
||||||
|
import boto3
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
import json
|
||||||
|
|
||||||
|
from moto.core import ACCOUNT_ID
|
||||||
|
from moto.ec2 import utils as ec2_utils
|
||||||
|
|
||||||
|
from moto import mock_ecs, mock_ec2
|
||||||
|
import pytest
|
||||||
|
from tests import EXAMPLE_AMI_ID
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_list_account_settings_initial():
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
|
||||||
|
resp = client.list_account_settings()
|
||||||
|
resp.should.have.key("settings").equal([])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"name",
|
||||||
|
["containerInstanceLongArnFormat", "serviceLongArnFormat", "taskLongArnFormat"],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("value", ["enabled", "disabled"])
|
||||||
|
def test_put_account_setting(name, value):
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
|
||||||
|
resp = client.put_account_setting(name=name, value=value)
|
||||||
|
resp.should.have.key("setting")
|
||||||
|
resp["setting"].should.equal({"name": name, "value": value})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_list_account_setting():
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
|
||||||
|
client.put_account_setting(name="containerInstanceLongArnFormat", value="enabled")
|
||||||
|
client.put_account_setting(name="serviceLongArnFormat", value="disabled")
|
||||||
|
client.put_account_setting(name="taskLongArnFormat", value="enabled")
|
||||||
|
|
||||||
|
resp = client.list_account_settings()
|
||||||
|
resp.should.have.key("settings").length_of(3)
|
||||||
|
resp["settings"].should.contain(
|
||||||
|
{"name": "containerInstanceLongArnFormat", "value": "enabled"}
|
||||||
|
)
|
||||||
|
resp["settings"].should.contain(
|
||||||
|
{"name": "serviceLongArnFormat", "value": "disabled"}
|
||||||
|
)
|
||||||
|
resp["settings"].should.contain({"name": "taskLongArnFormat", "value": "enabled"})
|
||||||
|
|
||||||
|
resp = client.list_account_settings(name="serviceLongArnFormat")
|
||||||
|
resp.should.have.key("settings").length_of(1)
|
||||||
|
resp["settings"].should.contain(
|
||||||
|
{"name": "serviceLongArnFormat", "value": "disabled"}
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = client.list_account_settings(value="enabled")
|
||||||
|
resp.should.have.key("settings").length_of(2)
|
||||||
|
resp["settings"].should.contain(
|
||||||
|
{"name": "containerInstanceLongArnFormat", "value": "enabled"}
|
||||||
|
)
|
||||||
|
resp["settings"].should.contain({"name": "taskLongArnFormat", "value": "enabled"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_list_account_settings_wrong_name():
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.list_account_settings(name="unknown")
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("InvalidParameterException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"unknown should be one of [serviceLongArnFormat,taskLongArnFormat,containerInstanceLongArnFormat,containerLongArnFormat,awsvpcTrunking,containerInsights,dualStackIPv6]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ecs
|
||||||
|
def test_delete_account_setting():
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
|
||||||
|
client.put_account_setting(name="containerInstanceLongArnFormat", value="enabled")
|
||||||
|
client.put_account_setting(name="serviceLongArnFormat", value="enabled")
|
||||||
|
client.put_account_setting(name="taskLongArnFormat", value="enabled")
|
||||||
|
|
||||||
|
resp = client.list_account_settings()
|
||||||
|
resp.should.have.key("settings").length_of(3)
|
||||||
|
|
||||||
|
client.delete_account_setting(name="serviceLongArnFormat")
|
||||||
|
|
||||||
|
resp = client.list_account_settings()
|
||||||
|
resp.should.have.key("settings").length_of(2)
|
||||||
|
resp["settings"].should.contain(
|
||||||
|
{"name": "containerInstanceLongArnFormat", "value": "enabled"}
|
||||||
|
)
|
||||||
|
resp["settings"].should.contain({"name": "taskLongArnFormat", "value": "enabled"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_ecs
|
||||||
|
def test_put_account_setting_changes_service_arn():
|
||||||
|
client = boto3.client("ecs", region_name="eu-west-1")
|
||||||
|
client.put_account_setting(name="serviceLongArnFormat", value="enabled")
|
||||||
|
|
||||||
|
_ = client.create_cluster(clusterName="dummy-cluster")
|
||||||
|
_ = client.register_task_definition(
|
||||||
|
family="test_ecs_task",
|
||||||
|
containerDefinitions=[
|
||||||
|
{
|
||||||
|
"name": "hello_world",
|
||||||
|
"image": "docker/hello-world:latest",
|
||||||
|
"cpu": 1024,
|
||||||
|
"memory": 400,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
client.create_service(
|
||||||
|
cluster="dummy-cluster",
|
||||||
|
serviceName="test-ecs-service",
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
desiredCount=2,
|
||||||
|
launchType="FARGATE",
|
||||||
|
tags=[{"key": "ResourceOwner", "value": "Dummy"}],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initial response is long
|
||||||
|
response = client.list_services(cluster="dummy-cluster", launchType="FARGATE")
|
||||||
|
service_arn = response["serviceArns"][0]
|
||||||
|
service_arn.should.equal(
|
||||||
|
"arn:aws:ecs:eu-west-1:{}:service/dummy-cluster/test-ecs-service".format(
|
||||||
|
ACCOUNT_ID
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Second invocation returns short ARN's, after deleting the longArn-preference
|
||||||
|
client.delete_account_setting(name="serviceLongArnFormat")
|
||||||
|
response = client.list_services(cluster="dummy-cluster", launchType="FARGATE")
|
||||||
|
service_arn = response["serviceArns"][0]
|
||||||
|
service_arn.should.equal(
|
||||||
|
"arn:aws:ecs:eu-west-1:{}:service/test-ecs-service".format(ACCOUNT_ID)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_ecs
|
||||||
|
def test_put_account_setting_changes_containerinstance_arn():
|
||||||
|
ecs_client = boto3.client("ecs", region_name="us-east-1")
|
||||||
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
test_cluster_name = "test_ecs_cluster"
|
||||||
|
|
||||||
|
ecs_client.create_cluster(clusterName=test_cluster_name)
|
||||||
|
|
||||||
|
test_instance = ec2.create_instances(
|
||||||
|
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
instance_id_document = json.dumps(
|
||||||
|
ec2_utils.generate_instance_identity_document(test_instance)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initial ARN should be short
|
||||||
|
response = ecs_client.register_container_instance(
|
||||||
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
||||||
|
)
|
||||||
|
full_arn = response["containerInstance"]["containerInstanceArn"]
|
||||||
|
full_arn.should.match(
|
||||||
|
f"arn:aws:ecs:us-east-1:{ACCOUNT_ID}:container-instance/[a-z0-9-]+$"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now enable long-format
|
||||||
|
ecs_client.put_account_setting(
|
||||||
|
name="containerInstanceLongArnFormat", value="enabled"
|
||||||
|
)
|
||||||
|
response = ecs_client.register_container_instance(
|
||||||
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
||||||
|
)
|
||||||
|
full_arn = response["containerInstance"]["containerInstanceArn"]
|
||||||
|
full_arn.should.match(
|
||||||
|
f"arn:aws:ecs:us-east-1:{ACCOUNT_ID}:container-instance/{test_cluster_name}/[a-z0-9-]+$"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
@mock_ecs
|
||||||
|
def test_run_task_default_cluster_new_arn_format():
|
||||||
|
client = boto3.client("ecs", region_name="us-east-1")
|
||||||
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
test_cluster_name = "default"
|
||||||
|
|
||||||
|
client.create_cluster(clusterName=test_cluster_name)
|
||||||
|
|
||||||
|
test_instance = ec2.create_instances(
|
||||||
|
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
instance_id_document = json.dumps(
|
||||||
|
ec2_utils.generate_instance_identity_document(test_instance)
|
||||||
|
)
|
||||||
|
|
||||||
|
client.register_container_instance(
|
||||||
|
cluster=test_cluster_name, instanceIdentityDocument=instance_id_document
|
||||||
|
)
|
||||||
|
|
||||||
|
client.register_task_definition(
|
||||||
|
family="test_ecs_task",
|
||||||
|
containerDefinitions=[
|
||||||
|
{
|
||||||
|
"name": "hello_world",
|
||||||
|
"image": "docker/hello-world:latest",
|
||||||
|
"cpu": 1024,
|
||||||
|
"memory": 400,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
# Initial ARN is short-format
|
||||||
|
client.put_account_setting(name="taskLongArnFormat", value="disabled")
|
||||||
|
response = client.run_task(
|
||||||
|
launchType="FARGATE",
|
||||||
|
overrides={},
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
count=1,
|
||||||
|
startedBy="moto",
|
||||||
|
)
|
||||||
|
response["tasks"][0]["taskArn"].should.match(
|
||||||
|
f"arn:aws:ecs:us-east-1:{ACCOUNT_ID}:task/[a-z0-9-]+$"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Enable long-format for the next task
|
||||||
|
client.put_account_setting(name="taskLongArnFormat", value="enabled")
|
||||||
|
response = client.run_task(
|
||||||
|
launchType="FARGATE",
|
||||||
|
overrides={},
|
||||||
|
taskDefinition="test_ecs_task",
|
||||||
|
count=1,
|
||||||
|
startedBy="moto",
|
||||||
|
)
|
||||||
|
response["tasks"][0]["taskArn"].should.match(
|
||||||
|
f"arn:aws:ecs:us-east-1:{ACCOUNT_ID}:task/{test_cluster_name}/[a-z0-9-]+$"
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user