Merge pull request #658 from kierandoonan/master
Add encrypted attribute to Volumes/Snapshots
This commit is contained in:
		
						commit
						3e797d9c50
					
				| @ -1536,7 +1536,7 @@ class VolumeAttachment(object): | ||||
| 
 | ||||
| 
 | ||||
| class Volume(TaggedEC2Resource): | ||||
|     def __init__(self, ec2_backend, volume_id, size, zone, snapshot_id=None): | ||||
|     def __init__(self, ec2_backend, volume_id, size, zone, snapshot_id=None, encrypted=False): | ||||
|         self.id = volume_id | ||||
|         self.size = size | ||||
|         self.zone = zone | ||||
| @ -1544,6 +1544,7 @@ class Volume(TaggedEC2Resource): | ||||
|         self.attachment = None | ||||
|         self.snapshot_id = snapshot_id | ||||
|         self.ec2_backend = ec2_backend | ||||
|         self.encrypted = encrypted | ||||
| 
 | ||||
|     @classmethod | ||||
|     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): | ||||
| @ -1593,6 +1594,9 @@ class Volume(TaggedEC2Resource): | ||||
|         if filter_name == 'volume-id': | ||||
|             return self.id | ||||
| 
 | ||||
|         if filter_name == 'encrypted': | ||||
|             return str(self.encrypted).lower() | ||||
| 
 | ||||
|         filter_value = super(Volume, self).get_filter_value(filter_name) | ||||
| 
 | ||||
|         if filter_value is None: | ||||
| @ -1602,7 +1606,7 @@ class Volume(TaggedEC2Resource): | ||||
| 
 | ||||
| 
 | ||||
| class Snapshot(TaggedEC2Resource): | ||||
|     def __init__(self, ec2_backend, snapshot_id, volume, description): | ||||
|     def __init__(self, ec2_backend, snapshot_id, volume, description, encrypted=False): | ||||
|         self.id = snapshot_id | ||||
|         self.volume = volume | ||||
|         self.description = description | ||||
| @ -1610,6 +1614,7 @@ class Snapshot(TaggedEC2Resource): | ||||
|         self.create_volume_permission_groups = set() | ||||
|         self.ec2_backend = ec2_backend | ||||
|         self.status = 'completed' | ||||
|         self.encrypted = encrypted | ||||
| 
 | ||||
|     def get_filter_value(self, filter_name): | ||||
| 
 | ||||
| @ -1628,6 +1633,9 @@ class Snapshot(TaggedEC2Resource): | ||||
|         if filter_name == 'volume-size': | ||||
|             return self.volume.size | ||||
| 
 | ||||
|         if filter_name == 'encrypted': | ||||
|             return str(self.encrypted).lower() | ||||
| 
 | ||||
|         filter_value = super(Snapshot, self).get_filter_value(filter_name) | ||||
| 
 | ||||
|         if filter_value is None: | ||||
| @ -1643,14 +1651,16 @@ class EBSBackend(object): | ||||
|         self.snapshots = {} | ||||
|         super(EBSBackend, self).__init__() | ||||
| 
 | ||||
|     def create_volume(self, size, zone_name, snapshot_id=None): | ||||
|     def create_volume(self, size, zone_name, snapshot_id=None, encrypted=False): | ||||
|         volume_id = random_volume_id() | ||||
|         zone = self.get_zone_by_name(zone_name) | ||||
|         if snapshot_id: | ||||
|             snapshot = self.get_snapshot(snapshot_id) | ||||
|             if size is None: | ||||
|                 size = snapshot.volume.size | ||||
|         volume = Volume(self, volume_id, size, zone, snapshot_id) | ||||
|             if snapshot.encrypted: | ||||
|                 encrypted = snapshot.encrypted | ||||
|         volume = Volume(self, volume_id, size, zone, snapshot_id, encrypted) | ||||
|         self.volumes[volume_id] = volume | ||||
|         return volume | ||||
| 
 | ||||
| @ -1699,7 +1709,7 @@ class EBSBackend(object): | ||||
|     def create_snapshot(self, volume_id, description): | ||||
|         snapshot_id = random_snapshot_id() | ||||
|         volume = self.get_volume(volume_id) | ||||
|         snapshot = Snapshot(self, snapshot_id, volume, description) | ||||
|         snapshot = Snapshot(self, snapshot_id, volume, description, volume.encrypted) | ||||
|         self.snapshots[snapshot_id] = snapshot | ||||
|         return snapshot | ||||
| 
 | ||||
|  | ||||
| @ -29,7 +29,8 @@ class ElasticBlockStore(BaseResponse): | ||||
|         size = self._get_param('Size') | ||||
|         zone = self._get_param('AvailabilityZone') | ||||
|         snapshot_id = self._get_param('SnapshotId') | ||||
|         volume = self.ec2_backend.create_volume(size, zone, snapshot_id) | ||||
|         encrypted = self._get_param('Encrypted') or 'false' | ||||
|         volume = self.ec2_backend.create_volume(size, zone, snapshot_id, encrypted) | ||||
|         template = self.response_template(CREATE_VOLUME_RESPONSE) | ||||
|         return template.render(volume=volume) | ||||
| 
 | ||||
| @ -117,6 +118,7 @@ CREATE_VOLUME_RESPONSE = """<CreateVolumeResponse xmlns="http://ec2.amazonaws.co | ||||
|   {% else %} | ||||
|     <snapshotId/> | ||||
|   {% endif %} | ||||
|   <encrypted>{{ volume.encrypted }}</encrypted> | ||||
|   <availabilityZone>{{ volume.zone.name }}</availabilityZone> | ||||
|   <status>creating</status> | ||||
|   <createTime>{{ volume.create_time}}</createTime> | ||||
| @ -135,6 +137,7 @@ DESCRIBE_VOLUMES_RESPONSE = """<DescribeVolumesResponse xmlns="http://ec2.amazon | ||||
|              {% else %} | ||||
|                <snapshotId/> | ||||
|              {% endif %} | ||||
|              <encrypted>{{ volume.encrypted }}</encrypted> | ||||
|              <availabilityZone>{{ volume.zone.name }}</availabilityZone> | ||||
|              <status>{{ volume.status }}</status> | ||||
|              <createTime>{{ volume.create_time}}</createTime> | ||||
| @ -199,6 +202,7 @@ CREATE_SNAPSHOT_RESPONSE = """<CreateSnapshotResponse xmlns="http://ec2.amazonaw | ||||
|   <ownerId>111122223333</ownerId> | ||||
|   <volumeSize>{{ snapshot.volume.size }}</volumeSize> | ||||
|   <description>{{ snapshot.description }}</description> | ||||
|   <encrypted>{{ snapshot.encrypted }}</encrypted> | ||||
| </CreateSnapshotResponse>""" | ||||
| 
 | ||||
| DESCRIBE_SNAPSHOTS_RESPONSE = """<DescribeSnapshotsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> | ||||
| @ -214,6 +218,7 @@ DESCRIBE_SNAPSHOTS_RESPONSE = """<DescribeSnapshotsResponse xmlns="http://ec2.am | ||||
|              <ownerId>111122223333</ownerId> | ||||
|              <volumeSize>{{ snapshot.volume.size }}</volumeSize> | ||||
|              <description>{{ snapshot.description }}</description> | ||||
|              <encrypted>{{ snapshot.encrypted }}</encrypted> | ||||
|              <tagSet> | ||||
|                {% for tag in snapshot.get_tags() %} | ||||
|                  <item> | ||||
|  | ||||
| @ -20,6 +20,7 @@ def test_create_and_delete_volume(): | ||||
|     all_volumes.should.have.length_of(1) | ||||
|     all_volumes[0].size.should.equal(80) | ||||
|     all_volumes[0].zone.should.equal("us-east-1a") | ||||
|     all_volumes[0].encrypted.should.be(False) | ||||
| 
 | ||||
|     volume = all_volumes[0] | ||||
|     volume.delete() | ||||
| @ -34,6 +35,15 @@ def test_create_and_delete_volume(): | ||||
|     cm.exception.request_id.should_not.be.none | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_create_encrypted_volume(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
|     conn.create_volume(80, "us-east-1a", encrypted=True) | ||||
| 
 | ||||
|     all_volumes = conn.get_all_volumes() | ||||
|     all_volumes[0].encrypted.should.be(True) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_filter_volume_by_id(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
| @ -57,9 +67,9 @@ def test_volume_filters(): | ||||
| 
 | ||||
|     instance.update() | ||||
| 
 | ||||
|     volume1 = conn.create_volume(80, "us-east-1a") | ||||
|     volume2 = conn.create_volume(36, "us-east-1b") | ||||
|     volume3 = conn.create_volume(20, "us-east-1c") | ||||
|     volume1 = conn.create_volume(80, "us-east-1a", encrypted=True) | ||||
|     volume2 = conn.create_volume(36, "us-east-1b", encrypted=False) | ||||
|     volume3 = conn.create_volume(20, "us-east-1c", encrypted=True) | ||||
| 
 | ||||
|     snapshot = volume3.create_snapshot(description='testsnap') | ||||
|     volume4 = conn.create_volume(25, "us-east-1a", snapshot=snapshot) | ||||
| @ -107,6 +117,16 @@ def test_volume_filters(): | ||||
|     volumes_by_tag = conn.get_all_volumes(filters={'tag:testkey1': 'testvalue1'}) | ||||
|     set([vol.id for vol in volumes_by_tag]).should.equal(set([volume1.id])) | ||||
| 
 | ||||
|     volumes_by_unencrypted = conn.get_all_volumes(filters={'encrypted': 'false'}) | ||||
|     set([vol.id for vol in volumes_by_unencrypted]).should.equal( | ||||
|         set([block_mapping.volume_id, volume2.id]) | ||||
|     ) | ||||
| 
 | ||||
|     volumes_by_encrypted = conn.get_all_volumes(filters={'encrypted': 'true'}) | ||||
|     set([vol.id for vol in volumes_by_encrypted]).should.equal( | ||||
|         set([volume1.id, volume3.id, volume4.id]) | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_volume_attach_and_detach(): | ||||
| @ -162,6 +182,7 @@ def test_create_snapshot(): | ||||
|     snapshots.should.have.length_of(1) | ||||
|     snapshots[0].description.should.equal('a test snapshot') | ||||
|     snapshots[0].start_time.should_not.be.none | ||||
|     snapshots[0].encrypted.should.be(False) | ||||
| 
 | ||||
|     # Create snapshot without description | ||||
|     snapshot = volume.create_snapshot() | ||||
| @ -178,6 +199,21 @@ def test_create_snapshot(): | ||||
|     cm.exception.request_id.should_not.be.none | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_create_encrypted_snapshot(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
|     volume = conn.create_volume(80, "us-east-1a", encrypted=True) | ||||
|     snapshot = volume.create_snapshot('a test snapshot') | ||||
|     snapshot.update() | ||||
|     snapshot.status.should.equal('completed') | ||||
| 
 | ||||
|     snapshots = conn.get_all_snapshots() | ||||
|     snapshots.should.have.length_of(1) | ||||
|     snapshots[0].description.should.equal('a test snapshot') | ||||
|     snapshots[0].start_time.should_not.be.none | ||||
|     snapshots[0].encrypted.should.be(True) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_filter_snapshot_by_id(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
| @ -202,8 +238,8 @@ def test_filter_snapshot_by_id(): | ||||
| @mock_ec2 | ||||
| def test_snapshot_filters(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
|     volume1 = conn.create_volume(20, "us-east-1a") | ||||
|     volume2 = conn.create_volume(25, "us-east-1a") | ||||
|     volume1 = conn.create_volume(20, "us-east-1a", encrypted=False) | ||||
|     volume2 = conn.create_volume(25, "us-east-1a", encrypted=True) | ||||
| 
 | ||||
|     snapshot1 = volume1.create_snapshot(description='testsnapshot1') | ||||
|     snapshot2 = volume1.create_snapshot(description='testsnapshot2') | ||||
| @ -236,6 +272,9 @@ def test_snapshot_filters(): | ||||
|     snapshots_by_tag = conn.get_all_snapshots(filters={'tag:testkey1': 'testvalue1'}) | ||||
|     set([snap.id for snap in snapshots_by_tag]).should.equal(set([snapshot1.id])) | ||||
| 
 | ||||
|     snapshots_by_encrypted = conn.get_all_snapshots(filters={'encrypted': 'true'}) | ||||
|     set([snap.id for snap in snapshots_by_encrypted]).should.equal(set([snapshot3.id])) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_snapshot_attribute(): | ||||
| @ -332,6 +371,21 @@ def test_create_volume_from_snapshot(): | ||||
|     new_volume.snapshot_id.should.equal(snapshot.id) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_create_volume_from_encrypted_snapshot(): | ||||
|     conn = boto.connect_ec2('the_key', 'the_secret') | ||||
|     volume = conn.create_volume(80, "us-east-1a", encrypted=True) | ||||
| 
 | ||||
|     snapshot = volume.create_snapshot('a test snapshot') | ||||
|     snapshot.update() | ||||
|     snapshot.status.should.equal('completed') | ||||
| 
 | ||||
|     new_volume = snapshot.create_volume('us-east-1a') | ||||
|     new_volume.size.should.equal(80) | ||||
|     new_volume.snapshot_id.should.equal(snapshot.id) | ||||
|     new_volume.encrypted.should.be(True) | ||||
| 
 | ||||
| 
 | ||||
| @mock_ec2 | ||||
| def test_modify_attribute_blockDeviceMapping(): | ||||
|     """ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user