def test_can_get_latest_snapshot(self): client = boto3.client('ec2') stubber = Stubber(client) response = { "Snapshots": [{ "StartTime": datetime.datetime.now(), "State": "available", "SnapshotId": "old" }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=1), "State": "available", "SnapshotId": "new" }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "newest" }] } params = {'Filters': ANY} stubber.add_response('describe_snapshots', response) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.get_latest_snapshot_id("foobar") self.assertEqual(response, "newest")
def test_can_create_snapshot(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) stubber.add_response('create_snapshot', {"SnapshotId": "foo"}) stubber.add_response( 'describe_volumes', { "Volumes": [{ "Tags": [{ "Key": "Name", "Value": "bar-/dev/xvda" }, { "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }] }] }) stubber.add_response('create_tags', {}) stubber.add_response('describe_snapshots', {"Snapshots": []}) stubber.add_response( 'describe_snapshots', {"Snapshots": [{ "SnapshotId": "foo", "State": "completed" }]}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.create_snapshot("foo", {"extra": "tag"}) self.assertEqual(response, "foo")
def test_can_get_latest_volume_id(self): """Returns latest volume even if it is in-use""" client = boto3.client('ec2') stubber = Stubber(client) response = { "Volumes": [{ "CreateTime": datetime.datetime.now(), "State": "available", "VolumeId": "old" }, { "CreateTime": datetime.datetime.now() + datetime.timedelta(days=1), "State": "available", "VolumeId": "new" }, { "CreateTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "in-use", "VolumeId": "newest" }] } params = {'Filters': ANY} stubber.add_response('describe_volumes', response) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.get_latest_volume_id_available("foobar") self.assertEqual(response, "newest")
def test_no_snapshots(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) snapshots = [] stubber.add_response('describe_snapshots', {"Snapshots": snapshots}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) ebspin_ec2.clean_snapshots("01c6b711-a7d4-4bdf-bb2b-10b4b60594bc")
def test_raises_boto3_exception(self): client = boto3.client('ec2') stubber = Stubber(client) stubber.add_client_error('describe_volumes', service_error_code="401") stubber.activate() ebspin_ec2 = ec2.Ec2(client) with self.assertRaises(botocore.exceptions.ClientError): ebspin_ec2.get_latest_volume_id_available("foobar")
def test_create_volume_with_exception(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) stubber.add_client_error('create_volume', service_error_code="401") stubber.activate() ebspin_ec2 = ec2.Ec2(client) with self.assertRaises(botocore.exceptions.ClientError): ebspin_ec2.create_volume(10, "gp2", "ap-southeast-2a", "foo")
def test_can_clean_snapshots(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) tags = [ { "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }, { "Key": "Name", "Value": "myvolume" }, ] snapshots = [ { "StartTime": datetime.datetime.now(), "State": "available", "SnapshotId": "old", "Tags": tags }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=1), "State": "available", "SnapshotId": "new", "Tags": tags }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "newest", "Tags": tags }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "backup", "Tags": tags + [{ "Key": "aws:dlm:lifecycle:schedule-name", "Value": "Default Schedule" }] }, ] stubber.add_response('describe_snapshots', {"Snapshots": snapshots}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "old"}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "new"}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "newest"}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) ebspin_ec2.clean_snapshots("01c6b711-a7d4-4bdf-bb2b-10b4b60594bc") stubber.assert_no_pending_responses()
def test_no_snapshots_found(self): client = boto3.client('ec2') stubber = Stubber(client) response = {"Snapshots": []} params = {'Filters': ANY} stubber.add_response('describe_snapshots', response) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.get_latest_snapshot_id("foobar") self.assertEqual(response, None)
def test_no_volumes_found(self): client = boto3.client('ec2') stubber = Stubber(client) response = {"Volumes": []} params = {'Filters': ANY} stubber.add_response('describe_volumes', response) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.get_latest_volume_id_available("foobar") self.assertEqual(response, None)
def test_can_create_volume(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) stubber.add_response('create_volume', {"VolumeId": "foo"}) stubber.add_response('describe_volumes', {"Volumes": [{ "State": "in-use" }]}) stubber.add_response('describe_volumes', {"Volumes": [{ "State": "available" }]}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.create_volume(10, "gp2", "ap-southeast-2a") self.assertEqual(response, "foo")
def test_no_old_volumes(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) volumes = [ { "VolumeId": "1", "State": "in-use", "Tags": [{ "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }] }, ] stubber.add_response('describe_volumes', {"Volumes": volumes}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) ebspin_ec2.clean_old_volumes("01c6b711-a7d4-4bdf-bb2b-10b4b60594bc", "1")
def test_can_wait_for_attach_volume(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) stubber.add_response( # return no results as volume is "in-use" 'describe_volumes', {"Volumes": []}) stubber.add_response( 'describe_volumes', { "Volumes": [{ "CreateTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "available", "VolumeId": "foo" }] }) stubber.add_response('attach_volume', {'AttachTime': datetime.datetime(2015, 1, 1)}) stubber.add_response( 'describe_volumes', {"Volumes": []}) # return no results as volume is "available" stubber.add_response( 'describe_volumes', { "Volumes": [{ "State": "in-use", "VolumeId": "foo", "Attachments": [{ "Device": "xvda", "InstanceId": "bar", "State": "attached" }] }] }) stubber.activate() ebspin_ec2 = ec2.Ec2(client) response = ebspin_ec2.attach_volume(volume_id="foo", instance_id="bar", device="xvda") self.assertEqual(response, "foo")
def test_can_handle_multiple_volumes_in_use(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) volumes = [{ "VolumeId": "1", "State": "in-use", "Tags": [{ "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }] }, { "VolumeId": "2", "State": "in-use", "Tags": [{ "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }] }, { "VolumeId": "3", "State": "available", "Tags": [{ "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }] }] stubber.add_response('describe_volumes', {"Volumes": volumes}) stubber.add_client_error('delete_volume', service_error_code='VolumeInUse', expected_params={"VolumeId": "2"}) stubber.add_response('delete_volume', [], {"VolumeId": "3"}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) ebspin_ec2.clean_old_volumes("01c6b711-a7d4-4bdf-bb2b-10b4b60594bc", "1")
def test_can_attach_volume_from_snapshot(self, *args): client = boto3.client('ec2') stubber = Stubber(client) stubber.activate( ) # this is just to ensure that no real boto3 calls are made options = Mock() options.device = "/dev/xvdf" options.uuid = "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" options.size = 10 options.type = "gp2" options.tags = {} ebspin_base = base.Base(options, metadata={ "region": "ap-southeast-2", "availabilityZone": "ap-southeast-2a", "instanceId": "bar" }) ebspin_ec2 = ec2.Ec2(client) ebspin_base.ec2 = ebspin_ec2 ebspin_base.attach() for arg in args: arg.assert_called()
def test_can_clean_snapshots_with_extra_tags(self, mock_sleep): client = boto3.client('ec2') stubber = Stubber(client) tags = [ { "Key": "UUID", "Value": "01c6b711-a7d4-4bdf-bb2b-10b4b60594bc" }, { "Key": "Name", "Value": "myvolume" }, { "Key": "Team", "Value": "DevOps" }, # additional tag specified on CLI ] snapshots = [ { "StartTime": datetime.datetime.now(), "State": "available", "SnapshotId": "missing_tags_on_snapshot", "Tags": [x for x in tags if x["Key"] != "Team"] }, # if a new tag gets added to CLI { "StartTime": datetime.datetime.now(), "State": "available", "SnapshotId": "same", "Tags": tags }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=1), "State": "available", "SnapshotId": "same_tags_just_newer", "Tags": tags }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "unordered_tags", "Tags": list(reversed(tags)) }, # tag order may not be deterministic? { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "backup", "Tags": tags + [{ "Key": "aws:dlm:lifecycle:schedule-name", "Value": "Default Schedule" }] }, { "StartTime": datetime.datetime.now() + datetime.timedelta(days=2), "State": "pending", "SnapshotId": "no_tags", "Tags": [] }, ] stubber.add_response('describe_snapshots', {"Snapshots": snapshots}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "missing_tags_on_snapshot"}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "same"}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "same_tags_just_newer"}) stubber.add_response('delete_snapshot', [], {"SnapshotId": "unordered_tags"}) stubber.activate() ebspin_ec2 = ec2.Ec2(client) ebspin_ec2.clean_snapshots("01c6b711-a7d4-4bdf-bb2b-10b4b60594bc", extra_tags={"Team": "DevOps"}) stubber.assert_no_pending_responses()
def __init__(self, options, metadata): self.options = options self.metadata = metadata self.session = boto3.Session(region_name=metadata['region']) self.ec2 = ec2.Ec2(self.session.client('ec2'))