diff env/lib/python3.7/site-packages/boto/ec2/connection.py @ 5:9b1c78e6ba9c draft default tip

"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author shellac
date Mon, 01 Jun 2020 08:59:25 -0400
parents 79f47841a781
children
line wrap: on
line diff
--- a/env/lib/python3.7/site-packages/boto/ec2/connection.py	Thu May 14 16:47:39 2020 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4527 +0,0 @@
-# Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
-# Copyright (c) 2010, Eucalyptus Systems, Inc.
-# Copyright (c) 2013 Amazon.com, Inc. or its affiliates.  All Rights Reserved
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish, dis-
-# tribute, sublicense, and/or sell copies of the Software, and to permit
-# persons to whom the Software is furnished to do so, subject to the fol-
-# lowing conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
-# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-"""
-Represents a connection to the EC2 service.
-"""
-
-import base64
-import warnings
-from datetime import datetime
-from datetime import timedelta
-
-import boto
-from boto.auth import detect_potential_sigv4
-from boto.connection import AWSQueryConnection
-from boto.resultset import ResultSet
-from boto.ec2.image import Image, ImageAttribute, CopyImage
-from boto.ec2.instance import Reservation, Instance
-from boto.ec2.instance import ConsoleOutput, InstanceAttribute
-from boto.ec2.keypair import KeyPair
-from boto.ec2.address import Address
-from boto.ec2.volume import Volume, VolumeAttribute
-from boto.ec2.snapshot import Snapshot
-from boto.ec2.snapshot import SnapshotAttribute
-from boto.ec2.zone import Zone
-from boto.ec2.securitygroup import SecurityGroup
-from boto.ec2.regioninfo import RegionInfo
-from boto.ec2.instanceinfo import InstanceInfo
-from boto.ec2.reservedinstance import ReservedInstancesOffering
-from boto.ec2.reservedinstance import ReservedInstance
-from boto.ec2.reservedinstance import ReservedInstanceListing
-from boto.ec2.reservedinstance import ReservedInstancesConfiguration
-from boto.ec2.reservedinstance import ModifyReservedInstancesResult
-from boto.ec2.reservedinstance import ReservedInstancesModification
-from boto.ec2.spotinstancerequest import SpotInstanceRequest
-from boto.ec2.spotpricehistory import SpotPriceHistory
-from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
-from boto.ec2.bundleinstance import BundleInstanceTask
-from boto.ec2.placementgroup import PlacementGroup
-from boto.ec2.tag import Tag
-from boto.ec2.instancetype import InstanceType
-from boto.ec2.instancestatus import InstanceStatusSet
-from boto.ec2.volumestatus import VolumeStatusSet
-from boto.ec2.networkinterface import NetworkInterface
-from boto.ec2.attributes import AccountAttribute, VPCAttribute
-from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
-from boto.exception import EC2ResponseError
-from boto.compat import six
-
-#boto.set_stream_logger('ec2')
-
-
-class EC2Connection(AWSQueryConnection):
-
-    APIVersion = boto.config.get('Boto', 'ec2_version', '2014-10-01')
-    DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
-    DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
-                                            'ec2.us-east-1.amazonaws.com')
-    ResponseError = EC2ResponseError
-
-    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
-                 is_secure=True, host=None, port=None,
-                 proxy=None, proxy_port=None,
-                 proxy_user=None, proxy_pass=None, debug=0,
-                 https_connection_factory=None, region=None, path='/',
-                 api_version=None, security_token=None,
-                 validate_certs=True, profile_name=None):
-        """
-        Init method to create a new connection to EC2.
-        """
-        if not region:
-            region = RegionInfo(self, self.DefaultRegionName,
-                                self.DefaultRegionEndpoint)
-        self.region = region
-        super(EC2Connection, self).__init__(aws_access_key_id,
-                                            aws_secret_access_key,
-                                            is_secure, port, proxy, proxy_port,
-                                            proxy_user, proxy_pass,
-                                            self.region.endpoint, debug,
-                                            https_connection_factory, path,
-                                            security_token,
-                                            validate_certs=validate_certs,
-                                            profile_name=profile_name)
-        if api_version:
-            self.APIVersion = api_version
-
-    def _required_auth_capability(self):
-        return ['hmac-v4']
-
-    def get_params(self):
-        """
-        Returns a dictionary containing the value of all of the keyword
-        arguments passed when constructing this connection.
-        """
-        param_names = ['aws_access_key_id', 'aws_secret_access_key',
-                       'is_secure', 'port', 'proxy', 'proxy_port',
-                       'proxy_user', 'proxy_pass',
-                       'debug', 'https_connection_factory']
-        params = {}
-        for name in param_names:
-            params[name] = getattr(self, name)
-        return params
-
-    def build_filter_params(self, params, filters):
-        if not isinstance(filters, dict):
-            filters = dict(filters)
-
-        i = 1
-        for name in filters:
-            aws_name = name
-            if not aws_name.startswith('tag:'):
-                aws_name = name.replace('_', '-')
-            params['Filter.%d.Name' % i] = aws_name
-            value = filters[name]
-            if not isinstance(value, list):
-                value = [value]
-            j = 1
-            for v in value:
-                params['Filter.%d.Value.%d' % (i, j)] = v
-                j += 1
-            i += 1
-
-    # Image methods
-
-    def get_all_images(self, image_ids=None, owners=None,
-                       executable_by=None, filters=None, dry_run=False):
-        """
-        Retrieve all the EC2 images available on your account.
-
-        :type image_ids: list
-        :param image_ids: A list of strings with the image IDs wanted
-
-        :type owners: list
-        :param owners: A list of owner IDs, the special strings 'self',
-            'amazon', and 'aws-marketplace', may be used to describe
-            images owned by you, Amazon or AWS Marketplace
-            respectively
-
-        :type executable_by: list
-        :param executable_by: Returns AMIs for which the specified
-                              user ID has explicit launch permissions
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.image.Image`
-        """
-        params = {}
-        if image_ids:
-            self.build_list_params(params, image_ids, 'ImageId')
-        if owners:
-            self.build_list_params(params, owners, 'Owner')
-        if executable_by:
-            self.build_list_params(params, executable_by, 'ExecutableBy')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeImages', params,
-                             [('item', Image)], verb='POST')
-
-    def get_all_kernels(self, kernel_ids=None, owners=None, dry_run=False):
-        """
-        Retrieve all the EC2 kernels available on your account.
-        Constructs a filter to allow the processing to happen server side.
-
-        :type kernel_ids: list
-        :param kernel_ids: A list of strings with the image IDs wanted
-
-        :type owners: list
-        :param owners: A list of owner IDs
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.image.Image`
-        """
-        params = {}
-        if kernel_ids:
-            self.build_list_params(params, kernel_ids, 'ImageId')
-        if owners:
-            self.build_list_params(params, owners, 'Owner')
-        filter = {'image-type': 'kernel'}
-        self.build_filter_params(params, filter)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeImages', params,
-                             [('item', Image)], verb='POST')
-
-    def get_all_ramdisks(self, ramdisk_ids=None, owners=None, dry_run=False):
-        """
-        Retrieve all the EC2 ramdisks available on your account.
-        Constructs a filter to allow the processing to happen server side.
-
-        :type ramdisk_ids: list
-        :param ramdisk_ids: A list of strings with the image IDs wanted
-
-        :type owners: list
-        :param owners: A list of owner IDs
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.image.Image`
-        """
-        params = {}
-        if ramdisk_ids:
-            self.build_list_params(params, ramdisk_ids, 'ImageId')
-        if owners:
-            self.build_list_params(params, owners, 'Owner')
-        filter = {'image-type': 'ramdisk'}
-        self.build_filter_params(params, filter)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeImages', params,
-                             [('item', Image)], verb='POST')
-
-    def get_image(self, image_id, dry_run=False):
-        """
-        Shortcut method to retrieve a specific image (AMI).
-
-        :type image_id: string
-        :param image_id: the ID of the Image to retrieve
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.image.Image`
-        :return: The EC2 Image specified or None if the image is not found
-        """
-        try:
-            return self.get_all_images(image_ids=[image_id], dry_run=dry_run)[0]
-        except IndexError:  # None of those images available
-            return None
-
-    def register_image(self, name=None, description=None, image_location=None,
-                       architecture=None, kernel_id=None, ramdisk_id=None,
-                       root_device_name=None, block_device_map=None,
-                       dry_run=False, virtualization_type=None,
-                       sriov_net_support=None,
-                       snapshot_id=None,
-                       delete_root_volume_on_termination=False):
-        """
-        Register an image.
-
-        :type name: string
-        :param name: The name of the AMI.  Valid only for EBS-based images.
-
-        :type description: string
-        :param description: The description of the AMI.
-
-        :type image_location: string
-        :param image_location: Full path to your AMI manifest in
-            Amazon S3 storage.  Only used for S3-based AMI's.
-
-        :type architecture: string
-        :param architecture: The architecture of the AMI.  Valid choices are:
-            * i386
-            * x86_64
-
-        :type kernel_id: string
-        :param kernel_id: The ID of the kernel with which to launch
-            the instances
-
-        :type root_device_name: string
-        :param root_device_name: The root device name (e.g. /dev/sdh)
-
-        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
-        :param block_device_map: A BlockDeviceMapping data structure
-            describing the EBS volumes associated with the Image.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type virtualization_type: string
-        :param virtualization_type: The virutalization_type of the image.
-            Valid choices are:
-            * paravirtual
-            * hvm
-
-        :type sriov_net_support: string
-        :param sriov_net_support: Advanced networking support.
-            Valid choices are:
-            * simple
-
-        :type snapshot_id: string
-        :param snapshot_id: A snapshot ID for the snapshot to be used
-            as root device for the image. Mutually exclusive with
-            block_device_map, requires root_device_name
-
-        :type delete_root_volume_on_termination: bool
-        :param delete_root_volume_on_termination: Whether to delete the root
-            volume of the image after instance termination. Only applies when
-            creating image from snapshot_id. Defaults to False.  Note that
-            leaving volumes behind after instance termination is not free.
-
-        :rtype: string
-        :return: The new image id
-        """
-        params = {}
-        if name:
-            params['Name'] = name
-        if description:
-            params['Description'] = description
-        if architecture:
-            params['Architecture'] = architecture
-        if kernel_id:
-            params['KernelId'] = kernel_id
-        if ramdisk_id:
-            params['RamdiskId'] = ramdisk_id
-        if image_location:
-            params['ImageLocation'] = image_location
-        if root_device_name:
-            params['RootDeviceName'] = root_device_name
-        if snapshot_id:
-            root_vol = BlockDeviceType(snapshot_id=snapshot_id,
-                delete_on_termination=delete_root_volume_on_termination)
-            block_device_map = BlockDeviceMapping()
-            block_device_map[root_device_name] = root_vol
-        if block_device_map:
-            block_device_map.ec2_build_list_params(params)
-        if dry_run:
-            params['DryRun'] = 'true'
-        if virtualization_type:
-            params['VirtualizationType'] = virtualization_type
-        if sriov_net_support:
-            params['SriovNetSupport'] = sriov_net_support
-
-        rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
-        image_id = getattr(rs, 'imageId', None)
-        return image_id
-
-    def deregister_image(self, image_id, delete_snapshot=False, dry_run=False):
-        """
-        Unregister an AMI.
-
-        :type image_id: string
-        :param image_id: the ID of the Image to unregister
-
-        :type delete_snapshot: bool
-        :param delete_snapshot: Set to True if we should delete the
-            snapshot associated with an EBS volume mounted at /dev/sda1
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        snapshot_id = None
-        if delete_snapshot:
-            image = self.get_image(image_id)
-            for key in image.block_device_mapping:
-                if key == "/dev/sda1":
-                    snapshot_id = image.block_device_mapping[key].snapshot_id
-                    break
-        params = {
-            'ImageId': image_id,
-        }
-        if dry_run:
-            params['DryRun'] = 'true'
-        result = self.get_status('DeregisterImage',
-                                 params, verb='POST')
-        if result and snapshot_id:
-            return result and self.delete_snapshot(snapshot_id)
-        return result
-
-    def create_image(self, instance_id, name,
-                     description=None, no_reboot=False,
-                     block_device_mapping=None, dry_run=False):
-        """
-        Will create an AMI from the instance in the running or stopped
-        state.
-
-        :type instance_id: string
-        :param instance_id: the ID of the instance to image.
-
-        :type name: string
-        :param name: The name of the new image
-
-        :type description: string
-        :param description: An optional human-readable string describing
-            the contents and purpose of the AMI.
-
-        :type no_reboot: bool
-        :param no_reboot: An optional flag indicating that the
-            bundling process should not attempt to shutdown the
-            instance before bundling.  If this flag is True, the
-            responsibility of maintaining file system integrity is
-            left to the owner of the instance.
-
-        :type block_device_mapping: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
-        :param block_device_mapping: A BlockDeviceMapping data structure
-            describing the EBS volumes associated with the Image.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: string
-        :return: The new image id
-        """
-        params = {'InstanceId': instance_id,
-                  'Name': name}
-        if description:
-            params['Description'] = description
-        if no_reboot:
-            params['NoReboot'] = 'true'
-        if block_device_mapping:
-            block_device_mapping.ec2_build_list_params(params)
-        if dry_run:
-            params['DryRun'] = 'true'
-        img = self.get_object('CreateImage', params, Image, verb='POST')
-        return img.id
-
-    # ImageAttribute methods
-
-    def get_image_attribute(self, image_id, attribute='launchPermission',
-                            dry_run=False):
-        """
-        Gets an attribute from an image.
-
-        :type image_id: string
-        :param image_id: The Amazon image id for which you want info about
-
-        :type attribute: string
-        :param attribute: The attribute you need information about.
-            Valid choices are:
-            * launchPermission
-            * productCodes
-            * blockDeviceMapping
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.image.ImageAttribute`
-        :return: An ImageAttribute object representing the value of the
-                 attribute requested
-        """
-        params = {'ImageId': image_id,
-                  'Attribute': attribute}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeImageAttribute', params,
-                               ImageAttribute, verb='POST')
-
-    def modify_image_attribute(self, image_id, attribute='launchPermission',
-                               operation='add', user_ids=None, groups=None,
-                               product_codes=None, dry_run=False):
-        """
-        Changes an attribute of an image.
-
-        :type image_id: string
-        :param image_id: The image id you wish to change
-
-        :type attribute: string
-        :param attribute: The attribute you wish to change
-
-        :type operation: string
-        :param operation: Either add or remove (this is required for changing
-            launchPermissions)
-
-        :type user_ids: list
-        :param user_ids: The Amazon IDs of users to add/remove attributes
-
-        :type groups: list
-        :param groups: The groups to add/remove attributes
-
-        :type product_codes: list
-        :param product_codes: Amazon DevPay product code. Currently only one
-            product code can be associated with an AMI. Once
-            set, the product code cannot be changed or reset.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'ImageId': image_id,
-                  'Attribute': attribute,
-                  'OperationType': operation}
-        if user_ids:
-            self.build_list_params(params, user_ids, 'UserId')
-        if groups:
-            self.build_list_params(params, groups, 'UserGroup')
-        if product_codes:
-            self.build_list_params(params, product_codes, 'ProductCode')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ModifyImageAttribute', params, verb='POST')
-
-    def reset_image_attribute(self, image_id, attribute='launchPermission',
-                              dry_run=False):
-        """
-        Resets an attribute of an AMI to its default value.
-
-        :type image_id: string
-        :param image_id: ID of the AMI for which an attribute will be described
-
-        :type attribute: string
-        :param attribute: The attribute to reset
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: Whether the operation succeeded or not
-        """
-        params = {'ImageId': image_id,
-                  'Attribute': attribute}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ResetImageAttribute', params, verb='POST')
-
-    # Instance methods
-
-    def get_all_instances(self, instance_ids=None, filters=None, dry_run=False,
-                          max_results=None):
-        """
-        Retrieve all the instance reservations associated with your account.
-
-        .. note::
-        This method's current behavior is deprecated in favor of
-        :meth:`get_all_reservations`.  A future major release will change
-        :meth:`get_all_instances` to return a list of
-        :class:`boto.ec2.instance.Instance` objects as its name suggests.
-        To obtain that behavior today, use :meth:`get_only_instances`.
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of instance IDs
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :rtype: list
-        :return: A list of  :class:`boto.ec2.instance.Reservation`
-
-        """
-        warnings.warn(('The current get_all_instances implementation will be '
-                       'replaced with get_all_reservations.'),
-                      PendingDeprecationWarning)
-        return self.get_all_reservations(instance_ids=instance_ids,
-                                         filters=filters, dry_run=dry_run,
-                                         max_results=max_results)
-
-    def get_only_instances(self, instance_ids=None, filters=None,
-                           dry_run=False, max_results=None):
-        # A future release should rename this method to get_all_instances
-        # and make get_only_instances an alias for that.
-        """
-        Retrieve all the instances associated with your account.
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of instance IDs
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :rtype: list
-        :return: A list of  :class:`boto.ec2.instance.Instance`
-        """
-        next_token = None
-        retval = []
-        while True:
-            reservations = self.get_all_reservations(instance_ids=instance_ids,
-                                                     filters=filters,
-                                                     dry_run=dry_run,
-                                                     max_results=max_results,
-                                                     next_token=next_token)
-            retval.extend([instance for reservation in reservations for
-                           instance in reservation.instances])
-            next_token = reservations.next_token
-            if not next_token:
-                break
-
-        return retval
-
-    def get_all_reservations(self, instance_ids=None, filters=None,
-                             dry_run=False, max_results=None, next_token=None):
-        """
-        Retrieve all the instance reservations associated with your account.
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of instance IDs
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :type next_token: str
-        :param next_token: A string specifying the next paginated set
-            of results to return.
-
-        :rtype: list
-        :return: A list of  :class:`boto.ec2.instance.Reservation`
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if filters:
-            if 'group-id' in filters:
-                gid = filters.get('group-id')
-                if not gid.startswith('sg-') or len(gid) != 11:
-                    warnings.warn(
-                        "The group-id filter now requires a security group "
-                        "identifier (sg-*) instead of a group name. To filter "
-                        "by group name use the 'group-name' filter instead.",
-                        UserWarning)
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        if max_results is not None:
-            params['MaxResults'] = max_results
-        if next_token:
-            params['NextToken'] = next_token
-        return self.get_list('DescribeInstances', params,
-                             [('item', Reservation)], verb='POST')
-
-    def get_all_instance_status(self, instance_ids=None,
-                                max_results=None, next_token=None,
-                                filters=None, dry_run=False,
-                                include_all_instances=False):
-        """
-        Retrieve all the instances in your account scheduled for maintenance.
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of instance IDs
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :type next_token: str
-        :param next_token: A string specifying the next paginated set
-            of results to return.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-            the results returned.  Filters are provided
-            in the form of a dictionary consisting of
-            filter names as the key and filter values
-            as the value.  The set of allowable filter
-            names/values is dependent on the request
-            being performed.  Check the EC2 API guide
-            for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type include_all_instances: bool
-        :param include_all_instances: Set to True if all
-            instances should be returned. (Only running
-            instances are included by default.)
-
-        :rtype: list
-        :return: A list of instances that have maintenance scheduled.
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if max_results:
-            params['MaxResults'] = max_results
-        if next_token:
-            params['NextToken'] = next_token
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        if include_all_instances:
-            params['IncludeAllInstances'] = 'true'
-        return self.get_object('DescribeInstanceStatus', params,
-                               InstanceStatusSet, verb='POST')
-
-    def run_instances(self, image_id, min_count=1, max_count=1,
-                      key_name=None, security_groups=None,
-                      user_data=None, addressing_type=None,
-                      instance_type='m1.small', placement=None,
-                      kernel_id=None, ramdisk_id=None,
-                      monitoring_enabled=False, subnet_id=None,
-                      block_device_map=None,
-                      disable_api_termination=False,
-                      instance_initiated_shutdown_behavior=None,
-                      private_ip_address=None,
-                      placement_group=None, client_token=None,
-                      security_group_ids=None,
-                      additional_info=None, instance_profile_name=None,
-                      instance_profile_arn=None, tenancy=None,
-                      ebs_optimized=False, network_interfaces=None,
-                      dry_run=False):
-        """
-        Runs an image on EC2.
-
-        :type image_id: string
-        :param image_id: The ID of the image to run.
-
-        :type min_count: int
-        :param min_count: The minimum number of instances to launch.
-
-        :type max_count: int
-        :param max_count: The maximum number of instances to launch.
-
-        :type key_name: string
-        :param key_name: The name of the key pair with which to
-            launch instances.
-
-        :type security_groups: list of strings
-        :param security_groups: The names of the EC2 classic security groups
-            with which to associate instances
-
-        :type user_data: string
-        :param user_data: The user data passed to the launched instances
-
-        :type instance_type: string
-        :param instance_type: The type of instance to run:
-
-            * t1.micro
-            * m1.small
-            * m1.medium
-            * m1.large
-            * m1.xlarge
-            * m3.medium
-            * m3.large
-            * m3.xlarge
-            * m3.2xlarge
-            * c1.medium
-            * c1.xlarge
-            * m2.xlarge
-            * m2.2xlarge
-            * m2.4xlarge
-            * cr1.8xlarge
-            * hi1.4xlarge
-            * hs1.8xlarge
-            * cc1.4xlarge
-            * cg1.4xlarge
-            * cc2.8xlarge
-            * g2.2xlarge
-            * c3.large
-            * c3.xlarge
-            * c3.2xlarge
-            * c3.4xlarge
-            * c3.8xlarge
-            * c4.large
-            * c4.xlarge
-            * c4.2xlarge
-            * c4.4xlarge
-            * c4.8xlarge
-            * i2.xlarge
-            * i2.2xlarge
-            * i2.4xlarge
-            * i2.8xlarge
-            * t2.micro
-            * t2.small
-            * t2.medium
-
-        :type placement: string
-        :param placement: The Availability Zone to launch the instance into.
-
-        :type kernel_id: string
-        :param kernel_id: The ID of the kernel with which to launch the
-            instances.
-
-        :type ramdisk_id: string
-        :param ramdisk_id: The ID of the RAM disk with which to launch the
-            instances.
-
-        :type monitoring_enabled: bool
-        :param monitoring_enabled: Enable detailed CloudWatch monitoring on
-            the instance.
-
-        :type subnet_id: string
-        :param subnet_id: The subnet ID within which to launch the instances
-            for VPC.
-
-        :type private_ip_address: string
-        :param private_ip_address: If you're using VPC, you can
-            optionally use this parameter to assign the instance a
-            specific available IP address from the subnet (e.g.,
-            10.0.0.25).
-
-        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
-        :param block_device_map: A BlockDeviceMapping data structure
-            describing the EBS volumes associated with the Image.
-
-        :type disable_api_termination: bool
-        :param disable_api_termination: If True, the instances will be locked
-            and will not be able to be terminated via the API.
-
-        :type instance_initiated_shutdown_behavior: string
-        :param instance_initiated_shutdown_behavior: Specifies whether the
-            instance stops or terminates on instance-initiated shutdown.
-            Valid values are:
-
-            * stop
-            * terminate
-
-        :type placement_group: string
-        :param placement_group: If specified, this is the name of the placement
-            group in which the instance(s) will be launched.
-
-        :type client_token: string
-        :param client_token: Unique, case-sensitive identifier you provide
-            to ensure idempotency of the request. Maximum 64 ASCII characters.
-
-        :type security_group_ids: list of strings
-        :param security_group_ids: The ID of the VPC security groups with
-            which to associate instances.
-
-        :type additional_info: string
-        :param additional_info: Specifies additional information to make
-            available to the instance(s).
-
-        :type tenancy: string
-        :param tenancy: The tenancy of the instance you want to
-            launch. An instance with a tenancy of 'dedicated' runs on
-            single-tenant hardware and can only be launched into a
-            VPC. Valid values are:"default" or "dedicated".
-            NOTE: To use dedicated tenancy you MUST specify a VPC
-            subnet-ID as well.
-
-        :type instance_profile_arn: string
-        :param instance_profile_arn: The Amazon resource name (ARN) of
-            the IAM Instance Profile (IIP) to associate with the instances.
-
-        :type instance_profile_name: string
-        :param instance_profile_name: The name of
-            the IAM Instance Profile (IIP) to associate with the instances.
-
-        :type ebs_optimized: bool
-        :param ebs_optimized: Whether the instance is optimized for
-            EBS I/O.  This optimization provides dedicated throughput
-            to Amazon EBS and an optimized configuration stack to
-            provide optimal EBS I/O performance.  This optimization
-            isn't available with all instance types.
-
-        :type network_interfaces: :class:`boto.ec2.networkinterface.NetworkInterfaceCollection`
-        :param network_interfaces: A NetworkInterfaceCollection data
-            structure containing the ENI specifications for the instance.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: Reservation
-        :return: The :class:`boto.ec2.instance.Reservation` associated with
-                 the request for machines
-        """
-        params = {'ImageId': image_id,
-                  'MinCount': min_count,
-                  'MaxCount': max_count}
-        if key_name:
-            params['KeyName'] = key_name
-        if security_group_ids:
-            l = []
-            for group in security_group_ids:
-                if isinstance(group, SecurityGroup):
-                    l.append(group.id)
-                else:
-                    l.append(group)
-            self.build_list_params(params, l, 'SecurityGroupId')
-        if security_groups:
-            l = []
-            for group in security_groups:
-                if isinstance(group, SecurityGroup):
-                    l.append(group.name)
-                else:
-                    l.append(group)
-            self.build_list_params(params, l, 'SecurityGroup')
-        if user_data:
-            if isinstance(user_data, six.text_type):
-                user_data = user_data.encode('utf-8')
-            params['UserData'] = base64.b64encode(user_data).decode('utf-8')
-        if addressing_type:
-            params['AddressingType'] = addressing_type
-        if instance_type:
-            params['InstanceType'] = instance_type
-        if placement:
-            params['Placement.AvailabilityZone'] = placement
-        if placement_group:
-            params['Placement.GroupName'] = placement_group
-        if tenancy:
-            params['Placement.Tenancy'] = tenancy
-        if kernel_id:
-            params['KernelId'] = kernel_id
-        if ramdisk_id:
-            params['RamdiskId'] = ramdisk_id
-        if monitoring_enabled:
-            params['Monitoring.Enabled'] = 'true'
-        if subnet_id:
-            params['SubnetId'] = subnet_id
-        if private_ip_address:
-            params['PrivateIpAddress'] = private_ip_address
-        if block_device_map:
-            block_device_map.ec2_build_list_params(params)
-        if disable_api_termination:
-            params['DisableApiTermination'] = 'true'
-        if instance_initiated_shutdown_behavior:
-            val = instance_initiated_shutdown_behavior
-            params['InstanceInitiatedShutdownBehavior'] = val
-        if client_token:
-            params['ClientToken'] = client_token
-        if additional_info:
-            params['AdditionalInfo'] = additional_info
-        if instance_profile_name:
-            params['IamInstanceProfile.Name'] = instance_profile_name
-        if instance_profile_arn:
-            params['IamInstanceProfile.Arn'] = instance_profile_arn
-        if ebs_optimized:
-            params['EbsOptimized'] = 'true'
-        if network_interfaces:
-            network_interfaces.build_list_params(params)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('RunInstances', params, Reservation,
-                               verb='POST')
-
-    def terminate_instances(self, instance_ids=None, dry_run=False):
-        """
-        Terminate the instances specified
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of the Instance IDs to terminate
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of the instances terminated
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('TerminateInstances', params,
-                             [('item', Instance)], verb='POST')
-
-    def stop_instances(self, instance_ids=None, force=False, dry_run=False):
-        """
-        Stop the instances specified
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of the Instance IDs to stop
-
-        :type force: bool
-        :param force: Forces the instance to stop
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of the instances stopped
-        """
-        params = {}
-        if force:
-            params['Force'] = 'true'
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('StopInstances', params,
-                             [('item', Instance)], verb='POST')
-
-    def start_instances(self, instance_ids=None, dry_run=False):
-        """
-        Start the instances specified
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of the Instance IDs to start
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of the instances started
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('StartInstances', params,
-                             [('item', Instance)], verb='POST')
-
-    def get_console_output(self, instance_id, dry_run=False):
-        """
-        Retrieves the console output for the specified instance.
-
-        :type instance_id: string
-        :param instance_id: The instance ID of a running instance on the cloud.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.instance.ConsoleOutput`
-        :return: The console output as a ConsoleOutput object
-        """
-        params = {}
-        self.build_list_params(params, [instance_id], 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('GetConsoleOutput', params,
-                               ConsoleOutput, verb='POST')
-
-    def reboot_instances(self, instance_ids=None, dry_run=False):
-        """
-        Reboot the specified instances.
-
-        :type instance_ids: list
-        :param instance_ids: The instances to terminate and reboot
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('RebootInstances', params)
-
-    def confirm_product_instance(self, product_code, instance_id,
-                                 dry_run=False):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'ProductCode': product_code,
-                  'InstanceId': instance_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        rs = self.get_object('ConfirmProductInstance', params,
-                             ResultSet, verb='POST')
-        return (rs.status, rs.ownerId)
-
-    # InstanceAttribute methods
-
-    def get_instance_attribute(self, instance_id, attribute, dry_run=False):
-        """
-        Gets an attribute from an instance.
-
-        :type instance_id: string
-        :param instance_id: The Amazon id of the instance
-
-        :type attribute: string
-        :param attribute: The attribute you need information about
-            Valid choices are:
-
-            * instanceType
-            * kernel
-            * ramdisk
-            * userData
-            * disableApiTermination
-            * instanceInitiatedShutdownBehavior
-            * rootDeviceName
-            * blockDeviceMapping
-            * productCodes
-            * sourceDestCheck
-            * groupSet
-            * ebsOptimized
-            * sriovNetSupport
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.image.InstanceAttribute`
-        :return: An InstanceAttribute object representing the value of the
-                 attribute requested
-        """
-        params = {'InstanceId': instance_id}
-        if attribute:
-            params['Attribute'] = attribute
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeInstanceAttribute', params,
-                               InstanceAttribute, verb='POST')
-
-    def modify_network_interface_attribute(self, interface_id, attr, value,
-                                           attachment_id=None, dry_run=False):
-        """
-        Changes an attribute of a network interface.
-
-        :type interface_id: string
-        :param interface_id: The interface id. Looks like 'eni-xxxxxxxx'
-
-        :type attr: string
-        :param attr: The attribute you wish to change.
-
-            Learn more at http://docs.aws.amazon.com/AWSEC2/latest/API\
-            Reference/ApiReference-query-ModifyNetworkInterfaceAttribute.html
-
-            * description - Textual description of interface
-            * groupSet - List of security group ids or group objects
-            * sourceDestCheck - Boolean
-            * deleteOnTermination - Boolean. Must also specify attachment_id
-
-        :type value: string
-        :param value: The new value for the attribute
-
-        :rtype: bool
-        :return: Whether the operation succeeded or not
-
-        :type attachment_id: string
-        :param attachment_id: If you're modifying DeleteOnTermination you must
-            specify the attachment_id.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        bool_reqs = (
-            'deleteontermination',
-            'sourcedestcheck',
-        )
-        if attr.lower() in bool_reqs:
-            if isinstance(value, bool):
-                if value:
-                    value = 'true'
-                else:
-                    value = 'false'
-            elif value not in ['true', 'false']:
-                raise ValueError('%s must be a boolean, "true", or "false"!'
-                                 % attr)
-
-        params = {'NetworkInterfaceId': interface_id}
-
-        # groupSet is handled differently from other arguments
-        if attr.lower() == 'groupset':
-            for idx, sg in enumerate(value):
-                if isinstance(sg, SecurityGroup):
-                    sg = sg.id
-                params['SecurityGroupId.%s' % (idx + 1)] = sg
-        elif attr.lower() == 'description':
-            params['Description.Value'] = value
-        elif attr.lower() == 'sourcedestcheck':
-            params['SourceDestCheck.Value'] = value
-        elif attr.lower() == 'deleteontermination':
-            params['Attachment.DeleteOnTermination'] = value
-            if not attachment_id:
-                raise ValueError('You must also specify an attachment_id')
-            params['Attachment.AttachmentId'] = attachment_id
-        else:
-            raise ValueError('Unknown attribute "%s"' % (attr,))
-
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status(
-            'ModifyNetworkInterfaceAttribute', params, verb='POST')
-
-    def modify_instance_attribute(self, instance_id, attribute, value,
-                                  dry_run=False):
-        """
-        Changes an attribute of an instance
-
-        :type instance_id: string
-        :param instance_id: The instance id you wish to change
-
-        :type attribute: string
-        :param attribute: The attribute you wish to change.
-
-            * instanceType - A valid instance type (m1.small)
-            * kernel - Kernel ID (None)
-            * ramdisk - Ramdisk ID (None)
-            * userData - Base64 encoded String (None)
-            * disableApiTermination - Boolean (true)
-            * instanceInitiatedShutdownBehavior - stop|terminate
-            * blockDeviceMapping - List of strings - ie: ['/dev/sda=false']
-            * sourceDestCheck - Boolean (true)
-            * groupSet - Set of Security Groups or IDs
-            * ebsOptimized - Boolean (false)
-            * sriovNetSupport - String - ie: 'simple'
-
-        :type value: string
-        :param value: The new value for the attribute
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: Whether the operation succeeded or not
-        """
-        # Allow a bool to be passed in for value of disableApiTermination
-        bool_reqs = ('disableapitermination',
-                     'sourcedestcheck',
-                     'ebsoptimized')
-        if attribute.lower() in bool_reqs:
-            if isinstance(value, bool):
-                if value:
-                    value = 'true'
-                else:
-                    value = 'false'
-
-        params = {'InstanceId': instance_id}
-
-        # groupSet is handled differently from other arguments
-        if attribute.lower() == 'groupset':
-            for idx, sg in enumerate(value):
-                if isinstance(sg, SecurityGroup):
-                    sg = sg.id
-                params['GroupId.%s' % (idx + 1)] = sg
-        elif attribute.lower() == 'blockdevicemapping':
-            for idx, kv in enumerate(value):
-                dev_name, _, flag = kv.partition('=')
-                pre = 'BlockDeviceMapping.%d' % (idx + 1)
-                params['%s.DeviceName' % pre] = dev_name
-                params['%s.Ebs.DeleteOnTermination' % pre] = flag or 'true'
-        else:
-            # for backwards compatibility handle lowercase first letter
-            attribute = attribute[0].upper() + attribute[1:]
-            params['%s.Value' % attribute] = value
-
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ModifyInstanceAttribute', params, verb='POST')
-
-    def reset_instance_attribute(self, instance_id, attribute, dry_run=False):
-        """
-        Resets an attribute of an instance to its default value.
-
-        :type instance_id: string
-        :param instance_id: ID of the instance
-
-        :type attribute: string
-        :param attribute: The attribute to reset. Valid values are:
-                          kernel|ramdisk
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: Whether the operation succeeded or not
-        """
-        params = {'InstanceId': instance_id,
-                  'Attribute': attribute}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ResetInstanceAttribute', params, verb='POST')
-
-    # Spot Instances
-
-    def get_all_spot_instance_requests(self, request_ids=None,
-                                       filters=None, dry_run=False):
-        """
-        Retrieve all the spot instances requests associated with your account.
-
-        :type request_ids: list
-        :param request_ids: A list of strings of spot instance request IDs
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of
-                 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
-        """
-        params = {}
-        if request_ids:
-            self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
-        if filters:
-            if 'launch.group-id' in filters:
-                lgid = filters.get('launch.group-id')
-                if not lgid.startswith('sg-') or len(lgid) != 11:
-                    warnings.warn(
-                        "The 'launch.group-id' filter now requires a security "
-                        "group id (sg-*) and no longer supports filtering by "
-                        "group name. Please update your filters accordingly.",
-                        UserWarning)
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeSpotInstanceRequests', params,
-                             [('item', SpotInstanceRequest)], verb='POST')
-
-    def get_spot_price_history(self, start_time=None, end_time=None,
-                               instance_type=None, product_description=None,
-                               availability_zone=None, dry_run=False,
-                               max_results=None, next_token=None,
-                               filters=None):
-        """
-        Retrieve the recent history of spot instances pricing.
-
-        :type start_time: str
-        :param start_time: An indication of how far back to provide price
-            changes for. An ISO8601 DateTime string.
-
-        :type end_time: str
-        :param end_time: An indication of how far forward to provide price
-            changes for.  An ISO8601 DateTime string.
-
-        :type instance_type: str
-        :param instance_type: Filter responses to a particular instance type.
-
-        :type product_description: str
-        :param product_description: Filter responses to a particular platform.
-            Valid values are currently:
-
-            * Linux/UNIX
-            * SUSE Linux
-            * Windows
-            * Linux/UNIX (Amazon VPC)
-            * SUSE Linux (Amazon VPC)
-            * Windows (Amazon VPC)
-
-        :type availability_zone: str
-        :param availability_zone: The availability zone for which prices
-            should be returned.  If not specified, data for all
-            availability zones will be returned.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated items
-            per response.
-
-        :type next_token: str
-        :param next_token: The next set of rows to return.  This should
-            be the value of the ``next_token`` attribute from a previous
-            call to ``get_spot_price_history``.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :rtype: list
-        :return: A list tuples containing price and timestamp.
-        """
-        params = {}
-        if start_time:
-            params['StartTime'] = start_time
-        if end_time:
-            params['EndTime'] = end_time
-        if instance_type:
-            params['InstanceType'] = instance_type
-        if product_description:
-            params['ProductDescription'] = product_description
-        if availability_zone:
-            params['AvailabilityZone'] = availability_zone
-        if dry_run:
-            params['DryRun'] = 'true'
-        if max_results is not None:
-            params['MaxResults'] = max_results
-        if next_token:
-            params['NextToken'] = next_token
-        if filters:
-            self.build_filter_params(params, filters)
-        return self.get_list('DescribeSpotPriceHistory', params,
-                             [('item', SpotPriceHistory)], verb='POST')
-
-    def request_spot_instances(self, price, image_id, count=1, type='one-time',
-                               valid_from=None, valid_until=None,
-                               launch_group=None, availability_zone_group=None,
-                               key_name=None, security_groups=None,
-                               user_data=None, addressing_type=None,
-                               instance_type='m1.small', placement=None,
-                               kernel_id=None, ramdisk_id=None,
-                               monitoring_enabled=False, subnet_id=None,
-                               placement_group=None,
-                               block_device_map=None,
-                               instance_profile_arn=None,
-                               instance_profile_name=None,
-                               security_group_ids=None,
-                               ebs_optimized=False,
-                               network_interfaces=None, dry_run=False):
-        """
-        Request instances on the spot market at a particular price.
-
-        :type price: str
-        :param price: The maximum price of your bid
-
-        :type image_id: string
-        :param image_id: The ID of the image to run
-
-        :type count: int
-        :param count: The of instances to requested
-
-        :type type: str
-        :param type: Type of request. Can be 'one-time' or 'persistent'.
-                     Default is one-time.
-
-        :type valid_from: str
-        :param valid_from: Start date of the request. An ISO8601 time string.
-
-        :type valid_until: str
-        :param valid_until: End date of the request.  An ISO8601 time string.
-
-        :type launch_group: str
-        :param launch_group: If supplied, all requests will be fulfilled
-            as a group.
-
-        :type availability_zone_group: str
-        :param availability_zone_group: If supplied, all requests will be
-            fulfilled within a single availability zone.
-
-        :type key_name: string
-        :param key_name: The name of the key pair with which to
-            launch instances
-
-        :type security_groups: list of strings
-        :param security_groups: The names of the security groups with which to
-            associate instances
-
-        :type user_data: string
-        :param user_data: The user data passed to the launched instances
-
-        :type instance_type: string
-        :param instance_type: The type of instance to run:
-
-            * t1.micro
-            * m1.small
-            * m1.medium
-            * m1.large
-            * m1.xlarge
-            * m3.medium
-            * m3.large
-            * m3.xlarge
-            * m3.2xlarge
-            * c1.medium
-            * c1.xlarge
-            * m2.xlarge
-            * m2.2xlarge
-            * m2.4xlarge
-            * cr1.8xlarge
-            * hi1.4xlarge
-            * hs1.8xlarge
-            * cc1.4xlarge
-            * cg1.4xlarge
-            * cc2.8xlarge
-            * g2.2xlarge
-            * c3.large
-            * c3.xlarge
-            * c3.2xlarge
-            * c3.4xlarge
-            * c3.8xlarge
-            * c4.large
-            * c4.xlarge
-            * c4.2xlarge
-            * c4.4xlarge
-            * c4.8xlarge
-            * i2.xlarge
-            * i2.2xlarge
-            * i2.4xlarge
-            * i2.8xlarge
-            * t2.micro
-            * t2.small
-            * t2.medium
-
-        :type placement: string
-        :param placement: The availability zone in which to launch
-            the instances
-
-        :type kernel_id: string
-        :param kernel_id: The ID of the kernel with which to launch the
-            instances
-
-        :type ramdisk_id: string
-        :param ramdisk_id: The ID of the RAM disk with which to launch the
-            instances
-
-        :type monitoring_enabled: bool
-        :param monitoring_enabled: Enable detailed CloudWatch monitoring on
-            the instance.
-
-        :type subnet_id: string
-        :param subnet_id: The subnet ID within which to launch the instances
-            for VPC.
-
-        :type placement_group: string
-        :param placement_group: If specified, this is the name of the placement
-            group in which the instance(s) will be launched.
-
-        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
-        :param block_device_map: A BlockDeviceMapping data structure
-            describing the EBS volumes associated with the Image.
-
-        :type security_group_ids: list of strings
-        :param security_group_ids: The ID of the VPC security groups with
-            which to associate instances.
-
-        :type instance_profile_arn: string
-        :param instance_profile_arn: The Amazon resource name (ARN) of
-            the IAM Instance Profile (IIP) to associate with the instances.
-
-        :type instance_profile_name: string
-        :param instance_profile_name: The name of
-            the IAM Instance Profile (IIP) to associate with the instances.
-
-        :type ebs_optimized: bool
-        :param ebs_optimized: Whether the instance is optimized for
-            EBS I/O.  This optimization provides dedicated throughput
-            to Amazon EBS and an optimized configuration stack to
-            provide optimal EBS I/O performance.  This optimization
-            isn't available with all instance types.
-
-        :type network_interfaces: list
-        :param network_interfaces: A list of
-            :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: Reservation
-        :return: The :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
-                 associated with the request for machines
-        """
-        ls = 'LaunchSpecification'
-        params = {'%s.ImageId' % ls: image_id,
-                  'Type': type,
-                  'SpotPrice': price}
-        if count:
-            params['InstanceCount'] = count
-        if valid_from:
-            params['ValidFrom'] = valid_from
-        if valid_until:
-            params['ValidUntil'] = valid_until
-        if launch_group:
-            params['LaunchGroup'] = launch_group
-        if availability_zone_group:
-            params['AvailabilityZoneGroup'] = availability_zone_group
-        if key_name:
-            params['%s.KeyName' % ls] = key_name
-        if security_group_ids:
-            l = []
-            for group in security_group_ids:
-                if isinstance(group, SecurityGroup):
-                    l.append(group.id)
-                else:
-                    l.append(group)
-            self.build_list_params(params, l,
-                                   '%s.SecurityGroupId' % ls)
-        if security_groups:
-            l = []
-            for group in security_groups:
-                if isinstance(group, SecurityGroup):
-                    l.append(group.name)
-                else:
-                    l.append(group)
-            self.build_list_params(params, l, '%s.SecurityGroup' % ls)
-        if user_data:
-            params['%s.UserData' % ls] = base64.b64encode(user_data)
-        if addressing_type:
-            params['%s.AddressingType' % ls] = addressing_type
-        if instance_type:
-            params['%s.InstanceType' % ls] = instance_type
-        if placement:
-            params['%s.Placement.AvailabilityZone' % ls] = placement
-        if kernel_id:
-            params['%s.KernelId' % ls] = kernel_id
-        if ramdisk_id:
-            params['%s.RamdiskId' % ls] = ramdisk_id
-        if monitoring_enabled:
-            params['%s.Monitoring.Enabled' % ls] = 'true'
-        if subnet_id:
-            params['%s.SubnetId' % ls] = subnet_id
-        if placement_group:
-            params['%s.Placement.GroupName' % ls] = placement_group
-        if block_device_map:
-            block_device_map.ec2_build_list_params(params, '%s.' % ls)
-        if instance_profile_name:
-            params['%s.IamInstanceProfile.Name' % ls] = instance_profile_name
-        if instance_profile_arn:
-            params['%s.IamInstanceProfile.Arn' % ls] = instance_profile_arn
-        if ebs_optimized:
-            params['%s.EbsOptimized' % ls] = 'true'
-        if network_interfaces:
-            network_interfaces.build_list_params(params, prefix=ls + '.')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('RequestSpotInstances', params,
-                             [('item', SpotInstanceRequest)],
-                             verb='POST')
-
-    def cancel_spot_instance_requests(self, request_ids, dry_run=False):
-        """
-        Cancel the specified Spot Instance Requests.
-
-        :type request_ids: list
-        :param request_ids: A list of strings of the Request IDs to terminate
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of the instances terminated
-        """
-        params = {}
-        if request_ids:
-            self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('CancelSpotInstanceRequests', params,
-                             [('item', SpotInstanceRequest)], verb='POST')
-
-    def get_spot_datafeed_subscription(self, dry_run=False):
-        """
-        Return the current spot instance data feed subscription
-        associated with this account, if any.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
-        :return: The datafeed subscription object or None
-        """
-        params = {}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeSpotDatafeedSubscription',
-                               params, SpotDatafeedSubscription, verb='POST')
-
-    def create_spot_datafeed_subscription(self, bucket, prefix, dry_run=False):
-        """
-        Create a spot instance datafeed subscription for this account.
-
-        :type bucket: str or unicode
-        :param bucket: The name of the bucket where spot instance data
-                       will be written.  The account issuing this request
-                       must have FULL_CONTROL access to the bucket
-                       specified in the request.
-
-        :type prefix: str or unicode
-        :param prefix: An optional prefix that will be pre-pended to all
-                       data files written to the bucket.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
-        :return: The datafeed subscription object or None
-        """
-        params = {'Bucket': bucket}
-        if prefix:
-            params['Prefix'] = prefix
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CreateSpotDatafeedSubscription',
-                               params, SpotDatafeedSubscription, verb='POST')
-
-    def delete_spot_datafeed_subscription(self, dry_run=False):
-        """
-        Delete the current spot instance data feed subscription
-        associated with this account
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteSpotDatafeedSubscription',
-                               params, verb='POST')
-
-    # Zone methods
-
-    def get_all_zones(self, zones=None, filters=None, dry_run=False):
-        """
-        Get all Availability Zones associated with the current region.
-
-        :type zones: list
-        :param zones: Optional list of zones.  If this list is present,
-                      only the Zones associated with these zone names
-                      will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.zone.Zone`
-        :return: The requested Zone objects
-        """
-        params = {}
-        if zones:
-            self.build_list_params(params, zones, 'ZoneName')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeAvailabilityZones', params,
-                             [('item', Zone)], verb='POST')
-
-    # Address methods
-
-    def get_all_addresses(self, addresses=None, filters=None,
-                          allocation_ids=None, dry_run=False):
-        """
-        Get all EIP's associated with the current credentials.
-
-        :type addresses: list
-        :param addresses: Optional list of addresses.  If this list is present,
-                           only the Addresses associated with these addresses
-                           will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type allocation_ids: list
-        :param allocation_ids: Optional list of allocation IDs.  If this list is
-                           present, only the Addresses associated with the given
-                           allocation IDs will be returned.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.address.Address`
-        :return: The requested Address objects
-        """
-        params = {}
-        if addresses:
-            self.build_list_params(params, addresses, 'PublicIp')
-        if allocation_ids:
-            self.build_list_params(params, allocation_ids, 'AllocationId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeAddresses', params, [('item', Address)], verb='POST')
-
-    def allocate_address(self, domain=None, dry_run=False):
-        """
-        Allocate a new Elastic IP address and associate it with your account.
-
-        :type domain: string
-        :param domain: Optional string. If domain is set to "vpc" the address
-            will be allocated to VPC . Will return address object with
-            allocation_id.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.address.Address`
-        :return: The newly allocated Address
-        """
-        params = {}
-
-        if domain is not None:
-            params['Domain'] = domain
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_object('AllocateAddress', params, Address, verb='POST')
-
-    def assign_private_ip_addresses(self, network_interface_id=None,
-                                    private_ip_addresses=None,
-                                    secondary_private_ip_address_count=None,
-                                    allow_reassignment=False, dry_run=False):
-        """
-        Assigns one or more secondary private IP addresses to a network
-        interface in Amazon VPC.
-
-        :type network_interface_id: string
-        :param network_interface_id: The network interface to which the IP
-            address will be assigned.
-
-        :type private_ip_addresses: list
-        :param private_ip_addresses: Assigns the specified IP addresses as
-            secondary IP addresses to the network interface.
-
-        :type secondary_private_ip_address_count: int
-        :param secondary_private_ip_address_count: The number of secondary IP
-            addresses to assign to the network interface. You cannot specify
-            this parameter when also specifying private_ip_addresses.
-
-        :type allow_reassignment: bool
-        :param allow_reassignment: Specifies whether to allow an IP address
-            that is already assigned to another network interface or instance
-            to be reassigned to the specified network interface.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {}
-
-        if network_interface_id is not None:
-            params['NetworkInterfaceId'] = network_interface_id
-
-        if private_ip_addresses is not None:
-            self.build_list_params(params, private_ip_addresses,
-                                   'PrivateIpAddress')
-        elif secondary_private_ip_address_count is not None:
-            params['SecondaryPrivateIpAddressCount'] = \
-                secondary_private_ip_address_count
-
-        if allow_reassignment:
-            params['AllowReassignment'] = 'true'
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('AssignPrivateIpAddresses', params, verb='POST')
-
-    def _associate_address(self, status, instance_id=None, public_ip=None,
-                           allocation_id=None, network_interface_id=None,
-                           private_ip_address=None, allow_reassociation=False,
-                           dry_run=False):
-        params = {}
-        if instance_id is not None:
-                params['InstanceId'] = instance_id
-        elif network_interface_id is not None:
-                params['NetworkInterfaceId'] = network_interface_id
-
-        # Allocation id trumps public ip in order to associate with VPCs
-        if allocation_id is not None:
-            params['AllocationId'] = allocation_id
-        elif public_ip is not None:
-            params['PublicIp'] = public_ip
-
-        if private_ip_address is not None:
-            params['PrivateIpAddress'] = private_ip_address
-
-        if allow_reassociation:
-            params['AllowReassociation'] = 'true'
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        if status:
-            return self.get_status('AssociateAddress', params, verb='POST')
-        else:
-            return self.get_object('AssociateAddress', params, Address,
-                                   verb='POST')
-
-    def associate_address(self, instance_id=None, public_ip=None,
-                          allocation_id=None, network_interface_id=None,
-                          private_ip_address=None, allow_reassociation=False,
-                          dry_run=False):
-        """
-        Associate an Elastic IP address with a currently running instance.
-        This requires one of ``public_ip`` or ``allocation_id`` depending
-        on if you're associating a VPC address or a plain EC2 address.
-
-        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
-        as EC2 expects a single parameter and if ``public_ip`` is passed boto
-        will preference that instead of ``allocation_id``.
-
-        :type instance_id: string
-        :param instance_id: The ID of the instance
-
-        :type public_ip: string
-        :param public_ip: The public IP address for EC2 based allocations.
-
-        :type allocation_id: string
-        :param allocation_id: The allocation ID for a VPC-based elastic IP.
-
-        :type network_interface_id: string
-        :param network_interface_id: The network interface ID to which
-            elastic IP is to be assigned to
-
-        :type private_ip_address: string
-        :param private_ip_address: The primary or secondary private IP address
-            to associate with the Elastic IP address.
-
-        :type allow_reassociation: bool
-        :param allow_reassociation: Specify this option to allow an Elastic IP
-            address that is already associated with another network interface
-            or instance to be re-associated with the specified instance or
-            interface.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        return self._associate_address(True, instance_id=instance_id,
-            public_ip=public_ip, allocation_id=allocation_id,
-            network_interface_id=network_interface_id,
-            private_ip_address=private_ip_address,
-            allow_reassociation=allow_reassociation, dry_run=dry_run)
-
-    def associate_address_object(self, instance_id=None, public_ip=None,
-                                 allocation_id=None, network_interface_id=None,
-                                 private_ip_address=None, allow_reassociation=False,
-                                 dry_run=False):
-        """
-        Associate an Elastic IP address with a currently running instance.
-        This requires one of ``public_ip`` or ``allocation_id`` depending
-        on if you're associating a VPC address or a plain EC2 address.
-
-        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
-        as EC2 expects a single parameter and if ``public_ip`` is passed boto
-        will preference that instead of ``allocation_id``.
-
-        :type instance_id: string
-        :param instance_id: The ID of the instance
-
-        :type public_ip: string
-        :param public_ip: The public IP address for EC2 based allocations.
-
-        :type allocation_id: string
-        :param allocation_id: The allocation ID for a VPC-based elastic IP.
-
-        :type network_interface_id: string
-        :param network_interface_id: The network interface ID to which
-            elastic IP is to be assigned to
-
-        :type private_ip_address: string
-        :param private_ip_address: The primary or secondary private IP address
-            to associate with the Elastic IP address.
-
-        :type allow_reassociation: bool
-        :param allow_reassociation: Specify this option to allow an Elastic IP
-            address that is already associated with another network interface
-            or instance to be re-associated with the specified instance or
-            interface.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: class:`boto.ec2.address.Address`
-        :return: The associated address instance
-        """
-        return self._associate_address(False, instance_id=instance_id,
-            public_ip=public_ip, allocation_id=allocation_id,
-            network_interface_id=network_interface_id,
-            private_ip_address=private_ip_address,
-            allow_reassociation=allow_reassociation, dry_run=dry_run)
-
-    def disassociate_address(self, public_ip=None, association_id=None,
-                             dry_run=False):
-        """
-        Disassociate an Elastic IP address from a currently running instance.
-
-        :type public_ip: string
-        :param public_ip: The public IP address for EC2 elastic IPs.
-
-        :type association_id: string
-        :param association_id: The association ID for a VPC based elastic ip.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {}
-
-        # If there is an association id it trumps public ip
-        # in order to successfully dissassociate with a VPC elastic ip
-        if association_id is not None:
-            params['AssociationId'] = association_id
-        elif public_ip is not None:
-            params['PublicIp'] = public_ip
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('DisassociateAddress', params, verb='POST')
-
-    def release_address(self, public_ip=None, allocation_id=None,
-                        dry_run=False):
-        """
-        Free up an Elastic IP address.  Pass a public IP address to
-        release an EC2 Elastic IP address and an AllocationId to
-        release a VPC Elastic IP address.  You should only pass
-        one value.
-
-        This requires one of ``public_ip`` or ``allocation_id`` depending
-        on if you're associating a VPC address or a plain EC2 address.
-
-        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
-        as EC2 expects a single parameter and if ``public_ip`` is passed boto
-        will preference that instead of ``allocation_id``.
-
-        :type public_ip: string
-        :param public_ip: The public IP address for EC2 elastic IPs.
-
-        :type allocation_id: string
-        :param allocation_id: The Allocation ID for VPC elastic IPs.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {}
-
-        if public_ip is not None:
-            params['PublicIp'] = public_ip
-        elif allocation_id is not None:
-            params['AllocationId'] = allocation_id
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('ReleaseAddress', params, verb='POST')
-
-    def unassign_private_ip_addresses(self, network_interface_id=None,
-                                      private_ip_addresses=None, dry_run=False):
-        """
-        Unassigns one or more secondary private IP addresses from a network
-        interface in Amazon VPC.
-
-        :type network_interface_id: string
-        :param network_interface_id: The network interface from which the
-            secondary private IP address will be unassigned.
-
-        :type private_ip_addresses: list
-        :param private_ip_addresses: Specifies the secondary private IP
-            addresses that you want to unassign from the network interface.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {}
-
-        if network_interface_id is not None:
-            params['NetworkInterfaceId'] = network_interface_id
-
-        if private_ip_addresses is not None:
-            self.build_list_params(params, private_ip_addresses,
-                                   'PrivateIpAddress')
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('UnassignPrivateIpAddresses', params,
-                               verb='POST')
-
-    # Volume methods
-
-    def get_all_volumes(self, volume_ids=None, filters=None, dry_run=False):
-        """
-        Get all Volumes associated with the current credentials.
-
-        :type volume_ids: list
-        :param volume_ids: Optional list of volume ids.  If this list
-                           is present, only the volumes associated with
-                           these volume ids will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.volume.Volume`
-        :return: The requested Volume objects
-        """
-        params = {}
-        if volume_ids:
-            self.build_list_params(params, volume_ids, 'VolumeId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeVolumes', params,
-                             [('item', Volume)], verb='POST')
-
-    def get_all_volume_status(self, volume_ids=None,
-                              max_results=None, next_token=None,
-                              filters=None, dry_run=False):
-        """
-        Retrieve the status of one or more volumes.
-
-        :type volume_ids: list
-        :param volume_ids: A list of strings of volume IDs
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :type next_token: str
-        :param next_token: A string specifying the next paginated set
-            of results to return.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-            the results returned.  Filters are provided
-            in the form of a dictionary consisting of
-            filter names as the key and filter values
-            as the value.  The set of allowable filter
-            names/values is dependent on the request
-            being performed.  Check the EC2 API guide
-            for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of volume status.
-        """
-        params = {}
-        if volume_ids:
-            self.build_list_params(params, volume_ids, 'VolumeId')
-        if max_results:
-            params['MaxResults'] = max_results
-        if next_token:
-            params['NextToken'] = next_token
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeVolumeStatus', params,
-                               VolumeStatusSet, verb='POST')
-
-    def enable_volume_io(self, volume_id, dry_run=False):
-        """
-        Enables I/O operations for a volume that had I/O operations
-        disabled because the data on the volume was potentially inconsistent.
-
-        :type volume_id: str
-        :param volume_id: The ID of the volume.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {'VolumeId': volume_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('EnableVolumeIO', params, verb='POST')
-
-    def get_volume_attribute(self, volume_id,
-                             attribute='autoEnableIO', dry_run=False):
-        """
-        Describes attribute of the volume.
-
-        :type volume_id: str
-        :param volume_id: The ID of the volume.
-
-        :type attribute: str
-        :param attribute: The requested attribute.  Valid values are:
-
-            * autoEnableIO
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.volume.VolumeAttribute`
-        :return: The requested Volume attribute
-        """
-        params = {'VolumeId': volume_id, 'Attribute': attribute}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeVolumeAttribute', params,
-                               VolumeAttribute, verb='POST')
-
-    def modify_volume_attribute(self, volume_id, attribute, new_value,
-                                dry_run=False):
-        """
-        Changes an attribute of an Volume.
-
-        :type volume_id: string
-        :param volume_id: The volume id you wish to change
-
-        :type attribute: string
-        :param attribute: The attribute you wish to change.  Valid values are:
-            AutoEnableIO.
-
-        :type new_value: string
-        :param new_value: The new value of the attribute.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'VolumeId': volume_id}
-        if attribute == 'AutoEnableIO':
-            params['AutoEnableIO.Value'] = new_value
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ModifyVolumeAttribute', params, verb='POST')
-
-    def create_volume(self, size, zone, snapshot=None, volume_type=None,
-                      iops=None, encrypted=False, kms_key_id=None, dry_run=False):
-        """
-        Create a new EBS Volume.
-
-        :type size: int
-        :param size: The size of the new volume, in GiB
-
-        :type zone: string or :class:`boto.ec2.zone.Zone`
-        :param zone: The availability zone in which the Volume will be created.
-
-        :type snapshot: string or :class:`boto.ec2.snapshot.Snapshot`
-        :param snapshot: The snapshot from which the new Volume will be
-            created.
-
-        :type volume_type: string
-        :param volume_type: The type of the volume. (optional).  Valid
-            values are: standard | io1 | gp2.
-
-        :type iops: int
-        :param iops: The provisioned IOPS you want to associate with
-            this volume. (optional)
-
-        :type encrypted: bool
-        :param encrypted: Specifies whether the volume should be encrypted.
-            (optional)
-
-        :type kms_key_id: string
-        :params kms_key_id: If encrypted is True, this KMS Key ID may be specified to
-            encrypt volume with this key (optional)
-            e.g.: arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        if isinstance(zone, Zone):
-            zone = zone.name
-        params = {'AvailabilityZone': zone}
-        if size:
-            params['Size'] = size
-        if snapshot:
-            if isinstance(snapshot, Snapshot):
-                snapshot = snapshot.id
-            params['SnapshotId'] = snapshot
-        if volume_type:
-            params['VolumeType'] = volume_type
-        if iops:
-            params['Iops'] = str(iops)
-        if encrypted:
-            params['Encrypted'] = 'true'
-            if kms_key_id:
-                params['KmsKeyId'] = kms_key_id
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CreateVolume', params, Volume, verb='POST')
-
-    def delete_volume(self, volume_id, dry_run=False):
-        """
-        Delete an EBS volume.
-
-        :type volume_id: str
-        :param volume_id: The ID of the volume to be delete.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {'VolumeId': volume_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteVolume', params, verb='POST')
-
-    def attach_volume(self, volume_id, instance_id, device, dry_run=False):
-        """
-        Attach an EBS volume to an EC2 instance.
-
-        :type volume_id: str
-        :param volume_id: The ID of the EBS volume to be attached.
-
-        :type instance_id: str
-        :param instance_id: The ID of the EC2 instance to which it will
-                            be attached.
-
-        :type device: str
-        :param device: The device on the instance through which the
-                       volume will be exposted (e.g. /dev/sdh)
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {'InstanceId': instance_id,
-                  'VolumeId': volume_id,
-                  'Device': device}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('AttachVolume', params, verb='POST')
-
-    def detach_volume(self, volume_id, instance_id=None,
-                      device=None, force=False, dry_run=False):
-        """
-        Detach an EBS volume from an EC2 instance.
-
-        :type volume_id: str
-        :param volume_id: The ID of the EBS volume to be attached.
-
-        :type instance_id: str
-        :param instance_id: The ID of the EC2 instance from which it will
-            be detached.
-
-        :type device: str
-        :param device: The device on the instance through which the
-            volume is exposted (e.g. /dev/sdh)
-
-        :type force: bool
-        :param force: Forces detachment if the previous detachment
-            attempt did not occur cleanly.  This option can lead to
-            data loss or a corrupted file system. Use this option only
-            as a last resort to detach a volume from a failed
-            instance. The instance will not have an opportunity to
-            flush file system caches nor file system meta data. If you
-            use this option, you must perform file system check and
-            repair procedures.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {'VolumeId': volume_id}
-        if instance_id:
-            params['InstanceId'] = instance_id
-        if device:
-            params['Device'] = device
-        if force:
-            params['Force'] = 'true'
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DetachVolume', params, verb='POST')
-
-    # Snapshot methods
-
-    def get_all_snapshots(self, snapshot_ids=None,
-                          owner=None, restorable_by=None,
-                          filters=None, dry_run=False):
-        """
-        Get all EBS Snapshots associated with the current credentials.
-
-        :type snapshot_ids: list
-        :param snapshot_ids: Optional list of snapshot ids.  If this list is
-                             present, only the Snapshots associated with
-                             these snapshot ids will be returned.
-
-        :type owner: str or list
-        :param owner: If present, only the snapshots owned by the specified user(s)
-                      will be returned.  Valid values are:
-
-                      * self
-                      * amazon
-                      * AWS Account ID
-
-        :type restorable_by: str or list
-        :param restorable_by: If present, only the snapshots that are restorable
-                              by the specified account id(s) will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.snapshot.Snapshot`
-        :return: The requested Snapshot objects
-        """
-        params = {}
-        if snapshot_ids:
-            self.build_list_params(params, snapshot_ids, 'SnapshotId')
-
-        if owner:
-            self.build_list_params(params, owner, 'Owner')
-        if restorable_by:
-            self.build_list_params(params, restorable_by, 'RestorableBy')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeSnapshots', params,
-                             [('item', Snapshot)], verb='POST')
-
-    def create_snapshot(self, volume_id, description=None, dry_run=False):
-        """
-        Create a snapshot of an existing EBS Volume.
-
-        :type volume_id: str
-        :param volume_id: The ID of the volume to be snapshot'ed
-
-        :type description: str
-        :param description: A description of the snapshot.
-                            Limited to 255 characters.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.snapshot.Snapshot`
-        :return: The created Snapshot object
-        """
-        params = {'VolumeId': volume_id}
-        if description:
-            params['Description'] = description[0:255]
-        if dry_run:
-            params['DryRun'] = 'true'
-        snapshot = self.get_object('CreateSnapshot', params,
-                                   Snapshot, verb='POST')
-        volume = self.get_all_volumes([volume_id], dry_run=dry_run)[0]
-        volume_name = volume.tags.get('Name')
-        if volume_name:
-            snapshot.add_tag('Name', volume_name)
-        return snapshot
-
-    def delete_snapshot(self, snapshot_id, dry_run=False):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'SnapshotId': snapshot_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteSnapshot', params, verb='POST')
-
-    def copy_snapshot(self, source_region, source_snapshot_id,
-                      description=None, dry_run=False):
-        """
-        Copies a point-in-time snapshot of an Amazon Elastic Block Store
-        (Amazon EBS) volume and stores it in Amazon Simple Storage Service
-        (Amazon S3). You can copy the snapshot within the same region or from
-        one region to another. You can use the snapshot to create new Amazon
-        EBS volumes or Amazon Machine Images (AMIs).
-
-
-        :type source_region: str
-        :param source_region: The ID of the AWS region that contains the
-            snapshot to be copied (e.g 'us-east-1', 'us-west-2', etc.).
-
-        :type source_snapshot_id: str
-        :param source_snapshot_id: The ID of the Amazon EBS snapshot to copy
-
-        :type description: str
-        :param description: A description of the new Amazon EBS snapshot.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: str
-        :return: The snapshot ID
-
-        """
-        params = {
-            'SourceRegion': source_region,
-            'SourceSnapshotId': source_snapshot_id,
-        }
-        if description is not None:
-            params['Description'] = description
-        if dry_run:
-            params['DryRun'] = 'true'
-        snapshot = self.get_object('CopySnapshot', params, Snapshot,
-                                   verb='POST')
-        return snapshot.id
-
-    def trim_snapshots(self, hourly_backups=8, daily_backups=7,
-                       weekly_backups=4, monthly_backups=True):
-        """
-        Trim excess snapshots, based on when they were taken. More current
-        snapshots are retained, with the number retained decreasing as you
-        move back in time.
-
-        If ebs volumes have a 'Name' tag with a value, their snapshots
-        will be assigned the same tag when they are created. The values
-        of the 'Name' tags for snapshots are used by this function to
-        group snapshots taken from the same volume (or from a series
-        of like-named volumes over time) for trimming.
-
-        For every group of like-named snapshots, this function retains
-        the newest and oldest snapshots, as well as, by default,  the
-        first snapshots taken in each of the last eight hours, the first
-        snapshots taken in each of the last seven days, the first snapshots
-        taken in the last 4 weeks (counting Midnight Sunday morning as
-        the start of the week), and the first snapshot from the first
-        day of each month forever.
-
-        :type hourly_backups: int
-        :param hourly_backups: How many recent hourly backups should be saved.
-
-        :type daily_backups: int
-        :param daily_backups: How many recent daily backups should be saved.
-
-        :type weekly_backups: int
-        :param weekly_backups: How many recent weekly backups should be saved.
-
-        :type monthly_backups: int
-        :param monthly_backups: How many monthly backups should be saved. Use True for no limit.
-        """
-
-        # This function first builds up an ordered list of target times
-        # that snapshots should be saved for (last 8 hours, last 7 days, etc.).
-        # Then a map of snapshots is constructed, with the keys being
-        # the snapshot / volume names and the values being arrays of
-        # chronologically sorted snapshots.
-        # Finally, for each array in the map, we go through the snapshot
-        # array and the target time array in an interleaved fashion,
-        # deleting snapshots whose start_times don't immediately follow a
-        # target time (we delete a snapshot if there's another snapshot
-        # that was made closer to the preceding target time).
-
-        now = datetime.utcnow()
-        last_hour = datetime(now.year, now.month, now.day, now.hour)
-        last_midnight = datetime(now.year, now.month, now.day)
-        last_sunday = datetime(now.year, now.month, now.day) - timedelta(days=(now.weekday() + 1) % 7)
-        start_of_month = datetime(now.year, now.month, 1)
-
-        target_backup_times = []
-
-        # there are no snapshots older than 1/1/2007
-        oldest_snapshot_date = datetime(2007, 1, 1)
-
-        for hour in range(0, hourly_backups):
-            target_backup_times.append(last_hour - timedelta(hours=hour))
-
-        for day in range(0, daily_backups):
-            target_backup_times.append(last_midnight - timedelta(days=day))
-
-        for week in range(0, weekly_backups):
-            target_backup_times.append(last_sunday - timedelta(weeks=week))
-
-        one_day = timedelta(days=1)
-        monthly_snapshots_added = 0
-        while (start_of_month > oldest_snapshot_date and
-               (monthly_backups is True or
-                monthly_snapshots_added < monthly_backups)):
-            # append the start of the month to the list of
-            # snapshot dates to save:
-            target_backup_times.append(start_of_month)
-            monthly_snapshots_added += 1
-            # there's no timedelta setting for one month, so instead:
-            # decrement the day by one, so we go to the final day of
-            # the previous month...
-            start_of_month -= one_day
-            # ... and then go to the first day of that previous month:
-            start_of_month = datetime(start_of_month.year,
-                                      start_of_month.month, 1)
-
-        temp = []
-
-        for t in target_backup_times:
-            if temp.__contains__(t) == False:
-                temp.append(t)
-
-        # sort to make the oldest dates first, and make sure the month start
-        # and last four week's start are in the proper order
-        target_backup_times = sorted(temp)
-
-        # get all the snapshots, sort them by date and time, and
-        # organize them into one array for each volume:
-        all_snapshots = self.get_all_snapshots(owner = 'self')
-        all_snapshots.sort(key=lambda x: x.start_time)
-        snaps_for_each_volume = {}
-        for snap in all_snapshots:
-            # the snapshot name and the volume name are the same.
-            # The snapshot name is set from the volume
-            # name at the time the snapshot is taken
-            volume_name = snap.tags.get('Name')
-            if volume_name:
-                # only examine snapshots that have a volume name
-                snaps_for_volume = snaps_for_each_volume.get(volume_name)
-                if not snaps_for_volume:
-                    snaps_for_volume = []
-                    snaps_for_each_volume[volume_name] = snaps_for_volume
-                snaps_for_volume.append(snap)
-
-        # Do a running comparison of snapshot dates to desired time
-        #periods, keeping the oldest snapshot in each
-        # time period and deleting the rest:
-        for volume_name in snaps_for_each_volume:
-            snaps = snaps_for_each_volume[volume_name]
-            snaps = snaps[:-1] # never delete the newest snapshot
-            time_period_number = 0
-            snap_found_for_this_time_period = False
-            for snap in snaps:
-                check_this_snap = True
-                while check_this_snap and time_period_number < target_backup_times.__len__():
-                    snap_date = datetime.strptime(snap.start_time,
-                                                  '%Y-%m-%dT%H:%M:%S.000Z')
-                    if snap_date < target_backup_times[time_period_number]:
-                        # the snap date is before the cutoff date.
-                        # Figure out if it's the first snap in this
-                        # date range and act accordingly (since both
-                        #date the date ranges and the snapshots
-                        # are sorted chronologically, we know this
-                        #snapshot isn't in an earlier date range):
-                        if snap_found_for_this_time_period == True:
-                            if not snap.tags.get('preserve_snapshot'):
-                                # as long as the snapshot wasn't marked
-                                # with the 'preserve_snapshot' tag, delete it:
-                                try:
-                                    self.delete_snapshot(snap.id)
-                                    boto.log.info('Trimmed snapshot %s (%s)' % (snap.tags['Name'], snap.start_time))
-                                except EC2ResponseError:
-                                    boto.log.error('Attempt to trim snapshot %s (%s) failed. Possible result of a race condition with trimming on another server?' % (snap.tags['Name'], snap.start_time))
-                            # go on and look at the next snapshot,
-                            #leaving the time period alone
-                        else:
-                            # this was the first snapshot found for this
-                            #time period. Leave it alone and look at the
-                            # next snapshot:
-                            snap_found_for_this_time_period = True
-                        check_this_snap = False
-                    else:
-                        # the snap is after the cutoff date. Check it
-                        # against the next cutoff date
-                        time_period_number += 1
-                        snap_found_for_this_time_period = False
-
-    def get_snapshot_attribute(self, snapshot_id,
-                               attribute='createVolumePermission',
-                               dry_run=False):
-        """
-        Get information about an attribute of a snapshot.  Only one attribute
-        can be specified per call.
-
-        :type snapshot_id: str
-        :param snapshot_id: The ID of the snapshot.
-
-        :type attribute: str
-        :param attribute: The requested attribute.  Valid values are:
-
-                          * createVolumePermission
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute`
-        :return: The requested Snapshot attribute
-        """
-        params = {'Attribute': attribute}
-        if snapshot_id:
-            params['SnapshotId'] = snapshot_id
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeSnapshotAttribute', params,
-                               SnapshotAttribute, verb='POST')
-
-    def modify_snapshot_attribute(self, snapshot_id,
-                                  attribute='createVolumePermission',
-                                  operation='add', user_ids=None, groups=None,
-                                  dry_run=False):
-        """
-        Changes an attribute of an image.
-
-        :type snapshot_id: string
-        :param snapshot_id: The snapshot id you wish to change
-
-        :type attribute: string
-        :param attribute: The attribute you wish to change.  Valid values are:
-            createVolumePermission
-
-        :type operation: string
-        :param operation: Either add or remove (this is required for changing
-            snapshot ermissions)
-
-        :type user_ids: list
-        :param user_ids: The Amazon IDs of users to add/remove attributes
-
-        :type groups: list
-        :param groups: The groups to add/remove attributes.  The only valid
-            value at this time is 'all'.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'SnapshotId': snapshot_id,
-                  'Attribute': attribute,
-                  'OperationType': operation}
-        if user_ids:
-            self.build_list_params(params, user_ids, 'UserId')
-        if groups:
-            self.build_list_params(params, groups, 'UserGroup')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ModifySnapshotAttribute', params, verb='POST')
-
-    def reset_snapshot_attribute(self, snapshot_id,
-                                 attribute='createVolumePermission',
-                                 dry_run=False):
-        """
-        Resets an attribute of a snapshot to its default value.
-
-        :type snapshot_id: string
-        :param snapshot_id: ID of the snapshot
-
-        :type attribute: string
-        :param attribute: The attribute to reset
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: Whether the operation succeeded or not
-        """
-        params = {'SnapshotId': snapshot_id,
-                  'Attribute': attribute}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ResetSnapshotAttribute', params, verb='POST')
-
-    # Keypair methods
-
-    def get_all_key_pairs(self, keynames=None, filters=None, dry_run=False):
-        """
-        Get all key pairs associated with your account.
-
-        :type keynames: list
-        :param keynames: A list of the names of keypairs to retrieve.
-            If not provided, all key pairs will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.keypair.KeyPair`
-        """
-        params = {}
-        if keynames:
-            self.build_list_params(params, keynames, 'KeyName')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeKeyPairs', params,
-                             [('item', KeyPair)], verb='POST')
-
-    def get_key_pair(self, keyname, dry_run=False):
-        """
-        Convenience method to retrieve a specific keypair (KeyPair).
-
-        :type keyname: string
-        :param keyname: The name of the keypair to retrieve
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.keypair.KeyPair`
-        :return: The KeyPair specified or None if it is not found
-        """
-        try:
-            return self.get_all_key_pairs(
-                keynames=[keyname],
-                dry_run=dry_run
-            )[0]
-        except self.ResponseError as e:
-            if e.code == 'InvalidKeyPair.NotFound':
-                return None
-            else:
-                raise
-
-    def create_key_pair(self, key_name, dry_run=False):
-        """
-        Create a new key pair for your account.
-        This will create the key pair within the region you
-        are currently connected to.
-
-        :type key_name: string
-        :param key_name: The name of the new keypair
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.keypair.KeyPair`
-        :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
-                 The material attribute of the new KeyPair object
-                 will contain the the unencrypted PEM encoded RSA private key.
-        """
-        params = {'KeyName': key_name}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CreateKeyPair', params, KeyPair, verb='POST')
-
-    def delete_key_pair(self, key_name, dry_run=False):
-        """
-        Delete a key pair from your account.
-
-        :type key_name: string
-        :param key_name: The name of the keypair to delete
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'KeyName': key_name}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteKeyPair', params, verb='POST')
-
-    def import_key_pair(self, key_name, public_key_material, dry_run=False):
-        """
-        imports the public key from an RSA key pair that you created
-        with a third-party tool.
-
-        Supported formats:
-
-        * OpenSSH public key format (e.g., the format
-          in ~/.ssh/authorized_keys)
-
-        * Base64 encoded DER format
-
-        * SSH public key file format as specified in RFC4716
-
-        DSA keys are not supported. Make sure your key generator is
-        set up to create RSA keys.
-
-        Supported lengths: 1024, 2048, and 4096.
-
-        :type key_name: string
-        :param key_name: The name of the new keypair
-
-        :type public_key_material: string
-        :param public_key_material: The public key. You must base64 encode
-                                    the public key material before sending
-                                    it to AWS.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.keypair.KeyPair`
-        :return: A :class:`boto.ec2.keypair.KeyPair` object representing
-            the newly imported key pair.  This object will contain only
-            the key name and the fingerprint.
-        """
-        public_key_material = base64.b64encode(public_key_material)
-        params = {'KeyName': key_name,
-                  'PublicKeyMaterial': public_key_material}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('ImportKeyPair', params, KeyPair, verb='POST')
-
-    # SecurityGroup methods
-
-    def get_all_security_groups(self, groupnames=None, group_ids=None,
-                                filters=None, dry_run=False):
-        """
-        Get all security groups associated with your account in a region.
-
-        :type groupnames: list
-        :param groupnames: A list of the names of security groups to retrieve.
-                           If not provided, all security groups will be
-                           returned.
-
-        :type group_ids: list
-        :param group_ids: A list of IDs of security groups to retrieve for
-                          security groups within a VPC.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
-        """
-        params = {}
-        if groupnames is not None:
-            self.build_list_params(params, groupnames, 'GroupName')
-        if group_ids is not None:
-            self.build_list_params(params, group_ids, 'GroupId')
-        if filters is not None:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeSecurityGroups', params,
-                             [('item', SecurityGroup)], verb='POST')
-
-    def create_security_group(self, name, description, vpc_id=None,
-                              dry_run=False):
-        """
-        Create a new security group for your account.
-        This will create the security group within the region you
-        are currently connected to.
-
-        :type name: string
-        :param name: The name of the new security group
-
-        :type description: string
-        :param description: The description of the new security group
-
-        :type vpc_id: string
-        :param vpc_id: The ID of the VPC to create the security group in,
-                       if any.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
-        :return: The newly created :class:`boto.ec2.securitygroup.SecurityGroup`.
-        """
-        params = {'GroupName': name,
-                  'GroupDescription': description}
-
-        if vpc_id is not None:
-            params['VpcId'] = vpc_id
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        group = self.get_object('CreateSecurityGroup', params,
-                                SecurityGroup, verb='POST')
-        group.name = name
-        group.description = description
-        if vpc_id is not None:
-            group.vpc_id = vpc_id
-        return group
-
-    def delete_security_group(self, name=None, group_id=None, dry_run=False):
-        """
-        Delete a security group from your account.
-
-        :type name: string
-        :param name: The name of the security group to delete.
-
-        :type group_id: string
-        :param group_id: The ID of the security group to delete within
-          a VPC.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-        params = {}
-
-        if name is not None:
-            params['GroupName'] = name
-        elif group_id is not None:
-            params['GroupId'] = group_id
-
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('DeleteSecurityGroup', params, verb='POST')
-
-    def authorize_security_group_deprecated(self, group_name,
-                                            src_security_group_name=None,
-                                            src_security_group_owner_id=None,
-                                            ip_protocol=None,
-                                            from_port=None, to_port=None,
-                                            cidr_ip=None, dry_run=False):
-        """
-        NOTE: This method uses the old-style request parameters
-              that did not allow a port to be specified when
-              authorizing a group.
-
-        :type group_name: string
-        :param group_name: The name of the security group you are adding
-            the rule to.
-
-        :type src_security_group_name: string
-        :param src_security_group_name: The name of the security group you are
-            granting access to.
-
-        :type src_security_group_owner_id: string
-        :param src_security_group_owner_id: The ID of the owner of the security
-            group you are granting access to.
-
-        :type ip_protocol: string
-        :param ip_protocol: Either tcp | udp | icmp
-
-        :type from_port: int
-        :param from_port: The beginning port number you are enabling
-
-        :type to_port: int
-        :param to_port: The ending port number you are enabling
-
-        :type to_port: string
-        :param to_port: The CIDR block you are providing access to.
-            See http://goo.gl/Yj5QC
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-        params = {'GroupName': group_name}
-        if src_security_group_name:
-            params['SourceSecurityGroupName'] = src_security_group_name
-        if src_security_group_owner_id:
-            params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
-        if ip_protocol:
-            params['IpProtocol'] = ip_protocol
-        if from_port:
-            params['FromPort'] = from_port
-        if to_port:
-            params['ToPort'] = to_port
-        if cidr_ip:
-            params['CidrIp'] = cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('AuthorizeSecurityGroupIngress', params)
-
-    def authorize_security_group(self, group_name=None,
-                                 src_security_group_name=None,
-                                 src_security_group_owner_id=None,
-                                 ip_protocol=None,
-                                 from_port=None, to_port=None,
-                                 cidr_ip=None, group_id=None,
-                                 src_security_group_group_id=None,
-                                 dry_run=False):
-        """
-        Add a new rule to an existing security group.
-        You need to pass in either src_security_group_name and
-        src_security_group_owner_id OR ip_protocol, from_port, to_port,
-        and cidr_ip.  In other words, either you are authorizing another
-        group or you are authorizing some ip-based rule.
-
-        :type group_name: string
-        :param group_name: The name of the security group you are adding
-            the rule to.
-
-        :type src_security_group_name: string
-        :param src_security_group_name: The name of the security group you are
-            granting access to.
-
-        :type src_security_group_owner_id: string
-        :param src_security_group_owner_id: The ID of the owner of the security
-            group you are granting access to.
-
-        :type ip_protocol: string
-        :param ip_protocol: Either tcp | udp | icmp
-
-        :type from_port: int
-        :param from_port: The beginning port number you are enabling
-
-        :type to_port: int
-        :param to_port: The ending port number you are enabling
-
-        :type cidr_ip: string or list of strings
-        :param cidr_ip: The CIDR block you are providing access to.
-            See http://goo.gl/Yj5QC
-
-        :type group_id: string
-        :param group_id: ID of the EC2 or VPC security group to
-            modify.  This is required for VPC security groups and can
-            be used instead of group_name for EC2 security groups.
-
-        :type src_security_group_group_id: string
-        :param src_security_group_group_id: The ID of the security
-            group you are granting access to.  Can be used instead of
-            src_security_group_name
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-        if src_security_group_name:
-            if from_port is None and to_port is None and ip_protocol is None:
-                return self.authorize_security_group_deprecated(
-                    group_name, src_security_group_name,
-                    src_security_group_owner_id)
-
-        params = {}
-
-        if group_name:
-            params['GroupName'] = group_name
-        if group_id:
-            params['GroupId'] = group_id
-        if src_security_group_name:
-            param_name = 'IpPermissions.1.Groups.1.GroupName'
-            params[param_name] = src_security_group_name
-        if src_security_group_owner_id:
-            param_name = 'IpPermissions.1.Groups.1.UserId'
-            params[param_name] = src_security_group_owner_id
-        if src_security_group_group_id:
-            param_name = 'IpPermissions.1.Groups.1.GroupId'
-            params[param_name] = src_security_group_group_id
-        if ip_protocol:
-            params['IpPermissions.1.IpProtocol'] = ip_protocol
-        if from_port is not None:
-            params['IpPermissions.1.FromPort'] = from_port
-        if to_port is not None:
-            params['IpPermissions.1.ToPort'] = to_port
-        if cidr_ip:
-            if not isinstance(cidr_ip, list):
-                cidr_ip = [cidr_ip]
-            for i, single_cidr_ip in enumerate(cidr_ip):
-                params['IpPermissions.1.IpRanges.%d.CidrIp' % (i + 1)] = \
-                    single_cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('AuthorizeSecurityGroupIngress',
-                               params, verb='POST')
-
-    def authorize_security_group_egress(self,
-                                        group_id,
-                                        ip_protocol,
-                                        from_port=None,
-                                        to_port=None,
-                                        src_group_id=None,
-                                        cidr_ip=None,
-                                        dry_run=False):
-        """
-        The action adds one or more egress rules to a VPC security
-        group. Specifically, this action permits instances in a
-        security group to send traffic to one or more destination
-        CIDR IP address ranges, or to one or more destination
-        security groups in the same VPC.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {
-            'GroupId': group_id,
-            'IpPermissions.1.IpProtocol': ip_protocol
-        }
-
-        if from_port is not None:
-            params['IpPermissions.1.FromPort'] = from_port
-        if to_port is not None:
-            params['IpPermissions.1.ToPort'] = to_port
-        if src_group_id is not None:
-            params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
-        if cidr_ip is not None:
-            params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_status('AuthorizeSecurityGroupEgress',
-                               params, verb='POST')
-
-    def revoke_security_group_deprecated(self, group_name,
-                                         src_security_group_name=None,
-                                         src_security_group_owner_id=None,
-                                         ip_protocol=None,
-                                         from_port=None, to_port=None,
-                                         cidr_ip=None, dry_run=False):
-        """
-        NOTE: This method uses the old-style request parameters
-              that did not allow a port to be specified when
-              authorizing a group.
-
-        Remove an existing rule from an existing security group.
-        You need to pass in either src_security_group_name and
-        src_security_group_owner_id OR ip_protocol, from_port, to_port,
-        and cidr_ip.  In other words, either you are revoking another
-        group or you are revoking some ip-based rule.
-
-        :type group_name: string
-        :param group_name: The name of the security group you are removing
-                           the rule from.
-
-        :type src_security_group_name: string
-        :param src_security_group_name: The name of the security group you are
-                                        revoking access to.
-
-        :type src_security_group_owner_id: string
-        :param src_security_group_owner_id: The ID of the owner of the security
-                                            group you are revoking access to.
-
-        :type ip_protocol: string
-        :param ip_protocol: Either tcp | udp | icmp
-
-        :type from_port: int
-        :param from_port: The beginning port number you are disabling
-
-        :type to_port: int
-        :param to_port: The ending port number you are disabling
-
-        :type to_port: string
-        :param to_port: The CIDR block you are revoking access to.
-                        http://goo.gl/Yj5QC
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-        params = {'GroupName': group_name}
-        if src_security_group_name:
-            params['SourceSecurityGroupName'] = src_security_group_name
-        if src_security_group_owner_id:
-            params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
-        if ip_protocol:
-            params['IpProtocol'] = ip_protocol
-        if from_port:
-            params['FromPort'] = from_port
-        if to_port:
-            params['ToPort'] = to_port
-        if cidr_ip:
-            params['CidrIp'] = cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('RevokeSecurityGroupIngress', params)
-
-    def revoke_security_group(self, group_name=None,
-                              src_security_group_name=None,
-                              src_security_group_owner_id=None,
-                              ip_protocol=None, from_port=None, to_port=None,
-                              cidr_ip=None, group_id=None,
-                              src_security_group_group_id=None, dry_run=False):
-        """
-        Remove an existing rule from an existing security group.
-        You need to pass in either src_security_group_name and
-        src_security_group_owner_id OR ip_protocol, from_port, to_port,
-        and cidr_ip.  In other words, either you are revoking another
-        group or you are revoking some ip-based rule.
-
-        :type group_name: string
-        :param group_name: The name of the security group you are removing
-            the rule from.
-
-        :type src_security_group_name: string
-        :param src_security_group_name: The name of the security group you are
-            revoking access to.
-
-        :type src_security_group_owner_id: string
-        :param src_security_group_owner_id: The ID of the owner of the security
-            group you are revoking access to.
-
-        :type ip_protocol: string
-        :param ip_protocol: Either tcp | udp | icmp
-
-        :type from_port: int
-        :param from_port: The beginning port number you are disabling
-
-        :type to_port: int
-        :param to_port: The ending port number you are disabling
-
-        :type cidr_ip: string
-        :param cidr_ip: The CIDR block you are revoking access to.
-            See http://goo.gl/Yj5QC
-
-        :type group_id: string
-        :param group_id: ID of the EC2 or VPC security group to
-            modify.  This is required for VPC security groups and can
-            be used instead of group_name for EC2 security groups.
-
-        :type src_security_group_group_id: string
-        :param src_security_group_group_id: The ID of the security group
-            for which you are revoking access.  Can be used instead
-            of src_security_group_name
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-        if src_security_group_name:
-            if from_port is None and to_port is None and ip_protocol is None:
-                return self.revoke_security_group_deprecated(
-                    group_name, src_security_group_name,
-                    src_security_group_owner_id)
-        params = {}
-        if group_name is not None:
-            params['GroupName'] = group_name
-        if group_id is not None:
-            params['GroupId'] = group_id
-        if src_security_group_name:
-            param_name = 'IpPermissions.1.Groups.1.GroupName'
-            params[param_name] = src_security_group_name
-        if src_security_group_group_id:
-            param_name = 'IpPermissions.1.Groups.1.GroupId'
-            params[param_name] = src_security_group_group_id
-        if src_security_group_owner_id:
-            param_name = 'IpPermissions.1.Groups.1.UserId'
-            params[param_name] = src_security_group_owner_id
-        if ip_protocol:
-            params['IpPermissions.1.IpProtocol'] = ip_protocol
-        if from_port is not None:
-            params['IpPermissions.1.FromPort'] = from_port
-        if to_port is not None:
-            params['IpPermissions.1.ToPort'] = to_port
-        if cidr_ip:
-            params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('RevokeSecurityGroupIngress',
-                               params, verb='POST')
-
-    def revoke_security_group_egress(self,
-                                     group_id,
-                                     ip_protocol,
-                                     from_port=None,
-                                     to_port=None,
-                                     src_group_id=None,
-                                     cidr_ip=None, dry_run=False):
-        """
-        Remove an existing egress rule from an existing VPC security
-        group.  You need to pass in an ip_protocol, from_port and
-        to_port range only if the protocol you are using is
-        port-based. You also need to pass in either a src_group_id or
-        cidr_ip.
-
-        :type group_name: string
-        :param group_id:  The name of the security group you are removing
-            the rule from.
-
-        :type ip_protocol: string
-        :param ip_protocol: Either tcp | udp | icmp | -1
-
-        :type from_port: int
-        :param from_port: The beginning port number you are disabling
-
-        :type to_port: int
-        :param to_port: The ending port number you are disabling
-
-        :type src_group_id: src_group_id
-        :param src_group_id: The source security group you are
-            revoking access to.
-
-        :type cidr_ip: string
-        :param cidr_ip: The CIDR block you are revoking access to.
-            See http://goo.gl/Yj5QC
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful.
-        """
-
-        params = {}
-        if group_id:
-            params['GroupId'] = group_id
-        if ip_protocol:
-            params['IpPermissions.1.IpProtocol'] = ip_protocol
-        if from_port is not None:
-            params['IpPermissions.1.FromPort'] = from_port
-        if to_port is not None:
-            params['IpPermissions.1.ToPort'] = to_port
-        if src_group_id is not None:
-            params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
-        if cidr_ip:
-            params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('RevokeSecurityGroupEgress',
-                               params, verb='POST')
-
-    #
-    # Regions
-    #
-
-    def get_all_regions(self, region_names=None, filters=None, dry_run=False):
-        """
-        Get all available regions for the EC2 service.
-
-        :type region_names: list of str
-        :param region_names: Names of regions to limit output
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
-        """
-        params = {}
-        if region_names:
-            self.build_list_params(params, region_names, 'RegionName')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        regions = self.get_list('DescribeRegions', params,
-                                [('item', RegionInfo)], verb='POST')
-        for region in regions:
-            region.connection_cls = EC2Connection
-        return regions
-
-    #
-    # Reservation methods
-    #
-
-    def get_all_reserved_instances_offerings(self,
-                                             reserved_instances_offering_ids=None,
-                                             instance_type=None,
-                                             availability_zone=None,
-                                             product_description=None,
-                                             filters=None,
-                                             instance_tenancy=None,
-                                             offering_type=None,
-                                             include_marketplace=None,
-                                             min_duration=None,
-                                             max_duration=None,
-                                             max_instance_count=None,
-                                             next_token=None,
-                                             max_results=None,
-                                             dry_run=False):
-        """
-        Describes Reserved Instance offerings that are available for purchase.
-
-        :type reserved_instances_offering_ids: list
-        :param reserved_instances_id: One or more Reserved Instances
-            offering IDs.
-
-        :type instance_type: str
-        :param instance_type: Displays Reserved Instances of the specified
-                              instance type.
-
-        :type availability_zone: str
-        :param availability_zone: Displays Reserved Instances within the
-                                  specified Availability Zone.
-
-        :type product_description: str
-        :param product_description: Displays Reserved Instances with the
-                                    specified product description.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type instance_tenancy: string
-        :param instance_tenancy: The tenancy of the Reserved Instance offering.
-            A Reserved Instance with tenancy of dedicated will run on
-            single-tenant hardware and can only be launched within a VPC.
-
-        :type offering_type: string
-        :param offering_type: The Reserved Instance offering type.  Valid
-            Values: `"Heavy Utilization" | "Medium Utilization" | "Light
-            Utilization"`
-
-        :type include_marketplace: bool
-        :param include_marketplace: Include Marketplace offerings in the
-            response.
-
-        :type min_duration: int :param min_duration: Minimum duration (in
-            seconds) to filter when searching for offerings.
-
-        :type max_duration: int
-        :param max_duration: Maximum duration (in seconds) to filter when
-            searching for offerings.
-
-        :type max_instance_count: int
-        :param max_instance_count: Maximum number of instances to filter when
-            searching for offerings.
-
-        :type next_token: string
-        :param next_token: Token to use when requesting the next paginated set
-            of offerings.
-
-        :type max_results: int
-        :param max_results: Maximum number of offerings to return per call.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of
-            :class:`boto.ec2.reservedinstance.ReservedInstancesOffering`.
-
-        """
-        params = {}
-        if reserved_instances_offering_ids is not None:
-            self.build_list_params(params, reserved_instances_offering_ids,
-                                   'ReservedInstancesOfferingId')
-        if instance_type:
-            params['InstanceType'] = instance_type
-        if availability_zone:
-            params['AvailabilityZone'] = availability_zone
-        if product_description:
-            params['ProductDescription'] = product_description
-        if filters:
-            self.build_filter_params(params, filters)
-        if instance_tenancy is not None:
-            params['InstanceTenancy'] = instance_tenancy
-        if offering_type is not None:
-            params['OfferingType'] = offering_type
-        if include_marketplace is not None:
-            if include_marketplace:
-                params['IncludeMarketplace'] = 'true'
-            else:
-                params['IncludeMarketplace'] = 'false'
-        if min_duration is not None:
-            params['MinDuration'] = str(min_duration)
-        if max_duration is not None:
-            params['MaxDuration'] = str(max_duration)
-        if max_instance_count is not None:
-            params['MaxInstanceCount'] = str(max_instance_count)
-        if next_token is not None:
-            params['NextToken'] = next_token
-        if max_results is not None:
-            params['MaxResults'] = str(max_results)
-        if dry_run:
-            params['DryRun'] = 'true'
-
-        return self.get_list('DescribeReservedInstancesOfferings',
-                             params, [('item', ReservedInstancesOffering)],
-                             verb='POST')
-
-    def get_all_reserved_instances(self, reserved_instances_id=None,
-                                   filters=None, dry_run=False):
-        """
-        Describes one or more of the Reserved Instances that you purchased.
-
-        :type reserved_instance_ids: list
-        :param reserved_instance_ids: A list of the reserved instance ids that
-            will be returned. If not provided, all reserved instances
-            will be returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
-        """
-        params = {}
-        if reserved_instances_id:
-            self.build_list_params(params, reserved_instances_id,
-                                   'ReservedInstancesId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeReservedInstances',
-                             params, [('item', ReservedInstance)], verb='POST')
-
-    def purchase_reserved_instance_offering(self,
-                                            reserved_instances_offering_id,
-                                            instance_count=1, limit_price=None,
-                                            dry_run=False):
-        """
-        Purchase a Reserved Instance for use with your account.
-        ** CAUTION **
-        This request can result in large amounts of money being charged to your
-        AWS account.  Use with caution!
-
-        :type reserved_instances_offering_id: string
-        :param reserved_instances_offering_id: The offering ID of the Reserved
-            Instance to purchase
-
-        :type instance_count: int
-        :param instance_count: The number of Reserved Instances to purchase.
-            Default value is 1.
-
-        :type limit_price: tuple
-        :param instance_count: Limit the price on the total order.
-            Must be a tuple of (amount, currency_code), for example:
-            (100.0, 'USD').
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
-        :return: The newly created Reserved Instance
-        """
-        params = {
-            'ReservedInstancesOfferingId': reserved_instances_offering_id,
-            'InstanceCount': instance_count}
-        if limit_price is not None:
-            params['LimitPrice.Amount'] = str(limit_price[0])
-            params['LimitPrice.CurrencyCode'] = str(limit_price[1])
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('PurchaseReservedInstancesOffering', params,
-                               ReservedInstance, verb='POST')
-
-    def create_reserved_instances_listing(self, reserved_instances_id,
-                                          instance_count, price_schedules,
-                                          client_token, dry_run=False):
-        """Creates a new listing for Reserved Instances.
-
-        Creates a new listing for Amazon EC2 Reserved Instances that will be
-        sold in the Reserved Instance Marketplace. You can submit one Reserved
-        Instance listing at a time.
-
-        The Reserved Instance Marketplace matches sellers who want to resell
-        Reserved Instance capacity that they no longer need with buyers who
-        want to purchase additional capacity. Reserved Instances bought and
-        sold through the Reserved Instance Marketplace work like any other
-        Reserved Instances.
-
-        If you want to sell your Reserved Instances, you must first register as
-        a Seller in the Reserved Instance Marketplace. After completing the
-        registration process, you can create a Reserved Instance Marketplace
-        listing of some or all of your Reserved Instances, and specify the
-        upfront price you want to receive for them. Your Reserved Instance
-        listings then become available for purchase.
-
-        :type reserved_instances_id: string
-        :param reserved_instances_id: The ID of the Reserved Instance that
-            will be listed.
-
-        :type instance_count: int
-        :param instance_count: The number of instances that are a part of a
-            Reserved Instance account that will be listed in the Reserved
-            Instance Marketplace. This number should be less than or equal to
-            the instance count associated with the Reserved Instance ID
-            specified in this call.
-
-        :type price_schedules: List of tuples
-        :param price_schedules: A list specifying the price of the Reserved
-            Instance for each month remaining in the Reserved Instance term.
-            Each tuple contains two elements, the price and the term.  For
-            example, for an instance that 11 months remaining in its term,
-            we can have a price schedule with an upfront price of $2.50.
-            At 8 months remaining we can drop the price down to $2.00.
-            This would be expressed as::
-
-                price_schedules=[('2.50', 11), ('2.00', 8)]
-
-        :type client_token: string
-        :param client_token: Unique, case-sensitive identifier you provide
-            to ensure idempotency of the request.  Maximum 64 ASCII characters.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of
-            :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
-
-        """
-        params = {
-            'ReservedInstancesId': reserved_instances_id,
-            'InstanceCount': str(instance_count),
-            'ClientToken': client_token,
-        }
-        for i, schedule in enumerate(price_schedules):
-            price, term = schedule
-            params['PriceSchedules.%s.Price' % i] = str(price)
-            params['PriceSchedules.%s.Term' % i] = str(term)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('CreateReservedInstancesListing',
-                             params, [('item', ReservedInstanceListing)], verb='POST')
-
-    def cancel_reserved_instances_listing(self,
-                                          reserved_instances_listing_ids=None,
-                                          dry_run=False):
-        """Cancels the specified Reserved Instance listing.
-
-        :type reserved_instances_listing_ids: List of strings
-        :param reserved_instances_listing_ids: The ID of the
-            Reserved Instance listing to be cancelled.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of
-            :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
-
-        """
-        params = {}
-        if reserved_instances_listing_ids is not None:
-            self.build_list_params(params, reserved_instances_listing_ids,
-                                   'ReservedInstancesListingId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('CancelReservedInstancesListing',
-                             params, [('item', ReservedInstanceListing)], verb='POST')
-
-    def build_configurations_param_list(self, params, target_configurations):
-        for offset, tc in enumerate(target_configurations):
-            prefix = 'ReservedInstancesConfigurationSetItemType.%d.' % offset
-            if tc.availability_zone is not None:
-                params[prefix + 'AvailabilityZone'] = tc.availability_zone
-            if tc.platform is not None:
-                params[prefix + 'Platform'] = tc.platform
-            if tc.instance_count is not None:
-                params[prefix + 'InstanceCount'] = tc.instance_count
-            if tc.instance_type is not None:
-                params[prefix + 'InstanceType'] = tc.instance_type
-
-    def modify_reserved_instances(self, client_token, reserved_instance_ids,
-                                  target_configurations):
-        """
-        Modifies the specified Reserved Instances.
-
-        :type client_token: string
-        :param client_token: A unique, case-sensitive, token you provide to
-                             ensure idempotency of your modification request.
-
-        :type reserved_instance_ids: List of strings
-        :param reserved_instance_ids: The IDs of the Reserved Instances to
-                                      modify.
-
-        :type target_configurations: List of :class:`boto.ec2.reservedinstance.ReservedInstancesConfiguration`
-        :param target_configurations: The configuration settings for the
-                                      modified Reserved Instances.
-
-        :rtype: string
-        :return: The unique ID for the submitted modification request.
-        """
-        params = {}
-        if client_token is not None:
-            params['ClientToken'] = client_token
-        if reserved_instance_ids is not None:
-            self.build_list_params(params, reserved_instance_ids,
-                                   'ReservedInstancesId')
-        if target_configurations is not None:
-            self.build_configurations_param_list(params, target_configurations)
-        mrir = self.get_object(
-            'ModifyReservedInstances',
-            params,
-            ModifyReservedInstancesResult,
-            verb='POST'
-        )
-        return mrir.modification_id
-
-    def describe_reserved_instances_modifications(self,
-            reserved_instances_modification_ids=None, next_token=None,
-            filters=None):
-        """
-        A request to describe the modifications made to Reserved Instances in
-        your account.
-
-        :type reserved_instances_modification_ids: list
-        :param reserved_instances_modification_ids: An optional list of
-            Reserved Instances modification IDs to describe.
-
-        :type next_token: str
-        :param next_token: A string specifying the next paginated set
-            of results to return.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
-        """
-        params = {}
-        if reserved_instances_modification_ids:
-            self.build_list_params(params, reserved_instances_modification_ids,
-                                   'ReservedInstancesModificationId')
-        if next_token:
-            params['NextToken'] = next_token
-        if filters:
-            self.build_filter_params(params, filters)
-        return self.get_list('DescribeReservedInstancesModifications',
-                             params, [('item', ReservedInstancesModification)],
-                             verb='POST')
-
-    #
-    # Monitoring
-    #
-
-    def monitor_instances(self, instance_ids, dry_run=False):
-        """
-        Enable detailed CloudWatch monitoring for the supplied instances.
-
-        :type instance_id: list of strings
-        :param instance_id: The instance ids
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
-        """
-        params = {}
-        self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('MonitorInstances', params,
-                             [('item', InstanceInfo)], verb='POST')
-
-    def monitor_instance(self, instance_id, dry_run=False):
-        """
-        Deprecated Version, maintained for backward compatibility.
-        Enable detailed CloudWatch monitoring for the supplied instance.
-
-        :type instance_id: string
-        :param instance_id: The instance id
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
-        """
-        return self.monitor_instances([instance_id], dry_run=dry_run)
-
-    def unmonitor_instances(self, instance_ids, dry_run=False):
-        """
-        Disable CloudWatch monitoring for the supplied instance.
-
-        :type instance_id: list of string
-        :param instance_id: The instance id
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
-        """
-        params = {}
-        self.build_list_params(params, instance_ids, 'InstanceId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('UnmonitorInstances', params,
-                             [('item', InstanceInfo)], verb='POST')
-
-    def unmonitor_instance(self, instance_id, dry_run=False):
-        """
-        Deprecated Version, maintained for backward compatibility.
-        Disable detailed CloudWatch monitoring for the supplied instance.
-
-        :type instance_id: string
-        :param instance_id: The instance id
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
-        """
-        return self.unmonitor_instances([instance_id], dry_run=dry_run)
-
-    #
-    # Bundle Windows Instances
-    #
-
-    def bundle_instance(self, instance_id,
-                        s3_bucket,
-                        s3_prefix,
-                        s3_upload_policy, dry_run=False):
-        """
-        Bundle Windows instance.
-
-        :type instance_id: string
-        :param instance_id: The instance id
-
-        :type s3_bucket: string
-        :param s3_bucket: The bucket in which the AMI should be stored.
-
-        :type s3_prefix: string
-        :param s3_prefix: The beginning of the file name for the AMI.
-
-        :type s3_upload_policy: string
-        :param s3_upload_policy: Base64 encoded policy that specifies condition
-                                 and permissions for Amazon EC2 to upload the
-                                 user's image into Amazon S3.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-
-        params = {'InstanceId': instance_id,
-                  'Storage.S3.Bucket': s3_bucket,
-                  'Storage.S3.Prefix': s3_prefix,
-                  'Storage.S3.UploadPolicy': s3_upload_policy}
-        s3auth = boto.auth.get_auth_handler(None, boto.config,
-                                            self.provider, ['s3'])
-        params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
-        signature = s3auth.sign_string(s3_upload_policy)
-        params['Storage.S3.UploadPolicySignature'] = signature
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('BundleInstance', params,
-                               BundleInstanceTask, verb='POST')
-
-    def get_all_bundle_tasks(self, bundle_ids=None, filters=None,
-                             dry_run=False):
-        """
-        Retrieve current bundling tasks. If no bundle id is specified, all
-        tasks are retrieved.
-
-        :type bundle_ids: list
-        :param bundle_ids: A list of strings containing identifiers for
-                           previously created bundling tasks.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {}
-        if bundle_ids:
-            self.build_list_params(params, bundle_ids, 'BundleId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeBundleTasks', params,
-                             [('item', BundleInstanceTask)], verb='POST')
-
-    def cancel_bundle_task(self, bundle_id, dry_run=False):
-        """
-        Cancel a previously submitted bundle task
-
-        :type bundle_id: string
-        :param bundle_id: The identifier of the bundle task to cancel.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'BundleId': bundle_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CancelBundleTask', params,
-                               BundleInstanceTask, verb='POST')
-
-    def get_password_data(self, instance_id, dry_run=False):
-        """
-        Get encrypted administrator password for a Windows instance.
-
-        :type instance_id: string
-        :param instance_id: The identifier of the instance to retrieve the
-                            password for.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'InstanceId': instance_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST')
-        return rs.passwordData
-
-    #
-    # Cluster Placement Groups
-    #
-
-    def get_all_placement_groups(self, groupnames=None, filters=None,
-                                 dry_run=False):
-        """
-        Get all placement groups associated with your account in a region.
-
-        :type groupnames: list
-        :param groupnames: A list of the names of placement groups to retrieve.
-                           If not provided, all placement groups will be
-                           returned.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.placementgroup.PlacementGroup`
-        """
-        params = {}
-        if groupnames:
-            self.build_list_params(params, groupnames, 'GroupName')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribePlacementGroups', params,
-                             [('item', PlacementGroup)], verb='POST')
-
-    def create_placement_group(self, name, strategy='cluster', dry_run=False):
-        """
-        Create a new placement group for your account.
-        This will create the placement group within the region you
-        are currently connected to.
-
-        :type name: string
-        :param name: The name of the new placement group
-
-        :type strategy: string
-        :param strategy: The placement strategy of the new placement group.
-                         Currently, the only acceptable value is "cluster".
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: bool
-        :return: True if successful
-        """
-        params = {'GroupName': name, 'Strategy': strategy}
-        if dry_run:
-            params['DryRun'] = 'true'
-        group = self.get_status('CreatePlacementGroup', params, verb='POST')
-        return group
-
-    def delete_placement_group(self, name, dry_run=False):
-        """
-        Delete a placement group from your account.
-
-        :type key_name: string
-        :param key_name: The name of the keypair to delete
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'GroupName': name}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeletePlacementGroup', params, verb='POST')
-
-    # Tag methods
-
-    def build_tag_param_list(self, params, tags):
-        keys = sorted(tags.keys())
-        i = 1
-        for key in keys:
-            value = tags[key]
-            params['Tag.%d.Key' % i] = key
-            if value is not None:
-                params['Tag.%d.Value' % i] = value
-            i += 1
-
-    def get_all_tags(self, filters=None, dry_run=False, max_results=None):
-        """
-        Retrieve all the metadata tags associated with your account.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.tag.Tag` objects
-        """
-        params = {}
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        if max_results is not None:
-            params['MaxResults'] = max_results
-        return self.get_list('DescribeTags', params,
-                             [('item', Tag)], verb='POST')
-
-    def create_tags(self, resource_ids, tags, dry_run=False):
-        """
-        Create new metadata tags for the specified resource ids.
-
-        :type resource_ids: list
-        :param resource_ids: List of strings
-
-        :type tags: dict
-        :param tags: A dictionary containing the name/value pairs.
-                     If you want to create only a tag name, the
-                     value for that tag should be the empty string
-                     (e.g. '').
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {}
-        self.build_list_params(params, resource_ids, 'ResourceId')
-        self.build_tag_param_list(params, tags)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('CreateTags', params, verb='POST')
-
-    def delete_tags(self, resource_ids, tags, dry_run=False):
-        """
-        Delete metadata tags for the specified resource ids.
-
-        :type resource_ids: list
-        :param resource_ids: List of strings
-
-        :type tags: dict or list
-        :param tags: Either a dictionary containing name/value pairs
-                     or a list containing just tag names.
-                     If you pass in a dictionary, the values must
-                     match the actual tag values or the tag will
-                     not be deleted.  If you pass in a value of None
-                     for the tag value, all tags with that name will
-                     be deleted.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        if isinstance(tags, list):
-            tags = {}.fromkeys(tags, None)
-        params = {}
-        self.build_list_params(params, resource_ids, 'ResourceId')
-        self.build_tag_param_list(params, tags)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteTags', params, verb='POST')
-
-    # Network Interface methods
-
-    def get_all_network_interfaces(self, network_interface_ids=None, filters=None, dry_run=False):
-        """
-        Retrieve all of the Elastic Network Interfaces (ENI's)
-        associated with your account.
-
-        :type network_interface_ids: list
-        :param network_interface_ids: a list of strings representing ENI IDs
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit
-                        the results returned.  Filters are provided
-                        in the form of a dictionary consisting of
-                        filter names as the key and filter values
-                        as the value.  The set of allowable filter
-                        names/values is dependent on the request
-                        being performed.  Check the EC2 API guide
-                        for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: list
-        :return: A list of :class:`boto.ec2.networkinterface.NetworkInterface`
-        """
-        params = {}
-        if network_interface_ids:
-            self.build_list_params(params, network_interface_ids, 'NetworkInterfaceId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeNetworkInterfaces', params,
-                             [('item', NetworkInterface)], verb='POST')
-
-    def create_network_interface(self, subnet_id, private_ip_address=None,
-                                 description=None, groups=None, dry_run=False):
-        """
-        Creates a network interface in the specified subnet.
-
-        :type subnet_id: str
-        :param subnet_id: The ID of the subnet to associate with the
-            network interface.
-
-        :type private_ip_address: str
-        :param private_ip_address: The private IP address of the
-            network interface.  If not supplied, one will be chosen
-            for you.
-
-        :type description: str
-        :param description: The description of the network interface.
-
-        :type groups: list
-        :param groups: Lists the groups for use by the network interface.
-            This can be either a list of group ID's or a list of
-            :class:`boto.ec2.securitygroup.SecurityGroup` objects.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :rtype: :class:`boto.ec2.networkinterface.NetworkInterface`
-        :return: The newly created network interface.
-        """
-        params = {'SubnetId': subnet_id}
-        if private_ip_address:
-            params['PrivateIpAddress'] = private_ip_address
-        if description:
-            params['Description'] = description
-        if groups:
-            ids = []
-            for group in groups:
-                if isinstance(group, SecurityGroup):
-                    ids.append(group.id)
-                else:
-                    ids.append(group)
-            self.build_list_params(params, ids, 'SecurityGroupId')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CreateNetworkInterface', params,
-                               NetworkInterface, verb='POST')
-
-    def attach_network_interface(self, network_interface_id,
-                                 instance_id, device_index, dry_run=False):
-        """
-        Attaches a network interface to an instance.
-
-        :type network_interface_id: str
-        :param network_interface_id: The ID of the network interface to attach.
-
-        :type instance_id: str
-        :param instance_id: The ID of the instance that will be attached
-            to the network interface.
-
-        :type device_index: int
-        :param device_index: The index of the device for the network
-            interface attachment on the instance.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'NetworkInterfaceId': network_interface_id,
-                  'InstanceId': instance_id,
-                  'DeviceIndex': device_index}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('AttachNetworkInterface', params, verb='POST')
-
-    def detach_network_interface(self, attachment_id, force=False,
-                                 dry_run=False):
-        """
-        Detaches a network interface from an instance.
-
-        :type attachment_id: str
-        :param attachment_id: The ID of the attachment.
-
-        :type force: bool
-        :param force: Set to true to force a detachment.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'AttachmentId': attachment_id}
-        if force:
-            params['Force'] = 'true'
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DetachNetworkInterface', params, verb='POST')
-
-    def delete_network_interface(self, network_interface_id, dry_run=False):
-        """
-        Delete the specified network interface.
-
-        :type network_interface_id: str
-        :param network_interface_id: The ID of the network interface to delete.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {'NetworkInterfaceId': network_interface_id}
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('DeleteNetworkInterface', params, verb='POST')
-
-    def get_all_instance_types(self):
-        """
-        Get all instance_types available on this cloud (eucalyptus specific)
-
-        :rtype: list of :class:`boto.ec2.instancetype.InstanceType`
-        :return: The requested InstanceType objects
-        """
-        params = {}
-        return self.get_list('DescribeInstanceTypes', params, [('item', InstanceType)], verb='POST')
-
-    def copy_image(self, source_region, source_image_id, name=None,
-                   description=None, client_token=None, dry_run=False,
-                   encrypted=None, kms_key_id=None):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-        :rtype: :class:`boto.ec2.image.CopyImage`
-        :return: Object containing the image_id of the copied image.
-        """
-        params = {
-            'SourceRegion': source_region,
-            'SourceImageId': source_image_id,
-        }
-        if name is not None:
-            params['Name'] = name
-        if description is not None:
-            params['Description'] = description
-        if client_token is not None:
-            params['ClientToken'] = client_token
-        if encrypted is not None:
-            params['Encrypted'] = 'true' if encrypted else 'false'
-        if kms_key_id is not None:
-            params['KmsKeyId'] = kms_key_id
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('CopyImage', params, CopyImage,
-                               verb='POST')
-
-    def describe_account_attributes(self, attribute_names=None, dry_run=False):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {}
-        if attribute_names is not None:
-            self.build_list_params(params, attribute_names, 'AttributeName')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_list('DescribeAccountAttributes', params,
-                             [('item', AccountAttribute)], verb='POST')
-
-    def describe_vpc_attribute(self, vpc_id, attribute=None, dry_run=False):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {
-            'VpcId': vpc_id
-        }
-        if attribute is not None:
-            params['Attribute'] = attribute
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_object('DescribeVpcAttribute', params,
-                               VPCAttribute, verb='POST')
-
-    def modify_vpc_attribute(self, vpc_id, enable_dns_support=None,
-                             enable_dns_hostnames=None, dry_run=False):
-        """
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        """
-        params = {
-            'VpcId': vpc_id
-        }
-        if enable_dns_support is not None:
-            params['EnableDnsSupport.Value'] = (
-                'true' if enable_dns_support else 'false')
-        if enable_dns_hostnames is not None:
-            params['EnableDnsHostnames.Value'] = (
-                'true' if enable_dns_hostnames else 'false')
-        if dry_run:
-            params['DryRun'] = 'true'
-        return self.get_status('ModifyVpcAttribute', params, verb='POST')
-
-    def get_all_classic_link_instances(self, instance_ids=None, filters=None,
-                                       dry_run=False, max_results=None,
-                                       next_token=None):
-        """
-        Get all of your linked EC2-Classic instances. This request only
-        returns information about EC2-Classic instances linked  to
-        a VPC through ClassicLink
-
-        :type instance_ids: list
-        :param instance_ids: A list of strings of instance IDs. Must be
-            instances linked to a VPC through ClassicLink.
-
-        :type filters: dict
-        :param filters: Optional filters that can be used to limit the
-            results returned.  Filters are provided in the form of a
-            dictionary consisting of filter names as the key and
-            filter values as the value.  The set of allowable filter
-            names/values is dependent on the request being performed.
-            Check the EC2 API guide for details.
-
-        :type dry_run: bool
-        :param dry_run: Set to True if the operation should not actually run.
-
-        :type max_results: int
-        :param max_results: The maximum number of paginated instance
-            items per response.
-
-        :rtype: list
-        :return: A list of  :class:`boto.ec2.instance.Instance`
-        """
-        params = {}
-        if instance_ids:
-            self.build_list_params(params, instance_ids, 'InstanceId')
-        if filters:
-            self.build_filter_params(params, filters)
-        if dry_run:
-            params['DryRun'] = 'true'
-        if max_results is not None:
-            params['MaxResults'] = max_results
-        if next_token:
-            params['NextToken'] = next_token
-        return self.get_list('DescribeClassicLinkInstances', params,
-                             [('item', Instance)], verb='POST')