| 
									
										
										
										
											2014-08-27 11:17:06 -04:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							| 
									
										
										
										
											2014-08-25 15:09:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 23:13:01 -05:00
										 |  |  | import boto | 
					
						
							| 
									
										
										
										
											2014-11-15 10:06:14 -05:00
										 |  |  | import boto.ec2 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:33:30 -04:00
										 |  |  | import boto3 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | from boto.exception import EC2ResponseError | 
					
						
							| 
									
										
										
										
											2017-12-22 18:50:18 +05:30
										 |  |  | from botocore.exceptions import ClientError | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  | # Ensure 'pytest.raises' context manager support for Python 2.6 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  | import sure  # noqa | 
					
						
							| 
									
										
										
										
											2013-02-21 23:13:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | from moto import mock_ec2_deprecated, mock_ec2 | 
					
						
							| 
									
										
										
										
											2019-07-22 21:57:15 -05:00
										 |  |  | from moto.ec2.models import AMIS, OWNER_ID | 
					
						
							| 
									
										
										
										
											2020-09-13 16:08:23 +01:00
										 |  |  | from moto.core import ACCOUNT_ID | 
					
						
							| 
									
										
										
										
											2014-09-29 12:28:53 -07:00
										 |  |  | from tests.helpers import requires_boto_gte | 
					
						
							| 
									
										
										
										
											2013-02-21 23:13:01 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | def test_ami_create_and_delete(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     initial_ami_count = len(AMIS) | 
					
						
							|  |  |  |     conn.get_all_volumes().should.have.length_of(0) | 
					
						
							|  |  |  |     conn.get_all_snapshots().should.have.length_of(initial_ami_count) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as ex: | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |         image_id = conn.create_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             instance.id, "test-ami", "this is a test ami", dry_run=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.error_code.should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.status.should.equal(400) | 
					
						
							|  |  |  |     ex.value.message.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the CreateImage operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     all_images = conn.get_all_images() | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     set([i.id for i in all_images]).should.contain(image_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retrieved_image = [i for i in all_images if i.id == image_id][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retrieved_image.id.should.equal(image_id) | 
					
						
							|  |  |  |     retrieved_image.virtualization_type.should.equal(instance.virtualization_type) | 
					
						
							|  |  |  |     retrieved_image.architecture.should.equal(instance.architecture) | 
					
						
							|  |  |  |     retrieved_image.kernel_id.should.equal(instance.kernel) | 
					
						
							|  |  |  |     retrieved_image.platform.should.equal(instance.platform) | 
					
						
							|  |  |  |     retrieved_image.creationDate.should_not.be.none | 
					
						
							| 
									
										
										
										
											2015-11-28 09:19:45 -05:00
										 |  |  |     instance.terminate() | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     # Ensure we're no longer creating a volume | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     volumes = conn.get_all_volumes() | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     volumes.should.have.length_of(0) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     # Validate auto-created snapshot | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     snapshots = conn.get_all_snapshots() | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     snapshots.should.have.length_of(initial_ami_count + 1) | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     retrieved_image_snapshot_id = ( | 
					
						
							|  |  |  |         retrieved_image.block_device_mapping.current_value.snapshot_id | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     [s.id for s in snapshots].should.contain(retrieved_image_snapshot_id) | 
					
						
							|  |  |  |     snapshot = [s for s in snapshots if s.id == retrieved_image_snapshot_id][0] | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     snapshot.description.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "Auto-created snapshot for AMI {0}".format(retrieved_image.id) | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-15 21:30:32 +05:30
										 |  |  |     # root device should be in AMI's block device mappings | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     root_mapping = retrieved_image.block_device_mapping.get( | 
					
						
							|  |  |  |         retrieved_image.root_device_name | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-09-15 21:30:32 +05:30
										 |  |  |     root_mapping.should_not.be.none | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     # Deregister | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as ex: | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  |         success = conn.deregister_image(image_id, dry_run=True) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.error_code.should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.status.should.equal(400) | 
					
						
							|  |  |  |     ex.value.message.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the DeregisterImage operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     success = conn.deregister_image(image_id) | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  |     success.should.be.true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |         conn.deregister_image(image_id) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2013-03-11 00:12:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-29 12:28:53 -07:00
										 |  |  | @requires_boto_gte("2.14.0") | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  | def test_ami_copy(): | 
					
						
							| 
									
										
										
										
											2014-11-15 10:06:14 -05:00
										 |  |  |     conn = boto.ec2.connect_to_region("us-west-1") | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     initial_ami_count = len(AMIS) | 
					
						
							|  |  |  |     conn.get_all_volumes().should.have.length_of(0) | 
					
						
							|  |  |  |     conn.get_all_snapshots().should.have.length_of(initial_ami_count) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     source_image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2015-11-28 09:19:45 -05:00
										 |  |  |     instance.terminate() | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  |     source_image = conn.get_all_images(image_ids=[source_image_id])[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     # Boto returns a 'CopyImage' object with an image_id attribute here. Use | 
					
						
							|  |  |  |     # the image_id to fetch the full info. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as ex: | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |         copy_image_ref = conn.copy_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             source_image.region.name, | 
					
						
							|  |  |  |             source_image.id, | 
					
						
							|  |  |  |             "test-copy-ami", | 
					
						
							|  |  |  |             "this is a test copy ami", | 
					
						
							|  |  |  |             dry_run=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.error_code.should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.status.should.equal(400) | 
					
						
							|  |  |  |     ex.value.message.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the CopyImage operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     copy_image_ref = conn.copy_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         source_image.region.name, | 
					
						
							|  |  |  |         source_image.id, | 
					
						
							|  |  |  |         "test-copy-ami", | 
					
						
							|  |  |  |         "this is a test copy ami", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  |     copy_image_id = copy_image_ref.image_id | 
					
						
							|  |  |  |     copy_image = conn.get_all_images(image_ids=[copy_image_id])[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     copy_image.id.should.equal(copy_image_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     copy_image.virtualization_type.should.equal(source_image.virtualization_type) | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  |     copy_image.architecture.should.equal(source_image.architecture) | 
					
						
							|  |  |  |     copy_image.kernel_id.should.equal(source_image.kernel_id) | 
					
						
							|  |  |  |     copy_image.platform.should.equal(source_image.platform) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     # Ensure we're no longer creating a volume | 
					
						
							|  |  |  |     conn.get_all_volumes().should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Validate auto-created snapshot | 
					
						
							|  |  |  |     conn.get_all_snapshots().should.have.length_of(initial_ami_count + 2) | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     copy_image.block_device_mapping.current_value.snapshot_id.should_not.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         source_image.block_device_mapping.current_value.snapshot_id | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Copy from non-existent source ID. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.copy_image( | 
					
						
							|  |  |  |             source_image.region.name, | 
					
						
							|  |  |  |             "ami-abcd1234", | 
					
						
							|  |  |  |             "test-copy-ami", | 
					
						
							|  |  |  |             "this is a test copy ami", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Copy from non-existent source region. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         invalid_region = ( | 
					
						
							|  |  |  |             "us-east-1" if (source_image.region.name != "us-east-1") else "us-west-1" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         conn.copy_image( | 
					
						
							|  |  |  |             invalid_region, source_image.id, "test-copy-ami", "this is a test copy ami" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-09-29 12:06:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 21:57:15 -05:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_copy_image_changes_owner_id(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-07-22 21:57:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # this source AMI ID is from moto/ec2/resources/amis.json | 
					
						
							|  |  |  |     source_ami_id = "ami-03cf127a" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # confirm the source ami owner id is different from the default owner id. | 
					
						
							|  |  |  |     # if they're ever the same it means this test is invalid. | 
					
						
							|  |  |  |     check_resp = conn.describe_images(ImageIds=[source_ami_id]) | 
					
						
							|  |  |  |     check_resp["Images"][0]["OwnerId"].should_not.equal(OWNER_ID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     copy_resp = conn.copy_image( | 
					
						
							|  |  |  |         SourceImageId=source_ami_id, | 
					
						
							|  |  |  |         Name="new-image", | 
					
						
							|  |  |  |         Description="a copy of an image", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         SourceRegion="us-east-1", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-07-22 21:57:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe_resp = conn.describe_images(Owners=["self"]) | 
					
						
							|  |  |  |     describe_resp["Images"][0]["OwnerId"].should.equal(OWNER_ID) | 
					
						
							|  |  |  |     describe_resp["Images"][0]["ImageId"].should.equal(copy_resp["ImageId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-05-11 19:00:28 -04:00
										 |  |  | def test_ami_tagging(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_vpc("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2014-05-11 19:00:28 -04:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     image = conn.get_all_images()[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as ex: | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  |         image.add_tag("a key", "some value", dry_run=True) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.error_code.should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.status.should.equal(400) | 
					
						
							|  |  |  |     ex.value.message.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the CreateTags operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-11 19:00:28 -04:00
										 |  |  |     image.add_tag("a key", "some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tag = conn.get_all_tags()[0] | 
					
						
							|  |  |  |     tag.name.should.equal("a key") | 
					
						
							|  |  |  |     tag.value.should.equal("some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Refresh the DHCP options | 
					
						
							|  |  |  |     image = conn.get_all_images()[0] | 
					
						
							|  |  |  |     image.tags.should.have.length_of(1) | 
					
						
							|  |  |  |     image.tags["a key"].should.equal("some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | def test_ami_create_from_missing_instance(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2013-03-05 08:14:43 -05:00
										 |  |  |     args = ["i-abcdefg", "test-ami", "this is a test ami"] | 
					
						
							| 
									
										
										
										
											2014-08-25 10:54:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2014-08-25 10:54:47 -07:00
										 |  |  |         conn.create_image(*args) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidInstanceID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  | def test_ami_pulls_attributes_from_instance(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     instance.modify_attribute("kernel", "test-kernel") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 00:08:35 -05:00
										 |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2013-02-23 14:22:09 -05:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     image.kernel_id.should.equal("test-kernel") | 
					
						
							| 
									
										
										
										
											2014-01-28 18:14:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 10:58:31 +00:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							|  |  |  | def test_ami_uses_account_id_if_valid_access_key_is_supplied(): | 
					
						
							|  |  |  |     access_key = "AKIAXXXXXXXXXXXXXXXX" | 
					
						
							|  |  |  |     conn = boto.connect_ec2(access_key, "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							|  |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     instance.modify_attribute("kernel", "test-kernel") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     images = conn.get_all_images(owners=["self"]) | 
					
						
							|  |  |  |     [(ami.id, ami.owner_id) for ami in images].should.equal([(image_id, ACCOUNT_ID)]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | def test_ami_filters(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservationA = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     instanceA = reservationA.instances[0] | 
					
						
							|  |  |  |     instanceA.modify_attribute("architecture", "i386") | 
					
						
							|  |  |  |     instanceA.modify_attribute("kernel", "k-1234abcd") | 
					
						
							|  |  |  |     instanceA.modify_attribute("platform", "windows") | 
					
						
							|  |  |  |     instanceA.modify_attribute("virtualization_type", "hvm") | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     imageA_id = conn.create_image(instanceA.id, "test-ami-A", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     imageA = conn.get_image(imageA_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservationB = conn.run_instances("ami-abcd1234") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     instanceB = reservationB.instances[0] | 
					
						
							|  |  |  |     instanceB.modify_attribute("architecture", "x86_64") | 
					
						
							|  |  |  |     instanceB.modify_attribute("kernel", "k-abcd1234") | 
					
						
							|  |  |  |     instanceB.modify_attribute("platform", "linux") | 
					
						
							|  |  |  |     instanceB.modify_attribute("virtualization_type", "paravirtual") | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     imageB_id = conn.create_image(instanceB.id, "test-ami-B", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     imageB = conn.get_image(imageB_id) | 
					
						
							| 
									
										
										
										
											2014-11-19 20:09:46 -05:00
										 |  |  |     imageB.set_launch_permissions(group_names=("all")) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_architecture = conn.get_all_images(filters={"architecture": "x86_64"}) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     set([ami.id for ami in amis_by_architecture]).should.contain(imageB.id) | 
					
						
							|  |  |  |     len(amis_by_architecture).should.equal(35) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_kernel = conn.get_all_images(filters={"kernel-id": "k-abcd1234"}) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     set([ami.id for ami in amis_by_kernel]).should.equal(set([imageB.id])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     amis_by_virtualization = conn.get_all_images( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         filters={"virtualization-type": "paravirtual"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     set([ami.id for ami in amis_by_virtualization]).should.contain(imageB.id) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     len(amis_by_virtualization).should.equal(3) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_platform = conn.get_all_images(filters={"platform": "windows"}) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     set([ami.id for ami in amis_by_platform]).should.contain(imageA.id) | 
					
						
							|  |  |  |     len(amis_by_platform).should.equal(24) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_id = conn.get_all_images(filters={"image-id": imageA.id}) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     set([ami.id for ami in amis_by_id]).should.equal(set([imageA.id])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_state = conn.get_all_images(filters={"state": "available"}) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     ami_ids_by_state = [ami.id for ami in amis_by_state] | 
					
						
							|  |  |  |     ami_ids_by_state.should.contain(imageA.id) | 
					
						
							|  |  |  |     ami_ids_by_state.should.contain(imageB.id) | 
					
						
							|  |  |  |     len(amis_by_state).should.equal(36) | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_name = conn.get_all_images(filters={"name": imageA.name}) | 
					
						
							| 
									
										
										
										
											2014-10-10 15:14:46 -04:00
										 |  |  |     set([ami.id for ami in amis_by_name]).should.equal(set([imageA.id])) | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_public = conn.get_all_images(filters={"is-public": "true"}) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     set([ami.id for ami in amis_by_public]).should.contain(imageB.id) | 
					
						
							|  |  |  |     len(amis_by_public).should.equal(35) | 
					
						
							| 
									
										
										
										
											2014-11-19 20:09:46 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_nonpublic = conn.get_all_images(filters={"is-public": "false"}) | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     set([ami.id for ami in amis_by_nonpublic]).should.contain(imageA.id) | 
					
						
							|  |  |  |     len(amis_by_nonpublic).should.equal(1) | 
					
						
							| 
									
										
										
										
											2014-11-19 20:09:46 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-15 10:06:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  | def test_ami_filtering_via_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_vpc("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservationA = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     instanceA = reservationA.instances[0] | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     imageA_id = conn.create_image(instanceA.id, "test-ami-A", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     imageA = conn.get_image(imageA_id) | 
					
						
							|  |  |  |     imageA.add_tag("a key", "some value") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     reservationB = conn.run_instances("ami-abcd1234") | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     instanceB = reservationB.instances[0] | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     imageB_id = conn.create_image(instanceB.id, "test-ami-B", "this is a test ami") | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     imageB = conn.get_image(imageB_id) | 
					
						
							|  |  |  |     imageB.add_tag("another key", "some other value") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_tagA = conn.get_all_images(filters={"tag:a key": "some value"}) | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     set([ami.id for ami in amis_by_tagA]).should.equal(set([imageA.id])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     amis_by_tagB = conn.get_all_images(filters={"tag:another key": "some other value"}) | 
					
						
							| 
									
										
										
										
											2014-09-30 16:42:52 -04:00
										 |  |  |     set([ami.id for ami in amis_by_tagB]).should.equal(set([imageB.id])) | 
					
						
							| 
									
										
										
										
											2014-09-30 16:12:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-01-28 18:14:00 -05:00
										 |  |  | def test_getting_missing_ami(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2014-08-25 10:54:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.get_image("ami-missing") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-08-25 10:54:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | def test_getting_malformed_ami(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.get_image("foo-missing") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.Malformed") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | def test_ami_attribute_group_permissions(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Baseline | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.name.should.equal("launch_permission") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ADD_GROUP_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "add", | 
					
						
							|  |  |  |         "groups": "all", | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     REMOVE_GROUP_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "remove", | 
					
						
							|  |  |  |         "groups": "all", | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add 'all' group and confirm | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as ex: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute(**dict(ADD_GROUP_ARGS, **{"dry_run": True})) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex.value.error_code.should.equal("DryRunOperation") | 
					
						
							|  |  |  |     ex.value.status.should.equal(400) | 
					
						
							|  |  |  |     ex.value.message.should.equal( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         "An error occurred (DryRunOperation) when calling the ModifyImageAttribute operation: Request would have succeeded, but DryRun flag is set" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-10-15 23:08:44 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     conn.modify_image_attribute(**ADD_GROUP_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.attrs["groups"].should.have.length_of(1) | 
					
						
							|  |  |  |     attributes.attrs["groups"].should.equal(["all"]) | 
					
						
							| 
									
										
										
										
											2014-11-19 20:09:46 -05:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(True) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add is idempotent | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn.modify_image_attribute.when.called_with(**ADD_GROUP_ARGS).should_not.throw( | 
					
						
							|  |  |  |         EC2ResponseError | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Remove 'all' group and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**REMOVE_GROUP_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							| 
									
										
										
										
											2014-11-19 20:09:46 -05:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(False) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Remove is idempotent | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn.modify_image_attribute.when.called_with(**REMOVE_GROUP_ARGS).should_not.throw( | 
					
						
							|  |  |  |         EC2ResponseError | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | def test_ami_attribute_user_permissions(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Baseline | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.name.should.equal("launch_permission") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Both str and int values should work. | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     USER1 = "123456789011" | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     USER2 = 123456789022 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ADD_USERS_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "add", | 
					
						
							|  |  |  |         "user_ids": [USER1, USER2], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REMOVE_USERS_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "remove", | 
					
						
							|  |  |  |         "user_ids": [USER1, USER2], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REMOVE_SINGLE_USER_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "remove", | 
					
						
							|  |  |  |         "user_ids": [USER1], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add multiple users and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**ADD_USERS_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.attrs["user_ids"].should.have.length_of(2) | 
					
						
							|  |  |  |     set(attributes.attrs["user_ids"]).should.equal(set([str(USER1), str(USER2)])) | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Add is idempotent | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn.modify_image_attribute.when.called_with(**ADD_USERS_ARGS).should_not.throw( | 
					
						
							|  |  |  |         EC2ResponseError | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Remove single user and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**REMOVE_SINGLE_USER_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.attrs["user_ids"].should.have.length_of(1) | 
					
						
							|  |  |  |     set(attributes.attrs["user_ids"]).should.equal(set([str(USER2)])) | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Remove multiple users and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**REMOVE_USERS_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Remove is idempotent | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn.modify_image_attribute.when.called_with(**REMOVE_USERS_ARGS).should_not.throw( | 
					
						
							|  |  |  |         EC2ResponseError | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | def test_ami_describe_executable_users(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     ec2.create_instances(ImageId="", MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     response = conn.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-state-name", "Values": ["running"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_id = response["Reservations"][0]["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  |     image_id = conn.create_image(InstanceId=instance_id, Name="TestImage")["ImageId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     USER1 = "123456789011" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_USER_ARGS = { | 
					
						
							|  |  |  |         "ImageId": image_id, | 
					
						
							|  |  |  |         "Attribute": "launchPermission", | 
					
						
							|  |  |  |         "OperationType": "add", | 
					
						
							|  |  |  |         "UserIds": [USER1], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add users and get no images | 
					
						
							|  |  |  |     conn.modify_image_attribute(**ADD_USER_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.describe_image_attribute( | 
					
						
							|  |  |  |         ImageId=image_id, Attribute="LaunchPermissions", DryRun=False | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"][0]["UserId"].should.equal(USER1) | 
					
						
							|  |  |  |     images = conn.describe_images(ExecutableUsers=[USER1])["Images"] | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  |     images.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     images[0]["ImageId"].should.equal(image_id) | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | def test_ami_describe_executable_users_negative(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     ec2.create_instances(ImageId="", MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     response = conn.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-state-name", "Values": ["running"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_id = response["Reservations"][0]["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  |     image_id = conn.create_image(InstanceId=instance_id, Name="TestImage")["ImageId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     USER1 = "123456789011" | 
					
						
							|  |  |  |     USER2 = "113355789012" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_USER_ARGS = { | 
					
						
							|  |  |  |         "ImageId": image_id, | 
					
						
							|  |  |  |         "Attribute": "launchPermission", | 
					
						
							|  |  |  |         "OperationType": "add", | 
					
						
							|  |  |  |         "UserIds": [USER1], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  |     # Add users and get no images | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  |     # Add users and get no images | 
					
						
							|  |  |  |     conn.modify_image_attribute(**ADD_USER_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.describe_image_attribute( | 
					
						
							|  |  |  |         ImageId=image_id, Attribute="LaunchPermissions", DryRun=False | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"][0]["UserId"].should.equal(USER1) | 
					
						
							|  |  |  |     images = conn.describe_images(ExecutableUsers=[USER2])["Images"] | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  |     images.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | @mock_ec2 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | def test_ami_describe_executable_users_and_filter(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     ec2 = boto3.resource("ec2", "us-east-1") | 
					
						
							|  |  |  |     ec2.create_instances(ImageId="", MinCount=1, MaxCount=1) | 
					
						
							|  |  |  |     response = conn.describe_instances( | 
					
						
							|  |  |  |         Filters=[{"Name": "instance-state-name", "Values": ["running"]}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     instance_id = response["Reservations"][0]["Instances"][0]["InstanceId"] | 
					
						
							|  |  |  |     image_id = conn.create_image(InstanceId=instance_id, Name="ImageToDelete")[ | 
					
						
							|  |  |  |         "ImageId" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     USER1 = "123456789011" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_USER_ARGS = { | 
					
						
							|  |  |  |         "ImageId": image_id, | 
					
						
							|  |  |  |         "Attribute": "launchPermission", | 
					
						
							|  |  |  |         "OperationType": "add", | 
					
						
							|  |  |  |         "UserIds": [USER1], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add users and get no images | 
					
						
							|  |  |  |     conn.modify_image_attribute(**ADD_USER_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.describe_image_attribute( | 
					
						
							|  |  |  |         ImageId=image_id, Attribute="LaunchPermissions", DryRun=False | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"].should.have.length_of(1) | 
					
						
							|  |  |  |     attributes["LaunchPermissions"][0]["UserId"].should.equal(USER1) | 
					
						
							|  |  |  |     images = conn.describe_images( | 
					
						
							|  |  |  |         ExecutableUsers=[USER1], Filters=[{"Name": "state", "Values": ["available"]}] | 
					
						
							|  |  |  |     )["Images"] | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  |     images.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     images[0]["ImageId"].should.equal(image_id) | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | def test_ami_attribute_user_and_group_permissions(): | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:46:05 +02:00
										 |  |  |     Boto supports adding/removing both users and groups at the same time. | 
					
						
							|  |  |  |     Just spot-check this -- input variations, idempotency, etc are validated | 
					
						
							|  |  |  |       via user-specific and group-specific tests above. | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Baseline | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.name.should.equal("launch_permission") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     USER1 = "123456789011" | 
					
						
							|  |  |  |     USER2 = "123456789022" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ADD_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "add", | 
					
						
							|  |  |  |         "groups": ["all"], | 
					
						
							|  |  |  |         "user_ids": [USER1, USER2], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REMOVE_ARGS = { | 
					
						
							|  |  |  |         "image_id": image.id, | 
					
						
							|  |  |  |         "attribute": "launchPermission", | 
					
						
							|  |  |  |         "operation": "remove", | 
					
						
							|  |  |  |         "groups": ["all"], | 
					
						
							|  |  |  |         "user_ids": [USER1, USER2], | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Add and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**ADD_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							|  |  |  |     attributes.attrs["user_ids"].should.have.length_of(2) | 
					
						
							|  |  |  |     set(attributes.attrs["user_ids"]).should.equal(set([USER1, USER2])) | 
					
						
							|  |  |  |     set(attributes.attrs["groups"]).should.equal(set(["all"])) | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Remove and confirm | 
					
						
							|  |  |  |     conn.modify_image_attribute(**REMOVE_ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  |     image.is_public.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:58:42 -04:00
										 |  |  | @mock_ec2_deprecated | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | def test_ami_attribute_error_cases(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     conn = boto.connect_ec2("the_key", "the_secret") | 
					
						
							|  |  |  |     reservation = conn.run_instances("ami-1234abcd") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     instance = reservation.instances[0] | 
					
						
							|  |  |  |     image_id = conn.create_image(instance.id, "test-ami", "this is a test ami") | 
					
						
							|  |  |  |     image = conn.get_image(image_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     # Error: Add with group != 'all' | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             image.id, attribute="launchPermission", operation="add", groups="everyone" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIAttributeItemValue") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     # Error: Add with user ID that isn't an integer. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             image.id, | 
					
						
							|  |  |  |             attribute="launchPermission", | 
					
						
							|  |  |  |             operation="add", | 
					
						
							|  |  |  |             user_ids="12345678901A", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIAttributeItemValue") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Error: Add with user ID that is > length 12. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             image.id, | 
					
						
							|  |  |  |             attribute="launchPermission", | 
					
						
							|  |  |  |             operation="add", | 
					
						
							|  |  |  |             user_ids="1234567890123", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIAttributeItemValue") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Error: Add with user ID that is < length 12. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             image.id, | 
					
						
							|  |  |  |             attribute="launchPermission", | 
					
						
							|  |  |  |             operation="add", | 
					
						
							|  |  |  |             user_ids="12345678901", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIAttributeItemValue") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     # Error: Add with one invalid user ID among other valid IDs, ensure no | 
					
						
							|  |  |  |     # partial changes. | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             image.id, | 
					
						
							|  |  |  |             attribute="launchPermission", | 
					
						
							|  |  |  |             operation="add", | 
					
						
							|  |  |  |             user_ids=["123456789011", "foo", "123456789022"], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIAttributeItemValue") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     attributes = conn.get_image_attribute(image.id, attribute="launchPermission") | 
					
						
							| 
									
										
										
										
											2015-01-23 09:43:54 -08:00
										 |  |  |     attributes.attrs.should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  |     # Error: Add with invalid image ID | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             "ami-abcd1234", attribute="launchPermission", operation="add", groups="all" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2014-08-27 11:53:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Error: Remove with invalid image ID | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(EC2ResponseError) as cm: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.modify_image_attribute( | 
					
						
							|  |  |  |             "ami-abcd1234", | 
					
						
							|  |  |  |             attribute="launchPermission", | 
					
						
							|  |  |  |             operation="remove", | 
					
						
							|  |  |  |             groups="all", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     cm.value.code.should.equal("InvalidAMIID.NotFound") | 
					
						
							|  |  |  |     cm.value.status.should.equal(400) | 
					
						
							|  |  |  |     cm.value.request_id.should_not.be.none | 
					
						
							| 
									
										
										
										
											2017-05-10 21:33:30 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-22 18:50:18 +05:30
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_describe_non_existent(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ec2 = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2017-12-22 18:50:18 +05:30
										 |  |  |     # Valid pattern but non-existent id | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     img = ec2.Image("ami-abcd1234") | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError): | 
					
						
							| 
									
										
										
										
											2017-12-22 18:50:18 +05:30
										 |  |  |         img.load() | 
					
						
							|  |  |  |     # Invalid ami pattern | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     img = ec2.Image("not_an_ami_id") | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError): | 
					
						
							| 
									
										
										
										
											2017-12-22 18:50:18 +05:30
										 |  |  |         img.load() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-01 12:03:54 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_registration(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     image_id = ec2.register_image(Name="test-register-image").get("ImageId", "") | 
					
						
							|  |  |  |     images = ec2.describe_images(ImageIds=[image_id]).get("Images", []) | 
					
						
							|  |  |  |     assert images[0]["Name"] == "test-register-image", "No image was registered." | 
					
						
							|  |  |  |     assert images[0]["RootDeviceName"] == "/dev/sda1", "Wrong root device name." | 
					
						
							|  |  |  |     assert images[0]["State"] == "available", "State should be available." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 08:51:26 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_registration(): | 
					
						
							|  |  |  |     ec2 = boto3.client("ec2", region_name="us-east-1") | 
					
						
							|  |  |  |     image_id = ec2.register_image(Name="test-register-image").get("ImageId", "") | 
					
						
							|  |  |  |     images = ec2.describe_images(ImageIds=[image_id]).get("Images", []) | 
					
						
							|  |  |  |     assert images[0]["Name"] == "test-register-image", "No image was registered." | 
					
						
							|  |  |  |     assert images[0]["RootDeviceName"] == "/dev/sda1", "Wrong root device name." | 
					
						
							|  |  |  |     assert images[0]["State"] == "available", "State should be available." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-10 21:33:30 -04:00
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_filter_wildcard(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ec2_resource = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     instance = ec2_resource.create_instances( | 
					
						
							|  |  |  |         ImageId="ami-1234abcd", MinCount=1, MaxCount=1 | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  |     instance.create_image(Name="test-image") | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # create an image with the same owner but will not match the filter | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     instance.create_image(Name="not-matching-image") | 
					
						
							| 
									
										
										
										
											2017-12-05 16:53:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  |     my_images = ec2_client.describe_images( | 
					
						
							| 
									
										
										
										
											2020-02-08 10:58:31 +00:00
										 |  |  |         Owners=[ACCOUNT_ID], Filters=[{"Name": "name", "Values": ["test*"]}] | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     )["Images"] | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  |     my_images.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2017-05-10 21:33:30 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-12 11:18:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_filter_by_owner_id(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ec2", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2017-11-12 11:18:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ubuntu_id = "099720109477" | 
					
						
							| 
									
										
										
										
											2017-11-12 11:18:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ubuntu_images = client.describe_images(Owners=[ubuntu_id]) | 
					
						
							|  |  |  |     all_images = client.describe_images() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ubuntu_ids = [ami["OwnerId"] for ami in ubuntu_images["Images"]] | 
					
						
							|  |  |  |     all_ids = [ami["OwnerId"] for ami in all_images["Images"]] | 
					
						
							| 
									
										
										
										
											2017-11-12 11:18:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Assert all ubuntu_ids are the same and one equals ubuntu_id | 
					
						
							|  |  |  |     assert all(ubuntu_ids) and ubuntu_ids[0] == ubuntu_id | 
					
						
							|  |  |  |     # Check we actually have a subset of images | 
					
						
							|  |  |  |     assert len(ubuntu_ids) < len(all_ids) | 
					
						
							| 
									
										
										
										
											2018-01-04 15:31:17 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 15:31:17 +05:30
										 |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_filter_by_self(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ec2_resource = boto3.resource("ec2", region_name="us-west-1") | 
					
						
							|  |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2018-01-04 15:31:17 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     my_images = ec2_client.describe_images(Owners=["self"])["Images"] | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  |     my_images.should.have.length_of(0) | 
					
						
							| 
									
										
										
										
											2018-01-04 15:31:17 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     # Create a new image | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     instance = ec2_resource.create_instances( | 
					
						
							|  |  |  |         ImageId="ami-1234abcd", MinCount=1, MaxCount=1 | 
					
						
							|  |  |  |     )[0] | 
					
						
							|  |  |  |     instance.create_image(Name="test-image") | 
					
						
							| 
									
										
										
										
											2018-01-04 15:31:17 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     my_images = ec2_client.describe_images(Owners=["self"])["Images"] | 
					
						
							| 
									
										
										
										
											2018-01-11 14:51:42 -05:00
										 |  |  |     my_images.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ec2 | 
					
						
							|  |  |  | def test_ami_snapshots_have_correct_owner(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ec2_client = boto3.client("ec2", region_name="us-west-1") | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     images_response = ec2_client.describe_images() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     owner_id_to_snapshot_ids = {} | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     for image in images_response["Images"]: | 
					
						
							|  |  |  |         owner_id = image["OwnerId"] | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |         snapshot_ids = [ | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             block_device_mapping["Ebs"]["SnapshotId"] | 
					
						
							|  |  |  |             for block_device_mapping in image["BlockDeviceMappings"] | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |         ] | 
					
						
							|  |  |  |         existing_snapshot_ids = owner_id_to_snapshot_ids.get(owner_id, []) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         owner_id_to_snapshot_ids[owner_id] = existing_snapshot_ids + snapshot_ids | 
					
						
							| 
									
										
										
										
											2020-06-15 15:02:43 +05:30
										 |  |  |         # adding an assertion to volumeType | 
					
						
							|  |  |  |         assert ( | 
					
						
							|  |  |  |             image.get("BlockDeviceMappings", {})[0].get("Ebs", {}).get("VolumeType") | 
					
						
							|  |  |  |             == "standard" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2018-03-21 15:55:58 +00:00
										 |  |  |     for owner_id in owner_id_to_snapshot_ids: | 
					
						
							|  |  |  |         snapshots_rseponse = ec2_client.describe_snapshots( | 
					
						
							|  |  |  |             SnapshotIds=owner_id_to_snapshot_ids[owner_id] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         for snapshot in snapshots_rseponse["Snapshots"]: | 
					
						
							|  |  |  |             assert owner_id == snapshot["OwnerId"] |