| 
									
										
										
										
											2013-05-17 19:35:53 -04:00
										 |  |  | import base64 | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  | import ipaddress | 
					
						
							| 
									
										
										
										
											2023-02-25 10:19:28 -01:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2022-08-17 14:01:22 +00:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2022-05-26 18:04:36 +02:00
										 |  |  | from unittest import SkipTest, mock | 
					
						
							|  |  |  | from uuid import uuid4 | 
					
						
							| 
									
										
										
										
											2013-05-17 19:35:53 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | import boto3 | 
					
						
							| 
									
										
										
										
											2022-05-26 18:04:36 +02:00
										 |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2022-05-26 18:04:36 +02:00
										 |  |  | from botocore.exceptions import ClientError, ParamValidationError | 
					
						
							|  |  |  | from freezegun import freeze_time | 
					
						
							| 
									
										
										
										
											2022-10-29 23:06:21 +01:00
										 |  |  | from moto import mock_ec2, mock_iam, settings | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  | from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  | from tests import EXAMPLE_AMI_ID | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  | decode_method = base64.decodebytes | 
					
						
							| 
									
										
										
										
											2020-09-02 15:40:29 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 08:14:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_add_servers(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resp = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2) | 
					
						
							|  |  |  |     for i in resp["Instances"]: | 
					
						
							|  |  |  |         i["ImageId"].should.equal(EXAMPLE_AMI_ID) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = client.describe_instances( | 
					
						
							|  |  |  |         InstanceIds=[i["InstanceId"] for i in resp["Instances"]] | 
					
						
							|  |  |  |     )["Reservations"][0]["Instances"] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     instances.should.have.length_of(2) | 
					
						
							|  |  |  |     for i in instances: | 
					
						
							|  |  |  |         i["ImageId"].should.equal(EXAMPLE_AMI_ID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freeze_time("2014-01-01 05:00:00") | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_launch_and_terminate(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.run_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, DryRun=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     reservation["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     instance = reservation["Instances"][0] | 
					
						
							|  |  |  |     instance["State"].should.equal({"Code": 0, "Name": "pending"}) | 
					
						
							|  |  |  |     instance_id = instance["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     reservations = client.describe_instances(InstanceIds=[instance_id])["Reservations"] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     reservations.should.have.length_of(1) | 
					
						
							|  |  |  |     reservations[0]["ReservationId"].should.equal(reservation["ReservationId"]) | 
					
						
							|  |  |  |     instances = reservations[0]["Instances"] | 
					
						
							|  |  |  |     instances.should.have.length_of(1) | 
					
						
							|  |  |  |     instance = instances[0] | 
					
						
							|  |  |  |     instance["InstanceId"].should.equal(instance_id) | 
					
						
							|  |  |  |     instance["State"].should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         # Exact value can't be determined in ServerMode | 
					
						
							|  |  |  |         instance.should.have.key("LaunchTime") | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         launch_time = instance["LaunchTime"].strftime("%Y-%m-%dT%H:%M:%S.000Z") | 
					
						
							|  |  |  |         launch_time.should.equal("2014-01-01T05:00:00.000Z") | 
					
						
							|  |  |  |     instance["VpcId"].shouldnt.equal(None) | 
					
						
							|  |  |  |     instance["Placement"]["AvailabilityZone"].should.equal("us-east-1a") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     root_device_name = instance["RootDeviceName"] | 
					
						
							|  |  |  |     mapping = instance["BlockDeviceMappings"][0] | 
					
						
							|  |  |  |     mapping["DeviceName"].should.equal(root_device_name) | 
					
						
							|  |  |  |     mapping["Ebs"]["Status"].should.equal("in-use") | 
					
						
							|  |  |  |     volume_id = mapping["Ebs"]["VolumeId"] | 
					
						
							|  |  |  |     volume_id.should.match(r"vol-\w+") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volume = client.describe_volumes(VolumeIds=[volume_id])["Volumes"][0] | 
					
						
							|  |  |  |     volume["Attachments"][0]["InstanceId"].should.equal(instance_id) | 
					
						
							|  |  |  |     volume["State"].should.equal("in-use") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=[instance_id], DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the TerminateInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-04 20:36:39 +10:00
										 |  |  |     response = client.terminate_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  |     response["TerminatingInstances"].should.have.length_of(1) | 
					
						
							|  |  |  |     instance = response["TerminatingInstances"][0] | 
					
						
							|  |  |  |     instance["InstanceId"].should.equal(instance_id) | 
					
						
							|  |  |  |     instance["PreviousState"].should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  |     instance["CurrentState"].should.equal({"Code": 32, "Name": "shutting-down"}) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     reservations = client.describe_instances(InstanceIds=[instance_id])["Reservations"] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     instance = reservations[0]["Instances"][0] | 
					
						
							|  |  |  |     instance["State"].should.equal({"Code": 48, "Name": "terminated"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_terminate_discard_volumes(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         BlockDeviceMappings=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "DeviceName": "/dev/sda1", | 
					
						
							|  |  |  |                 "Ebs": {"VolumeSize": 50, "DeleteOnTermination": True}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_volume_ids = [] | 
					
						
							|  |  |  |     for volume in instance.volumes.all(): | 
					
						
							|  |  |  |         instance_volume_ids.append(volume.volume_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.terminate() | 
					
						
							|  |  |  |     instance.wait_until_terminated() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_volumes_ids = [v.id for v in list(ec2_resource.volumes.all())] | 
					
						
							|  |  |  |     for my_id in instance_volume_ids: | 
					
						
							|  |  |  |         all_volumes_ids.shouldnt.contain(my_id) | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2020-06-16 08:03:02 +03:00
										 |  |  | def test_instance_terminate_keep_volumes_explicit(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-06-16 08:03:02 +03:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         BlockDeviceMappings=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "DeviceName": "/dev/sda1", | 
					
						
							|  |  |  |                 "Ebs": {"VolumeSize": 50, "DeleteOnTermination": False}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_volume_ids = [] | 
					
						
							|  |  |  |     for volume in instance.volumes.all(): | 
					
						
							|  |  |  |         instance_volume_ids.append(volume.volume_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.terminate() | 
					
						
							|  |  |  |     instance.wait_until_terminated() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_volumes_ids = [v.id for v in list(ec2_resource.volumes.all())] | 
					
						
							|  |  |  |     for my_id in instance_volume_ids: | 
					
						
							|  |  |  |         all_volumes_ids.should.contain(my_id) | 
					
						
							| 
									
										
										
										
											2020-06-16 08:03:02 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_terminate_keep_volumes_implicit(): | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         BlockDeviceMappings=[{"DeviceName": "/dev/sda1", "Ebs": {"VolumeSize": 50}}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_volume_ids = [] | 
					
						
							|  |  |  |     for volume in instance.volumes.all(): | 
					
						
							|  |  |  |         instance_volume_ids.append(volume.volume_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.terminate() | 
					
						
							|  |  |  |     instance.wait_until_terminated() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert len(instance_volume_ids) == 1 | 
					
						
							|  |  |  |     volume = ec2_resource.Volume(instance_volume_ids[0]) | 
					
						
							|  |  |  |     volume.state.should.equal("available") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_terminate_detach_volumes(): | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         BlockDeviceMappings=[ | 
					
						
							|  |  |  |             {"DeviceName": "/dev/sda1", "Ebs": {"VolumeSize": 50}}, | 
					
						
							|  |  |  |             {"DeviceName": "/dev/sda2", "Ebs": {"VolumeSize": 50}}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     my_volume_ids = [] | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |     for volume in instance.volumes.all(): | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         my_volume_ids.append(volume.volume_id) | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         response = instance.detach_volume(VolumeId=volume.volume_id) | 
					
						
							|  |  |  |         response["State"].should.equal("detaching") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.terminate() | 
					
						
							|  |  |  |     instance.wait_until_terminated() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     all_volumes_ids = [v.id for v in list(ec2_resource.volumes.all())] | 
					
						
							|  |  |  |     for my_id in my_volume_ids: | 
					
						
							|  |  |  |         all_volumes_ids.should.contain(my_id) | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_detach_volume_wrong_path(): | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  |         BlockDeviceMappings=[{"DeviceName": "/dev/sda1", "Ebs": {"VolumeSize": 50}}], | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							|  |  |  |     for volume in instance.volumes.all(): | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         with pytest.raises(ClientError) as ex: | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |             instance.detach_volume(VolumeId=volume.volume_id, Device="/dev/sdf") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:46:05 +02:00
										 |  |  |         ex.value.response["Error"]["Code"].should.equal("InvalidAttachment.NotFound") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |         ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |             f"The volume {volume.volume_id} is not attached to instance {instance.instance_id} as device /dev/sdf" | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_terminate_empty_instances(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=[]) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidParameterCombination") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal("No instances specified") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freeze_time("2014-01-01 05:00:00") | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_attach_volume(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance = ec2.Instance(reservation["Instances"][0]["InstanceId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vol1 = ec2.create_volume(Size=36, AvailabilityZone="us-east-1a") | 
					
						
							|  |  |  |     vol1.attach_to_instance(InstanceId=instance.id, Device="/dev/sda1") | 
					
						
							|  |  |  |     vol2 = ec2.create_volume(Size=65, AvailabilityZone="us-east-1a") | 
					
						
							|  |  |  |     vol2.attach_to_instance(InstanceId=instance.id, Device="/dev/sdb1") | 
					
						
							|  |  |  |     vol3 = ec2.create_volume(Size=130, AvailabilityZone="us-east-1a") | 
					
						
							|  |  |  |     vol3.attach_to_instance(InstanceId=instance.id, Device="/dev/sdc1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.reload() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.block_device_mappings.should.have.length_of(3) | 
					
						
							|  |  |  |     expected_vol3_id = [ | 
					
						
							|  |  |  |         m["Ebs"]["VolumeId"] | 
					
						
							|  |  |  |         for m in instance.block_device_mappings | 
					
						
							|  |  |  |         if m["DeviceName"] == "/dev/sdc1" | 
					
						
							|  |  |  |     ][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expected_vol3 = ec2.Volume(expected_vol3_id) | 
					
						
							|  |  |  |     expected_vol3.attachments[0]["InstanceId"].should.equal(instance.id) | 
					
						
							|  |  |  |     expected_vol3.availability_zone.should.equal("us-east-1a") | 
					
						
							|  |  |  |     expected_vol3.state.should.equal("in-use") | 
					
						
							|  |  |  |     if not settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         # FreezeTime does not work in ServerMode | 
					
						
							|  |  |  |         expected_vol3.attachments[0]["AttachTime"].should.equal(instance.launch_time) | 
					
						
							|  |  |  |         expected_vol3.create_time.should.equal(instance.launch_time) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_by_id(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2) | 
					
						
							|  |  |  |     instance1 = ec2.Instance(reservation["Instances"][0]["InstanceId"]) | 
					
						
							|  |  |  |     instance2 = ec2.Instance(reservation["Instances"][1]["InstanceId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances(InstanceIds=[instance1.id])["Reservations"] | 
					
						
							|  |  |  |     reservations.should.have.length_of(1) | 
					
						
							|  |  |  |     reservation = reservations[0] | 
					
						
							|  |  |  |     reservation["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     reservation["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances(InstanceIds=[instance1.id, instance2.id])[ | 
					
						
							|  |  |  |         "Reservations" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     reservations.should.have.length_of(1) | 
					
						
							|  |  |  |     reservation = reservations[0] | 
					
						
							|  |  |  |     reservation["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     instance_ids = [instance["InstanceId"] for instance in reservation["Instances"]] | 
					
						
							|  |  |  |     set(instance_ids).should.equal(set([instance1.id, instance2.id])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Call describe_instances with a bad id should raise an error | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.describe_instances(InstanceIds=[instance1.id, "i-1234abcd"]) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"].should.have.key("RequestId") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_paginated_instances(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     conn = boto3.resource("ec2", "us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = [] | 
					
						
							|  |  |  |     for i in range(12): | 
					
						
							|  |  |  |         instances.extend( | 
					
						
							|  |  |  |             conn.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     instance_ids = [i.id for i in instances] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp1 = client.describe_instances(InstanceIds=instance_ids, MaxResults=5) | 
					
						
							|  |  |  |     res1 = resp1["Reservations"] | 
					
						
							|  |  |  |     res1.should.have.length_of(5) | 
					
						
							|  |  |  |     next_token = resp1["NextToken"] | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     next_token.should_not.equal(None) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     resp2 = client.describe_instances(InstanceIds=instance_ids, NextToken=next_token) | 
					
						
							|  |  |  |     resp2["Reservations"].should.have.length_of(7)  # 12 total - 5 from the first call | 
					
						
							|  |  |  |     assert "NextToken" not in resp2  # This is it - no more pages | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for i in instances: | 
					
						
							|  |  |  |         i.terminate() | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 19:48:14 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_create_with_tags(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-2") | 
					
						
							|  |  |  |     instances = ec2.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2017-05-12 19:48:14 -04:00
										 |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         InstanceType="t2.micro", | 
					
						
							|  |  |  |         TagSpecifications=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "ResourceType": "instance", | 
					
						
							|  |  |  |                 "Tags": [ | 
					
						
							|  |  |  |                     {"Key": "MY_TAG1", "Value": "MY_VALUE1"}, | 
					
						
							|  |  |  |                     {"Key": "MY_TAG2", "Value": "MY_VALUE2"}, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "ResourceType": "instance", | 
					
						
							|  |  |  |                 "Tags": [{"Key": "MY_TAG3", "Value": "MY_VALUE3"}], | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert "Tags" in instances["Instances"][0] | 
					
						
							|  |  |  |     len(instances["Instances"][0]["Tags"]).should.equal(3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-20 22:35:34 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_create_with_volume_tags(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-west-2") | 
					
						
							|  |  |  |     volume_tags = [ | 
					
						
							|  |  |  |         {"Key": "MY_TAG1", "Value": "MY_VALUE1"}, | 
					
						
							|  |  |  |         {"Key": "MY_TAG2", "Value": "MY_VALUE2"}, | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     instances = ec2.run_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=2, | 
					
						
							|  |  |  |         MaxCount=2, | 
					
						
							|  |  |  |         InstanceType="t2.micro", | 
					
						
							|  |  |  |         TagSpecifications=[{"ResourceType": "volume", "Tags": volume_tags}], | 
					
						
							|  |  |  |     ).get("Instances") | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     instances = ( | 
					
						
							|  |  |  |         ec2.describe_instances(InstanceIds=instance_ids) | 
					
						
							|  |  |  |         .get("Reservations")[0] | 
					
						
							|  |  |  |         .get("Instances") | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     for instance in instances: | 
					
						
							|  |  |  |         instance_volume = instance["BlockDeviceMappings"][0]["Ebs"] | 
					
						
							|  |  |  |         volumes = ec2.describe_volumes(VolumeIds=[instance_volume["VolumeId"]]).get( | 
					
						
							|  |  |  |             "Volumes" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for volume in volumes: | 
					
						
							|  |  |  |             sorted(volume["Tags"], key=lambda i: i["Key"]).should.equal(volume_tags) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_state(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.terminate_instances(InstanceIds=[instance1.id]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "instance-state-name", "Values": ["running"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     # Since we terminated instance1, only instance2 and instance3 should be | 
					
						
							|  |  |  |     # returned | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_ids.shouldnt.contain(instance1.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance2.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance3.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         InstanceIds=[instance2.id], | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-state-name", "Values": ["running"]}], | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations.should.have.length_of(1) | 
					
						
							|  |  |  |     instance_ids = [instance["InstanceId"] for instance in reservations[0]["Instances"]] | 
					
						
							|  |  |  |     instance_ids.should.equal([instance2.id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         InstanceIds=[instance2.id], | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-state-name", "Values": ["terminated"]}], | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations.should.equal([]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # get_all_reservations should still return all 3 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances(client, filters=[]) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     instance_ids.should.contain(instance1.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance2.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance3.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         # ServerMode will just throw a generic 500 | 
					
						
							|  |  |  |         filters = [{"Name": "not-implemented-filter", "Values": ["foobar"]}] | 
					
						
							|  |  |  |         client.describe_instances.when.called_with(Filters=filters).should.throw( | 
					
						
							|  |  |  |             NotImplementedError | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_instance_id(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     instance1, instance2, _ = reservation | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     def _filter(values, exists=True): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |         f = [{"Name": "instance-id", "Values": values}] | 
					
						
							|  |  |  |         r = client.describe_instances(Filters=f)["Reservations"] | 
					
						
							|  |  |  |         if exists: | 
					
						
							|  |  |  |             r[0]["Instances"].should.have.length_of(len(values)) | 
					
						
							|  |  |  |             found_ids = [i["InstanceId"] for i in r[0]["Instances"]] | 
					
						
							|  |  |  |             set(found_ids).should.equal(set(values)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             r.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     _filter(values=[instance1.id]) | 
					
						
							|  |  |  |     _filter(values=[instance1.id, instance2.id]) | 
					
						
							|  |  |  |     _filter(values=["non-existing-id"], exists=False) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_instance_type(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     instance1 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, InstanceType="m1.small" | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  |     instance2 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, InstanceType="m1.small" | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  |     instance3 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, InstanceType="t1.micro" | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "instance-type", "Values": ["m1.small"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     set(instance_ids).should.contain(instance1.id) | 
					
						
							|  |  |  |     set(instance_ids).should.contain(instance2.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "instance-type", "Values": ["t1.micro"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     instance_ids.should.contain(instance3.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "instance-type", "Values": ["t1.micro", "m1.small"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     instance_ids.should.contain(instance1.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance2.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance3.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-type", "Values": ["bogus"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_reason_code(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							|  |  |  |     instance1.stop() | 
					
						
							|  |  |  |     instance2.terminate() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     filters = [ | 
					
						
							|  |  |  |         {"Name": "state-reason-code", "Values": ["Client.UserInitiatedShutdown"]} | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     instances = retrieve_all_instances(client, filters) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_ids.should.contain(instance1.id) | 
					
						
							|  |  |  |     instance_ids.should.contain(instance2.id) | 
					
						
							|  |  |  |     instance_ids.shouldnt.contain(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     filters = [{"Name": "state-reason-code", "Values": [""]}] | 
					
						
							|  |  |  |     instances = retrieve_all_instances(client, filters) | 
					
						
							|  |  |  |     instance_ids = [i["InstanceId"] for i in instances] | 
					
						
							|  |  |  |     instance_ids.should.contain(instance3.id) | 
					
						
							|  |  |  |     instance_ids.shouldnt.contain(instance1.id) | 
					
						
							|  |  |  |     instance_ids.shouldnt.contain(instance2.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_source_dest_check(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2) | 
					
						
							|  |  |  |     instance1, instance2 = reservation | 
					
						
							|  |  |  |     client.modify_instance_attribute( | 
					
						
							|  |  |  |         InstanceId=instance1.id, SourceDestCheck={"Value": False} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances_false = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "source-dest-check", "Values": ["false"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instances_true = retrieve_all_instances( | 
					
						
							|  |  |  |         client, [{"Name": "source-dest-check", "Values": ["true"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     [i["InstanceId"] for i in instances_false].should.contain(instance1.id) | 
					
						
							|  |  |  |     [i["InstanceId"] for i in instances_false].shouldnt.contain(instance2.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     [i["InstanceId"] for i in instances_true].shouldnt.contain(instance1.id) | 
					
						
							|  |  |  |     [i["InstanceId"] for i in instances_true].should.contain(instance2.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_vpc_id(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet1 = ec2.create_subnet(VpcId=vpc1.id, CidrBlock="10.0.0.0/27") | 
					
						
							|  |  |  |     reservation1 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SubnetId=subnet1.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance1 = reservation1[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vpc2 = ec2.create_vpc(CidrBlock="10.1.0.0/16") | 
					
						
							|  |  |  |     subnet2 = ec2.create_subnet(VpcId=vpc2.id, CidrBlock="10.1.0.0/27") | 
					
						
							|  |  |  |     reservation2 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SubnetId=subnet2.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance2 = reservation2[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res1 = client.describe_instances(Filters=[{"Name": "vpc-id", "Values": [vpc1.id]}])[ | 
					
						
							|  |  |  |         "Reservations" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     res1.should.have.length_of(1) | 
					
						
							|  |  |  |     res1[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res1[0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res1[0]["Instances"][0]["VpcId"].should.equal(vpc1.id) | 
					
						
							|  |  |  |     res1[0]["Instances"][0]["SubnetId"].should.equal(subnet1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res2 = client.describe_instances(Filters=[{"Name": "vpc-id", "Values": [vpc2.id]}])[ | 
					
						
							|  |  |  |         "Reservations" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     res2.should.have.length_of(1) | 
					
						
							|  |  |  |     res2[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res2[0]["Instances"][0]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  |     res2[0]["Instances"][0]["VpcId"].should.equal(vpc2.id) | 
					
						
							|  |  |  |     res2[0]["Instances"][0]["SubnetId"].should.equal(subnet2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 14:20:23 -01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_dns_name(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc1 = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc1.id, CidrBlock="10.0.0.0/27") | 
					
						
							|  |  |  |     client.modify_subnet_attribute( | 
					
						
							|  |  |  |         SubnetId=subnet.id, MapPublicIpOnLaunch={"Value": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     reservation1 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SubnetId=subnet.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance1 = reservation1[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservation2 = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SubnetId=subnet.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance2 = reservation2[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res1 = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "dns-name", "Values": [instance1.public_dns_name]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     res1.should.have.length_of(1) | 
					
						
							|  |  |  |     res1[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res1[0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res2 = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "dns-name", "Values": [instance2.public_dns_name]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     res2.should.have.length_of(1) | 
					
						
							|  |  |  |     res2[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res2[0]["Instances"][0]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_architecture(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "architecture", "Values": ["x86_64"]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     # get_all_reservations should return the instance | 
					
						
							|  |  |  |     reservations[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_image_id(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     conn = boto3.resource("ec2", "us-east-1") | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |     conn.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         Filters=[{"Name": "image-id", "Values": [EXAMPLE_AMI_ID]}] | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  |     )["Reservations"] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     assert len(reservations[0]["Instances"]) >= 1, "Should return just created instance" | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 15:14:58 +05:30
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_account_id(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     conn = boto3.resource("ec2", "us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance = conn.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							| 
									
										
										
										
											2020-07-19 15:14:58 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = retrieve_all_instances( | 
					
						
							|  |  |  |         client, filters=[{"Name": "owner-id", "Values": [ACCOUNT_ID]}] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-07-19 15:14:58 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     [i["InstanceId"] for i in instances].should.contain(instance.id) | 
					
						
							| 
									
										
										
										
											2020-07-19 15:14:58 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 01:39:50 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_private_dns(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     conn = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     conn.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, PrivateIpAddress="10.0.0.1" | 
					
						
							| 
									
										
										
										
											2017-08-23 01:39:50 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "private-dns-name", "Values": ["ip-10-0-0-1.ec2.internal"]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 01:39:50 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_ni_private_dns(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-west-2") | 
					
						
							|  |  |  |     conn = boto3.resource("ec2", "us-west-2") | 
					
						
							|  |  |  |     conn.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, PrivateIpAddress="10.0.0.1" | 
					
						
							| 
									
										
										
										
											2017-08-23 01:39:50 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Name": "network-interface.private-dns-name", | 
					
						
							|  |  |  |                 "Values": ["ip-10-0-0-1.us-west-2.compute.internal"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations[0]["Instances"].should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 21:34:06 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instances_with_unknown_security_group(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     sg_id = f"sg-{str(uuid4())[0:6]}" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         client.run_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SecurityGroupIds=[sg_id] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     err["Code"].should.equal("InvalidGroup.NotFound") | 
					
						
							|  |  |  |     err["Message"].should.equal(f"The security group '{sg_id}' does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_instance_group_name(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sec_group_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     client.create_security_group(Description="test", GroupName=sec_group_name) | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  |     client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SecurityGroups=[sec_group_name] | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "instance.group-name", "Values": [sec_group_name]}] | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_instance_group_id(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sec_group_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     create_sg = client.create_security_group( | 
					
						
							|  |  |  |         Description="test", GroupName=sec_group_name | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  |     group_id = create_sg["GroupId"] | 
					
						
							|  |  |  |     client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SecurityGroups=[sec_group_name] | 
					
						
							| 
									
										
										
										
											2017-08-25 23:43:29 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "instance.group-id", "Values": [group_id]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations[0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-15 09:38:40 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_get_instances_filtering_by_subnet_id(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vpc_cidr = ipaddress.ip_network("192.168.42.0/24") | 
					
						
							|  |  |  |     subnet_cidr = ipaddress.ip_network("192.168.42.0/25") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_vpc(CidrBlock=str(vpc_cidr)) | 
					
						
							|  |  |  |     vpc_id = resp["Vpc"]["VpcId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_subnet(CidrBlock=str(subnet_cidr), VpcId=vpc_id) | 
					
						
							|  |  |  |     subnet_id = resp["Subnet"]["SubnetId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.run_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1, SubnetId=subnet_id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reservations = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "subnet-id", "Values": [subnet_id]}] | 
					
						
							|  |  |  |     )["Reservations"] | 
					
						
							|  |  |  |     reservations.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_tag(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tag1_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     tag1_val = str(uuid4()) | 
					
						
							|  |  |  |     tag2_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     tag2_val = str(uuid4()) | 
					
						
							| 
									
										
										
										
											2023-02-25 10:19:28 -01:00
										 |  |  |     tag3_name = str(uuid4())[0:6] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-25 10:19:28 -01:00
										 |  |  |     instance1.create_tags( | 
					
						
							|  |  |  |         Tags=[ | 
					
						
							|  |  |  |             {"Key": tag1_name, "Value": tag1_val}, | 
					
						
							|  |  |  |             {"Key": tag2_name, "Value": tag2_val}, | 
					
						
							|  |  |  |             {"Key": tag3_name, "Value": json.dumps(["entry1", "entry2"])}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance2.create_tags(Tags=[{"Key": tag1_name, "Value": tag1_val}]) | 
					
						
							|  |  |  |     instance2.create_tags(Tags=[{"Key": tag2_name, "Value": "wrong value"}]) | 
					
						
							|  |  |  |     instance3.create_tags(Tags=[{"Key": tag2_name, "Value": tag2_val}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "tag:tag0", "Values": ["value0"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return no instances | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": f"tag:{tag1_name}", "Values": [tag1_val]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with this tag value | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[ | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |             {"Name": f"tag:{tag1_name}", "Values": [tag1_val]}, | 
					
						
							|  |  |  |             {"Name": f"tag:{tag2_name}", "Values": [tag2_val]}, | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return the instance with both tag values | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": f"tag:{tag2_name}", "Values": [tag2_val, "bogus"]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with one of the | 
					
						
							|  |  |  |     # acceptable tag values | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-25 10:19:28 -01:00
										 |  |  |     # We should be able to use tags containing special characters | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[ | 
					
						
							|  |  |  |             {"Name": f"tag:{tag3_name}", "Values": [json.dumps(["entry1", "entry2"])]} | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_tag_value(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tag1_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     tag1_val = str(uuid4()) | 
					
						
							|  |  |  |     tag2_name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     tag2_val = str(uuid4()) | 
					
						
							|  |  |  |     instance1.create_tags(Tags=[{"Key": tag1_name, "Value": tag1_val}]) | 
					
						
							|  |  |  |     instance1.create_tags(Tags=[{"Key": tag2_name, "Value": tag2_val}]) | 
					
						
							|  |  |  |     instance2.create_tags(Tags=[{"Key": tag1_name, "Value": tag1_val}]) | 
					
						
							|  |  |  |     instance2.create_tags(Tags=[{"Key": tag2_name, "Value": "wrong value"}]) | 
					
						
							|  |  |  |     instance3.create_tags(Tags=[{"Key": tag2_name, "Value": tag2_val}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "tag-value", "Values": ["value0"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return no instances | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "tag-value", "Values": [tag1_val]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with this tag value | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "tag-value", "Values": [tag2_val, tag1_val]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with one of the | 
					
						
							|  |  |  |     # acceptable tag values | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(3) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][2]["InstanceId"].should.equal(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "tag-value", "Values": [tag2_val, "bogus"]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with one of the | 
					
						
							|  |  |  |     # acceptable tag values | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instances_filtering_by_tag_name(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tag1 = str(uuid4()) | 
					
						
							|  |  |  |     tag3 = str(uuid4()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance1.create_tags(Tags=[{"Key": tag1, "Value": ""}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     instance1.create_tags(Tags=[{"Key": "tag2", "Value": ""}]) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance2.create_tags(Tags=[{"Key": tag1, "Value": ""}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     instance2.create_tags(Tags=[{"Key": "tag2X", "Value": ""}]) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance3.create_tags(Tags=[{"Key": tag3, "Value": ""}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances(Filters=[{"Name": "tag-key", "Values": ["tagX"]}]) | 
					
						
							|  |  |  |     # describe_instances should return no instances | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     res = client.describe_instances(Filters=[{"Name": "tag-key", "Values": [tag1]}]) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     # describe_instances should return both instances with this tag value | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(2) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "tag-key", "Values": [tag1, tag3]}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     # describe_instances should return both instances with one of the | 
					
						
							|  |  |  |     # acceptable tag values | 
					
						
							|  |  |  |     res["Reservations"].should.have.length_of(1) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"].should.have.length_of(3) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][0]["InstanceId"].should.equal(instance1.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][1]["InstanceId"].should.equal(instance2.id) | 
					
						
							|  |  |  |     res["Reservations"][0]["Instances"][2]["InstanceId"].should.equal(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_start_and_stop(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2) | 
					
						
							|  |  |  |     instance1, instance2 = reservation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_ids = [instance1.id, instance2.id] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.stop_instances(InstanceIds=instance_ids, DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the StopInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stopped_instances = client.stop_instances(InstanceIds=instance_ids)[ | 
					
						
							|  |  |  |         "StoppingInstances" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for instance in stopped_instances: | 
					
						
							|  |  |  |         instance["PreviousState"].should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  |         instance["CurrentState"].should.equal({"Code": 64, "Name": "stopping"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance1.reload() | 
					
						
							|  |  |  |     instance1.state.should.equal({"Code": 80, "Name": "stopped"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.start_instances(InstanceIds=[instance1.id], DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the StartInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance1.reload() | 
					
						
							|  |  |  |     # The DryRun-operation did not change anything | 
					
						
							|  |  |  |     instance1.state.should.equal({"Code": 80, "Name": "stopped"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     started_instances = client.start_instances(InstanceIds=[instance1.id])[ | 
					
						
							|  |  |  |         "StartingInstances" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     started_instances[0]["CurrentState"].should.equal({"Code": 0, "Name": "pending"}) | 
					
						
							| 
									
										
										
										
											2022-10-04 20:36:39 +10:00
										 |  |  |     started_instances[0]["PreviousState"].should.equal({"Code": 80, "Name": "stopped"}) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_reboot(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     response = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance = response[0] | 
					
						
							|  |  |  |     instance.state.should.equal({"Code": 0, "Name": "pending"}) | 
					
						
							|  |  |  |     instance.reload() | 
					
						
							|  |  |  |     instance.state.should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         instance.reboot(DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the RebootInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.state.should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.reboot() | 
					
						
							|  |  |  |     instance.state.should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_attribute_instance_type(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     response = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance = response[0] | 
					
						
							|  |  |  |     instance.instance_type.should.equal("m1.small") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         instance.modify_attribute(InstanceType={"Value": "m1.medium"}, DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.modify_attribute(InstanceType={"Value": "m1.medium"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.instance_type.should.equal("m1.medium") | 
					
						
							|  |  |  |     instance.describe_attribute(Attribute="instanceType")["InstanceType"].should.equal( | 
					
						
							|  |  |  |         {"Value": "m1.medium"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_modify_instance_attribute_security_groups(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     response = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance = response[0] | 
					
						
							|  |  |  |     old_groups = instance.describe_attribute(Attribute="groupSet")["Groups"] | 
					
						
							|  |  |  |     old_groups.should.equal([]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sg_id = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="this is a test security group" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ).id | 
					
						
							|  |  |  |     sg_id2 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="this is a test security group 2" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ).id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         instance.modify_attribute(Groups=[sg_id, sg_id2], DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.modify_attribute(Groups=[sg_id, sg_id2]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new_groups = instance.describe_attribute(Attribute="groupSet")["Groups"] | 
					
						
							|  |  |  |     new_groups.should.have.length_of(2) | 
					
						
							|  |  |  |     new_groups.should.contain({"GroupId": sg_id}) | 
					
						
							|  |  |  |     new_groups.should.contain({"GroupId": sg_id2}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_attribute_user_data(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     res = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance = res[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         instance.modify_attribute( | 
					
						
							|  |  |  |             UserData={"Value": "this is my user data"}, DryRun=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.modify_attribute(UserData={"Value": "this is my user data"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attribute = instance.describe_attribute(Attribute="userData")["UserData"] | 
					
						
							|  |  |  |     retrieved_user_data = attribute["Value"].encode("utf-8") | 
					
						
							|  |  |  |     decode_method(retrieved_user_data).should.equal(b"this is my user data") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_attribute_source_dest_check(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_attribute = instance.describe_attribute(Attribute="sourceDestCheck") | 
					
						
							|  |  |  |     instance_attribute.get("SourceDestCheck").should.equal({"Value": True}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set to false (note: Boto converts bool to string, eg 'false') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         instance.modify_attribute(SourceDestCheck={"Value": False}, DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.modify_attribute(SourceDestCheck={"Value": False}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_attribute = instance.describe_attribute(Attribute="sourceDestCheck") | 
					
						
							|  |  |  |     instance_attribute.get("SourceDestCheck").should.equal({"Value": False}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set back to true | 
					
						
							|  |  |  |     instance.modify_attribute(SourceDestCheck={"Value": True}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_attribute = instance.describe_attribute(Attribute="sourceDestCheck") | 
					
						
							|  |  |  |     instance_attribute.get("SourceDestCheck").should.equal({"Value": True}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_user_data_with_run_instance(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     user_data = b"some user data" | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, UserData=user_data | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attribute = instance.describe_attribute(Attribute="userData")["UserData"] | 
					
						
							|  |  |  |     retrieved_user_data = attribute["Value"].encode("utf-8") | 
					
						
							|  |  |  |     decoded_user_data = decode_method(retrieved_user_data) | 
					
						
							|  |  |  |     decoded_user_data.should.equal(b"some user data") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_security_group_name(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sec_group_name = str(uuid4())[0:6] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         ec2.create_security_group( | 
					
						
							|  |  |  |             GroupName=sec_group_name, Description="d", DryRun=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "An error occurred (DryRunOperation) when calling the CreateSecurityGroup operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     group = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=sec_group_name, Description="some description" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = ec2.create_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SecurityGroups=[sec_group_name] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     instance = res[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.security_groups.should.equal( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         [{"GroupName": sec_group_name, "GroupId": group.id}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_security_group_id(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     sec_group_name = str(uuid4()) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     group = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=sec_group_name, Description="some description" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, SecurityGroupIds=[group.id] | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.security_groups.should.equal( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         [{"GroupName": sec_group_name, "GroupId": group.id}] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-08-23 17:22:24 +00:00
										 |  |  | @pytest.mark.parametrize("hibernate", [True, False]) | 
					
						
							|  |  |  | def test_run_instance_with_additional_args(hibernate): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							| 
									
										
										
										
											2022-08-23 17:22:24 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         InstanceType="t1.micro", | 
					
						
							|  |  |  |         Placement={"AvailabilityZone": "us-east-1b"}, | 
					
						
							|  |  |  |         HibernationOptions={"Configured": hibernate}, | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.instance_type.should.equal("t1.micro") | 
					
						
							| 
									
										
										
										
											2022-08-23 17:22:24 +00:00
										 |  |  |     instance.placement.should.have.key("AvailabilityZone").equal("us-east-1b") | 
					
						
							|  |  |  |     instance.hibernation_options.should.equal({"Configured": hibernate}) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_default_placement(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.placement.should.have.key("AvailabilityZone").equal("us-east-1a") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-18 19:51:51 +02:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock.patch( | 
					
						
							|  |  |  |     "moto.ec2.models.instances.settings.EC2_ENABLE_INSTANCE_TYPE_VALIDATION", | 
					
						
							|  |  |  |     new_callable=mock.PropertyMock(return_value=True), | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_run_instance_with_invalid_instance_type(m_flag): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest( | 
					
						
							|  |  |  |             "It is not possible to set the environment variable in server mode" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="invalid_type", | 
					
						
							|  |  |  |             MinCount=1, | 
					
						
							|  |  |  |             MaxCount=1, | 
					
						
							|  |  |  |             Placement={"AvailabilityZone": "us-east-1b"}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The instance type 'invalid_type' does not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert m_flag is True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-16 18:58:14 +02:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_availability_zone_not_from_region(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             InstanceType="t2.nano", | 
					
						
							|  |  |  |             MinCount=1, | 
					
						
							|  |  |  |             MaxCount=1, | 
					
						
							|  |  |  |             Placement={"AvailabilityZone": "us-west-1b"}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid Availability Zone (us-west-1b)" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_subnet(): | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |     client = boto3.client("ec2", region_name="eu-central-1") | 
					
						
							| 
									
										
										
										
											2014-09-08 16:50:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |     ip_networks = [ | 
					
						
							|  |  |  |         (ipaddress.ip_network("10.0.0.0/16"), ipaddress.ip_network("10.0.99.0/24")), | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             ipaddress.ip_network("192.168.42.0/24"), | 
					
						
							|  |  |  |             ipaddress.ip_network("192.168.42.0/25"), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         ), | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2014-09-08 16:50:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |     # Tests instances are created with the correct IPs | 
					
						
							|  |  |  |     for vpc_cidr, subnet_cidr in ip_networks: | 
					
						
							|  |  |  |         resp = client.create_vpc( | 
					
						
							|  |  |  |             CidrBlock=str(vpc_cidr), | 
					
						
							|  |  |  |             AmazonProvidedIpv6CidrBlock=False, | 
					
						
							|  |  |  |             DryRun=False, | 
					
						
							|  |  |  |             InstanceTenancy="default", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         vpc_id = resp["Vpc"]["VpcId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         resp = client.create_subnet(CidrBlock=str(subnet_cidr), VpcId=vpc_id) | 
					
						
							|  |  |  |         subnet_id = resp["Subnet"]["SubnetId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         resp = client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |             ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1, SubnetId=subnet_id | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         instance = resp["Instances"][0] | 
					
						
							|  |  |  |         instance["SubnetId"].should.equal(subnet_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |         priv_ipv4 = ipaddress.ip_address(str(instance["PrivateIpAddress"])) | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |         subnet_cidr.should.contain(priv_ipv4) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_specified_private_ipv4(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="eu-central-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vpc_cidr = ipaddress.ip_network("192.168.42.0/24") | 
					
						
							|  |  |  |     subnet_cidr = ipaddress.ip_network("192.168.42.0/25") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_vpc( | 
					
						
							|  |  |  |         CidrBlock=str(vpc_cidr), | 
					
						
							|  |  |  |         AmazonProvidedIpv6CidrBlock=False, | 
					
						
							|  |  |  |         DryRun=False, | 
					
						
							|  |  |  |         InstanceTenancy="default", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     vpc_id = resp["Vpc"]["VpcId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_subnet(CidrBlock=str(subnet_cidr), VpcId=vpc_id) | 
					
						
							|  |  |  |     subnet_id = resp["Subnet"]["SubnetId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         SubnetId=subnet_id, | 
					
						
							|  |  |  |         PrivateIpAddress="192.168.42.5", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = resp["Instances"][0] | 
					
						
							|  |  |  |     instance["SubnetId"].should.equal(subnet_id) | 
					
						
							| 
									
										
										
										
											2017-10-25 19:29:56 +01:00
										 |  |  |     instance["PrivateIpAddress"].should.equal("192.168.42.5") | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_mapped_public_ipv4(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="eu-central-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vpc_cidr = ipaddress.ip_network("192.168.42.0/24") | 
					
						
							|  |  |  |     subnet_cidr = ipaddress.ip_network("192.168.42.0/25") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_vpc( | 
					
						
							|  |  |  |         CidrBlock=str(vpc_cidr), | 
					
						
							|  |  |  |         AmazonProvidedIpv6CidrBlock=False, | 
					
						
							|  |  |  |         DryRun=False, | 
					
						
							|  |  |  |         InstanceTenancy="default", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     vpc_id = resp["Vpc"]["VpcId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.create_subnet(CidrBlock=str(subnet_cidr), VpcId=vpc_id) | 
					
						
							|  |  |  |     subnet_id = resp["Subnet"]["SubnetId"] | 
					
						
							|  |  |  |     client.modify_subnet_attribute( | 
					
						
							|  |  |  |         SubnetId=subnet_id, MapPublicIpOnLaunch={"Value": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1, SubnetId=subnet_id | 
					
						
							| 
									
										
										
										
											2017-10-24 23:57:43 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     instance = resp["Instances"][0] | 
					
						
							|  |  |  |     instance.should.contain("PublicDnsName") | 
					
						
							|  |  |  |     instance.should.contain("PublicIpAddress") | 
					
						
							|  |  |  |     len(instance["PublicDnsName"]).should.be.greater_than(0) | 
					
						
							|  |  |  |     len(instance["PublicIpAddress"]).should.be.greater_than(0) | 
					
						
							| 
									
										
										
										
											2014-09-08 16:50:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_nic_autocreated(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  |     security_group1 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     security_group2 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     private_ip = "10.0.0.1" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         SubnetId=subnet.id, | 
					
						
							|  |  |  |         SecurityGroups=[security_group1.group_name], | 
					
						
							|  |  |  |         SecurityGroupIds=[security_group2.group_id], | 
					
						
							|  |  |  |         PrivateIpAddress=private_ip, | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_eni = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     instance_eni.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     nii = instance_eni[0]["NetworkInterfaceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     my_enis = client.describe_network_interfaces(NetworkInterfaceIds=[nii])[ | 
					
						
							|  |  |  |         "NetworkInterfaces" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     my_enis.should.have.length_of(1) | 
					
						
							|  |  |  |     eni = my_enis[0] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     instance.subnet_id.should.equal(subnet.id) | 
					
						
							|  |  |  |     instance.security_groups.should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in instance.security_groups]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     eni["SubnetId"].should.equal(subnet.id) | 
					
						
							|  |  |  |     eni["Groups"].should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     eni["PrivateIpAddresses"].should.have.length_of(1) | 
					
						
							|  |  |  |     eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should.equal(private_ip) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_nic_preexisting(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  |     security_group1 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     security_group2 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     private_ip = "54.0.0.1" | 
					
						
							|  |  |  |     eni = ec2.create_network_interface( | 
					
						
							|  |  |  |         SubnetId=subnet.id, | 
					
						
							|  |  |  |         PrivateIpAddress=private_ip, | 
					
						
							|  |  |  |         Groups=[security_group1.group_id], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         NetworkInterfaces=[{"DeviceIndex": 0, "NetworkInterfaceId": eni.id}], | 
					
						
							|  |  |  |         SecurityGroupIds=[security_group2.group_id], | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.subnet_id.should.equal(subnet.id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     nii = instance.network_interfaces_attribute[0]["NetworkInterfaceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all_enis = client.describe_network_interfaces(NetworkInterfaceIds=[nii])[ | 
					
						
							|  |  |  |         "NetworkInterfaces" | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     all_enis.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_enis = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     instance_enis.should.have.length_of(1) | 
					
						
							|  |  |  |     instance_eni = instance_enis[0] | 
					
						
							|  |  |  |     instance_eni["NetworkInterfaceId"].should.equal(eni.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_eni["SubnetId"].should.equal(subnet.id) | 
					
						
							|  |  |  |     instance_eni["Groups"].should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in instance_eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_eni["PrivateIpAddresses"].should.have.length_of(1) | 
					
						
							|  |  |  |     instance_eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should.equal(private_ip) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-27 14:32:37 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_new_nic_and_security_groups(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     security_group1 = ec2.create_security_group( | 
					
						
							|  |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     security_group2 = ec2.create_security_group( | 
					
						
							|  |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         NetworkInterfaces=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "DeviceIndex": 0, | 
					
						
							|  |  |  |                 "Groups": [security_group1.group_id, security_group2.group_id], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     nii = instance.network_interfaces_attribute[0]["NetworkInterfaceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all_enis = client.describe_network_interfaces(NetworkInterfaceIds=[nii])[ | 
					
						
							|  |  |  |         "NetworkInterfaces" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     all_enis.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_enis = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     instance_enis.should.have.length_of(1) | 
					
						
							|  |  |  |     instance_eni = instance_enis[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_eni["Groups"].should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in instance_eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_instance_with_nic_attach_detach(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  |     security_group1 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  |     security_group2 = ec2.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         SecurityGroupIds=[security_group1.group_id], | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     eni = ec2.create_network_interface(SubnetId=subnet.id, Groups=[security_group2.id]) | 
					
						
							|  |  |  |     eni_id = eni.id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check initial instance and ENI data | 
					
						
							|  |  |  |     instance.network_interfaces_attribute.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     eni.groups.should.have.length_of(1) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in eni.groups]).should.equal( | 
					
						
							|  |  |  |         set([security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Attach | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.attach_network_interface( | 
					
						
							|  |  |  |             NetworkInterfaceId=eni_id, | 
					
						
							|  |  |  |             InstanceId=instance.id, | 
					
						
							|  |  |  |             DeviceIndex=1, | 
					
						
							|  |  |  |             DryRun=True, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "An error occurred (DryRunOperation) when calling the AttachNetworkInterface operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.attach_network_interface( | 
					
						
							|  |  |  |         NetworkInterfaceId=eni_id, InstanceId=instance.id, DeviceIndex=1 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check attached instance and ENI data | 
					
						
							|  |  |  |     instance.reload() | 
					
						
							|  |  |  |     instance.network_interfaces_attribute.should.have.length_of(2) | 
					
						
							|  |  |  |     instance_eni = instance.network_interfaces_attribute[1] | 
					
						
							|  |  |  |     instance_eni["NetworkInterfaceId"].should.equal(eni_id) | 
					
						
							|  |  |  |     instance_eni["Groups"].should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in instance_eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     eni = client.describe_network_interfaces( | 
					
						
							|  |  |  |         Filters=[{"Name": "network-interface-id", "Values": [eni_id]}] | 
					
						
							|  |  |  |     )["NetworkInterfaces"][0] | 
					
						
							|  |  |  |     eni["Groups"].should.have.length_of(2) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group1.id, security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Detach | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.detach_network_interface( | 
					
						
							|  |  |  |             AttachmentId=instance_eni["Attachment"]["AttachmentId"], DryRun=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "An error occurred (DryRunOperation) when calling the DetachNetworkInterface operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.detach_network_interface( | 
					
						
							|  |  |  |         AttachmentId=instance_eni["Attachment"]["AttachmentId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check detached instance and ENI data | 
					
						
							|  |  |  |     instance.reload() | 
					
						
							|  |  |  |     instance.network_interfaces_attribute.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     eni = client.describe_network_interfaces( | 
					
						
							|  |  |  |         Filters=[{"Name": "network-interface-id", "Values": [eni_id]}] | 
					
						
							|  |  |  |     )["NetworkInterfaces"][0] | 
					
						
							|  |  |  |     eni["Groups"].should.have.length_of(1) | 
					
						
							|  |  |  |     set([group["GroupId"] for group in eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |         set([security_group2.id]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Detach with invalid attachment ID | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.detach_network_interface(AttachmentId="eni-attach-1234abcd") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"].should.have.key("RequestId") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidAttachmentID.NotFound") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_ec2_classic_has_public_ip_address(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							|  |  |  |     instance.public_ip_address.should_not.equal(None) | 
					
						
							|  |  |  |     instance.public_dns_name.should.contain( | 
					
						
							|  |  |  |         instance.public_ip_address.replace(".", "-") | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance.private_ip_address.should_not.equal(None) | 
					
						
							|  |  |  |     instance.private_dns_name.should.contain( | 
					
						
							|  |  |  |         instance.private_ip_address.replace(".", "-") | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_run_instance_with_keypair(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2022-05-25 16:18:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, KeyName="keypair_name" | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.key_name.should.equal("keypair_name") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 00:19:47 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instances_with_keypair_filter(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     for i in range(3): | 
					
						
							|  |  |  |         key_name = "kp-single" if i % 2 else "kp-multiple" | 
					
						
							|  |  |  |         ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, KeyName=key_name | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     test_data = [ | 
					
						
							|  |  |  |         (["kp-single"], 1), | 
					
						
							|  |  |  |         (["kp-multiple"], 2), | 
					
						
							|  |  |  |         (["kp-single", "kp-multiple"], 3), | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     for filter_values, expected_instance_count in test_data: | 
					
						
							|  |  |  |         _filter = [{"Name": "key-name", "Values": filter_values}] | 
					
						
							|  |  |  |         instances_found = list(ec2.instances.filter(Filters=_filter)) | 
					
						
							|  |  |  |         instances_found.should.have.length_of(expected_instance_count) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-25 16:18:03 +02:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock.patch( | 
					
						
							|  |  |  |     "moto.ec2.models.instances.settings.ENABLE_KEYPAIR_VALIDATION", | 
					
						
							|  |  |  |     new_callable=mock.PropertyMock(return_value=True), | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_run_instance_with_invalid_keypair(m_flag): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest( | 
					
						
							|  |  |  |             "It is not possible to set the environment variable in server mode" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     keypair_name = "keypair_name" | 
					
						
							|  |  |  |     ec2.create_key_pair(KeyName=keypair_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, KeyName="not a key name" | 
					
						
							|  |  |  |         )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.NotFound") | 
					
						
							|  |  |  |     assert m_flag is True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_block_device_mappings(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "MinCount": 1, | 
					
						
							|  |  |  |         "MaxCount": 1, | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "KeyName": "the_key", | 
					
						
							|  |  |  |         "InstanceType": "t1.micro", | 
					
						
							|  |  |  |         "BlockDeviceMappings": [{"DeviceName": "/dev/sda2", "Ebs": {"VolumeSize": 50}}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_id = ec2_client.run_instances(**kwargs)["Instances"][0]["InstanceId"] | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = ec2_client.describe_instances(InstanceIds=[instance_id]) | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |     volume = instances["Reservations"][0]["Instances"][0]["BlockDeviceMappings"][0][ | 
					
						
							|  |  |  |         "Ebs" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volumes = ec2_client.describe_volumes(VolumeIds=[volume["VolumeId"]]) | 
					
						
							|  |  |  |     volumes["Volumes"][0]["Size"].should.equal(50) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_block_device_mappings_missing_ebs(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "MinCount": 1, | 
					
						
							|  |  |  |         "MaxCount": 1, | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "KeyName": "the_key", | 
					
						
							|  |  |  |         "InstanceType": "t1.micro", | 
					
						
							|  |  |  |         "BlockDeviceMappings": [{"DeviceName": "/dev/sda2"}], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.response["Error"]["Code"].should.equal("MissingParameter") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "The request must contain the parameter ebs" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 03:37:46 -06:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_block_device_mappings_using_no_device(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "MinCount": 1, | 
					
						
							|  |  |  |         "MaxCount": 1, | 
					
						
							|  |  |  |         "ImageId": EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         "KeyName": "the_key", | 
					
						
							|  |  |  |         "InstanceType": "t1.micro", | 
					
						
							|  |  |  |         "BlockDeviceMappings": [{"DeviceName": "/dev/sda2", "NoDevice": ""}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     resp = ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  |     instance_id = resp["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instances = ec2_client.describe_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  |     # Assuming that /dev/sda2 is not the root device and that there is a /dev/sda1, boto would | 
					
						
							|  |  |  |     # create an instance with one block device instead of two.  However, moto's modeling of | 
					
						
							|  |  |  |     # BlockDeviceMappings is simplified, so we will accept that moto creates an instance without | 
					
						
							|  |  |  |     # block devices for now | 
					
						
							|  |  |  |     # instances["Reservations"][0]["Instances"][0].shouldnt.have.key("BlockDeviceMappings") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # moto gives the key with an empty list instead of not having it at all, that's also fine | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     instances["Reservations"][0]["Instances"][0]["BlockDeviceMappings"].should.equal([]) | 
					
						
							| 
									
										
										
										
											2022-02-14 03:37:46 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # passing None with NoDevice should raise ParamValidationError | 
					
						
							|  |  |  |     kwargs["BlockDeviceMappings"][0]["NoDevice"] = None | 
					
						
							|  |  |  |     with pytest.raises(ParamValidationError) as ex: | 
					
						
							|  |  |  |         ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # passing a string other than "" with NoDevice should raise InvalidRequest | 
					
						
							|  |  |  |     kwargs["BlockDeviceMappings"][0]["NoDevice"] = "yes" | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidRequest") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The request received was invalid" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_block_device_mappings_missing_size(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "MinCount": 1, | 
					
						
							|  |  |  |         "MaxCount": 1, | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "KeyName": "the_key", | 
					
						
							|  |  |  |         "InstanceType": "t1.micro", | 
					
						
							|  |  |  |         "BlockDeviceMappings": [ | 
					
						
							|  |  |  |             {"DeviceName": "/dev/sda2", "Ebs": {"VolumeType": "standard"}} | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.response["Error"]["Code"].should.equal("MissingParameter") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "The request must contain the parameter size or snapshotId" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_with_block_device_mappings_from_snapshot(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2022-05-25 16:18:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |     volume_details = { | 
					
						
							|  |  |  |         "AvailabilityZone": "1a", | 
					
						
							|  |  |  |         "Size": 30, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volume = ec2_resource.create_volume(**volume_details) | 
					
						
							|  |  |  |     snapshot = volume.create_snapshot() | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "MinCount": 1, | 
					
						
							|  |  |  |         "MaxCount": 1, | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |         "KeyName": "the_key", | 
					
						
							|  |  |  |         "InstanceType": "t1.micro", | 
					
						
							|  |  |  |         "BlockDeviceMappings": [ | 
					
						
							|  |  |  |             {"DeviceName": "/dev/sda2", "Ebs": {"SnapshotId": snapshot.snapshot_id}} | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resp = ec2_client.run_instances(**kwargs) | 
					
						
							|  |  |  |     instance_id = resp["Instances"][0]["InstanceId"] | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = ec2_client.describe_instances(InstanceIds=[instance_id]) | 
					
						
							| 
									
										
										
										
											2020-05-11 15:23:45 +03:00
										 |  |  |     volume = instances["Reservations"][0]["Instances"][0]["BlockDeviceMappings"][0][ | 
					
						
							|  |  |  |         "Ebs" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volumes = ec2_client.describe_volumes(VolumeIds=[volume["VolumeId"]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     volumes["Volumes"][0]["Size"].should.equal(30) | 
					
						
							|  |  |  |     volumes["Volumes"][0]["SnapshotId"].should.equal(snapshot.snapshot_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_describe_instance_status_no_instances(): | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest("ServerMode is not guaranteed to be empty") | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     all_status = client.describe_instance_status()["InstanceStatuses"] | 
					
						
							|  |  |  |     all_status.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_describe_instance_status_with_instances(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     all_status = client.describe_instance_status()["InstanceStatuses"] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_ids = [s["InstanceId"] for s in all_status] | 
					
						
							|  |  |  |     instance_ids.should.contain(instance.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     my_status = [s for s in all_status if s["InstanceId"] == instance.id][0] | 
					
						
							|  |  |  |     my_status["InstanceStatus"]["Status"].should.equal("ok") | 
					
						
							|  |  |  |     my_status["SystemStatus"]["Status"].should.equal("ok") | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_describe_instance_status_with_instance_filter_deprecated(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We want to filter based on this one | 
					
						
							|  |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # This is just to setup the test | 
					
						
							|  |  |  |     ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all_status = client.describe_instance_status(InstanceIds=[instance.id])[ | 
					
						
							|  |  |  |         "InstanceStatuses" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     all_status.should.have.length_of(1) | 
					
						
							|  |  |  |     all_status[0]["InstanceId"].should.equal(instance.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Call get_all_instance_status with a bad id should raise an error | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.describe_instance_status(InstanceIds=[instance.id, "i-1234abcd"]) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"].should.have.key("RequestId") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-06 21:25:59 +05:30
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instance_credit_specifications(): | 
					
						
							|  |  |  |     conn = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We want to filter based on this one | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |     reservation = conn.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							| 
									
										
										
										
											2020-04-07 08:49:19 +01:00
										 |  |  |     result = conn.describe_instance_credit_specifications( | 
					
						
							|  |  |  |         InstanceIds=[reservation["Instances"][0]["InstanceId"]] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["InstanceCreditSpecifications"][0]["InstanceId"] | 
					
						
							|  |  |  |         == reservation["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instance_status_with_instance_filter(): | 
					
						
							|  |  |  |     conn = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We want to filter based on this one | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |     reservation = conn.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     instance1 = reservation["Instances"][0] | 
					
						
							|  |  |  |     instance2 = reservation["Instances"][1] | 
					
						
							|  |  |  |     instance3 = reservation["Instances"][2] | 
					
						
							|  |  |  |     conn.stop_instances(InstanceIds=[instance1["InstanceId"]]) | 
					
						
							|  |  |  |     stopped_instance_ids = [instance1["InstanceId"]] | 
					
						
							|  |  |  |     running_instance_ids = sorted([instance2["InstanceId"], instance3["InstanceId"]]) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  |     all_instance_ids = sorted(stopped_instance_ids + running_instance_ids) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Filter instance using the state name | 
					
						
							|  |  |  |     state_name_filter = { | 
					
						
							|  |  |  |         "running_and_stopped": [ | 
					
						
							|  |  |  |             {"Name": "instance-state-name", "Values": ["running", "stopped"]} | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         "running": [{"Name": "instance-state-name", "Values": ["running"]}], | 
					
						
							|  |  |  |         "stopped": [{"Name": "instance-state-name", "Values": ["stopped"]}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_name_filter["running_and_stopped"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in all_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_name_filter["running"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in stopped_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.shouldnt.contain(_id) | 
					
						
							|  |  |  |     for _id in running_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_name_filter["stopped"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in stopped_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							|  |  |  |     for _id in running_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.shouldnt.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Filter instance using the state code | 
					
						
							|  |  |  |     state_code_filter = { | 
					
						
							|  |  |  |         "running_and_stopped": [ | 
					
						
							|  |  |  |             {"Name": "instance-state-code", "Values": ["16", "80"]} | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |         "running": [{"Name": "instance-state-code", "Values": ["16"]}], | 
					
						
							|  |  |  |         "stopped": [{"Name": "instance-state-code", "Values": ["80"]}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_code_filter["running_and_stopped"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in all_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_code_filter["running"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in stopped_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.shouldnt.contain(_id) | 
					
						
							|  |  |  |     for _id in running_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:58 +00:00
										 |  |  |     found_statuses = conn.describe_instance_status( | 
					
						
							|  |  |  |         IncludeAllInstances=True, Filters=state_code_filter["stopped"] | 
					
						
							|  |  |  |     )["InstanceStatuses"] | 
					
						
							|  |  |  |     found_instance_ids = [status["InstanceId"] for status in found_statuses] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     for _id in stopped_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.should.contain(_id) | 
					
						
							|  |  |  |     for _id in running_instance_ids: | 
					
						
							|  |  |  |         found_instance_ids.shouldnt.contain(_id) | 
					
						
							| 
									
										
										
										
											2020-02-24 13:43:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_describe_instance_status_with_non_running_instances(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     reservation = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3) | 
					
						
							|  |  |  |     instance1, instance2, instance3 = reservation | 
					
						
							|  |  |  |     instance1.stop() | 
					
						
							|  |  |  |     instance2.terminate() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all_running_status = client.describe_instance_status()["InstanceStatuses"] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     [status["InstanceId"] for status in all_running_status].shouldnt.contain( | 
					
						
							|  |  |  |         instance1.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     [status["InstanceId"] for status in all_running_status].shouldnt.contain( | 
					
						
							|  |  |  |         instance2.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     [status["InstanceId"] for status in all_running_status].should.contain(instance3.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     my_status = [s for s in all_running_status if s["InstanceId"] == instance3.id][0] | 
					
						
							|  |  |  |     my_status["InstanceState"].should.equal({"Code": 16, "Name": "running"}) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     all_status = client.describe_instance_status(IncludeAllInstances=True)[ | 
					
						
							|  |  |  |         "InstanceStatuses" | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     [status["InstanceId"] for status in all_status].should.contain(instance1.id) | 
					
						
							|  |  |  |     [status["InstanceId"] for status in all_status].should.contain(instance2.id) | 
					
						
							|  |  |  |     [status["InstanceId"] for status in all_status].should.contain(instance3.id) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     status1 = next((s for s in all_status if s["InstanceId"] == instance1.id), None) | 
					
						
							|  |  |  |     status1["InstanceState"].should.equal({"Code": 80, "Name": "stopped"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status2 = next((s for s in all_status if s["InstanceId"] == instance2.id), None) | 
					
						
							|  |  |  |     status2["InstanceState"].should.equal({"Code": 48, "Name": "terminated"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     status3 = next((s for s in all_status if s["InstanceId"] == instance3.id), None) | 
					
						
							|  |  |  |     status3["InstanceState"].should.equal({"Code": 16, "Name": "running"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  | def test_get_instance_by_security_group(): | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     security_group = ec2.create_security_group( | 
					
						
							|  |  |  |         GroupName=str(uuid4())[0:6], Description="test" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.modify_instance_attribute( | 
					
						
							|  |  |  |             InstanceId=instance.id, Groups=[security_group.id], DryRun=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2023-02-14 12:43:28 -01:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyInstanceAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							| 
									
										
										
										
											2021-09-25 11:13:07 +00:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.modify_instance_attribute(InstanceId=instance.id, Groups=[security_group.id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.reload() | 
					
						
							|  |  |  |     security_group_instances = instance.describe_attribute(Attribute="groupSet")[ | 
					
						
							|  |  |  |         "Groups" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     security_group_instances.should.have.length_of(1) | 
					
						
							|  |  |  |     security_group_instances.should.equal([{"GroupId": security_group.id}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-12 21:59:02 +01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_modify_delete_on_termination(): | 
					
						
							|  |  |  |     ec2_client = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |     result = ec2_client.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							| 
									
										
										
										
											2017-10-12 21:59:02 +01:00
										 |  |  |     instance = result[0] | 
					
						
							|  |  |  |     instance.load() | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |     instance.block_device_mappings[0]["Ebs"]["DeleteOnTermination"].should.be(True) | 
					
						
							| 
									
										
										
										
											2017-10-12 21:59:02 +01:00
										 |  |  |     instance.modify_attribute( | 
					
						
							|  |  |  |         BlockDeviceMappings=[ | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |             {"DeviceName": "/dev/sda1", "Ebs": {"DeleteOnTermination": False}} | 
					
						
							| 
									
										
										
										
											2017-10-12 21:59:02 +01:00
										 |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance.load() | 
					
						
							| 
									
										
										
										
											2020-05-24 14:22:45 +03:00
										 |  |  |     instance.block_device_mappings[0]["Ebs"]["DeleteOnTermination"].should.be(False) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 15:31:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 14:12:57 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_create_instance_with_default_options(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="eu-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assert_instance(instance): | 
					
						
							|  |  |  |         # TODO: Add additional asserts for default instance response | 
					
						
							|  |  |  |         assert instance["ImageId"] == EXAMPLE_AMI_ID | 
					
						
							|  |  |  |         assert "KeyName" not in instance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.run_instances(ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1) | 
					
						
							|  |  |  |     assert_instance(resp["Instances"][0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.describe_instances(InstanceIds=[resp["Instances"][0]["InstanceId"]]) | 
					
						
							|  |  |  |     assert_instance(resp["Reservations"][0]["Instances"][0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 15:31:54 +01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_create_instance_ebs_optimized(): | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", region_name="eu-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1, EbsOptimized=True | 
					
						
							| 
									
										
										
										
											2017-11-14 15:31:54 +01:00
										 |  |  |     )[0] | 
					
						
							|  |  |  |     instance.load() | 
					
						
							|  |  |  |     instance.ebs_optimized.should.be(True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.modify_attribute(EbsOptimized={"Value": False}) | 
					
						
							|  |  |  |     instance.load() | 
					
						
							|  |  |  |     instance.ebs_optimized.should.be(False) | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-24 09:24:38 +00:00
										 |  |  |     instance = ec2_resource.create_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MaxCount=1, MinCount=1 | 
					
						
							| 
									
										
										
										
											2020-03-24 09:24:38 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  |     instance.load() | 
					
						
							|  |  |  |     instance.ebs_optimized.should.be(False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_multiple_instances_in_same_command(): | 
					
						
							|  |  |  |     instance_count = 4 | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instances = client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, MinCount=instance_count, MaxCount=instance_count | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     reservation_id = instances["ReservationId"] | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     # TODO: use this filter when implemented | 
					
						
							|  |  |  |     # client.describe_instances(Filters=[{"Name": "reservation-id", "Values": [instances["ReservationId"]]}])["Reservations"] | 
					
						
							|  |  |  |     all_reservations = retrieve_all_reservations(client) | 
					
						
							|  |  |  |     my_reservation = [ | 
					
						
							|  |  |  |         r for r in all_reservations if r["ReservationId"] == reservation_id | 
					
						
							|  |  |  |     ][0] | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     my_reservation["Instances"].should.have.length_of(instance_count) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instances = my_reservation["Instances"] | 
					
						
							| 
									
										
										
										
											2019-01-15 17:34:22 +01:00
										 |  |  |     for i in range(0, instance_count): | 
					
						
							|  |  |  |         instances[i]["AmiLaunchIndex"].should.be(i) | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instance_attribute(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-07-05 15:12:38 +02:00
										 |  |  |     security_group_id = client.create_security_group( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         GroupName=str(uuid4()), Description="this is a test security group" | 
					
						
							| 
									
										
										
										
											2019-07-05 15:12:38 +02:00
										 |  |  |     )["GroupId"] | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resp = client.run_instances( | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  |         MinCount=1, | 
					
						
							| 
									
										
										
										
											2019-07-05 15:12:38 +02:00
										 |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         SecurityGroupIds=[security_group_id], | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     instance_id = resp["Instances"][0]["InstanceId"] | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     valid_instance_attributes = [ | 
					
						
							|  |  |  |         "instanceType", | 
					
						
							|  |  |  |         "kernel", | 
					
						
							|  |  |  |         "ramdisk", | 
					
						
							|  |  |  |         "userData", | 
					
						
							|  |  |  |         "disableApiTermination", | 
					
						
							|  |  |  |         "instanceInitiatedShutdownBehavior", | 
					
						
							|  |  |  |         "rootDeviceName", | 
					
						
							|  |  |  |         "blockDeviceMapping", | 
					
						
							|  |  |  |         "productCodes", | 
					
						
							|  |  |  |         "sourceDestCheck", | 
					
						
							|  |  |  |         "groupSet", | 
					
						
							|  |  |  |         "ebsOptimized", | 
					
						
							|  |  |  |         "sriovNetSupport", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for valid_instance_attribute in valid_instance_attributes: | 
					
						
							| 
									
										
										
										
											2019-07-05 15:12:38 +02:00
										 |  |  |         response = client.describe_instance_attribute( | 
					
						
							|  |  |  |             InstanceId=instance_id, Attribute=valid_instance_attribute | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         if valid_instance_attribute == "groupSet": | 
					
						
							| 
									
										
										
										
											2019-07-05 15:24:16 +02:00
										 |  |  |             response.should.have.key("Groups") | 
					
						
							| 
									
										
										
										
											2019-07-05 15:12:38 +02:00
										 |  |  |             response["Groups"].should.have.length_of(1) | 
					
						
							|  |  |  |             response["Groups"][0]["GroupId"].should.equal(security_group_id) | 
					
						
							| 
									
										
										
										
											2019-07-05 15:24:16 +02:00
										 |  |  |         elif valid_instance_attribute == "userData": | 
					
						
							|  |  |  |             response.should.have.key("UserData") | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |             response["UserData"].should.equal({}) | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     invalid_instance_attributes = [ | 
					
						
							|  |  |  |         "abc", | 
					
						
							|  |  |  |         "Kernel", | 
					
						
							|  |  |  |         "RamDisk", | 
					
						
							|  |  |  |         "userdata", | 
					
						
							|  |  |  |         "iNsTaNcEtYpE", | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for invalid_instance_attribute in invalid_instance_attributes: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |         with pytest.raises(ClientError) as ex: | 
					
						
							| 
									
										
										
										
											2019-07-05 13:43:47 +02:00
										 |  |  |             client.describe_instance_attribute( | 
					
						
							|  |  |  |                 InstanceId=instance_id, Attribute=invalid_instance_attribute | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue") | 
					
						
							|  |  |  |         ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         message = f"Value ({invalid_instance_attribute}) for parameter attribute is invalid. Unknown attribute." | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         ex.value.response["Error"]["Message"].should.equal(message) | 
					
						
							| 
									
										
										
										
											2021-01-29 03:31:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_warn_on_invalid_ami(): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest("Can't capture warnings in server mode.") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     with pytest.warns( | 
					
						
							|  |  |  |         PendingDeprecationWarning, | 
					
						
							|  |  |  |         match=r"Could not find AMI with image-id:invalid-ami.+", | 
					
						
							|  |  |  |     ): | 
					
						
							|  |  |  |         ec2.create_instances(ImageId="invalid-ami", MinCount=1, MaxCount=1) | 
					
						
							| 
									
										
										
										
											2021-08-17 22:02:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 18:04:36 +02:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock.patch( | 
					
						
							|  |  |  |     "moto.ec2.models.instances.settings.ENABLE_AMI_VALIDATION", | 
					
						
							|  |  |  |     new_callable=mock.PropertyMock(return_value=True), | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_error_on_invalid_ami(m_flag): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest("Can't capture warnings in server mode.") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2.create_instances(ImageId="ami-invalid", MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The image id '[['ami-invalid']]' does not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert m_flag is True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock.patch( | 
					
						
							|  |  |  |     "moto.ec2.models.instances.settings.ENABLE_AMI_VALIDATION", | 
					
						
							|  |  |  |     new_callable=mock.PropertyMock(return_value=True), | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_error_on_invalid_ami_format(m_flag): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest( | 
					
						
							|  |  |  |             "It is not possible to set the environment variable in server mode" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         ec2.create_instances(ImageId="invalid-ami-format", MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("InvalidAMIID.Malformed") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         'Invalid id: "[\'invalid-ami-format\']" (expecting "ami-...")' | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert m_flag is True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 22:02:19 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_filter_wildcard_in_specified_tag_only(): | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     name = str(uuid4())[0:6] | 
					
						
							|  |  |  |     tags_name = [{"Key": "Name", "Value": f"{name} in wonderland"}] | 
					
						
							| 
									
										
										
										
											2021-08-17 22:02:19 -07:00
										 |  |  |     ec2_client.run_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         TagSpecifications=[{"ResourceType": "instance", "Tags": tags_name}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     tags_owner = [{"Key": "Owner", "Value": f"{name} in wonderland"}] | 
					
						
							| 
									
										
										
										
											2021-08-17 22:02:19 -07:00
										 |  |  |     ec2_client.run_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         TagSpecifications=[{"ResourceType": "instance", "Tags": tags_owner}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # should only match the Name tag | 
					
						
							|  |  |  |     response = ec2_client.describe_instances( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         Filters=[{"Name": "tag:Name", "Values": [f"*{name}*"]}] | 
					
						
							| 
									
										
										
										
											2021-08-17 22:02:19 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     instances = [i for r in response["Reservations"] for i in r["Instances"]] | 
					
						
							|  |  |  |     instances.should.have.length_of(1) | 
					
						
							|  |  |  |     instances[0]["Tags"][0].should.have.key("Key").should.equal("Name") | 
					
						
							| 
									
										
										
										
											2021-08-18 22:47:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_termination_protection(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance_id = resp["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.modify_instance_attribute( | 
					
						
							|  |  |  |         InstanceId=instance_id, DisableApiTermination={"Value": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     client.stop_instances(InstanceIds=[instance_id], Force=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  |     error = ex.value.response["Error"] | 
					
						
							|  |  |  |     error["Code"].should.equal("OperationNotPermitted") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.match( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         rf"The instance '{instance_id}' may not be terminated.*$" | 
					
						
							| 
									
										
										
										
											2021-08-18 22:47:05 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 23:04:15 -07:00
										 |  |  |     # Use alternate request syntax for setting attribute. | 
					
						
							| 
									
										
										
										
											2021-08-18 22:47:05 -07:00
										 |  |  |     client.modify_instance_attribute( | 
					
						
							| 
									
										
										
										
											2021-08-27 23:04:15 -07:00
										 |  |  |         InstanceId=instance_id, Attribute="disableApiTermination", Value="false" | 
					
						
							| 
									
										
										
										
											2021-08-18 22:47:05 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     client.terminate_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.describe_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  |     instances = resp["Reservations"][0]["Instances"] | 
					
						
							|  |  |  |     instances.should.have.length_of(1) | 
					
						
							|  |  |  |     instance = instances[0] | 
					
						
							|  |  |  |     instance["State"]["Name"].should.equal("terminated") | 
					
						
							| 
									
										
										
										
											2021-09-22 09:32:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-07 21:25:35 -01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_terminate_unknown_instances(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Correct error message for single unknown instance | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=["i-12345678"]) | 
					
						
							|  |  |  |     error = ex.value.response["Error"] | 
					
						
							|  |  |  |     error["Code"].should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  |     error["Message"].should.equal("The instance ID 'i-12345678' does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Correct error message for multiple unknown instances | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=["i-12345678", "i-12345668"]) | 
					
						
							|  |  |  |     error = ex.value.response["Error"] | 
					
						
							|  |  |  |     error["Code"].should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  |     error["Message"].should.equal( | 
					
						
							|  |  |  |         "The instance IDs 'i-12345678, i-12345668' do not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create an instance | 
					
						
							|  |  |  |     resp = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     instance_id = resp["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Correct error message if one instance is known | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.terminate_instances(InstanceIds=["i-12345678", instance_id]) | 
					
						
							|  |  |  |     error = ex.value.response["Error"] | 
					
						
							|  |  |  |     error["Code"].should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  |     error["Message"].should.equal("The instance ID 'i-12345678' does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # status = still running | 
					
						
							|  |  |  |     resp = client.describe_instances(InstanceIds=[instance_id]) | 
					
						
							|  |  |  |     instance = resp["Reservations"][0]["Instances"][0] | 
					
						
							|  |  |  |     instance["State"]["Name"].should.equal("running") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 09:32:30 -07:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_instance_lifecycle(): | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = ec2_resource.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         BlockDeviceMappings=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "DeviceName": "/dev/sda1", | 
					
						
							|  |  |  |                 "Ebs": {"VolumeSize": 50, "DeleteOnTermination": True}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert instance.instance_lifecycle is None | 
					
						
							| 
									
										
										
										
											2021-09-27 16:00:29 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "launch_template_kind", ("LaunchTemplateId", "LaunchTemplateName") | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_create_instance_with_launch_template_id_produces_no_warning( | 
					
						
							|  |  |  |     launch_template_kind, | 
					
						
							|  |  |  | ): | 
					
						
							|  |  |  |     client, resource = ( | 
					
						
							|  |  |  |         boto3.client("ec2", region_name="us-west-1"), | 
					
						
							|  |  |  |         boto3.resource("ec2", region_name="us-west-1"), | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template = client.create_launch_template( | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |         LaunchTemplateName=str(uuid4()), LaunchTemplateData={"ImageId": EXAMPLE_AMI_ID} | 
					
						
							| 
									
										
										
										
											2021-09-27 16:00:29 -04:00
										 |  |  |     )["LaunchTemplate"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-17 14:01:22 +00:00
										 |  |  |     with warnings.catch_warnings(): | 
					
						
							|  |  |  |         warnings.simplefilter("error") | 
					
						
							| 
									
										
										
										
											2021-09-27 16:00:29 -04:00
										 |  |  |         resource.create_instances( | 
					
						
							|  |  |  |             MinCount=1, | 
					
						
							|  |  |  |             MaxCount=1, | 
					
						
							|  |  |  |             LaunchTemplate={launch_template_kind: template[launch_template_kind]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-01 19:27:25 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_create_instance_from_launch_template__process_tags(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template = client.create_launch_template( | 
					
						
							|  |  |  |         LaunchTemplateName=str(uuid4()), | 
					
						
							|  |  |  |         LaunchTemplateData={ | 
					
						
							|  |  |  |             "ImageId": EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             "TagSpecifications": [ | 
					
						
							|  |  |  |                 {"ResourceType": "instance", "Tags": [{"Key": "k", "Value": "v"}]} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     )["LaunchTemplate"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance = client.run_instances( | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         LaunchTemplate={"LaunchTemplateId": template["LaunchTemplateId"]}, | 
					
						
							|  |  |  |     )["Instances"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance.should.have.key("Tags").equals([{"Key": "k", "Value": "v"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 09:57:39 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_and_associate_public_ip(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Do not pass AssociatePublicIpAddress-argument | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							| 
									
										
										
										
											2021-12-24 14:12:57 -01:00
										 |  |  |         NetworkInterfaces=[{"DeviceIndex": 0, "SubnetId": subnet.id}], | 
					
						
							| 
									
										
										
										
											2021-10-13 09:57:39 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  |     interfaces = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     addresses = interfaces[0]["PrivateIpAddresses"][0] | 
					
						
							|  |  |  |     addresses.should.have.key("Primary").equal(True) | 
					
						
							|  |  |  |     addresses.should.have.key("PrivateIpAddress") | 
					
						
							|  |  |  |     addresses.shouldnt.have.key("Association") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Pass AssociatePublicIpAddress=False | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							| 
									
										
										
										
											2021-12-24 14:12:57 -01:00
										 |  |  |         NetworkInterfaces=[ | 
					
						
							|  |  |  |             {"DeviceIndex": 0, "SubnetId": subnet.id, "AssociatePublicIpAddress": False} | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2021-10-13 09:57:39 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  |     interfaces = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     addresses = interfaces[0]["PrivateIpAddresses"][0] | 
					
						
							|  |  |  |     addresses.should.have.key("Primary").equal(True) | 
					
						
							|  |  |  |     addresses.should.have.key("PrivateIpAddress") | 
					
						
							|  |  |  |     addresses.shouldnt.have.key("Association") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Pass AssociatePublicIpAddress=True | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							| 
									
										
										
										
											2021-12-24 14:12:57 -01:00
										 |  |  |         NetworkInterfaces=[ | 
					
						
							|  |  |  |             {"DeviceIndex": 0, "SubnetId": subnet.id, "AssociatePublicIpAddress": True} | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2021-10-13 09:57:39 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  |     interfaces = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     addresses = interfaces[0]["PrivateIpAddresses"][0] | 
					
						
							|  |  |  |     addresses.should.have.key("Primary").equal(True) | 
					
						
							|  |  |  |     addresses.should.have.key("PrivateIpAddress") | 
					
						
							|  |  |  |     addresses.should.have.key("Association") | 
					
						
							|  |  |  |     # Only now should we have a PublicIp | 
					
						
							|  |  |  |     addresses["Association"].should.have.key("IpOwnerId").equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     addresses["Association"].should.have.key("PublicIp") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-24 14:12:57 -01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_cannot_have_subnet_and_networkinterface_parameter(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         ec2.create_instances( | 
					
						
							|  |  |  |             ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |             MinCount=1, | 
					
						
							|  |  |  |             MaxCount=1, | 
					
						
							|  |  |  |             SubnetId=subnet.id, | 
					
						
							|  |  |  |             NetworkInterfaces=[{"DeviceIndex": 0}], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     err = exc.value.response["Error"] | 
					
						
							|  |  |  |     err["Code"].should.equal("InvalidParameterCombination") | 
					
						
							|  |  |  |     err["Message"].should.equal( | 
					
						
							|  |  |  |         "Network interfaces and an instance-level subnet ID may not be specified on the same request" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-04 05:21:38 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_in_subnet_with_nic_private_ip(): | 
					
						
							|  |  |  |     vpc_cidr_block = "10.26.0.0/16" | 
					
						
							|  |  |  |     subnet_cidr_block = "10.26.1.0/24" | 
					
						
							|  |  |  |     private_ip = "10.26.1.3" | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="eu-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock=vpc_cidr_block) | 
					
						
							|  |  |  |     subnet = ec2.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc.id, | 
					
						
							|  |  |  |         CidrBlock=subnet_cidr_block, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     my_interface = { | 
					
						
							|  |  |  |         "SubnetId": subnet.id, | 
					
						
							|  |  |  |         "DeviceIndex": 0, | 
					
						
							|  |  |  |         "PrivateIpAddress": private_ip, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     [instance] = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, NetworkInterfaces=[my_interface], MinCount=1, MaxCount=1 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance.private_ip_address.should.equal(private_ip) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     interfaces = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     address = interfaces[0]["PrivateIpAddresses"][0] | 
					
						
							|  |  |  |     address.shouldnt.have.key("Association") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_instance_in_subnet_with_nic_private_ip_and_public_association(): | 
					
						
							|  |  |  |     vpc_cidr_block = "10.26.0.0/16" | 
					
						
							|  |  |  |     subnet_cidr_block = "10.26.1.0/24" | 
					
						
							|  |  |  |     primary_private_ip = "10.26.1.3" | 
					
						
							|  |  |  |     other_private_ip = "10.26.1.4" | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="eu-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock=vpc_cidr_block) | 
					
						
							|  |  |  |     subnet = ec2.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc.id, | 
					
						
							|  |  |  |         CidrBlock=subnet_cidr_block, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     my_interface = { | 
					
						
							|  |  |  |         "SubnetId": subnet.id, | 
					
						
							|  |  |  |         "DeviceIndex": 0, | 
					
						
							|  |  |  |         "AssociatePublicIpAddress": True, | 
					
						
							|  |  |  |         "PrivateIpAddresses": [ | 
					
						
							|  |  |  |             {"Primary": True, "PrivateIpAddress": primary_private_ip}, | 
					
						
							|  |  |  |             {"Primary": False, "PrivateIpAddress": other_private_ip}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     [instance] = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, NetworkInterfaces=[my_interface], MinCount=1, MaxCount=1 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance.private_ip_address.should.equal(primary_private_ip) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     interfaces = instance.network_interfaces_attribute | 
					
						
							|  |  |  |     address = interfaces[0]["PrivateIpAddresses"][0] | 
					
						
							|  |  |  |     address["Association"].should.have.key("IpOwnerId").equal(ACCOUNT_ID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 22:43:00 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instances_dryrun(): | 
					
						
							|  |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.describe_instances(DryRun=True) | 
					
						
							|  |  |  |     ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(412) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "An error occurred (DryRunOperation) when calling the DescribeInstances operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 16:14:06 +00:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_describe_instances_filter_vpcid_via_networkinterface(): | 
					
						
							|  |  |  |     vpc_cidr_block = "10.26.0.0/16" | 
					
						
							|  |  |  |     subnet_cidr_block = "10.26.1.0/24" | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", region_name="eu-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock=vpc_cidr_block) | 
					
						
							|  |  |  |     subnet = ec2.create_subnet( | 
					
						
							|  |  |  |         VpcId=vpc.id, CidrBlock=subnet_cidr_block, AvailabilityZone="eu-west-1a" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     my_interface = { | 
					
						
							|  |  |  |         "SubnetId": subnet.id, | 
					
						
							|  |  |  |         "DeviceIndex": 0, | 
					
						
							|  |  |  |         "PrivateIpAddresses": [{"Primary": True, "PrivateIpAddress": "10.26.1.3"}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     instance = ec2.create_instances( | 
					
						
							| 
									
										
										
										
											2022-05-26 18:04:36 +02:00
										 |  |  |         ImageId=EXAMPLE_AMI_ID, NetworkInterfaces=[my_interface], MinCount=1, MaxCount=1 | 
					
						
							| 
									
										
										
										
											2021-10-20 16:14:06 +00:00
										 |  |  |     )[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _filter = [{"Name": "vpc-id", "Values": [vpc.id]}] | 
					
						
							|  |  |  |     found = list(ec2.instances.filter(Filters=_filter)) | 
					
						
							|  |  |  |     found.should.have.length_of(1) | 
					
						
							|  |  |  |     found.should.equal([instance]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 23:06:21 +01:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | @mock_iam | 
					
						
							|  |  |  | def test_instance_iam_instance_profile(): | 
					
						
							|  |  |  |     ec2_resource = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     iam = boto3.client("iam", "us-west-1") | 
					
						
							|  |  |  |     profile_name = "fake_profile" | 
					
						
							|  |  |  |     profile = iam.create_instance_profile( | 
					
						
							|  |  |  |         InstanceProfileName=profile_name, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result1 = ec2_resource.create_instances( | 
					
						
							|  |  |  |         ImageId="ami-d3adb33f", | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         IamInstanceProfile={ | 
					
						
							|  |  |  |             "Name": profile_name, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result1[0] | 
					
						
							|  |  |  |     assert "Arn" in instance.iam_instance_profile | 
					
						
							|  |  |  |     assert "Id" in instance.iam_instance_profile | 
					
						
							|  |  |  |     assert profile["InstanceProfile"]["Arn"] == instance.iam_instance_profile["Arn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result2 = ec2_resource.create_instances( | 
					
						
							|  |  |  |         ImageId="ami-d3adb33f", | 
					
						
							|  |  |  |         MinCount=1, | 
					
						
							|  |  |  |         MaxCount=1, | 
					
						
							|  |  |  |         IamInstanceProfile={ | 
					
						
							|  |  |  |             "Arn": profile["InstanceProfile"]["Arn"], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance = result2[0] | 
					
						
							|  |  |  |     assert "Arn" in instance.iam_instance_profile | 
					
						
							|  |  |  |     assert "Id" in instance.iam_instance_profile | 
					
						
							|  |  |  |     assert profile["InstanceProfile"]["Arn"] == instance.iam_instance_profile["Arn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | def retrieve_all_reservations(client, filters=[]):  # pylint: disable=W0102 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     resp = client.describe_instances(Filters=filters) | 
					
						
							|  |  |  |     all_reservations = resp["Reservations"] | 
					
						
							|  |  |  |     next_token = resp.get("NextToken") | 
					
						
							|  |  |  |     while next_token: | 
					
						
							|  |  |  |         resp = client.describe_instances(Filters=filters, NextToken=next_token) | 
					
						
							|  |  |  |         all_reservations.extend(resp["Reservations"]) | 
					
						
							|  |  |  |         next_token = resp.get("NextToken") | 
					
						
							|  |  |  |     return all_reservations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | def retrieve_all_instances(client, filters=[]):  # pylint: disable=W0102 | 
					
						
							| 
									
										
										
										
											2021-10-05 17:11:07 +00:00
										 |  |  |     reservations = retrieve_all_reservations(client, filters) | 
					
						
							|  |  |  |     return [i for r in reservations for i in r["Instances"]] | 
					
						
							| 
									
										
										
										
											2023-01-31 23:21:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_run_multiple_instances_with_single_nic_template(): | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-west-1") | 
					
						
							|  |  |  |     client = boto3.client("ec2", "us-west-1") | 
					
						
							|  |  |  |     vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") | 
					
						
							|  |  |  |     subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") | 
					
						
							|  |  |  |     security_group1 = ec2.create_security_group( | 
					
						
							|  |  |  |         GroupName=str(uuid4()), Description="n/a" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instances = ec2.create_instances( | 
					
						
							|  |  |  |         ImageId=EXAMPLE_AMI_ID, | 
					
						
							|  |  |  |         MinCount=2, | 
					
						
							|  |  |  |         MaxCount=2, | 
					
						
							|  |  |  |         NetworkInterfaces=[ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "AssociatePublicIpAddress": False, | 
					
						
							|  |  |  |                 "DeleteOnTermination": True, | 
					
						
							|  |  |  |                 "DeviceIndex": 0, | 
					
						
							|  |  |  |                 "Groups": [security_group1.group_id], | 
					
						
							|  |  |  |                 "SubnetId": subnet.id, | 
					
						
							|  |  |  |                 "InterfaceType": "interface", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enis = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for instance in instances: | 
					
						
							|  |  |  |         instance_eni = instance.network_interfaces_attribute | 
					
						
							|  |  |  |         instance_eni.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         nii = instance_eni[0]["NetworkInterfaceId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         my_enis = client.describe_network_interfaces(NetworkInterfaceIds=[nii])[ | 
					
						
							|  |  |  |             "NetworkInterfaces" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         my_enis.should.have.length_of(1) | 
					
						
							|  |  |  |         eni = my_enis[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         instance.subnet_id.should.equal(subnet.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         eni["SubnetId"].should.equal(subnet.id) | 
					
						
							|  |  |  |         eni["Groups"].should.have.length_of(1) | 
					
						
							|  |  |  |         set([group["GroupId"] for group in eni["Groups"]]).should.equal( | 
					
						
							|  |  |  |             set([security_group1.id]) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         eni["PrivateIpAddresses"].should.have.length_of(1) | 
					
						
							|  |  |  |         eni["PrivateIpAddresses"][0]["PrivateIpAddress"].should_not.equal(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enis.append(eni) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_0_ip = enis[0]["PrivateIpAddresses"][0]["PrivateIpAddress"] | 
					
						
							|  |  |  |     instance_1_ip = enis[1]["PrivateIpAddresses"][0]["PrivateIpAddress"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     instance_0_ip.should_not.equal(instance_1_ip) |