399 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			399 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|  | from botocore.exceptions import ClientError | ||
|  | import boto3 | ||
|  | import sure  # noqa # pylint: disable=unused-import | ||
|  | 
 | ||
|  | from moto import mock_ecs | ||
|  | import pytest | ||
|  | 
 | ||
|  | 
 | ||
|  | cluster_name = "test_ecs_cluster" | ||
|  | service_name = "test_ecs_service" | ||
|  | task_def_name = "test_ecs_task" | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_create_task_set(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  |     load_balancers = [ | ||
|  |         { | ||
|  |             "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a", | ||
|  |             "containerName": "hello_world", | ||
|  |             "containerPort": 8080, | ||
|  |         }, | ||
|  |     ] | ||
|  | 
 | ||
|  |     task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         loadBalancers=load_balancers, | ||
|  |     )["taskSet"] | ||
|  | 
 | ||
|  |     cluster_arn = client.describe_clusters(clusters=[cluster_name])["clusters"][0][ | ||
|  |         "clusterArn" | ||
|  |     ] | ||
|  |     service_arn = client.describe_services( | ||
|  |         cluster=cluster_name, services=[service_name] | ||
|  |     )["services"][0]["serviceArn"] | ||
|  |     task_set["clusterArn"].should.equal(cluster_arn) | ||
|  |     task_set["serviceArn"].should.equal(service_arn) | ||
|  |     task_set["taskDefinition"].should.match(f"{task_def_name}:1$") | ||
|  |     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") | ||
|  |     task_set["platformVersion"].should.equal("LATEST") | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_create_task_set_errors(): | ||
|  |     # given | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = 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]" | ||
|  |     ) | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_describe_task_sets(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     load_balancers = [ | ||
|  |         { | ||
|  |             "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a", | ||
|  |             "containerName": "hello_world", | ||
|  |             "containerPort": 8080, | ||
|  |         } | ||
|  |     ] | ||
|  | 
 | ||
|  |     _ = client.create_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         loadBalancers=load_balancers, | ||
|  |     ) | ||
|  |     task_sets = client.describe_task_sets(cluster=cluster_name, service=service_name)[ | ||
|  |         "taskSets" | ||
|  |     ] | ||
|  |     assert "tags" not in task_sets[0] | ||
|  | 
 | ||
|  |     task_sets = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, include=["TAGS"] | ||
|  |     )["taskSets"] | ||
|  | 
 | ||
|  |     cluster_arn = client.describe_clusters(clusters=[cluster_name])["clusters"][0][ | ||
|  |         "clusterArn" | ||
|  |     ] | ||
|  | 
 | ||
|  |     service_arn = client.describe_services( | ||
|  |         cluster=cluster_name, services=[service_name] | ||
|  |     )["services"][0]["serviceArn"] | ||
|  | 
 | ||
|  |     task_sets.should.have.length_of(1) | ||
|  |     task_sets[0].should.have.key("tags") | ||
|  |     task_sets[0]["taskDefinition"].should.match(f"{task_def_name}:1$") | ||
|  |     task_sets[0]["clusterArn"].should.equal(cluster_arn) | ||
|  |     task_sets[0]["serviceArn"].should.equal(service_arn) | ||
|  |     task_sets[0]["serviceArn"].should.match(f"{service_name}$") | ||
|  |     task_sets[0]["scale"].should.equal({"value": 100.0, "unit": "PERCENT"}) | ||
|  |     task_sets[0]["taskSetArn"].should.match(f"{task_sets[0]['id']}$") | ||
|  |     task_sets[0]["loadBalancers"][0]["targetGroupArn"].should.equal( | ||
|  |         "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/" | ||
|  |         "c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a" | ||
|  |     ) | ||
|  |     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 | ||
|  | def test_delete_task_set(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  | 
 | ||
|  |     task_sets = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, taskSets=[task_set["taskSetArn"]] | ||
|  |     )["taskSets"] | ||
|  | 
 | ||
|  |     assert len(task_sets) == 1 | ||
|  | 
 | ||
|  |     task_sets = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, taskSets=[task_set["taskSetArn"]] | ||
|  |     )["taskSets"] | ||
|  | 
 | ||
|  |     assert len(task_sets) == 1 | ||
|  | 
 | ||
|  |     response = client.delete_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskSet=task_set["taskSetArn"] | ||
|  |     ) | ||
|  |     assert response["taskSet"]["taskSetArn"] == task_set["taskSetArn"] | ||
|  | 
 | ||
|  |     task_sets = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, taskSets=[task_set["taskSetArn"]] | ||
|  |     )["taskSets"] | ||
|  | 
 | ||
|  |     assert len(task_sets) == 0 | ||
|  | 
 | ||
|  |     with pytest.raises(ClientError): | ||
|  |         _ = client.delete_task_set( | ||
|  |             cluster=cluster_name, service=service_name, taskSet=task_set["taskSetArn"] | ||
|  |         ) | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_delete_task_set__using_partial_arn(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  | 
 | ||
|  |     # Partial ARN match | ||
|  |     # arn:aws:ecs:us-east-1:123456789012:task-set/test_ecs_cluster/test_ecs_service/ecs-svc/386233676373827416 | ||
|  |     # --> ecs-svc/386233676373827416 | ||
|  |     partial_arn = "/".join(task_set["taskSetArn"].split("/")[-2:]) | ||
|  |     task_sets = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, taskSets=[partial_arn] | ||
|  |     )["taskSets"] | ||
|  | 
 | ||
|  |     assert len(task_sets) == 1 | ||
|  | 
 | ||
|  |     response = client.delete_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskSet=partial_arn | ||
|  |     ) | ||
|  |     assert response["taskSet"]["taskSetArn"] == task_set["taskSetArn"] | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_update_service_primary_task_set(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  | 
 | ||
|  |     service = client.describe_services(cluster=cluster_name, services=[service_name],)[ | ||
|  |         "services" | ||
|  |     ][0] | ||
|  | 
 | ||
|  |     _ = client.update_service_primary_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         primaryTaskSet=task_set["taskSetArn"], | ||
|  |     ) | ||
|  | 
 | ||
|  |     service = client.describe_services(cluster=cluster_name, services=[service_name],)[ | ||
|  |         "services" | ||
|  |     ][0] | ||
|  |     assert service["taskSets"][0]["status"] == "PRIMARY" | ||
|  |     assert service["taskDefinition"] == service["taskSets"][0]["taskDefinition"] | ||
|  | 
 | ||
|  |     another_task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  |     service = client.describe_services(cluster=cluster_name, services=[service_name],)[ | ||
|  |         "services" | ||
|  |     ][0] | ||
|  |     assert service["taskSets"][1]["status"] == "ACTIVE" | ||
|  | 
 | ||
|  |     _ = client.update_service_primary_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         primaryTaskSet=another_task_set["taskSetArn"], | ||
|  |     ) | ||
|  |     service = client.describe_services(cluster=cluster_name, services=[service_name],)[ | ||
|  |         "services" | ||
|  |     ][0] | ||
|  |     assert service["taskSets"][0]["status"] == "ACTIVE" | ||
|  |     assert service["taskSets"][1]["status"] == "PRIMARY" | ||
|  |     assert service["taskDefinition"] == service["taskSets"][1]["taskDefinition"] | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_update_task_set(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  | 
 | ||
|  |     another_task_set = client.create_task_set( | ||
|  |         cluster=cluster_name, service=service_name, taskDefinition=task_def_name | ||
|  |     )["taskSet"] | ||
|  |     assert another_task_set["scale"]["unit"] == "PERCENT" | ||
|  |     assert another_task_set["scale"]["value"] == 100.0 | ||
|  | 
 | ||
|  |     client.update_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         taskSet=task_set["taskSetArn"], | ||
|  |         scale={"value": 25.0, "unit": "PERCENT"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     updated_task_set = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, taskSets=[task_set["taskSetArn"]] | ||
|  |     )["taskSets"][0] | ||
|  |     assert updated_task_set["scale"]["value"] == 25.0 | ||
|  |     assert updated_task_set["scale"]["unit"] == "PERCENT" | ||
|  | 
 | ||
|  | 
 | ||
|  | @mock_ecs | ||
|  | def test_create_task_sets_with_tags(): | ||
|  |     client = boto3.client("ecs", region_name="us-east-1") | ||
|  |     _ = client.create_cluster(clusterName=cluster_name) | ||
|  |     create_task_def(client) | ||
|  |     _ = client.create_service( | ||
|  |         cluster=cluster_name, | ||
|  |         serviceName=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         desiredCount=2, | ||
|  |         deploymentController={"type": "EXTERNAL"}, | ||
|  |     ) | ||
|  | 
 | ||
|  |     load_balancers = [ | ||
|  |         { | ||
|  |             "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:01234567890:targetgroup/c26b93c1bc35466ba792d5b08fe6a5bc/ec39113f8831453a", | ||
|  |             "containerName": "hello_world", | ||
|  |             "containerPort": 8080, | ||
|  |         } | ||
|  |     ] | ||
|  | 
 | ||
|  |     _ = client.create_task_set( | ||
|  |         cluster=cluster_name, | ||
|  |         service=service_name, | ||
|  |         taskDefinition=task_def_name, | ||
|  |         loadBalancers=load_balancers, | ||
|  |         tags=[{"key": "k1", "value": "v1"}, {"key": "k2", "value": "v2"}], | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, include=["TAGS"] | ||
|  |     )["taskSets"][0] | ||
|  |     task_set.should.have.key("tags").equals( | ||
|  |         [{"key": "k1", "value": "v1"}, {"key": "k2", "value": "v2"}] | ||
|  |     ) | ||
|  | 
 | ||
|  |     client.tag_resource( | ||
|  |         resourceArn=task_set["taskSetArn"], tags=[{"key": "k3", "value": "v3"}] | ||
|  |     ) | ||
|  | 
 | ||
|  |     task_set = client.describe_task_sets( | ||
|  |         cluster=cluster_name, service=service_name, include=["TAGS"] | ||
|  |     )["taskSets"][0] | ||
|  |     task_set.should.have.key("tags") | ||
|  |     task_set["tags"].should.have.length_of(3) | ||
|  |     task_set["tags"].should.contain({"key": "k1", "value": "v1"}) | ||
|  |     task_set["tags"].should.contain({"key": "k2", "value": "v2"}) | ||
|  |     task_set["tags"].should.contain({"key": "k3", "value": "v3"}) | ||
|  | 
 | ||
|  |     client.untag_resource(resourceArn=task_set["taskSetArn"], tagKeys=["k2"]) | ||
|  | 
 | ||
|  |     resp = client.list_tags_for_resource(resourceArn=task_set["taskSetArn"]) | ||
|  |     resp.should.have.key("tags") | ||
|  |     resp["tags"].should.have.length_of(2) | ||
|  |     resp["tags"].should.contain({"key": "k1", "value": "v1"}) | ||
|  |     resp["tags"].should.contain({"key": "k3", "value": "v3"}) | ||
|  | 
 | ||
|  | 
 | ||
|  | def create_task_def(client): | ||
|  |     client.register_task_definition( | ||
|  |         family=task_def_name, | ||
|  |         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"}, | ||
|  |             } | ||
|  |         ], | ||
|  |     ) |