Guest User

connections.py

a guest
Aug 19th, 2016
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 179.17 KB | None | 0 0
  1. # Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
  2. # Copyright (c) 2010, Eucalyptus Systems, Inc.
  3. # Copyright (c) 2013 Amazon.com, Inc. or its affiliates.  All Rights Reserved
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the
  7. # "Software"), to deal in the Software without restriction, including
  8. # without limitation the rights to use, copy, modify, merge, publish, dis-
  9. # tribute, sublicense, and/or sell copies of the Software, and to permit
  10. # persons to whom the Software is furnished to do so, subject to the fol-
  11. # lowing conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included
  14. # in all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  18. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  19. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. # IN THE SOFTWARE.
  23.  
  24. """
  25. Represents a connection to the EC2 service.
  26. """
  27.  
  28. import base64
  29. import warnings
  30. from datetime import datetime
  31. from datetime import timedelta
  32.  
  33. import boto
  34. from boto.auth import detect_potential_sigv4
  35. from boto.connection import AWSQueryConnection
  36. from boto.resultset import ResultSet
  37. from boto.ec2.image import Image, ImageAttribute, CopyImage
  38. from boto.ec2.instance import Reservation, Instance
  39. from boto.ec2.instance import ConsoleOutput, InstanceAttribute
  40. from boto.ec2.keypair import KeyPair
  41. from boto.ec2.address import Address
  42. from boto.ec2.volume import Volume, VolumeAttribute
  43. from boto.ec2.snapshot import Snapshot
  44. from boto.ec2.snapshot import SnapshotAttribute
  45. from boto.ec2.zone import Zone
  46. from boto.ec2.securitygroup import SecurityGroup
  47. from boto.ec2.regioninfo import RegionInfo
  48. from boto.ec2.instanceinfo import InstanceInfo
  49. from boto.ec2.reservedinstance import ReservedInstancesOffering
  50. from boto.ec2.reservedinstance import ReservedInstance
  51. from boto.ec2.reservedinstance import ReservedInstanceListing
  52. from boto.ec2.reservedinstance import ReservedInstancesConfiguration
  53. from boto.ec2.reservedinstance import ModifyReservedInstancesResult
  54. from boto.ec2.reservedinstance import ReservedInstancesModification
  55. from boto.ec2.spotinstancerequest import SpotInstanceRequest
  56. from boto.ec2.spotpricehistory import SpotPriceHistory
  57. from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
  58. from boto.ec2.bundleinstance import BundleInstanceTask
  59. from boto.ec2.placementgroup import PlacementGroup
  60. from boto.ec2.tag import Tag
  61. from boto.ec2.instancetype import InstanceType
  62. from boto.ec2.instancestatus import InstanceStatusSet
  63. from boto.ec2.volumestatus import VolumeStatusSet
  64. from boto.ec2.networkinterface import NetworkInterface
  65. from boto.ec2.attributes import AccountAttribute, VPCAttribute
  66. from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
  67. from boto.exception import EC2ResponseError
  68. from boto.compat import six
  69.  
  70. #boto.set_stream_logger('ec2')
  71.  
  72.  
  73. class EC2Connection(AWSQueryConnection):
  74.  
  75.     APIVersion = boto.config.get('Boto', 'ec2_version', '2014-10-01')
  76.     DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
  77.     DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
  78.                                             'ec2.us-east-1.amazonaws.com')
  79.     ResponseError = EC2ResponseError
  80.  
  81.     def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
  82.                  is_secure=True, host=None, port=None,
  83.                  proxy=None, proxy_port=None,
  84.                  proxy_user=None, proxy_pass=None, debug=0,
  85.                  https_connection_factory=None, region=None, path='/',
  86.                  api_version=None, security_token=None,
  87.                  validate_certs=True, profile_name=None):
  88.         """
  89.        Init method to create a new connection to EC2.
  90.        """
  91.         if not region:
  92.             region = RegionInfo(self, self.DefaultRegionName,
  93.                                 self.DefaultRegionEndpoint)
  94.         self.region = region
  95.         super(EC2Connection, self).__init__(aws_access_key_id,
  96.                                             aws_secret_access_key,
  97.                                             is_secure, port, proxy, proxy_port,
  98.                                             proxy_user, proxy_pass,
  99.                                             self.region.endpoint, debug,
  100.                                             https_connection_factory, path,
  101.                                             security_token,
  102.                                             validate_certs=validate_certs,
  103.                                             profile_name=profile_name)
  104.         if api_version:
  105.             self.APIVersion = api_version
  106.  
  107.     def _required_auth_capability(self):
  108.         return ['hmac-v4']
  109.  
  110.     def get_params(self):
  111.         """
  112.        Returns a dictionary containing the value of all of the keyword
  113.        arguments passed when constructing this connection.
  114.        """
  115.         param_names = ['aws_access_key_id', 'aws_secret_access_key',
  116.                        'is_secure', 'port', 'proxy', 'proxy_port',
  117.                        'proxy_user', 'proxy_pass',
  118.                        'debug', 'https_connection_factory']
  119.         params = {}
  120.         for name in param_names:
  121.             params[name] = getattr(self, name)
  122.         return params
  123.  
  124.     def build_filter_params(self, params, filters):
  125.         if not isinstance(filters, dict):
  126.             filters = dict(filters)
  127.  
  128.         i = 1
  129.         for name in filters:
  130.             aws_name = name
  131.             if not aws_name.startswith('tag:'):
  132.                 aws_name = name.replace('_', '-')
  133.             params['Filter.%d.Name' % i] = aws_name
  134.             value = filters[name]
  135.             if not isinstance(value, list):
  136.                 value = [value]
  137.             j = 1
  138.             for v in value:
  139.                 params['Filter.%d.Value.%d' % (i, j)] = v
  140.                 j += 1
  141.             i += 1
  142.  
  143.     # Image methods
  144.  
  145.     def get_all_images(self, image_ids=None, owners=None,
  146.                        executable_by=None, filters=None, dry_run=False):
  147.         """
  148.        Retrieve all the EC2 images available on your account.
  149.  
  150.        :type image_ids: list
  151.        :param image_ids: A list of strings with the image IDs wanted
  152.  
  153.        :type owners: list
  154.        :param owners: A list of owner IDs, the special strings 'self',
  155.            'amazon', and 'aws-marketplace', may be used to describe
  156.            images owned by you, Amazon or AWS Marketplace
  157.            respectively
  158.  
  159.        :type executable_by: list
  160.        :param executable_by: Returns AMIs for which the specified
  161.                              user ID has explicit launch permissions
  162.  
  163.        :type filters: dict
  164.        :param filters: Optional filters that can be used to limit the
  165.            results returned.  Filters are provided in the form of a
  166.            dictionary consisting of filter names as the key and
  167.            filter values as the value.  The set of allowable filter
  168.            names/values is dependent on the request being performed.
  169.            Check the EC2 API guide for details.
  170.  
  171.        :type dry_run: bool
  172.        :param dry_run: Set to True if the operation should not actually run.
  173.  
  174.        :rtype: list
  175.        :return: A list of :class:`boto.ec2.image.Image`
  176.        """
  177.         params = {}
  178.         if image_ids:
  179.             self.build_list_params(params, image_ids, 'ImageId')
  180.         if owners:
  181.             self.build_list_params(params, owners, 'Owner')
  182.         if executable_by:
  183.             self.build_list_params(params, executable_by, 'ExecutableBy')
  184.         if filters:
  185.             self.build_filter_params(params, filters)
  186.         if dry_run:
  187.             params['DryRun'] = 'true'
  188.         return self.get_list('DescribeImages', params,
  189.                              [('item', Image)], verb='POST')
  190.  
  191.     def get_all_kernels(self, kernel_ids=None, owners=None, dry_run=False):
  192.         """
  193.        Retrieve all the EC2 kernels available on your account.
  194.        Constructs a filter to allow the processing to happen server side.
  195.  
  196.        :type kernel_ids: list
  197.        :param kernel_ids: A list of strings with the image IDs wanted
  198.  
  199.        :type owners: list
  200.        :param owners: A list of owner IDs
  201.  
  202.        :type dry_run: bool
  203.        :param dry_run: Set to True if the operation should not actually run.
  204.  
  205.        :rtype: list
  206.        :return: A list of :class:`boto.ec2.image.Image`
  207.        """
  208.         params = {}
  209.         if kernel_ids:
  210.             self.build_list_params(params, kernel_ids, 'ImageId')
  211.         if owners:
  212.             self.build_list_params(params, owners, 'Owner')
  213.         filter = {'image-type': 'kernel'}
  214.         self.build_filter_params(params, filter)
  215.         if dry_run:
  216.             params['DryRun'] = 'true'
  217.         return self.get_list('DescribeImages', params,
  218.                              [('item', Image)], verb='POST')
  219.  
  220.     def get_all_ramdisks(self, ramdisk_ids=None, owners=None, dry_run=False):
  221.         """
  222.        Retrieve all the EC2 ramdisks available on your account.
  223.        Constructs a filter to allow the processing to happen server side.
  224.  
  225.        :type ramdisk_ids: list
  226.        :param ramdisk_ids: A list of strings with the image IDs wanted
  227.  
  228.        :type owners: list
  229.        :param owners: A list of owner IDs
  230.  
  231.        :type dry_run: bool
  232.        :param dry_run: Set to True if the operation should not actually run.
  233.  
  234.        :rtype: list
  235.        :return: A list of :class:`boto.ec2.image.Image`
  236.        """
  237.         params = {}
  238.         if ramdisk_ids:
  239.             self.build_list_params(params, ramdisk_ids, 'ImageId')
  240.         if owners:
  241.             self.build_list_params(params, owners, 'Owner')
  242.         filter = {'image-type': 'ramdisk'}
  243.         self.build_filter_params(params, filter)
  244.         if dry_run:
  245.             params['DryRun'] = 'true'
  246.         return self.get_list('DescribeImages', params,
  247.                              [('item', Image)], verb='POST')
  248.  
  249.     def get_image(self, image_id, dry_run=False):
  250.         """
  251.        Shortcut method to retrieve a specific image (AMI).
  252.  
  253.        :type image_id: string
  254.        :param image_id: the ID of the Image to retrieve
  255.  
  256.        :type dry_run: bool
  257.        :param dry_run: Set to True if the operation should not actually run.
  258.  
  259.        :rtype: :class:`boto.ec2.image.Image`
  260.        :return: The EC2 Image specified or None if the image is not found
  261.        """
  262.         try:
  263.             return self.get_all_images(image_ids=[image_id], dry_run=dry_run)[0]
  264.         except IndexError:  # None of those images available
  265.             return None
  266.  
  267.     def register_image(self, name=None, description=None, image_location=None,
  268.                        architecture=None, kernel_id=None, ramdisk_id=None,
  269.                        root_device_name=None, block_device_map=None,
  270.                        dry_run=False, virtualization_type=None,
  271.                        sriov_net_support=None,
  272.                        snapshot_id=None,
  273.                        delete_root_volume_on_termination=False):
  274.         """
  275.        Register an image.
  276.  
  277.        :type name: string
  278.        :param name: The name of the AMI.  Valid only for EBS-based images.
  279.  
  280.        :type description: string
  281.        :param description: The description of the AMI.
  282.  
  283.        :type image_location: string
  284.        :param image_location: Full path to your AMI manifest in
  285.            Amazon S3 storage.  Only used for S3-based AMI's.
  286.  
  287.        :type architecture: string
  288.        :param architecture: The architecture of the AMI.  Valid choices are:
  289.            * i386
  290.            * x86_64
  291.  
  292.        :type kernel_id: string
  293.        :param kernel_id: The ID of the kernel with which to launch
  294.            the instances
  295.  
  296.        :type root_device_name: string
  297.        :param root_device_name: The root device name (e.g. /dev/sdh)
  298.  
  299.        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
  300.        :param block_device_map: A BlockDeviceMapping data structure
  301.            describing the EBS volumes associated with the Image.
  302.  
  303.        :type dry_run: bool
  304.        :param dry_run: Set to True if the operation should not actually run.
  305.  
  306.        :type virtualization_type: string
  307.        :param virtualization_type: The virutalization_type of the image.
  308.            Valid choices are:
  309.            * paravirtual
  310.            * hvm
  311.  
  312.        :type sriov_net_support: string
  313.        :param sriov_net_support: Advanced networking support.
  314.            Valid choices are:
  315.            * simple
  316.  
  317.        :type snapshot_id: string
  318.        :param snapshot_id: A snapshot ID for the snapshot to be used
  319.            as root device for the image. Mutually exclusive with
  320.            block_device_map, requires root_device_name
  321.  
  322.        :type delete_root_volume_on_termination: bool
  323.        :param delete_root_volume_on_termination: Whether to delete the root
  324.            volume of the image after instance termination. Only applies when
  325.            creating image from snapshot_id. Defaults to False.  Note that
  326.            leaving volumes behind after instance termination is not free.
  327.  
  328.        :rtype: string
  329.        :return: The new image id
  330.        """
  331.         params = {}
  332.         if name:
  333.             params['Name'] = name
  334.         if description:
  335.             params['Description'] = description
  336.         if architecture:
  337.             params['Architecture'] = architecture
  338.         if kernel_id:
  339.             params['KernelId'] = kernel_id
  340.         if ramdisk_id:
  341.             params['RamdiskId'] = ramdisk_id
  342.         if image_location:
  343.             params['ImageLocation'] = image_location
  344.         if root_device_name:
  345.             params['RootDeviceName'] = root_device_name
  346.         if snapshot_id:
  347.             root_vol = BlockDeviceType(snapshot_id=snapshot_id,
  348.                 delete_on_termination=delete_root_volume_on_termination)
  349.             block_device_map = BlockDeviceMapping()
  350.             block_device_map[root_device_name] = root_vol
  351.         if block_device_map:
  352.             block_device_map.ec2_build_list_params(params)
  353.         if dry_run:
  354.             params['DryRun'] = 'true'
  355.         if virtualization_type:
  356.             params['VirtualizationType'] = virtualization_type
  357.         if sriov_net_support:
  358.             params['SriovNetSupport'] = sriov_net_support
  359.  
  360.         rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
  361.         image_id = getattr(rs, 'imageId', None)
  362.         return image_id
  363.  
  364.     def deregister_image(self, image_id, delete_snapshot=False, dry_run=False):
  365.         """
  366.        Unregister an AMI.
  367.  
  368.        :type image_id: string
  369.        :param image_id: the ID of the Image to unregister
  370.  
  371.        :type delete_snapshot: bool
  372.        :param delete_snapshot: Set to True if we should delete the
  373.            snapshot associated with an EBS volume mounted at /dev/sda1
  374.  
  375.        :type dry_run: bool
  376.        :param dry_run: Set to True if the operation should not actually run.
  377.  
  378.        :rtype: bool
  379.        :return: True if successful
  380.        """
  381.         snapshot_id = None
  382.         if delete_snapshot:
  383.             image = self.get_image(image_id)
  384.             for key in image.block_device_mapping:
  385.                 if key == "/dev/sda1":
  386.                     snapshot_id = image.block_device_mapping[key].snapshot_id
  387.                     break
  388.         params = {
  389.             'ImageId': image_id,
  390.         }
  391.         if dry_run:
  392.             params['DryRun'] = 'true'
  393.         result = self.get_status('DeregisterImage',
  394.                                  params, verb='POST')
  395.         if result and snapshot_id:
  396.             return result and self.delete_snapshot(snapshot_id)
  397.         return result
  398.  
  399.     def create_image(self, instance_id, name,
  400.                      description=None, no_reboot=False,
  401.                      block_device_mapping=None, dry_run=False):
  402.         """
  403.        Will create an AMI from the instance in the running or stopped
  404.        state.
  405.  
  406.        :type instance_id: string
  407.        :param instance_id: the ID of the instance to image.
  408.  
  409.        :type name: string
  410.        :param name: The name of the new image
  411.  
  412.        :type description: string
  413.        :param description: An optional human-readable string describing
  414.            the contents and purpose of the AMI.
  415.  
  416.        :type no_reboot: bool
  417.        :param no_reboot: An optional flag indicating that the
  418.            bundling process should not attempt to shutdown the
  419.            instance before bundling.  If this flag is True, the
  420.            responsibility of maintaining file system integrity is
  421.            left to the owner of the instance.
  422.  
  423.        :type block_device_mapping: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
  424.        :param block_device_mapping: A BlockDeviceMapping data structure
  425.            describing the EBS volumes associated with the Image.
  426.  
  427.        :type dry_run: bool
  428.        :param dry_run: Set to True if the operation should not actually run.
  429.  
  430.        :rtype: string
  431.        :return: The new image id
  432.        """
  433.         params = {'InstanceId': instance_id,
  434.                   'Name': name}
  435.         if description:
  436.             params['Description'] = description
  437.         if no_reboot:
  438.             params['NoReboot'] = 'true'
  439.         if block_device_mapping:
  440.             block_device_mapping.ec2_build_list_params(params)
  441.         if dry_run:
  442.             params['DryRun'] = 'true'
  443.         img = self.get_object('CreateImage', params, Image, verb='POST')
  444.         return img.id
  445.  
  446.     # ImageAttribute methods
  447.  
  448.     def get_image_attribute(self, image_id, attribute='launchPermission',
  449.                             dry_run=False):
  450.         """
  451.        Gets an attribute from an image.
  452.  
  453.        :type image_id: string
  454.        :param image_id: The Amazon image id for which you want info about
  455.  
  456.        :type attribute: string
  457.        :param attribute: The attribute you need information about.
  458.            Valid choices are:
  459.            * launchPermission
  460.            * productCodes
  461.            * blockDeviceMapping
  462.  
  463.        :type dry_run: bool
  464.        :param dry_run: Set to True if the operation should not actually run.
  465.  
  466.        :rtype: :class:`boto.ec2.image.ImageAttribute`
  467.        :return: An ImageAttribute object representing the value of the
  468.                 attribute requested
  469.        """
  470.         params = {'ImageId': image_id,
  471.                   'Attribute': attribute}
  472.         if dry_run:
  473.             params['DryRun'] = 'true'
  474.         return self.get_object('DescribeImageAttribute', params,
  475.                                ImageAttribute, verb='POST')
  476.  
  477.     def modify_image_attribute(self, image_id, attribute='launchPermission',
  478.                                operation='add', user_ids=None, groups=None,
  479.                                product_codes=None, dry_run=False):
  480.         """
  481.        Changes an attribute of an image.
  482.  
  483.        :type image_id: string
  484.        :param image_id: The image id you wish to change
  485.  
  486.        :type attribute: string
  487.        :param attribute: The attribute you wish to change
  488.  
  489.        :type operation: string
  490.        :param operation: Either add or remove (this is required for changing
  491.            launchPermissions)
  492.  
  493.        :type user_ids: list
  494.        :param user_ids: The Amazon IDs of users to add/remove attributes
  495.  
  496.        :type groups: list
  497.        :param groups: The groups to add/remove attributes
  498.  
  499.        :type product_codes: list
  500.        :param product_codes: Amazon DevPay product code. Currently only one
  501.            product code can be associated with an AMI. Once
  502.            set, the product code cannot be changed or reset.
  503.  
  504.        :type dry_run: bool
  505.        :param dry_run: Set to True if the operation should not actually run.
  506.  
  507.        """
  508.         params = {'ImageId': image_id,
  509.                   'Attribute': attribute,
  510.                   'OperationType': operation}
  511.         if user_ids:
  512.             self.build_list_params(params, user_ids, 'UserId')
  513.         if groups:
  514.             self.build_list_params(params, groups, 'UserGroup')
  515.         if product_codes:
  516.             self.build_list_params(params, product_codes, 'ProductCode')
  517.         if dry_run:
  518.             params['DryRun'] = 'true'
  519.         return self.get_status('ModifyImageAttribute', params, verb='POST')
  520.  
  521.     def reset_image_attribute(self, image_id, attribute='launchPermission',
  522.                               dry_run=False):
  523.         """
  524.        Resets an attribute of an AMI to its default value.
  525.  
  526.        :type image_id: string
  527.        :param image_id: ID of the AMI for which an attribute will be described
  528.  
  529.        :type attribute: string
  530.        :param attribute: The attribute to reset
  531.  
  532.        :type dry_run: bool
  533.        :param dry_run: Set to True if the operation should not actually run.
  534.  
  535.        :rtype: bool
  536.        :return: Whether the operation succeeded or not
  537.        """
  538.         params = {'ImageId': image_id,
  539.                   'Attribute': attribute}
  540.         if dry_run:
  541.             params['DryRun'] = 'true'
  542.         return self.get_status('ResetImageAttribute', params, verb='POST')
  543.  
  544.     # Instance methods
  545.  
  546.     def get_all_instances(self, instance_ids=None, filters=None, dry_run=False,
  547.                           max_results=None):
  548.         """
  549.        Retrieve all the instance reservations associated with your account.
  550.  
  551.        .. note::
  552.        This method's current behavior is deprecated in favor of
  553.        :meth:`get_all_reservations`.  A future major release will change
  554.        :meth:`get_all_instances` to return a list of
  555.        :class:`boto.ec2.instance.Instance` objects as its name suggests.
  556.        To obtain that behavior today, use :meth:`get_only_instances`.
  557.  
  558.        :type instance_ids: list
  559.        :param instance_ids: A list of strings of instance IDs
  560.  
  561.        :type filters: dict
  562.        :param filters: Optional filters that can be used to limit the
  563.            results returned.  Filters are provided in the form of a
  564.            dictionary consisting of filter names as the key and
  565.            filter values as the value.  The set of allowable filter
  566.            names/values is dependent on the request being performed.
  567.            Check the EC2 API guide for details.
  568.  
  569.        :type dry_run: bool
  570.        :param dry_run: Set to True if the operation should not actually run.
  571.  
  572.        :type max_results: int
  573.        :param max_results: The maximum number of paginated instance
  574.            items per response.
  575.  
  576.        :rtype: list
  577.        :return: A list of  :class:`boto.ec2.instance.Reservation`
  578.  
  579.        """
  580.         warnings.warn(('The current get_all_instances implementation will be '
  581.                        'replaced with get_all_reservations.'),
  582.                       PendingDeprecationWarning)
  583.         return self.get_all_reservations(instance_ids=instance_ids,
  584.                                          filters=filters, dry_run=dry_run,
  585.                                          max_results=max_results)
  586.  
  587.     def get_only_instances(self, instance_ids=None, filters=None,
  588.                            dry_run=False, max_results=None):
  589.         # A future release should rename this method to get_all_instances
  590.         # and make get_only_instances an alias for that.
  591.         """
  592.        Retrieve all the instances associated with your account.
  593.  
  594.        :type instance_ids: list
  595.        :param instance_ids: A list of strings of instance IDs
  596.  
  597.        :type filters: dict
  598.        :param filters: Optional filters that can be used to limit the
  599.            results returned.  Filters are provided in the form of a
  600.            dictionary consisting of filter names as the key and
  601.            filter values as the value.  The set of allowable filter
  602.            names/values is dependent on the request being performed.
  603.            Check the EC2 API guide for details.
  604.  
  605.        :type dry_run: bool
  606.        :param dry_run: Set to True if the operation should not actually run.
  607.  
  608.        :type max_results: int
  609.        :param max_results: The maximum number of paginated instance
  610.            items per response.
  611.  
  612.        :rtype: list
  613.        :return: A list of  :class:`boto.ec2.instance.Instance`
  614.        """
  615.         next_token = None
  616.         retval = []
  617.         while True:
  618.             reservations = self.get_all_reservations(instance_ids=instance_ids,
  619.                                                      filters=filters,
  620.                                                      dry_run=dry_run,
  621.                                                      max_results=max_results,
  622.                                                      next_token=next_token)
  623.             retval.extend([instance for reservation in reservations for
  624.                            instance in reservation.instances])
  625.             next_token = reservations.next_token
  626.             if not next_token:
  627.                 break
  628.  
  629.         return retval
  630.  
  631.     def get_all_reservations(self, instance_ids=None, filters=None,
  632.                              dry_run=False, max_results=None, next_token=None):
  633.         """
  634.        Retrieve all the instance reservations associated with your account.
  635.  
  636.        :type instance_ids: list
  637.        :param instance_ids: A list of strings of instance IDs
  638.  
  639.        :type filters: dict
  640.        :param filters: Optional filters that can be used to limit the
  641.            results returned.  Filters are provided in the form of a
  642.            dictionary consisting of filter names as the key and
  643.            filter values as the value.  The set of allowable filter
  644.            names/values is dependent on the request being performed.
  645.            Check the EC2 API guide for details.
  646.  
  647.        :type dry_run: bool
  648.        :param dry_run: Set to True if the operation should not actually run.
  649.  
  650.        :type max_results: int
  651.        :param max_results: The maximum number of paginated instance
  652.            items per response.
  653.  
  654.        :type next_token: str
  655.        :param next_token: A string specifying the next paginated set
  656.            of results to return.
  657.  
  658.        :rtype: list
  659.        :return: A list of  :class:`boto.ec2.instance.Reservation`
  660.        """
  661.         params = {}
  662.         if instance_ids:
  663.             self.build_list_params(params, instance_ids, 'InstanceId')
  664.         if filters:
  665.             if 'group-id' in filters:
  666.                 gid = filters.get('group-id')
  667.                 if not gid.startswith('sg-') or len(gid) != 11:
  668.                     warnings.warn(
  669.                         "The group-id filter now requires a security group "
  670.                         "identifier (sg-*) instead of a group name. To filter "
  671.                         "by group name use the 'group-name' filter instead.",
  672.                         UserWarning)
  673.             self.build_filter_params(params, filters)
  674.         if dry_run:
  675.             params['DryRun'] = 'true'
  676.         if max_results is not None:
  677.             params['MaxResults'] = max_results
  678.         if next_token:
  679.             params['NextToken'] = next_token
  680.         return self.get_list('DescribeInstances', params,
  681.                              [('item', Reservation)], verb='POST')
  682.  
  683.     def get_all_instance_status(self, instance_ids=None,
  684.                                 max_results=None, next_token=None,
  685.                                 filters=None, dry_run=False,
  686.                                 include_all_instances=False):
  687.         """
  688.        Retrieve all the instances in your account scheduled for maintenance.
  689.  
  690.        :type instance_ids: list
  691.        :param instance_ids: A list of strings of instance IDs
  692.  
  693.        :type max_results: int
  694.        :param max_results: The maximum number of paginated instance
  695.            items per response.
  696.  
  697.        :type next_token: str
  698.        :param next_token: A string specifying the next paginated set
  699.            of results to return.
  700.  
  701.        :type filters: dict
  702.        :param filters: Optional filters that can be used to limit
  703.            the results returned.  Filters are provided
  704.            in the form of a dictionary consisting of
  705.            filter names as the key and filter values
  706.            as the value.  The set of allowable filter
  707.            names/values is dependent on the request
  708.            being performed.  Check the EC2 API guide
  709.            for details.
  710.  
  711.        :type dry_run: bool
  712.        :param dry_run: Set to True if the operation should not actually run.
  713.  
  714.        :type include_all_instances: bool
  715.        :param include_all_instances: Set to True if all
  716.            instances should be returned. (Only running
  717.            instances are included by default.)
  718.  
  719.        :rtype: list
  720.        :return: A list of instances that have maintenance scheduled.
  721.        """
  722.         params = {}
  723.         if instance_ids:
  724.             self.build_list_params(params, instance_ids, 'InstanceId')
  725.         if max_results:
  726.             params['MaxResults'] = max_results
  727.         if next_token:
  728.             params['NextToken'] = next_token
  729.         if filters:
  730.             self.build_filter_params(params, filters)
  731.         if dry_run:
  732.             params['DryRun'] = 'true'
  733.         if include_all_instances:
  734.             params['IncludeAllInstances'] = 'true'
  735.         return self.get_object('DescribeInstanceStatus', params,
  736.                                InstanceStatusSet, verb='POST')
  737.  
  738.     def run_instances(self, image_id, min_count=1, max_count=1,
  739.                       key_name=None, security_groups=None,
  740.                       user_data=None, addressing_type=None,
  741.                       instance_type='m1.small', placement=None,
  742.                       kernel_id=None, ramdisk_id=None,
  743.                       monitoring_enabled=False, subnet_id=None,
  744.                       block_device_map=None,
  745.                       disable_api_termination=False,
  746.                       instance_initiated_shutdown_behavior=None,
  747.                       private_ip_address=None,
  748.                       placement_group=None, client_token=None,
  749.                       security_group_ids=None,
  750.                       additional_info=None, instance_profile_name=None,
  751.                       instance_profile_arn=None, tenancy=None,
  752.                       ebs_optimized=False, network_interfaces=None,
  753.                       dry_run=False):
  754.         """
  755.        Runs an image on EC2.
  756.  
  757.        :type image_id: string
  758.        :param image_id: The ID of the image to run.
  759.  
  760.        :type min_count: int
  761.        :param min_count: The minimum number of instances to launch.
  762.  
  763.        :type max_count: int
  764.        :param max_count: The maximum number of instances to launch.
  765.  
  766.        :type key_name: string
  767.        :param key_name: The name of the key pair with which to
  768.            launch instances.
  769.  
  770.        :type security_groups: list of strings
  771.        :param security_groups: The names of the EC2 classic security groups
  772.            with which to associate instances
  773.  
  774.        :type user_data: string
  775.        :param user_data: The user data passed to the launched instances
  776.  
  777.        :type instance_type: string
  778.        :param instance_type: The type of instance to run:
  779.  
  780.            * t1.micro
  781.            * m1.small
  782.            * m1.medium
  783.            * m1.large
  784.            * m1.xlarge
  785.            * m3.medium
  786.            * m3.large
  787.            * m3.xlarge
  788.            * m3.2xlarge
  789.            * c1.medium
  790.            * c1.xlarge
  791.            * m2.xlarge
  792.            * m2.2xlarge
  793.            * m2.4xlarge
  794.            * cr1.8xlarge
  795.            * hi1.4xlarge
  796.            * hs1.8xlarge
  797.            * cc1.4xlarge
  798.            * cg1.4xlarge
  799.            * cc2.8xlarge
  800.            * g2.2xlarge
  801.            * c3.large
  802.            * c3.xlarge
  803.            * c3.2xlarge
  804.            * c3.4xlarge
  805.            * c3.8xlarge
  806.            * c4.large
  807.            * c4.xlarge
  808.            * c4.2xlarge
  809.            * c4.4xlarge
  810.            * c4.8xlarge
  811.            * i2.xlarge
  812.            * i2.2xlarge
  813.            * i2.4xlarge
  814.            * i2.8xlarge
  815.            * t2.micro
  816.            * t2.small
  817.            * t2.medium
  818.  
  819.        :type placement: string
  820.        :param placement: The Availability Zone to launch the instance into.
  821.  
  822.        :type kernel_id: string
  823.        :param kernel_id: The ID of the kernel with which to launch the
  824.            instances.
  825.  
  826.        :type ramdisk_id: string
  827.        :param ramdisk_id: The ID of the RAM disk with which to launch the
  828.            instances.
  829.  
  830.        :type monitoring_enabled: bool
  831.        :param monitoring_enabled: Enable detailed CloudWatch monitoring on
  832.            the instance.
  833.  
  834.        :type subnet_id: string
  835.        :param subnet_id: The subnet ID within which to launch the instances
  836.            for VPC.
  837.  
  838.        :type private_ip_address: string
  839.        :param private_ip_address: If you're using VPC, you can
  840.            optionally use this parameter to assign the instance a
  841.            specific available IP address from the subnet (e.g.,
  842.            10.0.0.25).
  843.  
  844.        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
  845.        :param block_device_map: A BlockDeviceMapping data structure
  846.            describing the EBS volumes associated with the Image.
  847.  
  848.        :type disable_api_termination: bool
  849.        :param disable_api_termination: If True, the instances will be locked
  850.            and will not be able to be terminated via the API.
  851.  
  852.        :type instance_initiated_shutdown_behavior: string
  853.        :param instance_initiated_shutdown_behavior: Specifies whether the
  854.            instance stops or terminates on instance-initiated shutdown.
  855.            Valid values are:
  856.  
  857.            * stop
  858.            * terminate
  859.  
  860.        :type placement_group: string
  861.        :param placement_group: If specified, this is the name of the placement
  862.            group in which the instance(s) will be launched.
  863.  
  864.        :type client_token: string
  865.        :param client_token: Unique, case-sensitive identifier you provide
  866.            to ensure idempotency of the request. Maximum 64 ASCII characters.
  867.  
  868.        :type security_group_ids: list of strings
  869.        :param security_group_ids: The ID of the VPC security groups with
  870.            which to associate instances.
  871.  
  872.        :type additional_info: string
  873.        :param additional_info: Specifies additional information to make
  874.            available to the instance(s).
  875.  
  876.        :type tenancy: string
  877.        :param tenancy: The tenancy of the instance you want to
  878.            launch. An instance with a tenancy of 'dedicated' runs on
  879.            single-tenant hardware and can only be launched into a
  880.            VPC. Valid values are:"default" or "dedicated".
  881.            NOTE: To use dedicated tenancy you MUST specify a VPC
  882.            subnet-ID as well.
  883.  
  884.        :type instance_profile_arn: string
  885.        :param instance_profile_arn: The Amazon resource name (ARN) of
  886.            the IAM Instance Profile (IIP) to associate with the instances.
  887.  
  888.        :type instance_profile_name: string
  889.        :param instance_profile_name: The name of
  890.            the IAM Instance Profile (IIP) to associate with the instances.
  891.  
  892.        :type ebs_optimized: bool
  893.        :param ebs_optimized: Whether the instance is optimized for
  894.            EBS I/O.  This optimization provides dedicated throughput
  895.            to Amazon EBS and an optimized configuration stack to
  896.            provide optimal EBS I/O performance.  This optimization
  897.            isn't available with all instance types.
  898.  
  899.        :type network_interfaces: :class:`boto.ec2.networkinterface.NetworkInterfaceCollection`
  900.        :param network_interfaces: A NetworkInterfaceCollection data
  901.            structure containing the ENI specifications for the instance.
  902.  
  903.        :type dry_run: bool
  904.        :param dry_run: Set to True if the operation should not actually run.
  905.  
  906.        :rtype: Reservation
  907.        :return: The :class:`boto.ec2.instance.Reservation` associated with
  908.                 the request for machines
  909.        """
  910.         params = {'ImageId': image_id,
  911.                   'MinCount': min_count,
  912.                   'MaxCount': max_count}
  913.         if key_name:
  914.             params['KeyName'] = key_name
  915.         if security_group_ids:
  916.             l = []
  917.             for group in security_group_ids:
  918.                 if isinstance(group, SecurityGroup):
  919.                     l.append(group.id)
  920.                 else:
  921.                     l.append(group)
  922.             self.build_list_params(params, l, 'SecurityGroupId')
  923.         if security_groups:
  924.             l = []
  925.             for group in security_groups:
  926.                 if isinstance(group, SecurityGroup):
  927.                     l.append(group.name)
  928.                 else:
  929.                     l.append(group)
  930.             self.build_list_params(params, l, 'SecurityGroup')
  931.         if user_data:
  932.             if isinstance(user_data, six.text_type):
  933.                 user_data = user_data.encode('utf-8')
  934.             params['UserData'] = base64.b64encode(user_data).decode('utf-8')
  935.         if addressing_type:
  936.             params['AddressingType'] = addressing_type
  937.         if instance_type:
  938.             params['InstanceType'] = instance_type
  939.         if placement:
  940.             params['Placement.AvailabilityZone'] = placement
  941.         if placement_group:
  942.             params['Placement.GroupName'] = placement_group
  943.         if tenancy:
  944.             params['Placement.Tenancy'] = tenancy
  945.         if kernel_id:
  946.             params['KernelId'] = kernel_id
  947.         if ramdisk_id:
  948.             params['RamdiskId'] = ramdisk_id
  949.         if monitoring_enabled:
  950.             params['Monitoring.Enabled'] = 'true'
  951.         if subnet_id:
  952.             params['SubnetId'] = subnet_id
  953.         if private_ip_address:
  954.             params['PrivateIpAddress'] = private_ip_address
  955.         if block_device_map:
  956.             block_device_map.ec2_build_list_params(params)
  957.         if disable_api_termination:
  958.             params['DisableApiTermination'] = 'true'
  959.         if instance_initiated_shutdown_behavior:
  960.             val = instance_initiated_shutdown_behavior
  961.             params['InstanceInitiatedShutdownBehavior'] = val
  962.         if client_token:
  963.             params['ClientToken'] = client_token
  964.         if additional_info:
  965.             params['AdditionalInfo'] = additional_info
  966.         if instance_profile_name:
  967.             params['IamInstanceProfile.Name'] = instance_profile_name
  968.         if instance_profile_arn:
  969.             params['IamInstanceProfile.Arn'] = instance_profile_arn
  970.         if ebs_optimized:
  971.             params['EbsOptimized'] = 'true'
  972.         if network_interfaces:
  973.             network_interfaces.build_list_params(params)
  974.         if dry_run:
  975.             params['DryRun'] = 'true'
  976.         return self.get_object('RunInstances', params, Reservation,
  977.                                verb='POST')
  978.  
  979.     def terminate_instances(self, instance_ids=None, dry_run=False):
  980.         """
  981.        Terminate the instances specified
  982.  
  983.        :type instance_ids: list
  984.        :param instance_ids: A list of strings of the Instance IDs to terminate
  985.  
  986.        :type dry_run: bool
  987.        :param dry_run: Set to True if the operation should not actually run.
  988.  
  989.        :rtype: list
  990.        :return: A list of the instances terminated
  991.        """
  992.         params = {}
  993.         if instance_ids:
  994.             self.build_list_params(params, instance_ids, 'InstanceId')
  995.         if dry_run:
  996.             params['DryRun'] = 'true'
  997.         return self.get_list('TerminateInstances', params,
  998.                              [('item', Instance)], verb='POST')
  999.  
  1000.     def stop_instances(self, instance_ids=None, force=False, dry_run=False):
  1001.         """
  1002.        Stop the instances specified
  1003.  
  1004.        :type instance_ids: list
  1005.        :param instance_ids: A list of strings of the Instance IDs to stop
  1006.  
  1007.        :type force: bool
  1008.        :param force: Forces the instance to stop
  1009.  
  1010.        :type dry_run: bool
  1011.        :param dry_run: Set to True if the operation should not actually run.
  1012.  
  1013.        :rtype: list
  1014.        :return: A list of the instances stopped
  1015.        """
  1016.         params = {}
  1017.         if force:
  1018.             params['Force'] = 'true'
  1019.         if instance_ids:
  1020.             self.build_list_params(params, instance_ids, 'InstanceId')
  1021.         if dry_run:
  1022.             params['DryRun'] = 'true'
  1023.         return self.get_list('StopInstances', params,
  1024.                              [('item', Instance)], verb='POST')
  1025.  
  1026.     def start_instances(self, instance_ids=None, dry_run=False):
  1027.         """
  1028.        Start the instances specified
  1029.  
  1030.        :type instance_ids: list
  1031.        :param instance_ids: A list of strings of the Instance IDs to start
  1032.  
  1033.        :type dry_run: bool
  1034.        :param dry_run: Set to True if the operation should not actually run.
  1035.  
  1036.        :rtype: list
  1037.        :return: A list of the instances started
  1038.        """
  1039.         params = {}
  1040.         if instance_ids:
  1041.             self.build_list_params(params, instance_ids, 'InstanceId')
  1042.         if dry_run:
  1043.             params['DryRun'] = 'true'
  1044.         return self.get_list('StartInstances', params,
  1045.                              [('item', Instance)], verb='POST')
  1046.  
  1047.     def get_console_output(self, instance_id, dry_run=False):
  1048.         """
  1049.        Retrieves the console output for the specified instance.
  1050.  
  1051.        :type instance_id: string
  1052.        :param instance_id: The instance ID of a running instance on the cloud.
  1053.  
  1054.        :type dry_run: bool
  1055.        :param dry_run: Set to True if the operation should not actually run.
  1056.  
  1057.        :rtype: :class:`boto.ec2.instance.ConsoleOutput`
  1058.        :return: The console output as a ConsoleOutput object
  1059.        """
  1060.         params = {}
  1061.         self.build_list_params(params, [instance_id], 'InstanceId')
  1062.         if dry_run:
  1063.             params['DryRun'] = 'true'
  1064.         return self.get_object('GetConsoleOutput', params,
  1065.                                ConsoleOutput, verb='POST')
  1066.  
  1067.     def reboot_instances(self, instance_ids=None, dry_run=False):
  1068.         """
  1069.        Reboot the specified instances.
  1070.  
  1071.        :type instance_ids: list
  1072.        :param instance_ids: The instances to terminate and reboot
  1073.  
  1074.        :type dry_run: bool
  1075.        :param dry_run: Set to True if the operation should not actually run.
  1076.  
  1077.        """
  1078.         params = {}
  1079.         if instance_ids:
  1080.             self.build_list_params(params, instance_ids, 'InstanceId')
  1081.         if dry_run:
  1082.             params['DryRun'] = 'true'
  1083.         return self.get_status('RebootInstances', params)
  1084.  
  1085.     def confirm_product_instance(self, product_code, instance_id,
  1086.                                  dry_run=False):
  1087.         """
  1088.        :type dry_run: bool
  1089.        :param dry_run: Set to True if the operation should not actually run.
  1090.  
  1091.        """
  1092.         params = {'ProductCode': product_code,
  1093.                   'InstanceId': instance_id}
  1094.         if dry_run:
  1095.             params['DryRun'] = 'true'
  1096.         rs = self.get_object('ConfirmProductInstance', params,
  1097.                              ResultSet, verb='POST')
  1098.         return (rs.status, rs.ownerId)
  1099.  
  1100.     # InstanceAttribute methods
  1101.  
  1102.     def get_instance_attribute(self, instance_id, attribute, dry_run=False):
  1103.         """
  1104.        Gets an attribute from an instance.
  1105.  
  1106.        :type instance_id: string
  1107.        :param instance_id: The Amazon id of the instance
  1108.  
  1109.        :type attribute: string
  1110.        :param attribute: The attribute you need information about
  1111.            Valid choices are:
  1112.  
  1113.            * instanceType
  1114.            * kernel
  1115.            * ramdisk
  1116.            * userData
  1117.            * disableApiTermination
  1118.            * instanceInitiatedShutdownBehavior
  1119.            * rootDeviceName
  1120.            * blockDeviceMapping
  1121.            * productCodes
  1122.            * sourceDestCheck
  1123.            * groupSet
  1124.            * ebsOptimized
  1125.            * sriovNetSupport
  1126.  
  1127.        :type dry_run: bool
  1128.        :param dry_run: Set to True if the operation should not actually run.
  1129.  
  1130.        :rtype: :class:`boto.ec2.image.InstanceAttribute`
  1131.        :return: An InstanceAttribute object representing the value of the
  1132.                 attribute requested
  1133.        """
  1134.         params = {'InstanceId': instance_id}
  1135.         if attribute:
  1136.             params['Attribute'] = attribute
  1137.         if dry_run:
  1138.             params['DryRun'] = 'true'
  1139.         return self.get_object('DescribeInstanceAttribute', params,
  1140.                                InstanceAttribute, verb='POST')
  1141.  
  1142.     def modify_network_interface_attribute(self, interface_id, attr, value,
  1143.                                            attachment_id=None, dry_run=False):
  1144.         """
  1145.        Changes an attribute of a network interface.
  1146.  
  1147.        :type interface_id: string
  1148.        :param interface_id: The interface id. Looks like 'eni-xxxxxxxx'
  1149.  
  1150.        :type attr: string
  1151.        :param attr: The attribute you wish to change.
  1152.  
  1153.            Learn more at http://docs.aws.amazon.com/AWSEC2/latest/API\
  1154.            Reference/ApiReference-query-ModifyNetworkInterfaceAttribute.html
  1155.  
  1156.            * description - Textual description of interface
  1157.            * groupSet - List of security group ids or group objects
  1158.            * sourceDestCheck - Boolean
  1159.            * deleteOnTermination - Boolean. Must also specify attachment_id
  1160.  
  1161.        :type value: string
  1162.        :param value: The new value for the attribute
  1163.  
  1164.        :rtype: bool
  1165.        :return: Whether the operation succeeded or not
  1166.  
  1167.        :type attachment_id: string
  1168.        :param attachment_id: If you're modifying DeleteOnTermination you must
  1169.            specify the attachment_id.
  1170.  
  1171.        :type dry_run: bool
  1172.        :param dry_run: Set to True if the operation should not actually run.
  1173.  
  1174.        """
  1175.         bool_reqs = (
  1176.             'deleteontermination',
  1177.             'sourcedestcheck',
  1178.         )
  1179.         if attr.lower() in bool_reqs:
  1180.             if isinstance(value, bool):
  1181.                 if value:
  1182.                     value = 'true'
  1183.                 else:
  1184.                     value = 'false'
  1185.             elif value not in ['true', 'false']:
  1186.                 raise ValueError('%s must be a boolean, "true", or "false"!'
  1187.                                  % attr)
  1188.  
  1189.         params = {'NetworkInterfaceId': interface_id}
  1190.  
  1191.         # groupSet is handled differently from other arguments
  1192.         if attr.lower() == 'groupset':
  1193.             for idx, sg in enumerate(value):
  1194.                 if isinstance(sg, SecurityGroup):
  1195.                     sg = sg.id
  1196.                 params['SecurityGroupId.%s' % (idx + 1)] = sg
  1197.         elif attr.lower() == 'description':
  1198.             params['Description.Value'] = value
  1199.         elif attr.lower() == 'sourcedestcheck':
  1200.             params['SourceDestCheck.Value'] = value
  1201.         elif attr.lower() == 'deleteontermination':
  1202.             params['Attachment.DeleteOnTermination'] = value
  1203.             if not attachment_id:
  1204.                 raise ValueError('You must also specify an attachment_id')
  1205.             params['Attachment.AttachmentId'] = attachment_id
  1206.         else:
  1207.             raise ValueError('Unknown attribute "%s"' % (attr,))
  1208.  
  1209.         if dry_run:
  1210.             params['DryRun'] = 'true'
  1211.         return self.get_status(
  1212.             'ModifyNetworkInterfaceAttribute', params, verb='POST')
  1213.  
  1214.     def modify_instance_attribute(self, instance_id, attribute, value,
  1215.                                   dry_run=False):
  1216.         """
  1217.        Changes an attribute of an instance
  1218.  
  1219.        :type instance_id: string
  1220.        :param instance_id: The instance id you wish to change
  1221.  
  1222.        :type attribute: string
  1223.        :param attribute: The attribute you wish to change.
  1224.  
  1225.            * instanceType - A valid instance type (m1.small)
  1226.            * kernel - Kernel ID (None)
  1227.            * ramdisk - Ramdisk ID (None)
  1228.            * userData - Base64 encoded String (None)
  1229.            * disableApiTermination - Boolean (true)
  1230.            * instanceInitiatedShutdownBehavior - stop|terminate
  1231.            * blockDeviceMapping - List of strings - ie: ['/dev/sda=false']
  1232.            * sourceDestCheck - Boolean (true)
  1233.            * groupSet - Set of Security Groups or IDs
  1234.            * ebsOptimized - Boolean (false)
  1235.            * sriovNetSupport - String - ie: 'simple'
  1236.  
  1237.        :type value: string
  1238.        :param value: The new value for the attribute
  1239.  
  1240.        :type dry_run: bool
  1241.        :param dry_run: Set to True if the operation should not actually run.
  1242.  
  1243.        :rtype: bool
  1244.        :return: Whether the operation succeeded or not
  1245.        """
  1246.         # Allow a bool to be passed in for value of disableApiTermination
  1247.         bool_reqs = ('disableapitermination',
  1248.                      'sourcedestcheck',
  1249.                      'ebsoptimized')
  1250.         if attribute.lower() in bool_reqs:
  1251.             if isinstance(value, bool):
  1252.                 if value:
  1253.                     value = 'true'
  1254.                 else:
  1255.                     value = 'false'
  1256.  
  1257.         params = {'InstanceId': instance_id}
  1258.  
  1259.         # groupSet is handled differently from other arguments
  1260.         if attribute.lower() == 'groupset':
  1261.             for idx, sg in enumerate(value):
  1262.                 if isinstance(sg, SecurityGroup):
  1263.                     sg = sg.id
  1264.                 params['GroupId.%s' % (idx + 1)] = sg
  1265.         elif attribute.lower() == 'blockdevicemapping':
  1266.             for idx, kv in enumerate(value):
  1267.                 dev_name, _, flag = kv.partition('=')
  1268.                 pre = 'BlockDeviceMapping.%d' % (idx + 1)
  1269.                 params['%s.DeviceName' % pre] = dev_name
  1270.                 params['%s.Ebs.DeleteOnTermination' % pre] = flag or 'true'
  1271.         else:
  1272.             # for backwards compatibility handle lowercase first letter
  1273.             attribute = attribute[0].upper() + attribute[1:]
  1274.             params['%s.Value' % attribute] = value
  1275.  
  1276.         if dry_run:
  1277.             params['DryRun'] = 'true'
  1278.         return self.get_status('ModifyInstanceAttribute', params, verb='POST')
  1279.  
  1280.     def reset_instance_attribute(self, instance_id, attribute, dry_run=False):
  1281.         """
  1282.        Resets an attribute of an instance to its default value.
  1283.  
  1284.        :type instance_id: string
  1285.        :param instance_id: ID of the instance
  1286.  
  1287.        :type attribute: string
  1288.        :param attribute: The attribute to reset. Valid values are:
  1289.                          kernel|ramdisk
  1290.  
  1291.        :type dry_run: bool
  1292.        :param dry_run: Set to True if the operation should not actually run.
  1293.  
  1294.        :rtype: bool
  1295.        :return: Whether the operation succeeded or not
  1296.        """
  1297.         params = {'InstanceId': instance_id,
  1298.                   'Attribute': attribute}
  1299.         if dry_run:
  1300.             params['DryRun'] = 'true'
  1301.         return self.get_status('ResetInstanceAttribute', params, verb='POST')
  1302.  
  1303.     # Spot Instances
  1304.  
  1305.     def get_all_spot_instance_requests(self, request_ids=None,
  1306.                                        filters=None, dry_run=False):
  1307.         """
  1308.        Retrieve all the spot instances requests associated with your account.
  1309.  
  1310.        :type request_ids: list
  1311.        :param request_ids: A list of strings of spot instance request IDs
  1312.  
  1313.        :type filters: dict
  1314.        :param filters: Optional filters that can be used to limit the
  1315.            results returned.  Filters are provided in the form of a
  1316.            dictionary consisting of filter names as the key and
  1317.            filter values as the value.  The set of allowable filter
  1318.            names/values is dependent on the request being performed.
  1319.            Check the EC2 API guide for details.
  1320.  
  1321.        :type dry_run: bool
  1322.        :param dry_run: Set to True if the operation should not actually run.
  1323.  
  1324.        :rtype: list
  1325.        :return: A list of
  1326.                 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
  1327.        """
  1328.         params = {}
  1329.         if request_ids:
  1330.             self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
  1331.         if filters:
  1332.             if 'launch.group-id' in filters:
  1333.                 lgid = filters.get('launch.group-id')
  1334.                 if not lgid.startswith('sg-') or len(lgid) != 11:
  1335.                     warnings.warn(
  1336.                         "The 'launch.group-id' filter now requires a security "
  1337.                         "group id (sg-*) and no longer supports filtering by "
  1338.                         "group name. Please update your filters accordingly.",
  1339.                         UserWarning)
  1340.             self.build_filter_params(params, filters)
  1341.         if dry_run:
  1342.             params['DryRun'] = 'true'
  1343.         return self.get_list('DescribeSpotInstanceRequests', params,
  1344.                              [('item', SpotInstanceRequest)], verb='POST')
  1345.  
  1346.     def get_spot_price_history(self, start_time=None, end_time=None,
  1347.                                instance_type=None, product_description=None,
  1348.                                availability_zone=None, dry_run=False,
  1349.                                max_results=None, next_token=None,
  1350.                                filters=None):
  1351.         """
  1352.        Retrieve the recent history of spot instances pricing.
  1353.  
  1354.        :type start_time: str
  1355.        :param start_time: An indication of how far back to provide price
  1356.            changes for. An ISO8601 DateTime string.
  1357.  
  1358.        :type end_time: str
  1359.        :param end_time: An indication of how far forward to provide price
  1360.            changes for.  An ISO8601 DateTime string.
  1361.  
  1362.        :type instance_type: str
  1363.        :param instance_type: Filter responses to a particular instance type.
  1364.  
  1365.        :type product_description: str
  1366.        :param product_description: Filter responses to a particular platform.
  1367.            Valid values are currently:
  1368.  
  1369.            * Linux/UNIX
  1370.            * SUSE Linux
  1371.            * Windows
  1372.            * Linux/UNIX (Amazon VPC)
  1373.            * SUSE Linux (Amazon VPC)
  1374.            * Windows (Amazon VPC)
  1375.  
  1376.        :type availability_zone: str
  1377.        :param availability_zone: The availability zone for which prices
  1378.            should be returned.  If not specified, data for all
  1379.            availability zones will be returned.
  1380.  
  1381.        :type dry_run: bool
  1382.        :param dry_run: Set to True if the operation should not actually run.
  1383.  
  1384.        :type max_results: int
  1385.        :param max_results: The maximum number of paginated items
  1386.            per response.
  1387.  
  1388.        :type next_token: str
  1389.        :param next_token: The next set of rows to return.  This should
  1390.            be the value of the ``next_token`` attribute from a previous
  1391.            call to ``get_spot_price_history``.
  1392.  
  1393.        :type filters: dict
  1394.        :param filters: Optional filters that can be used to limit the
  1395.            results returned.  Filters are provided in the form of a
  1396.            dictionary consisting of filter names as the key and
  1397.            filter values as the value.  The set of allowable filter
  1398.            names/values is dependent on the request being performed.
  1399.            Check the EC2 API guide for details.
  1400.  
  1401.        :rtype: list
  1402.        :return: A list tuples containing price and timestamp.
  1403.        """
  1404.         params = {}
  1405.         if start_time:
  1406.             params['StartTime'] = start_time
  1407.         if end_time:
  1408.             params['EndTime'] = end_time
  1409.         if instance_type:
  1410.             params['InstanceType'] = instance_type
  1411.         if product_description:
  1412.             params['ProductDescription'] = product_description
  1413.         if availability_zone:
  1414.             params['AvailabilityZone'] = availability_zone
  1415.         if dry_run:
  1416.             params['DryRun'] = 'true'
  1417.         if max_results is not None:
  1418.             params['MaxResults'] = max_results
  1419.         if next_token:
  1420.             params['NextToken'] = next_token
  1421.         if filters:
  1422.             self.build_filter_params(params, filters)
  1423.         return self.get_list('DescribeSpotPriceHistory', params,
  1424.                              [('item', SpotPriceHistory)], verb='POST')
  1425.  
  1426.     def request_spot_instances(self, price, image_id, count=1, type='one-time',
  1427.                                valid_from=None, valid_until=None,
  1428.                                launch_group=None, availability_zone_group=None,
  1429.                                key_name=None, security_groups=None,
  1430.                                user_data=None, addressing_type=None,
  1431.                                instance_type='m1.small', placement=None,
  1432.                                kernel_id=None, ramdisk_id=None,
  1433.                                monitoring_enabled=False, subnet_id=None,
  1434.                                placement_group=None,
  1435.                                block_device_map=None,
  1436.                                instance_profile_arn=None,
  1437.                                instance_profile_name=None,
  1438.                                security_group_ids=None,
  1439.                                ebs_optimized=False,
  1440.                                network_interfaces=None, dry_run=False):
  1441.         """
  1442.        Request instances on the spot market at a particular price.
  1443.  
  1444.        :type price: str
  1445.        :param price: The maximum price of your bid
  1446.  
  1447.        :type image_id: string
  1448.        :param image_id: The ID of the image to run
  1449.  
  1450.        :type count: int
  1451.        :param count: The of instances to requested
  1452.  
  1453.        :type type: str
  1454.        :param type: Type of request. Can be 'one-time' or 'persistent'.
  1455.                     Default is one-time.
  1456.  
  1457.        :type valid_from: str
  1458.        :param valid_from: Start date of the request. An ISO8601 time string.
  1459.  
  1460.        :type valid_until: str
  1461.        :param valid_until: End date of the request.  An ISO8601 time string.
  1462.  
  1463.        :type launch_group: str
  1464.        :param launch_group: If supplied, all requests will be fulfilled
  1465.            as a group.
  1466.  
  1467.        :type availability_zone_group: str
  1468.        :param availability_zone_group: If supplied, all requests will be
  1469.            fulfilled within a single availability zone.
  1470.  
  1471.        :type key_name: string
  1472.        :param key_name: The name of the key pair with which to
  1473.            launch instances
  1474.  
  1475.        :type security_groups: list of strings
  1476.        :param security_groups: The names of the security groups with which to
  1477.            associate instances
  1478.  
  1479.        :type user_data: string
  1480.        :param user_data: The user data passed to the launched instances
  1481.  
  1482.        :type instance_type: string
  1483.        :param instance_type: The type of instance to run:
  1484.  
  1485.            * t1.micro
  1486.            * m1.small
  1487.            * m1.medium
  1488.            * m1.large
  1489.            * m1.xlarge
  1490.            * m3.medium
  1491.            * m3.large
  1492.            * m3.xlarge
  1493.            * m3.2xlarge
  1494.            * c1.medium
  1495.            * c1.xlarge
  1496.            * m2.xlarge
  1497.            * m2.2xlarge
  1498.            * m2.4xlarge
  1499.            * cr1.8xlarge
  1500.            * hi1.4xlarge
  1501.            * hs1.8xlarge
  1502.            * cc1.4xlarge
  1503.            * cg1.4xlarge
  1504.            * cc2.8xlarge
  1505.            * g2.2xlarge
  1506.            * c3.large
  1507.            * c3.xlarge
  1508.            * c3.2xlarge
  1509.            * c3.4xlarge
  1510.            * c3.8xlarge
  1511.            * c4.large
  1512.            * c4.xlarge
  1513.            * c4.2xlarge
  1514.            * c4.4xlarge
  1515.            * c4.8xlarge
  1516.            * i2.xlarge
  1517.            * i2.2xlarge
  1518.            * i2.4xlarge
  1519.            * i2.8xlarge
  1520.            * t2.micro
  1521.            * t2.small
  1522.            * t2.medium
  1523.  
  1524.        :type placement: string
  1525.        :param placement: The availability zone in which to launch
  1526.            the instances
  1527.  
  1528.        :type kernel_id: string
  1529.        :param kernel_id: The ID of the kernel with which to launch the
  1530.            instances
  1531.  
  1532.        :type ramdisk_id: string
  1533.        :param ramdisk_id: The ID of the RAM disk with which to launch the
  1534.            instances
  1535.  
  1536.        :type monitoring_enabled: bool
  1537.        :param monitoring_enabled: Enable detailed CloudWatch monitoring on
  1538.            the instance.
  1539.  
  1540.        :type subnet_id: string
  1541.        :param subnet_id: The subnet ID within which to launch the instances
  1542.            for VPC.
  1543.  
  1544.        :type placement_group: string
  1545.        :param placement_group: If specified, this is the name of the placement
  1546.            group in which the instance(s) will be launched.
  1547.  
  1548.        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
  1549.        :param block_device_map: A BlockDeviceMapping data structure
  1550.            describing the EBS volumes associated with the Image.
  1551.  
  1552.        :type security_group_ids: list of strings
  1553.        :param security_group_ids: The ID of the VPC security groups with
  1554.            which to associate instances.
  1555.  
  1556.        :type instance_profile_arn: string
  1557.        :param instance_profile_arn: The Amazon resource name (ARN) of
  1558.            the IAM Instance Profile (IIP) to associate with the instances.
  1559.  
  1560.        :type instance_profile_name: string
  1561.        :param instance_profile_name: The name of
  1562.            the IAM Instance Profile (IIP) to associate with the instances.
  1563.  
  1564.        :type ebs_optimized: bool
  1565.        :param ebs_optimized: Whether the instance is optimized for
  1566.            EBS I/O.  This optimization provides dedicated throughput
  1567.            to Amazon EBS and an optimized configuration stack to
  1568.            provide optimal EBS I/O performance.  This optimization
  1569.            isn't available with all instance types.
  1570.  
  1571.        :type network_interfaces: list
  1572.        :param network_interfaces: A list of
  1573.            :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
  1574.  
  1575.        :type dry_run: bool
  1576.        :param dry_run: Set to True if the operation should not actually run.
  1577.  
  1578.        :rtype: Reservation
  1579.        :return: The :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
  1580.                 associated with the request for machines
  1581.        """
  1582.         ls = 'LaunchSpecification'
  1583.         params = {'%s.ImageId' % ls: image_id,
  1584.                   'Type': type,
  1585.                   'SpotPrice': price}
  1586.         if count:
  1587.             params['InstanceCount'] = count
  1588.         if valid_from:
  1589.             params['ValidFrom'] = valid_from
  1590.         if valid_until:
  1591.             params['ValidUntil'] = valid_until
  1592.         if launch_group:
  1593.             params['LaunchGroup'] = launch_group
  1594.         if availability_zone_group:
  1595.             params['AvailabilityZoneGroup'] = availability_zone_group
  1596.         if key_name:
  1597.             params['%s.KeyName' % ls] = key_name
  1598.         if security_group_ids:
  1599.             l = []
  1600.             for group in security_group_ids:
  1601.                 if isinstance(group, SecurityGroup):
  1602.                     l.append(group.id)
  1603.                 else:
  1604.                     l.append(group)
  1605.             self.build_list_params(params, l,
  1606.                                    '%s.SecurityGroupId' % ls)
  1607.         if security_groups:
  1608.             l = []
  1609.             for group in security_groups:
  1610.                 if isinstance(group, SecurityGroup):
  1611.                     l.append(group.name)
  1612.                 else:
  1613.                     l.append(group)
  1614.             self.build_list_params(params, l, '%s.SecurityGroup' % ls)
  1615.         if user_data:
  1616.             params['%s.UserData' % ls] = base64.b64encode(user_data)
  1617.         if addressing_type:
  1618.             params['%s.AddressingType' % ls] = addressing_type
  1619.         if instance_type:
  1620.             params['%s.InstanceType' % ls] = instance_type
  1621.         if placement:
  1622.             params['%s.Placement.AvailabilityZone' % ls] = placement
  1623.         if kernel_id:
  1624.             params['%s.KernelId' % ls] = kernel_id
  1625.         if ramdisk_id:
  1626.             params['%s.RamdiskId' % ls] = ramdisk_id
  1627.         if monitoring_enabled:
  1628.             params['%s.Monitoring.Enabled' % ls] = 'true'
  1629.         if subnet_id:
  1630.             params['%s.SubnetId' % ls] = subnet_id
  1631.         if placement_group:
  1632.             params['%s.Placement.GroupName' % ls] = placement_group
  1633.         if block_device_map:
  1634.             block_device_map.ec2_build_list_params(params, '%s.' % ls)
  1635.         if instance_profile_name:
  1636.             params['%s.IamInstanceProfile.Name' % ls] = instance_profile_name
  1637.         if instance_profile_arn:
  1638.             params['%s.IamInstanceProfile.Arn' % ls] = instance_profile_arn
  1639.         if ebs_optimized:
  1640.             params['%s.EbsOptimized' % ls] = 'true'
  1641.         if network_interfaces:
  1642.             network_interfaces.build_list_params(params, prefix=ls + '.')
  1643.         if dry_run:
  1644.             params['DryRun'] = 'true'
  1645.         return self.get_list('RequestSpotInstances', params,
  1646.                              [('item', SpotInstanceRequest)],
  1647.                              verb='POST')
  1648.  
  1649.     def cancel_spot_instance_requests(self, request_ids, dry_run=False):
  1650.         """
  1651.        Cancel the specified Spot Instance Requests.
  1652.  
  1653.        :type request_ids: list
  1654.        :param request_ids: A list of strings of the Request IDs to terminate
  1655.  
  1656.        :type dry_run: bool
  1657.        :param dry_run: Set to True if the operation should not actually run.
  1658.  
  1659.        :rtype: list
  1660.        :return: A list of the instances terminated
  1661.        """
  1662.         params = {}
  1663.         if request_ids:
  1664.             self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
  1665.         if dry_run:
  1666.             params['DryRun'] = 'true'
  1667.         return self.get_list('CancelSpotInstanceRequests', params,
  1668.                              [('item', SpotInstanceRequest)], verb='POST')
  1669.  
  1670.     def get_spot_datafeed_subscription(self, dry_run=False):
  1671.         """
  1672.        Return the current spot instance data feed subscription
  1673.        associated with this account, if any.
  1674.  
  1675.        :type dry_run: bool
  1676.        :param dry_run: Set to True if the operation should not actually run.
  1677.  
  1678.        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
  1679.        :return: The datafeed subscription object or None
  1680.        """
  1681.         params = {}
  1682.         if dry_run:
  1683.             params['DryRun'] = 'true'
  1684.         return self.get_object('DescribeSpotDatafeedSubscription',
  1685.                                params, SpotDatafeedSubscription, verb='POST')
  1686.  
  1687.     def create_spot_datafeed_subscription(self, bucket, prefix, dry_run=False):
  1688.         """
  1689.        Create a spot instance datafeed subscription for this account.
  1690.  
  1691.        :type bucket: str or unicode
  1692.        :param bucket: The name of the bucket where spot instance data
  1693.                       will be written.  The account issuing this request
  1694.                       must have FULL_CONTROL access to the bucket
  1695.                       specified in the request.
  1696.  
  1697.        :type prefix: str or unicode
  1698.        :param prefix: An optional prefix that will be pre-pended to all
  1699.                       data files written to the bucket.
  1700.  
  1701.        :type dry_run: bool
  1702.        :param dry_run: Set to True if the operation should not actually run.
  1703.  
  1704.        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
  1705.        :return: The datafeed subscription object or None
  1706.        """
  1707.         params = {'Bucket': bucket}
  1708.         if prefix:
  1709.             params['Prefix'] = prefix
  1710.         if dry_run:
  1711.             params['DryRun'] = 'true'
  1712.         return self.get_object('CreateSpotDatafeedSubscription',
  1713.                                params, SpotDatafeedSubscription, verb='POST')
  1714.  
  1715.     def delete_spot_datafeed_subscription(self, dry_run=False):
  1716.         """
  1717.        Delete the current spot instance data feed subscription
  1718.        associated with this account
  1719.  
  1720.        :type dry_run: bool
  1721.        :param dry_run: Set to True if the operation should not actually run.
  1722.  
  1723.        :rtype: bool
  1724.        :return: True if successful
  1725.        """
  1726.         params = {}
  1727.         if dry_run:
  1728.             params['DryRun'] = 'true'
  1729.         return self.get_status('DeleteSpotDatafeedSubscription',
  1730.                                params, verb='POST')
  1731.  
  1732.     # Zone methods
  1733.  
  1734.     def get_all_zones(self, zones=None, filters=None, dry_run=False):
  1735.         """
  1736.        Get all Availability Zones associated with the current region.
  1737.  
  1738.        :type zones: list
  1739.        :param zones: Optional list of zones.  If this list is present,
  1740.                      only the Zones associated with these zone names
  1741.                      will be returned.
  1742.  
  1743.        :type filters: dict
  1744.        :param filters: Optional filters that can be used to limit
  1745.                        the results returned.  Filters are provided
  1746.                        in the form of a dictionary consisting of
  1747.                        filter names as the key and filter values
  1748.                        as the value.  The set of allowable filter
  1749.                        names/values is dependent on the request
  1750.                        being performed.  Check the EC2 API guide
  1751.                        for details.
  1752.  
  1753.        :type dry_run: bool
  1754.        :param dry_run: Set to True if the operation should not actually run.
  1755.  
  1756.        :rtype: list of :class:`boto.ec2.zone.Zone`
  1757.        :return: The requested Zone objects
  1758.        """
  1759.         params = {}
  1760.         if zones:
  1761.             self.build_list_params(params, zones, 'ZoneName')
  1762.         if filters:
  1763.             self.build_filter_params(params, filters)
  1764.         if dry_run:
  1765.             params['DryRun'] = 'true'
  1766.         return self.get_list('DescribeAvailabilityZones', params,
  1767.                              [('item', Zone)], verb='POST')
  1768.  
  1769.     # Address methods
  1770.  
  1771.     def get_all_addresses(self, addresses=None, filters=None,
  1772.                           allocation_ids=None, dry_run=False):
  1773.         """
  1774.        Get all EIP's associated with the current credentials.
  1775.  
  1776.        :type addresses: list
  1777.        :param addresses: Optional list of addresses.  If this list is present,
  1778.                           only the Addresses associated with these addresses
  1779.                           will be returned.
  1780.  
  1781.        :type filters: dict
  1782.        :param filters: Optional filters that can be used to limit
  1783.                        the results returned.  Filters are provided
  1784.                        in the form of a dictionary consisting of
  1785.                        filter names as the key and filter values
  1786.                        as the value.  The set of allowable filter
  1787.                        names/values is dependent on the request
  1788.                        being performed.  Check the EC2 API guide
  1789.                        for details.
  1790.  
  1791.        :type allocation_ids: list
  1792.        :param allocation_ids: Optional list of allocation IDs.  If this list is
  1793.                           present, only the Addresses associated with the given
  1794.                           allocation IDs will be returned.
  1795.  
  1796.        :type dry_run: bool
  1797.        :param dry_run: Set to True if the operation should not actually run.
  1798.  
  1799.        :rtype: list of :class:`boto.ec2.address.Address`
  1800.        :return: The requested Address objects
  1801.        """
  1802.         params = {}
  1803.         if addresses:
  1804.             self.build_list_params(params, addresses, 'PublicIp')
  1805.         if allocation_ids:
  1806.             self.build_list_params(params, allocation_ids, 'AllocationId')
  1807.         if filters:
  1808.             self.build_filter_params(params, filters)
  1809.         if dry_run:
  1810.             params['DryRun'] = 'true'
  1811.         return self.get_list('DescribeAddresses', params, [('item', Address)], verb='POST')
  1812.  
  1813.     def allocate_address(self, domain=None, dry_run=False):
  1814.         """
  1815.        Allocate a new Elastic IP address and associate it with your account.
  1816.  
  1817.        :type domain: string
  1818.        :param domain: Optional string. If domain is set to "vpc" the address
  1819.            will be allocated to VPC . Will return address object with
  1820.            allocation_id.
  1821.  
  1822.        :type dry_run: bool
  1823.        :param dry_run: Set to True if the operation should not actually run.
  1824.  
  1825.        :rtype: :class:`boto.ec2.address.Address`
  1826.        :return: The newly allocated Address
  1827.        """
  1828.         params = {}
  1829.  
  1830.         if domain is not None:
  1831.             params['Domain'] = domain
  1832.  
  1833.         if dry_run:
  1834.             params['DryRun'] = 'true'
  1835.  
  1836.         return self.get_object('AllocateAddress', params, Address, verb='POST')
  1837.  
  1838.     def assign_private_ip_addresses(self, network_interface_id=None,
  1839.                                     private_ip_addresses=None,
  1840.                                     secondary_private_ip_address_count=None,
  1841.                                     allow_reassignment=False, dry_run=False):
  1842.         """
  1843.        Assigns one or more secondary private IP addresses to a network
  1844.        interface in Amazon VPC.
  1845.  
  1846.        :type network_interface_id: string
  1847.        :param network_interface_id: The network interface to which the IP
  1848.            address will be assigned.
  1849.  
  1850.        :type private_ip_addresses: list
  1851.        :param private_ip_addresses: Assigns the specified IP addresses as
  1852.            secondary IP addresses to the network interface.
  1853.  
  1854.        :type secondary_private_ip_address_count: int
  1855.        :param secondary_private_ip_address_count: The number of secondary IP
  1856.            addresses to assign to the network interface. You cannot specify
  1857.            this parameter when also specifying private_ip_addresses.
  1858.  
  1859.        :type allow_reassignment: bool
  1860.        :param allow_reassignment: Specifies whether to allow an IP address
  1861.            that is already assigned to another network interface or instance
  1862.            to be reassigned to the specified network interface.
  1863.  
  1864.        :type dry_run: bool
  1865.        :param dry_run: Set to True if the operation should not actually run.
  1866.  
  1867.        :rtype: bool
  1868.        :return: True if successful
  1869.        """
  1870.         params = {}
  1871.  
  1872.         if network_interface_id is not None:
  1873.             params['NetworkInterfaceId'] = network_interface_id
  1874.  
  1875.         if private_ip_addresses is not None:
  1876.             self.build_list_params(params, private_ip_addresses,
  1877.                                    'PrivateIpAddress')
  1878.         elif secondary_private_ip_address_count is not None:
  1879.             params['SecondaryPrivateIpAddressCount'] = \
  1880.                 secondary_private_ip_address_count
  1881.  
  1882.         if allow_reassignment:
  1883.             params['AllowReassignment'] = 'true'
  1884.  
  1885.         if dry_run:
  1886.             params['DryRun'] = 'true'
  1887.  
  1888.         return self.get_status('AssignPrivateIpAddresses', params, verb='POST')
  1889.  
  1890.     def _associate_address(self, status, instance_id=None, public_ip=None,
  1891.                            allocation_id=None, network_interface_id=None,
  1892.                            private_ip_address=None, allow_reassociation=False,
  1893.                            dry_run=False):
  1894.         params = {}
  1895.         if instance_id is not None:
  1896.                 params['InstanceId'] = instance_id
  1897.         elif network_interface_id is not None:
  1898.                 params['NetworkInterfaceId'] = network_interface_id
  1899.  
  1900.         # Allocation id trumps public ip in order to associate with VPCs
  1901.         if allocation_id is not None:
  1902.             params['AllocationId'] = allocation_id
  1903.         elif public_ip is not None:
  1904.             params['PublicIp'] = public_ip
  1905.  
  1906.         if private_ip_address is not None:
  1907.             params['PrivateIpAddress'] = private_ip_address
  1908.  
  1909.         if allow_reassociation:
  1910.             params['AllowReassociation'] = 'true'
  1911.  
  1912.         if dry_run:
  1913.             params['DryRun'] = 'true'
  1914.  
  1915.         if status:
  1916.             return self.get_status('AssociateAddress', params, verb='POST')
  1917.         else:
  1918.             return self.get_object('AssociateAddress', params, Address,
  1919.                                    verb='POST')
  1920.  
  1921.     def associate_address(self, instance_id=None, public_ip=None,
  1922.                           allocation_id=None, network_interface_id=None,
  1923.                           private_ip_address=None, allow_reassociation=False,
  1924.                           dry_run=False):
  1925.         """
  1926.        Associate an Elastic IP address with a currently running instance.
  1927.        This requires one of ``public_ip`` or ``allocation_id`` depending
  1928.        on if you're associating a VPC address or a plain EC2 address.
  1929.  
  1930.        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
  1931.        as EC2 expects a single parameter and if ``public_ip`` is passed boto
  1932.        will preference that instead of ``allocation_id``.
  1933.  
  1934.        :type instance_id: string
  1935.        :param instance_id: The ID of the instance
  1936.  
  1937.        :type public_ip: string
  1938.        :param public_ip: The public IP address for EC2 based allocations.
  1939.  
  1940.        :type allocation_id: string
  1941.        :param allocation_id: The allocation ID for a VPC-based elastic IP.
  1942.  
  1943.        :type network_interface_id: string
  1944.        :param network_interface_id: The network interface ID to which
  1945.            elastic IP is to be assigned to
  1946.  
  1947.        :type private_ip_address: string
  1948.        :param private_ip_address: The primary or secondary private IP address
  1949.            to associate with the Elastic IP address.
  1950.  
  1951.        :type allow_reassociation: bool
  1952.        :param allow_reassociation: Specify this option to allow an Elastic IP
  1953.            address that is already associated with another network interface
  1954.            or instance to be re-associated with the specified instance or
  1955.            interface.
  1956.  
  1957.        :type dry_run: bool
  1958.        :param dry_run: Set to True if the operation should not actually run.
  1959.  
  1960.        :rtype: bool
  1961.        :return: True if successful
  1962.        """
  1963.         return self._associate_address(True, instance_id=instance_id,
  1964.             public_ip=public_ip, allocation_id=allocation_id,
  1965.             network_interface_id=network_interface_id,
  1966.             private_ip_address=private_ip_address,
  1967.             allow_reassociation=allow_reassociation, dry_run=dry_run)
  1968.  
  1969.     def associate_address_object(self, instance_id=None, public_ip=None,
  1970.                                  allocation_id=None, network_interface_id=None,
  1971.                                  private_ip_address=None, allow_reassociation=False,
  1972.                                  dry_run=False):
  1973.         """
  1974.        Associate an Elastic IP address with a currently running instance.
  1975.        This requires one of ``public_ip`` or ``allocation_id`` depending
  1976.        on if you're associating a VPC address or a plain EC2 address.
  1977.  
  1978.        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
  1979.        as EC2 expects a single parameter and if ``public_ip`` is passed boto
  1980.        will preference that instead of ``allocation_id``.
  1981.  
  1982.        :type instance_id: string
  1983.        :param instance_id: The ID of the instance
  1984.  
  1985.        :type public_ip: string
  1986.        :param public_ip: The public IP address for EC2 based allocations.
  1987.  
  1988.        :type allocation_id: string
  1989.        :param allocation_id: The allocation ID for a VPC-based elastic IP.
  1990.  
  1991.        :type network_interface_id: string
  1992.        :param network_interface_id: The network interface ID to which
  1993.            elastic IP is to be assigned to
  1994.  
  1995.        :type private_ip_address: string
  1996.        :param private_ip_address: The primary or secondary private IP address
  1997.            to associate with the Elastic IP address.
  1998.  
  1999.        :type allow_reassociation: bool
  2000.        :param allow_reassociation: Specify this option to allow an Elastic IP
  2001.            address that is already associated with another network interface
  2002.            or instance to be re-associated with the specified instance or
  2003.            interface.
  2004.  
  2005.        :type dry_run: bool
  2006.        :param dry_run: Set to True if the operation should not actually run.
  2007.  
  2008.        :rtype: class:`boto.ec2.address.Address`
  2009.        :return: The associated address instance
  2010.        """
  2011.         return self._associate_address(False, instance_id=instance_id,
  2012.             public_ip=public_ip, allocation_id=allocation_id,
  2013.             network_interface_id=network_interface_id,
  2014.             private_ip_address=private_ip_address,
  2015.             allow_reassociation=allow_reassociation, dry_run=dry_run)
  2016.  
  2017.     def disassociate_address(self, public_ip=None, association_id=None,
  2018.                              dry_run=False):
  2019.         """
  2020.        Disassociate an Elastic IP address from a currently running instance.
  2021.  
  2022.        :type public_ip: string
  2023.        :param public_ip: The public IP address for EC2 elastic IPs.
  2024.  
  2025.        :type association_id: string
  2026.        :param association_id: The association ID for a VPC based elastic ip.
  2027.  
  2028.        :type dry_run: bool
  2029.        :param dry_run: Set to True if the operation should not actually run.
  2030.  
  2031.        :rtype: bool
  2032.        :return: True if successful
  2033.        """
  2034.         params = {}
  2035.  
  2036.         # If there is an association id it trumps public ip
  2037.         # in order to successfully dissassociate with a VPC elastic ip
  2038.         if association_id is not None:
  2039.             params['AssociationId'] = association_id
  2040.         elif public_ip is not None:
  2041.             params['PublicIp'] = public_ip
  2042.  
  2043.         if dry_run:
  2044.             params['DryRun'] = 'true'
  2045.  
  2046.         return self.get_status('DisassociateAddress', params, verb='POST')
  2047.  
  2048.     def release_address(self, public_ip=None, allocation_id=None,
  2049.                         dry_run=False):
  2050.         """
  2051.        Free up an Elastic IP address.  Pass a public IP address to
  2052.        release an EC2 Elastic IP address and an AllocationId to
  2053.        release a VPC Elastic IP address.  You should only pass
  2054.        one value.
  2055.  
  2056.        This requires one of ``public_ip`` or ``allocation_id`` depending
  2057.        on if you're associating a VPC address or a plain EC2 address.
  2058.  
  2059.        When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
  2060.        as EC2 expects a single parameter and if ``public_ip`` is passed boto
  2061.        will preference that instead of ``allocation_id``.
  2062.  
  2063.        :type public_ip: string
  2064.        :param public_ip: The public IP address for EC2 elastic IPs.
  2065.  
  2066.        :type allocation_id: string
  2067.        :param allocation_id: The Allocation ID for VPC elastic IPs.
  2068.  
  2069.        :type dry_run: bool
  2070.        :param dry_run: Set to True if the operation should not actually run.
  2071.  
  2072.        :rtype: bool
  2073.        :return: True if successful
  2074.        """
  2075.         params = {}
  2076.  
  2077.         if public_ip is not None:
  2078.             params['PublicIp'] = public_ip
  2079.         elif allocation_id is not None:
  2080.             params['AllocationId'] = allocation_id
  2081.  
  2082.         if dry_run:
  2083.             params['DryRun'] = 'true'
  2084.  
  2085.         return self.get_status('ReleaseAddress', params, verb='POST')
  2086.  
  2087.     def unassign_private_ip_addresses(self, network_interface_id=None,
  2088.                                       private_ip_addresses=None, dry_run=False):
  2089.         """
  2090.        Unassigns one or more secondary private IP addresses from a network
  2091.        interface in Amazon VPC.
  2092.  
  2093.        :type network_interface_id: string
  2094.        :param network_interface_id: The network interface from which the
  2095.            secondary private IP address will be unassigned.
  2096.  
  2097.        :type private_ip_addresses: list
  2098.        :param private_ip_addresses: Specifies the secondary private IP
  2099.            addresses that you want to unassign from the network interface.
  2100.  
  2101.        :type dry_run: bool
  2102.        :param dry_run: Set to True if the operation should not actually run.
  2103.  
  2104.        :rtype: bool
  2105.        :return: True if successful
  2106.        """
  2107.         params = {}
  2108.  
  2109.         if network_interface_id is not None:
  2110.             params['NetworkInterfaceId'] = network_interface_id
  2111.  
  2112.         if private_ip_addresses is not None:
  2113.             self.build_list_params(params, private_ip_addresses,
  2114.                                    'PrivateIpAddress')
  2115.  
  2116.         if dry_run:
  2117.             params['DryRun'] = 'true'
  2118.  
  2119.         return self.get_status('UnassignPrivateIpAddresses', params,
  2120.                                verb='POST')
  2121.  
  2122.     # Volume methods
  2123.  
  2124.     def get_all_volumes(self, volume_ids=None, filters=None, dry_run=False):
  2125.         """
  2126.        Get all Volumes associated with the current credentials.
  2127.  
  2128.        :type volume_ids: list
  2129.        :param volume_ids: Optional list of volume ids.  If this list
  2130.                           is present, only the volumes associated with
  2131.                           these volume ids will be returned.
  2132.  
  2133.        :type filters: dict
  2134.        :param filters: Optional filters that can be used to limit
  2135.                        the results returned.  Filters are provided
  2136.                        in the form of a dictionary consisting of
  2137.                        filter names as the key and filter values
  2138.                        as the value.  The set of allowable filter
  2139.                        names/values is dependent on the request
  2140.                        being performed.  Check the EC2 API guide
  2141.                        for details.
  2142.  
  2143.        :type dry_run: bool
  2144.        :param dry_run: Set to True if the operation should not actually run.
  2145.  
  2146.        :rtype: list of :class:`boto.ec2.volume.Volume`
  2147.        :return: The requested Volume objects
  2148.        """
  2149.         params = {}
  2150.         if volume_ids:
  2151.             self.build_list_params(params, volume_ids, 'VolumeId')
  2152.         if filters:
  2153.             self.build_filter_params(params, filters)
  2154.         if dry_run:
  2155.             params['DryRun'] = 'true'
  2156.         return self.get_list('DescribeVolumes', params,
  2157.                              [('item', Volume)], verb='POST')
  2158.  
  2159.     def get_all_volume_status(self, volume_ids=None,
  2160.                               max_results=None, next_token=None,
  2161.                               filters=None, dry_run=False):
  2162.         """
  2163.        Retrieve the status of one or more volumes.
  2164.  
  2165.        :type volume_ids: list
  2166.        :param volume_ids: A list of strings of volume IDs
  2167.  
  2168.        :type max_results: int
  2169.        :param max_results: The maximum number of paginated instance
  2170.            items per response.
  2171.  
  2172.        :type next_token: str
  2173.        :param next_token: A string specifying the next paginated set
  2174.            of results to return.
  2175.  
  2176.        :type filters: dict
  2177.        :param filters: Optional filters that can be used to limit
  2178.            the results returned.  Filters are provided
  2179.            in the form of a dictionary consisting of
  2180.            filter names as the key and filter values
  2181.            as the value.  The set of allowable filter
  2182.            names/values is dependent on the request
  2183.            being performed.  Check the EC2 API guide
  2184.            for details.
  2185.  
  2186.        :type dry_run: bool
  2187.        :param dry_run: Set to True if the operation should not actually run.
  2188.  
  2189.        :rtype: list
  2190.        :return: A list of volume status.
  2191.        """
  2192.         params = {}
  2193.         if volume_ids:
  2194.             self.build_list_params(params, volume_ids, 'VolumeId')
  2195.         if max_results:
  2196.             params['MaxResults'] = max_results
  2197.         if next_token:
  2198.             params['NextToken'] = next_token
  2199.         if filters:
  2200.             self.build_filter_params(params, filters)
  2201.         if dry_run:
  2202.             params['DryRun'] = 'true'
  2203.         return self.get_object('DescribeVolumeStatus', params,
  2204.                                VolumeStatusSet, verb='POST')
  2205.  
  2206.     def enable_volume_io(self, volume_id, dry_run=False):
  2207.         """
  2208.        Enables I/O operations for a volume that had I/O operations
  2209.        disabled because the data on the volume was potentially inconsistent.
  2210.  
  2211.        :type volume_id: str
  2212.        :param volume_id: The ID of the volume.
  2213.  
  2214.        :type dry_run: bool
  2215.        :param dry_run: Set to True if the operation should not actually run.
  2216.  
  2217.        :rtype: bool
  2218.        :return: True if successful
  2219.        """
  2220.         params = {'VolumeId': volume_id}
  2221.         if dry_run:
  2222.             params['DryRun'] = 'true'
  2223.         return self.get_status('EnableVolumeIO', params, verb='POST')
  2224.  
  2225.     def get_volume_attribute(self, volume_id,
  2226.                              attribute='autoEnableIO', dry_run=False):
  2227.         """
  2228.        Describes attribute of the volume.
  2229.  
  2230.        :type volume_id: str
  2231.        :param volume_id: The ID of the volume.
  2232.  
  2233.        :type attribute: str
  2234.        :param attribute: The requested attribute.  Valid values are:
  2235.  
  2236.            * autoEnableIO
  2237.  
  2238.        :type dry_run: bool
  2239.        :param dry_run: Set to True if the operation should not actually run.
  2240.  
  2241.        :rtype: list of :class:`boto.ec2.volume.VolumeAttribute`
  2242.        :return: The requested Volume attribute
  2243.        """
  2244.         params = {'VolumeId': volume_id, 'Attribute': attribute}
  2245.         if dry_run:
  2246.             params['DryRun'] = 'true'
  2247.         return self.get_object('DescribeVolumeAttribute', params,
  2248.                                VolumeAttribute, verb='POST')
  2249.  
  2250.     def modify_volume_attribute(self, volume_id, attribute, new_value,
  2251.                                 dry_run=False):
  2252.         """
  2253.        Changes an attribute of an Volume.
  2254.  
  2255.        :type volume_id: string
  2256.        :param volume_id: The volume id you wish to change
  2257.  
  2258.        :type attribute: string
  2259.        :param attribute: The attribute you wish to change.  Valid values are:
  2260.            AutoEnableIO.
  2261.  
  2262.        :type new_value: string
  2263.        :param new_value: The new value of the attribute.
  2264.  
  2265.        :type dry_run: bool
  2266.        :param dry_run: Set to True if the operation should not actually run.
  2267.  
  2268.        """
  2269.         params = {'VolumeId': volume_id}
  2270.         if attribute == 'AutoEnableIO':
  2271.             params['AutoEnableIO.Value'] = new_value
  2272.         if dry_run:
  2273.             params['DryRun'] = 'true'
  2274.         return self.get_status('ModifyVolumeAttribute', params, verb='POST')
  2275.  
  2276.     def create_volume(self, size, zone, snapshot=None, volume_type=None,
  2277.                       iops=None, encrypted=False, kms_key_id=None, dry_run=False):
  2278.         """
  2279.        Create a new EBS Volume.
  2280.  
  2281.        :type size: int
  2282.        :param size: The size of the new volume, in GiB
  2283.  
  2284.        :type zone: string or :class:`boto.ec2.zone.Zone`
  2285.        :param zone: The availability zone in which the Volume will be created.
  2286.  
  2287.        :type snapshot: string or :class:`boto.ec2.snapshot.Snapshot`
  2288.        :param snapshot: The snapshot from which the new Volume will be
  2289.            created.
  2290.  
  2291.        :type volume_type: string
  2292.        :param volume_type: The type of the volume. (optional).  Valid
  2293.            values are: standard | io1 | gp2.
  2294.  
  2295.        :type iops: int
  2296.        :param iops: The provisioned IOPS you want to associate with
  2297.            this volume. (optional)
  2298.  
  2299.        :type encrypted: bool
  2300.        :param encrypted: Specifies whether the volume should be encrypted.
  2301.            (optional)
  2302.  
  2303.        :type kms_key_id: string
  2304.        :params kms_key_id: If encrypted is True, this KMS Key ID may be specified to
  2305.            encrypt volume with this key (optional)
  2306.            e.g.: arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef
  2307.  
  2308.        :type dry_run: bool
  2309.        :param dry_run: Set to True if the operation should not actually run.
  2310.  
  2311.        """
  2312.         if isinstance(zone, Zone):
  2313.             zone = zone.name
  2314.         params = {'AvailabilityZone': zone}
  2315.         if size:
  2316.             params['Size'] = size
  2317.         if snapshot:
  2318.             if isinstance(snapshot, Snapshot):
  2319.                 snapshot = snapshot.id
  2320.             params['SnapshotId'] = snapshot
  2321.         if volume_type:
  2322.             params['VolumeType'] = volume_type
  2323.         if iops:
  2324.             params['Iops'] = str(iops)
  2325.         if encrypted:
  2326.             params['Encrypted'] = 'true'
  2327.             if kms_key_id:
  2328.                 params['KmsKeyId'] = kms_key_id
  2329.         if dry_run:
  2330.             params['DryRun'] = 'true'
  2331.         return self.get_object('CreateVolume', params, Volume, verb='POST')
  2332.  
  2333.     def delete_volume(self, volume_id, dry_run=False):
  2334.         """
  2335.        Delete an EBS volume.
  2336.  
  2337.        :type volume_id: str
  2338.        :param volume_id: The ID of the volume to be delete.
  2339.  
  2340.        :type dry_run: bool
  2341.        :param dry_run: Set to True if the operation should not actually run.
  2342.  
  2343.        :rtype: bool
  2344.        :return: True if successful
  2345.        """
  2346.         params = {'VolumeId': volume_id}
  2347.         if dry_run:
  2348.             params['DryRun'] = 'true'
  2349.         return self.get_status('DeleteVolume', params, verb='POST')
  2350.  
  2351.     def attach_volume(self, volume_id, instance_id, device, dry_run=False):
  2352.         """
  2353.        Attach an EBS volume to an EC2 instance.
  2354.  
  2355.        :type volume_id: str
  2356.        :param volume_id: The ID of the EBS volume to be attached.
  2357.  
  2358.        :type instance_id: str
  2359.        :param instance_id: The ID of the EC2 instance to which it will
  2360.                            be attached.
  2361.  
  2362.        :type device: str
  2363.        :param device: The device on the instance through which the
  2364.                       volume will be exposted (e.g. /dev/sdh)
  2365.  
  2366.        :type dry_run: bool
  2367.        :param dry_run: Set to True if the operation should not actually run.
  2368.  
  2369.        :rtype: bool
  2370.        :return: True if successful
  2371.        """
  2372.         params = {'InstanceId': instance_id,
  2373.                   'VolumeId': volume_id,
  2374.                   'Device': device}
  2375.         if dry_run:
  2376.             params['DryRun'] = 'true'
  2377.         return self.get_status('AttachVolume', params, verb='POST')
  2378.  
  2379.     def detach_volume(self, volume_id, instance_id=None,
  2380.                       device=None, force=False, dry_run=False):
  2381.         """
  2382.        Detach an EBS volume from an EC2 instance.
  2383.  
  2384.        :type volume_id: str
  2385.        :param volume_id: The ID of the EBS volume to be attached.
  2386.  
  2387.        :type instance_id: str
  2388.        :param instance_id: The ID of the EC2 instance from which it will
  2389.            be detached.
  2390.  
  2391.        :type device: str
  2392.        :param device: The device on the instance through which the
  2393.            volume is exposted (e.g. /dev/sdh)
  2394.  
  2395.        :type force: bool
  2396.        :param force: Forces detachment if the previous detachment
  2397.            attempt did not occur cleanly.  This option can lead to
  2398.            data loss or a corrupted file system. Use this option only
  2399.            as a last resort to detach a volume from a failed
  2400.            instance. The instance will not have an opportunity to
  2401.            flush file system caches nor file system meta data. If you
  2402.            use this option, you must perform file system check and
  2403.            repair procedures.
  2404.  
  2405.        :type dry_run: bool
  2406.        :param dry_run: Set to True if the operation should not actually run.
  2407.  
  2408.        :rtype: bool
  2409.        :return: True if successful
  2410.        """
  2411.         params = {'VolumeId': volume_id}
  2412.         if instance_id:
  2413.             params['InstanceId'] = instance_id
  2414.         if device:
  2415.             params['Device'] = device
  2416.         if force:
  2417.             params['Force'] = 'true'
  2418.         if dry_run:
  2419.             params['DryRun'] = 'true'
  2420.         return self.get_status('DetachVolume', params, verb='POST')
  2421.  
  2422.     # Snapshot methods
  2423.  
  2424.     def get_all_snapshots(self, snapshot_ids=None,
  2425.                           owner=None, restorable_by=None,
  2426.                           filters=None, dry_run=False):
  2427.         """
  2428.        Get all EBS Snapshots associated with the current credentials.
  2429.  
  2430.        :type snapshot_ids: list
  2431.        :param snapshot_ids: Optional list of snapshot ids.  If this list is
  2432.                             present, only the Snapshots associated with
  2433.                             these snapshot ids will be returned.
  2434.  
  2435.        :type owner: str or list
  2436.        :param owner: If present, only the snapshots owned by the specified user(s)
  2437.                      will be returned.  Valid values are:
  2438.  
  2439.                      * self
  2440.                      * amazon
  2441.                      * AWS Account ID
  2442.  
  2443.        :type restorable_by: str or list
  2444.        :param restorable_by: If present, only the snapshots that are restorable
  2445.                              by the specified account id(s) will be returned.
  2446.  
  2447.        :type filters: dict
  2448.        :param filters: Optional filters that can be used to limit
  2449.                        the results returned.  Filters are provided
  2450.                        in the form of a dictionary consisting of
  2451.                        filter names as the key and filter values
  2452.                        as the value.  The set of allowable filter
  2453.                        names/values is dependent on the request
  2454.                        being performed.  Check the EC2 API guide
  2455.                        for details.
  2456.  
  2457.        :type dry_run: bool
  2458.        :param dry_run: Set to True if the operation should not actually run.
  2459.  
  2460.        :rtype: list of :class:`boto.ec2.snapshot.Snapshot`
  2461.        :return: The requested Snapshot objects
  2462.        """
  2463.         params = {}
  2464.         if snapshot_ids:
  2465.             self.build_list_params(params, snapshot_ids, 'SnapshotId')
  2466.  
  2467.         if owner:
  2468.             self.build_list_params(params, owner, 'Owner')
  2469.         if restorable_by:
  2470.             self.build_list_params(params, restorable_by, 'RestorableBy')
  2471.         if filters:
  2472.             self.build_filter_params(params, filters)
  2473.         if dry_run:
  2474.             params['DryRun'] = 'true'
  2475.         return self.get_list('DescribeSnapshots', params,
  2476.                              [('item', Snapshot)], verb='POST')
  2477.  
  2478.     def create_snapshot(self, volume_id, description=None, dry_run=False):
  2479.         """
  2480.        Create a snapshot of an existing EBS Volume.
  2481.  
  2482.        :type volume_id: str
  2483.        :param volume_id: The ID of the volume to be snapshot'ed
  2484.  
  2485.        :type description: str
  2486.        :param description: A description of the snapshot.
  2487.                            Limited to 255 characters.
  2488.  
  2489.        :type dry_run: bool
  2490.        :param dry_run: Set to True if the operation should not actually run.
  2491.  
  2492.        :rtype: :class:`boto.ec2.snapshot.Snapshot`
  2493.        :return: The created Snapshot object
  2494.        """
  2495.         params = {'VolumeId': volume_id}
  2496.         if description:
  2497.             params['Description'] = description[0:255]
  2498.         if dry_run:
  2499.             params['DryRun'] = 'true'
  2500.         snapshot = self.get_object('CreateSnapshot', params,
  2501.                                    Snapshot, verb='POST')
  2502.         volume = self.get_all_volumes([volume_id], dry_run=dry_run)[0]
  2503.         volume_name = volume.tags.get('Name')
  2504.         if volume_name:
  2505.             snapshot.add_tag('Name', volume_name)
  2506.         return snapshot
  2507.  
  2508.     def delete_snapshot(self, snapshot_id, dry_run=False):
  2509.         """
  2510.        :type dry_run: bool
  2511.        :param dry_run: Set to True if the operation should not actually run.
  2512.  
  2513.        """
  2514.         params = {'SnapshotId': snapshot_id}
  2515.         if dry_run:
  2516.             params['DryRun'] = 'true'
  2517.         return self.get_status('DeleteSnapshot', params, verb='POST')
  2518.  
  2519.     def copy_snapshot(self, source_region, source_snapshot_id,
  2520.                       description=None, dry_run=False):
  2521.         """
  2522.        Copies a point-in-time snapshot of an Amazon Elastic Block Store
  2523.        (Amazon EBS) volume and stores it in Amazon Simple Storage Service
  2524.        (Amazon S3). You can copy the snapshot within the same region or from
  2525.        one region to another. You can use the snapshot to create new Amazon
  2526.        EBS volumes or Amazon Machine Images (AMIs).
  2527.  
  2528.  
  2529.        :type source_region: str
  2530.        :param source_region: The ID of the AWS region that contains the
  2531.            snapshot to be copied (e.g 'us-east-1', 'us-west-2', etc.).
  2532.  
  2533.        :type source_snapshot_id: str
  2534.        :param source_snapshot_id: The ID of the Amazon EBS snapshot to copy
  2535.  
  2536.        :type description: str
  2537.        :param description: A description of the new Amazon EBS snapshot.
  2538.  
  2539.        :type dry_run: bool
  2540.        :param dry_run: Set to True if the operation should not actually run.
  2541.  
  2542.        :rtype: str
  2543.        :return: The snapshot ID
  2544.  
  2545.        """
  2546.         params = {
  2547.             'SourceRegion': source_region,
  2548.             'SourceSnapshotId': source_snapshot_id,
  2549.         }
  2550.         if description is not None:
  2551.             params['Description'] = description
  2552.         if dry_run:
  2553.             params['DryRun'] = 'true'
  2554.         snapshot = self.get_object('CopySnapshot', params, Snapshot,
  2555.                                    verb='POST')
  2556.         return snapshot.id
  2557.  
  2558.     def trim_snapshots(self, hourly_backups=8, daily_backups=7,
  2559.                        weekly_backups=4, monthly_backups=True):
  2560.         """
  2561.        Trim excess snapshots, based on when they were taken. More current
  2562.        snapshots are retained, with the number retained decreasing as you
  2563.        move back in time.
  2564.  
  2565.        If ebs volumes have a 'Name' tag with a value, their snapshots
  2566.        will be assigned the same tag when they are created. The values
  2567.        of the 'Name' tags for snapshots are used by this function to
  2568.        group snapshots taken from the same volume (or from a series
  2569.        of like-named volumes over time) for trimming.
  2570.  
  2571.        For every group of like-named snapshots, this function retains
  2572.        the newest and oldest snapshots, as well as, by default,  the
  2573.        first snapshots taken in each of the last eight hours, the first
  2574.        snapshots taken in each of the last seven days, the first snapshots
  2575.        taken in the last 4 weeks (counting Midnight Sunday morning as
  2576.        the start of the week), and the first snapshot from the first
  2577.        day of each month forever.
  2578.  
  2579.        :type hourly_backups: int
  2580.        :param hourly_backups: How many recent hourly backups should be saved.
  2581.  
  2582.        :type daily_backups: int
  2583.        :param daily_backups: How many recent daily backups should be saved.
  2584.  
  2585.        :type weekly_backups: int
  2586.        :param weekly_backups: How many recent weekly backups should be saved.
  2587.  
  2588.        :type monthly_backups: int
  2589.        :param monthly_backups: How many monthly backups should be saved. Use True for no limit.
  2590.        """
  2591.  
  2592.         # This function first builds up an ordered list of target times
  2593.         # that snapshots should be saved for (last 8 hours, last 7 days, etc.).
  2594.         # Then a map of snapshots is constructed, with the keys being
  2595.         # the snapshot / volume names and the values being arrays of
  2596.         # chronologically sorted snapshots.
  2597.         # Finally, for each array in the map, we go through the snapshot
  2598.         # array and the target time array in an interleaved fashion,
  2599.         # deleting snapshots whose start_times don't immediately follow a
  2600.         # target time (we delete a snapshot if there's another snapshot
  2601.         # that was made closer to the preceding target time).
  2602.  
  2603.         now = datetime.utcnow()
  2604.         last_hour = datetime(now.year, now.month, now.day, now.hour)
  2605.         last_midnight = datetime(now.year, now.month, now.day)
  2606.         last_sunday = datetime(now.year, now.month, now.day) - timedelta(days=(now.weekday() + 1) % 7)
  2607.         start_of_month = datetime(now.year, now.month, 1)
  2608.  
  2609.         target_backup_times = []
  2610.  
  2611.         # there are no snapshots older than 1/1/2007
  2612.         oldest_snapshot_date = datetime(2007, 1, 1)
  2613.  
  2614.         for hour in range(0, hourly_backups):
  2615.             target_backup_times.append(last_hour - timedelta(hours=hour))
  2616.  
  2617.         for day in range(0, daily_backups):
  2618.             target_backup_times.append(last_midnight - timedelta(days=day))
  2619.  
  2620.         for week in range(0, weekly_backups):
  2621.             target_backup_times.append(last_sunday - timedelta(weeks=week))
  2622.  
  2623.         one_day = timedelta(days=1)
  2624.         monthly_snapshots_added = 0
  2625.         while (start_of_month > oldest_snapshot_date and
  2626.                (monthly_backups is True or
  2627.                 monthly_snapshots_added < monthly_backups)):
  2628.             # append the start of the month to the list of
  2629.             # snapshot dates to save:
  2630.             target_backup_times.append(start_of_month)
  2631.             monthly_snapshots_added += 1
  2632.             # there's no timedelta setting for one month, so instead:
  2633.             # decrement the day by one, so we go to the final day of
  2634.             # the previous month...
  2635.             start_of_month -= one_day
  2636.             # ... and then go to the first day of that previous month:
  2637.             start_of_month = datetime(start_of_month.year,
  2638.                                       start_of_month.month, 1)
  2639.  
  2640.         temp = []
  2641.  
  2642.         for t in target_backup_times:
  2643.             if temp.__contains__(t) == False:
  2644.                 temp.append(t)
  2645.  
  2646.         # sort to make the oldest dates first, and make sure the month start
  2647.         # and last four week's start are in the proper order
  2648.         target_backup_times = sorted(temp)
  2649.  
  2650.         # get all the snapshots, sort them by date and time, and
  2651.         # organize them into one array for each volume:
  2652.         all_snapshots = self.get_all_snapshots(owner = 'self')
  2653.         all_snapshots.sort(key=lambda x: x.start_time)
  2654.         snaps_for_each_volume = {}
  2655.         for snap in all_snapshots:
  2656.             # the snapshot name and the volume name are the same.
  2657.             # The snapshot name is set from the volume
  2658.             # name at the time the snapshot is taken
  2659.             volume_name = snap.tags.get('Name')
  2660.             if volume_name:
  2661.                 # only examine snapshots that have a volume name
  2662.                 snaps_for_volume = snaps_for_each_volume.get(volume_name)
  2663.                 if not snaps_for_volume:
  2664.                     snaps_for_volume = []
  2665.                     snaps_for_each_volume[volume_name] = snaps_for_volume
  2666.                 snaps_for_volume.append(snap)
  2667.  
  2668.         # Do a running comparison of snapshot dates to desired time
  2669.         #periods, keeping the oldest snapshot in each
  2670.         # time period and deleting the rest:
  2671.         for volume_name in snaps_for_each_volume:
  2672.             snaps = snaps_for_each_volume[volume_name]
  2673.             snaps = snaps[:-1] # never delete the newest snapshot
  2674.             time_period_number = 0
  2675.             snap_found_for_this_time_period = False
  2676.             for snap in snaps:
  2677.                 check_this_snap = True
  2678.                 while check_this_snap and time_period_number < target_backup_times.__len__():
  2679.                     snap_date = datetime.strptime(snap.start_time,
  2680.                                                   '%Y-%m-%dT%H:%M:%S.000Z')
  2681.                     if snap_date < target_backup_times[time_period_number]:
  2682.                         # the snap date is before the cutoff date.
  2683.                         # Figure out if it's the first snap in this
  2684.                         # date range and act accordingly (since both
  2685.                         #date the date ranges and the snapshots
  2686.                         # are sorted chronologically, we know this
  2687.                         #snapshot isn't in an earlier date range):
  2688.                         if snap_found_for_this_time_period == True:
  2689.                             if not snap.tags.get('preserve_snapshot'):
  2690.                                 # as long as the snapshot wasn't marked
  2691.                                 # with the 'preserve_snapshot' tag, delete it:
  2692.                                 try:
  2693.                                     self.delete_snapshot(snap.id)
  2694.                                     boto.log.info('Trimmed snapshot %s (%s)' % (snap.tags['Name'], snap.start_time))
  2695.                                 except EC2ResponseError:
  2696.                                     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))
  2697.                             # go on and look at the next snapshot,
  2698.                             #leaving the time period alone
  2699.                         else:
  2700.                             # this was the first snapshot found for this
  2701.                             #time period. Leave it alone and look at the
  2702.                             # next snapshot:
  2703.                             snap_found_for_this_time_period = True
  2704.                         check_this_snap = False
  2705.                     else:
  2706.                         # the snap is after the cutoff date. Check it
  2707.                         # against the next cutoff date
  2708.                         time_period_number += 1
  2709.                         snap_found_for_this_time_period = False
  2710.  
  2711.     def get_snapshot_attribute(self, snapshot_id,
  2712.                                attribute='createVolumePermission',
  2713.                                dry_run=False):
  2714.         """
  2715.        Get information about an attribute of a snapshot.  Only one attribute
  2716.        can be specified per call.
  2717.  
  2718.        :type snapshot_id: str
  2719.        :param snapshot_id: The ID of the snapshot.
  2720.  
  2721.        :type attribute: str
  2722.        :param attribute: The requested attribute.  Valid values are:
  2723.  
  2724.                          * createVolumePermission
  2725.  
  2726.        :type dry_run: bool
  2727.        :param dry_run: Set to True if the operation should not actually run.
  2728.  
  2729.        :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute`
  2730.        :return: The requested Snapshot attribute
  2731.        """
  2732.         params = {'Attribute': attribute}
  2733.         if snapshot_id:
  2734.             params['SnapshotId'] = snapshot_id
  2735.         if dry_run:
  2736.             params['DryRun'] = 'true'
  2737.         return self.get_object('DescribeSnapshotAttribute', params,
  2738.                                SnapshotAttribute, verb='POST')
  2739.  
  2740.     def modify_snapshot_attribute(self, snapshot_id,
  2741.                                   attribute='createVolumePermission',
  2742.                                   operation='add', user_ids=None, groups=None,
  2743.                                   dry_run=False):
  2744.         """
  2745.        Changes an attribute of an image.
  2746.  
  2747.        :type snapshot_id: string
  2748.        :param snapshot_id: The snapshot id you wish to change
  2749.  
  2750.        :type attribute: string
  2751.        :param attribute: The attribute you wish to change.  Valid values are:
  2752.            createVolumePermission
  2753.  
  2754.        :type operation: string
  2755.        :param operation: Either add or remove (this is required for changing
  2756.            snapshot ermissions)
  2757.  
  2758.        :type user_ids: list
  2759.        :param user_ids: The Amazon IDs of users to add/remove attributes
  2760.  
  2761.        :type groups: list
  2762.        :param groups: The groups to add/remove attributes.  The only valid
  2763.            value at this time is 'all'.
  2764.  
  2765.        :type dry_run: bool
  2766.        :param dry_run: Set to True if the operation should not actually run.
  2767.  
  2768.        """
  2769.         params = {'SnapshotId': snapshot_id,
  2770.                   'Attribute': attribute,
  2771.                   'OperationType': operation}
  2772.         if user_ids:
  2773.             self.build_list_params(params, user_ids, 'UserId')
  2774.         if groups:
  2775.             self.build_list_params(params, groups, 'UserGroup')
  2776.         if dry_run:
  2777.             params['DryRun'] = 'true'
  2778.         return self.get_status('ModifySnapshotAttribute', params, verb='POST')
  2779.  
  2780.     def reset_snapshot_attribute(self, snapshot_id,
  2781.                                  attribute='createVolumePermission',
  2782.                                  dry_run=False):
  2783.         """
  2784.        Resets an attribute of a snapshot to its default value.
  2785.  
  2786.        :type snapshot_id: string
  2787.        :param snapshot_id: ID of the snapshot
  2788.  
  2789.        :type attribute: string
  2790.        :param attribute: The attribute to reset
  2791.  
  2792.        :type dry_run: bool
  2793.        :param dry_run: Set to True if the operation should not actually run.
  2794.  
  2795.        :rtype: bool
  2796.        :return: Whether the operation succeeded or not
  2797.        """
  2798.         params = {'SnapshotId': snapshot_id,
  2799.                   'Attribute': attribute}
  2800.         if dry_run:
  2801.             params['DryRun'] = 'true'
  2802.         return self.get_status('ResetSnapshotAttribute', params, verb='POST')
  2803.  
  2804.     # Keypair methods
  2805.  
  2806.     def get_all_key_pairs(self, keynames=None, filters=None, dry_run=False):
  2807.         """
  2808.        Get all key pairs associated with your account.
  2809.  
  2810.        :type keynames: list
  2811.        :param keynames: A list of the names of keypairs to retrieve.
  2812.            If not provided, all key pairs will be returned.
  2813.  
  2814.        :type filters: dict
  2815.        :param filters: Optional filters that can be used to limit the
  2816.            results returned.  Filters are provided in the form of a
  2817.            dictionary consisting of filter names as the key and
  2818.            filter values as the value.  The set of allowable filter
  2819.            names/values is dependent on the request being performed.
  2820.            Check the EC2 API guide for details.
  2821.  
  2822.        :type dry_run: bool
  2823.        :param dry_run: Set to True if the operation should not actually run.
  2824.  
  2825.        :rtype: list
  2826.        :return: A list of :class:`boto.ec2.keypair.KeyPair`
  2827.        """
  2828.         params = {}
  2829.         if keynames:
  2830.             self.build_list_params(params, keynames, 'KeyName')
  2831.         if filters:
  2832.             self.build_filter_params(params, filters)
  2833.         if dry_run:
  2834.             params['DryRun'] = 'true'
  2835.         return self.get_list('DescribeKeyPairs', params,
  2836.                              [('item', KeyPair)], verb='POST')
  2837.  
  2838.     def get_key_pair(self, keyname, dry_run=False):
  2839.         """
  2840.        Convenience method to retrieve a specific keypair (KeyPair).
  2841.  
  2842.        :type keyname: string
  2843.        :param keyname: The name of the keypair to retrieve
  2844.  
  2845.        :type dry_run: bool
  2846.        :param dry_run: Set to True if the operation should not actually run.
  2847.  
  2848.        :rtype: :class:`boto.ec2.keypair.KeyPair`
  2849.        :return: The KeyPair specified or None if it is not found
  2850.        """
  2851.         try:
  2852.             return self.get_all_key_pairs(
  2853.                 keynames=[keyname],
  2854.                 dry_run=dry_run
  2855.             )[0]
  2856.         except self.ResponseError as e:
  2857.             if e.code == 'InvalidKeyPair.NotFound':
  2858.                 return None
  2859.             else:
  2860.                 raise
  2861.  
  2862.     def create_key_pair(self, key_name, dry_run=False):
  2863.         """
  2864.        Create a new key pair for your account.
  2865.        This will create the key pair within the region you
  2866.        are currently connected to.
  2867.  
  2868.        :type key_name: string
  2869.        :param key_name: The name of the new keypair
  2870.  
  2871.        :type dry_run: bool
  2872.        :param dry_run: Set to True if the operation should not actually run.
  2873.  
  2874.        :rtype: :class:`boto.ec2.keypair.KeyPair`
  2875.        :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
  2876.                 The material attribute of the new KeyPair object
  2877.                 will contain the the unencrypted PEM encoded RSA private key.
  2878.        """
  2879.         params = {'KeyName': key_name}
  2880.         if dry_run:
  2881.             params['DryRun'] = 'true'
  2882.         return self.get_object('CreateKeyPair', params, KeyPair, verb='POST')
  2883.  
  2884.     def delete_key_pair(self, key_name, dry_run=False):
  2885.         """
  2886.        Delete a key pair from your account.
  2887.  
  2888.        :type key_name: string
  2889.        :param key_name: The name of the keypair to delete
  2890.  
  2891.        :type dry_run: bool
  2892.        :param dry_run: Set to True if the operation should not actually run.
  2893.  
  2894.        """
  2895.         params = {'KeyName': key_name}
  2896.         if dry_run:
  2897.             params['DryRun'] = 'true'
  2898.         return self.get_status('DeleteKeyPair', params, verb='POST')
  2899.  
  2900.     def import_key_pair(self, key_name, public_key_material, dry_run=False):
  2901.         """
  2902.        imports the public key from an RSA key pair that you created
  2903.        with a third-party tool.
  2904.  
  2905.        Supported formats:
  2906.  
  2907.        * OpenSSH public key format (e.g., the format
  2908.          in ~/.ssh/authorized_keys)
  2909.  
  2910.        * Base64 encoded DER format
  2911.  
  2912.        * SSH public key file format as specified in RFC4716
  2913.  
  2914.        DSA keys are not supported. Make sure your key generator is
  2915.        set up to create RSA keys.
  2916.  
  2917.        Supported lengths: 1024, 2048, and 4096.
  2918.  
  2919.        :type key_name: string
  2920.        :param key_name: The name of the new keypair
  2921.  
  2922.        :type public_key_material: string
  2923.        :param public_key_material: The public key. You must base64 encode
  2924.                                    the public key material before sending
  2925.                                    it to AWS.
  2926.  
  2927.        :type dry_run: bool
  2928.        :param dry_run: Set to True if the operation should not actually run.
  2929.  
  2930.        :rtype: :class:`boto.ec2.keypair.KeyPair`
  2931.        :return: A :class:`boto.ec2.keypair.KeyPair` object representing
  2932.            the newly imported key pair.  This object will contain only
  2933.            the key name and the fingerprint.
  2934.        """
  2935.         public_key_material = base64.b64encode(public_key_material)
  2936.         params = {'KeyName': key_name,
  2937.                   'PublicKeyMaterial': public_key_material}
  2938.         if dry_run:
  2939.             params['DryRun'] = 'true'
  2940.         return self.get_object('ImportKeyPair', params, KeyPair, verb='POST')
  2941.  
  2942.     # SecurityGroup methods
  2943.  
  2944.     def get_all_security_groups(self, groupnames=None, group_ids=None,
  2945.                                 filters=None, dry_run=False):
  2946.         """
  2947.        Get all security groups associated with your account in a region.
  2948.  
  2949.        :type groupnames: list
  2950.        :param groupnames: A list of the names of security groups to retrieve.
  2951.                           If not provided, all security groups will be
  2952.                           returned.
  2953.  
  2954.        :type group_ids: list
  2955.        :param group_ids: A list of IDs of security groups to retrieve for
  2956.                          security groups within a VPC.
  2957.  
  2958.        :type filters: dict
  2959.        :param filters: Optional filters that can be used to limit
  2960.                        the results returned.  Filters are provided
  2961.                        in the form of a dictionary consisting of
  2962.                        filter names as the key and filter values
  2963.                        as the value.  The set of allowable filter
  2964.                        names/values is dependent on the request
  2965.                        being performed.  Check the EC2 API guide
  2966.                        for details.
  2967.  
  2968.        :type dry_run: bool
  2969.        :param dry_run: Set to True if the operation should not actually run.
  2970.  
  2971.        :rtype: list
  2972.        :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
  2973.        """
  2974.         params = {}
  2975.         if groupnames is not None:
  2976.             self.build_list_params(params, groupnames, 'GroupName')
  2977.         if group_ids is not None:
  2978.             self.build_list_params(params, group_ids, 'GroupId')
  2979.         if filters is not None:
  2980.             self.build_filter_params(params, filters)
  2981.         if dry_run:
  2982.             params['DryRun'] = 'true'
  2983.         return self.get_list('DescribeSecurityGroups', params,
  2984.                              [('item', SecurityGroup)], verb='POST')
  2985.  
  2986.     def create_security_group(self, name, description, vpc_id=None,
  2987.                               dry_run=False):
  2988.         """
  2989.        Create a new security group for your account.
  2990.        This will create the security group within the region you
  2991.        are currently connected to.
  2992.  
  2993.        :type name: string
  2994.        :param name: The name of the new security group
  2995.  
  2996.        :type description: string
  2997.        :param description: The description of the new security group
  2998.  
  2999.        :type vpc_id: string
  3000.        :param vpc_id: The ID of the VPC to create the security group in,
  3001.                       if any.
  3002.  
  3003.        :type dry_run: bool
  3004.        :param dry_run: Set to True if the operation should not actually run.
  3005.  
  3006.        :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
  3007.        :return: The newly created :class:`boto.ec2.securitygroup.SecurityGroup`.
  3008.        """
  3009.         params = {'GroupName': name,
  3010.                   'GroupDescription': description}
  3011.  
  3012.         if vpc_id is not None:
  3013.             params['VpcId'] = vpc_id
  3014.  
  3015.         if dry_run:
  3016.             params['DryRun'] = 'true'
  3017.  
  3018.         group = self.get_object('CreateSecurityGroup', params,
  3019.                                 SecurityGroup, verb='POST')
  3020.         group.name = name
  3021.         group.description = description
  3022.         if vpc_id is not None:
  3023.             group.vpc_id = vpc_id
  3024.         return group
  3025.  
  3026.     def delete_security_group(self, name=None, group_id=None, dry_run=False):
  3027.         """
  3028.        Delete a security group from your account.
  3029.  
  3030.        :type name: string
  3031.        :param name: The name of the security group to delete.
  3032.  
  3033.        :type group_id: string
  3034.        :param group_id: The ID of the security group to delete within
  3035.          a VPC.
  3036.  
  3037.        :type dry_run: bool
  3038.        :param dry_run: Set to True if the operation should not actually run.
  3039.  
  3040.        :rtype: bool
  3041.        :return: True if successful.
  3042.        """
  3043.         params = {}
  3044.  
  3045.         if name is not None:
  3046.             params['GroupName'] = name
  3047.         elif group_id is not None:
  3048.             params['GroupId'] = group_id
  3049.  
  3050.         if dry_run:
  3051.             params['DryRun'] = 'true'
  3052.  
  3053.         return self.get_status('DeleteSecurityGroup', params, verb='POST')
  3054.  
  3055.     def authorize_security_group_deprecated(self, group_name,
  3056.                                             src_security_group_name=None,
  3057.                                             src_security_group_owner_id=None,
  3058.                                             ip_protocol=None,
  3059.                                             from_port=None, to_port=None,
  3060.                                             cidr_ip=None, dry_run=False):
  3061.         """
  3062.        NOTE: This method uses the old-style request parameters
  3063.              that did not allow a port to be specified when
  3064.              authorizing a group.
  3065.  
  3066.        :type group_name: string
  3067.        :param group_name: The name of the security group you are adding
  3068.            the rule to.
  3069.  
  3070.        :type src_security_group_name: string
  3071.        :param src_security_group_name: The name of the security group you are
  3072.            granting access to.
  3073.  
  3074.        :type src_security_group_owner_id: string
  3075.        :param src_security_group_owner_id: The ID of the owner of the security
  3076.            group you are granting access to.
  3077.  
  3078.        :type ip_protocol: string
  3079.        :param ip_protocol: Either tcp | udp | icmp
  3080.  
  3081.        :type from_port: int
  3082.        :param from_port: The beginning port number you are enabling
  3083.  
  3084.        :type to_port: int
  3085.        :param to_port: The ending port number you are enabling
  3086.  
  3087.        :type to_port: string
  3088.        :param to_port: The CIDR block you are providing access to.
  3089.            See http://goo.gl/Yj5QC
  3090.  
  3091.        :type dry_run: bool
  3092.        :param dry_run: Set to True if the operation should not actually run.
  3093.  
  3094.        :rtype: bool
  3095.        :return: True if successful.
  3096.        """
  3097.         params = {'GroupName': group_name}
  3098.         if src_security_group_name:
  3099.             params['SourceSecurityGroupName'] = src_security_group_name
  3100.         if src_security_group_owner_id:
  3101.             params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
  3102.         if ip_protocol:
  3103.             params['IpProtocol'] = ip_protocol
  3104.         if from_port:
  3105.             params['FromPort'] = from_port
  3106.         if to_port:
  3107.             params['ToPort'] = to_port
  3108.         if cidr_ip:
  3109.             params['CidrIp'] = cidr_ip
  3110.         if dry_run:
  3111.             params['DryRun'] = 'true'
  3112.         return self.get_status('AuthorizeSecurityGroupIngress', params)
  3113.  
  3114.     def authorize_security_group(self, group_name=None,
  3115.                                  src_security_group_name=None,
  3116.                                  src_security_group_owner_id=None,
  3117.                                  ip_protocol=None,
  3118.                                  from_port=None, to_port=None,
  3119.                                  cidr_ip=None, group_id=None,
  3120.                                  src_security_group_group_id=None,
  3121.                                  dry_run=False):
  3122.         """
  3123.        Add a new rule to an existing security group.
  3124.        You need to pass in either src_security_group_name and
  3125.        src_security_group_owner_id OR ip_protocol, from_port, to_port,
  3126.        and cidr_ip.  In other words, either you are authorizing another
  3127.        group or you are authorizing some ip-based rule.
  3128.  
  3129.        :type group_name: string
  3130.        :param group_name: The name of the security group you are adding
  3131.            the rule to.
  3132.  
  3133.        :type src_security_group_name: string
  3134.        :param src_security_group_name: The name of the security group you are
  3135.            granting access to.
  3136.  
  3137.        :type src_security_group_owner_id: string
  3138.        :param src_security_group_owner_id: The ID of the owner of the security
  3139.            group you are granting access to.
  3140.  
  3141.        :type ip_protocol: string
  3142.        :param ip_protocol: Either tcp | udp | icmp
  3143.  
  3144.        :type from_port: int
  3145.        :param from_port: The beginning port number you are enabling
  3146.  
  3147.        :type to_port: int
  3148.        :param to_port: The ending port number you are enabling
  3149.  
  3150.        :type cidr_ip: string or list of strings
  3151.        :param cidr_ip: The CIDR block you are providing access to.
  3152.            See http://goo.gl/Yj5QC
  3153.  
  3154.        :type group_id: string
  3155.        :param group_id: ID of the EC2 or VPC security group to
  3156.            modify.  This is required for VPC security groups and can
  3157.            be used instead of group_name for EC2 security groups.
  3158.  
  3159.        :type src_security_group_group_id: string
  3160.        :param src_security_group_group_id: The ID of the security
  3161.            group you are granting access to.  Can be used instead of
  3162.            src_security_group_name
  3163.  
  3164.        :type dry_run: bool
  3165.        :param dry_run: Set to True if the operation should not actually run.
  3166.  
  3167.        :rtype: bool
  3168.        :return: True if successful.
  3169.        """
  3170.         if src_security_group_name:
  3171.             if from_port is None and to_port is None and ip_protocol is None:
  3172.                 return self.authorize_security_group_deprecated(
  3173.                     group_name, src_security_group_name,
  3174.                     src_security_group_owner_id)
  3175.  
  3176.         params = {}
  3177.  
  3178.         if group_name:
  3179.             params['GroupName'] = group_name
  3180.         if group_id:
  3181.             params['GroupId'] = group_id
  3182.         if src_security_group_name:
  3183.             param_name = 'IpPermissions.1.Groups.1.GroupName'
  3184.             params[param_name] = src_security_group_name
  3185.         if src_security_group_owner_id:
  3186.             param_name = 'IpPermissions.1.Groups.1.UserId'
  3187.             params[param_name] = src_security_group_owner_id
  3188.         if src_security_group_group_id:
  3189.             param_name = 'IpPermissions.1.Groups.1.GroupId'
  3190.             params[param_name] = src_security_group_group_id
  3191.         if ip_protocol:
  3192.             params['IpPermissions.1.IpProtocol'] = ip_protocol
  3193.         if from_port is not None:
  3194.             params['IpPermissions.1.FromPort'] = from_port
  3195.         if to_port is not None:
  3196.             params['IpPermissions.1.ToPort'] = to_port
  3197.         if cidr_ip:
  3198.             if not isinstance(cidr_ip, list):
  3199.                 cidr_ip = [cidr_ip]
  3200.             for i, single_cidr_ip in enumerate(cidr_ip):
  3201.                 params['IpPermissions.1.IpRanges.%d.CidrIp' % (i + 1)] = \
  3202.                     single_cidr_ip
  3203.         if dry_run:
  3204.             params['DryRun'] = 'true'
  3205.  
  3206.         return self.get_status('AuthorizeSecurityGroupIngress',
  3207.                                params, verb='POST')
  3208.  
  3209.     def authorize_security_group_egress(self,
  3210.                                         group_id,
  3211.                                         ip_protocol,
  3212.                                         from_port=None,
  3213.                                         to_port=None,
  3214.                                         src_group_id=None,
  3215.                                         cidr_ip=None,
  3216.                                         dry_run=False):
  3217.         """
  3218.        The action adds one or more egress rules to a VPC security
  3219.        group. Specifically, this action permits instances in a
  3220.        security group to send traffic to one or more destination
  3221.        CIDR IP address ranges, or to one or more destination
  3222.        security groups in the same VPC.
  3223.  
  3224.        :type dry_run: bool
  3225.        :param dry_run: Set to True if the operation should not actually run.
  3226.  
  3227.        """
  3228.         params = {
  3229.             'GroupId': group_id,
  3230.             'IpPermissions.1.IpProtocol': ip_protocol
  3231.         }
  3232.  
  3233.         if from_port is not None:
  3234.             params['IpPermissions.1.FromPort'] = from_port
  3235.         if to_port is not None:
  3236.             params['IpPermissions.1.ToPort'] = to_port
  3237.         if src_group_id is not None:
  3238.             params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
  3239.         if cidr_ip is not None:
  3240.             params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
  3241.         if dry_run:
  3242.             params['DryRun'] = 'true'
  3243.  
  3244.         return self.get_status('AuthorizeSecurityGroupEgress',
  3245.                                params, verb='POST')
  3246.  
  3247.     def revoke_security_group_deprecated(self, group_name,
  3248.                                          src_security_group_name=None,
  3249.                                          src_security_group_owner_id=None,
  3250.                                          ip_protocol=None,
  3251.                                          from_port=None, to_port=None,
  3252.                                          cidr_ip=None, dry_run=False):
  3253.         """
  3254.        NOTE: This method uses the old-style request parameters
  3255.              that did not allow a port to be specified when
  3256.              authorizing a group.
  3257.  
  3258.        Remove an existing rule from an existing security group.
  3259.        You need to pass in either src_security_group_name and
  3260.        src_security_group_owner_id OR ip_protocol, from_port, to_port,
  3261.        and cidr_ip.  In other words, either you are revoking another
  3262.        group or you are revoking some ip-based rule.
  3263.  
  3264.        :type group_name: string
  3265.        :param group_name: The name of the security group you are removing
  3266.                           the rule from.
  3267.  
  3268.        :type src_security_group_name: string
  3269.        :param src_security_group_name: The name of the security group you are
  3270.                                        revoking access to.
  3271.  
  3272.        :type src_security_group_owner_id: string
  3273.        :param src_security_group_owner_id: The ID of the owner of the security
  3274.                                            group you are revoking access to.
  3275.  
  3276.        :type ip_protocol: string
  3277.        :param ip_protocol: Either tcp | udp | icmp
  3278.  
  3279.        :type from_port: int
  3280.        :param from_port: The beginning port number you are disabling
  3281.  
  3282.        :type to_port: int
  3283.        :param to_port: The ending port number you are disabling
  3284.  
  3285.        :type to_port: string
  3286.        :param to_port: The CIDR block you are revoking access to.
  3287.                        http://goo.gl/Yj5QC
  3288.  
  3289.        :type dry_run: bool
  3290.        :param dry_run: Set to True if the operation should not actually run.
  3291.  
  3292.        :rtype: bool
  3293.        :return: True if successful.
  3294.        """
  3295.         params = {'GroupName': group_name}
  3296.         if src_security_group_name:
  3297.             params['SourceSecurityGroupName'] = src_security_group_name
  3298.         if src_security_group_owner_id:
  3299.             params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
  3300.         if ip_protocol:
  3301.             params['IpProtocol'] = ip_protocol
  3302.         if from_port:
  3303.             params['FromPort'] = from_port
  3304.         if to_port:
  3305.             params['ToPort'] = to_port
  3306.         if cidr_ip:
  3307.             params['CidrIp'] = cidr_ip
  3308.         if dry_run:
  3309.             params['DryRun'] = 'true'
  3310.         return self.get_status('RevokeSecurityGroupIngress', params)
  3311.  
  3312.     def revoke_security_group(self, group_name=None,
  3313.                               src_security_group_name=None,
  3314.                               src_security_group_owner_id=None,
  3315.                               ip_protocol=None, from_port=None, to_port=None,
  3316.                               cidr_ip=None, group_id=None,
  3317.                               src_security_group_group_id=None, dry_run=False):
  3318.         """
  3319.        Remove an existing rule from an existing security group.
  3320.        You need to pass in either src_security_group_name and
  3321.        src_security_group_owner_id OR ip_protocol, from_port, to_port,
  3322.        and cidr_ip.  In other words, either you are revoking another
  3323.        group or you are revoking some ip-based rule.
  3324.  
  3325.        :type group_name: string
  3326.        :param group_name: The name of the security group you are removing
  3327.            the rule from.
  3328.  
  3329.        :type src_security_group_name: string
  3330.        :param src_security_group_name: The name of the security group you are
  3331.            revoking access to.
  3332.  
  3333.        :type src_security_group_owner_id: string
  3334.        :param src_security_group_owner_id: The ID of the owner of the security
  3335.            group you are revoking access to.
  3336.  
  3337.        :type ip_protocol: string
  3338.        :param ip_protocol: Either tcp | udp | icmp
  3339.  
  3340.        :type from_port: int
  3341.        :param from_port: The beginning port number you are disabling
  3342.  
  3343.        :type to_port: int
  3344.        :param to_port: The ending port number you are disabling
  3345.  
  3346.        :type cidr_ip: string
  3347.        :param cidr_ip: The CIDR block you are revoking access to.
  3348.            See http://goo.gl/Yj5QC
  3349.  
  3350.        :type group_id: string
  3351.        :param group_id: ID of the EC2 or VPC security group to
  3352.            modify.  This is required for VPC security groups and can
  3353.            be used instead of group_name for EC2 security groups.
  3354.  
  3355.        :type src_security_group_group_id: string
  3356.        :param src_security_group_group_id: The ID of the security group
  3357.            for which you are revoking access.  Can be used instead
  3358.            of src_security_group_name
  3359.  
  3360.        :type dry_run: bool
  3361.        :param dry_run: Set to True if the operation should not actually run.
  3362.  
  3363.        :rtype: bool
  3364.        :return: True if successful.
  3365.        """
  3366.         if src_security_group_name:
  3367.             if from_port is None and to_port is None and ip_protocol is None:
  3368.                 return self.revoke_security_group_deprecated(
  3369.                     group_name, src_security_group_name,
  3370.                     src_security_group_owner_id)
  3371.         params = {}
  3372.         if group_name is not None:
  3373.             params['GroupName'] = group_name
  3374.         if group_id is not None:
  3375.             params['GroupId'] = group_id
  3376.         if src_security_group_name:
  3377.             param_name = 'IpPermissions.1.Groups.1.GroupName'
  3378.             params[param_name] = src_security_group_name
  3379.         if src_security_group_group_id:
  3380.             param_name = 'IpPermissions.1.Groups.1.GroupId'
  3381.             params[param_name] = src_security_group_group_id
  3382.         if src_security_group_owner_id:
  3383.             param_name = 'IpPermissions.1.Groups.1.UserId'
  3384.             params[param_name] = src_security_group_owner_id
  3385.         if ip_protocol:
  3386.             params['IpPermissions.1.IpProtocol'] = ip_protocol
  3387.         if from_port is not None:
  3388.             params['IpPermissions.1.FromPort'] = from_port
  3389.         if to_port is not None:
  3390.             params['IpPermissions.1.ToPort'] = to_port
  3391.         if cidr_ip:
  3392.             params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
  3393.         if dry_run:
  3394.             params['DryRun'] = 'true'
  3395.         return self.get_status('RevokeSecurityGroupIngress',
  3396.                                params, verb='POST')
  3397.  
  3398.     def revoke_security_group_egress(self,
  3399.                                      group_id,
  3400.                                      ip_protocol,
  3401.                                      from_port=None,
  3402.                                      to_port=None,
  3403.                                      src_group_id=None,
  3404.                                      cidr_ip=None, dry_run=False):
  3405.         """
  3406.        Remove an existing egress rule from an existing VPC security
  3407.        group.  You need to pass in an ip_protocol, from_port and
  3408.        to_port range only if the protocol you are using is
  3409.        port-based. You also need to pass in either a src_group_id or
  3410.        cidr_ip.
  3411.  
  3412.        :type group_name: string
  3413.        :param group_id:  The name of the security group you are removing
  3414.            the rule from.
  3415.  
  3416.        :type ip_protocol: string
  3417.        :param ip_protocol: Either tcp | udp | icmp | -1
  3418.  
  3419.        :type from_port: int
  3420.        :param from_port: The beginning port number you are disabling
  3421.  
  3422.        :type to_port: int
  3423.        :param to_port: The ending port number you are disabling
  3424.  
  3425.        :type src_group_id: src_group_id
  3426.        :param src_group_id: The source security group you are
  3427.            revoking access to.
  3428.  
  3429.        :type cidr_ip: string
  3430.        :param cidr_ip: The CIDR block you are revoking access to.
  3431.            See http://goo.gl/Yj5QC
  3432.  
  3433.        :type dry_run: bool
  3434.        :param dry_run: Set to True if the operation should not actually run.
  3435.  
  3436.        :rtype: bool
  3437.        :return: True if successful.
  3438.        """
  3439.  
  3440.         params = {}
  3441.         if group_id:
  3442.             params['GroupId'] = group_id
  3443.         if ip_protocol:
  3444.             params['IpPermissions.1.IpProtocol'] = ip_protocol
  3445.         if from_port is not None:
  3446.             params['IpPermissions.1.FromPort'] = from_port
  3447.         if to_port is not None:
  3448.             params['IpPermissions.1.ToPort'] = to_port
  3449.         if src_group_id is not None:
  3450.             params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
  3451.         if cidr_ip:
  3452.             params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
  3453.         if dry_run:
  3454.             params['DryRun'] = 'true'
  3455.         return self.get_status('RevokeSecurityGroupEgress',
  3456.                                params, verb='POST')
  3457.  
  3458.     #
  3459.     # Regions
  3460.     #
  3461.  
  3462.     def get_all_regions(self, region_names=None, filters=None, dry_run=False):
  3463.         """
  3464.        Get all available regions for the EC2 service.
  3465.  
  3466.        :type region_names: list of str
  3467.        :param region_names: Names of regions to limit output
  3468.  
  3469.        :type filters: dict
  3470.        :param filters: Optional filters that can be used to limit
  3471.                        the results returned.  Filters are provided
  3472.                        in the form of a dictionary consisting of
  3473.                        filter names as the key and filter values
  3474.                        as the value.  The set of allowable filter
  3475.                        names/values is dependent on the request
  3476.                        being performed.  Check the EC2 API guide
  3477.                        for details.
  3478.  
  3479.        :type dry_run: bool
  3480.        :param dry_run: Set to True if the operation should not actually run.
  3481.  
  3482.        :rtype: list
  3483.        :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
  3484.        """
  3485.         params = {}
  3486.         if region_names:
  3487.             self.build_list_params(params, region_names, 'RegionName')
  3488.         if filters:
  3489.             self.build_filter_params(params, filters)
  3490.         if dry_run:
  3491.             params['DryRun'] = 'true'
  3492.         regions = self.get_list('DescribeRegions', params,
  3493.                                 [('item', RegionInfo)], verb='POST')
  3494.         for region in regions:
  3495.             region.connection_cls = EC2Connection
  3496.         return regions
  3497.  
  3498.     #
  3499.     # Reservation methods
  3500.     #
  3501.  
  3502.     def get_all_reserved_instances_offerings(self,
  3503.                                              reserved_instances_offering_ids=None,
  3504.                                              instance_type=None,
  3505.                                              availability_zone=None,
  3506.                                              product_description=None,
  3507.                                              filters=None,
  3508.                                              instance_tenancy=None,
  3509.                                              offering_type=None,
  3510.                                              include_marketplace=None,
  3511.                                              min_duration=None,
  3512.                                              max_duration=None,
  3513.                                              max_instance_count=None,
  3514.                                              next_token=None,
  3515.                                              max_results=None,
  3516.                                              dry_run=False):
  3517.         """
  3518.        Describes Reserved Instance offerings that are available for purchase.
  3519.  
  3520.        :type reserved_instances_offering_ids: list
  3521.        :param reserved_instances_id: One or more Reserved Instances
  3522.            offering IDs.
  3523.  
  3524.        :type instance_type: str
  3525.        :param instance_type: Displays Reserved Instances of the specified
  3526.                              instance type.
  3527.  
  3528.        :type availability_zone: str
  3529.        :param availability_zone: Displays Reserved Instances within the
  3530.                                  specified Availability Zone.
  3531.  
  3532.        :type product_description: str
  3533.        :param product_description: Displays Reserved Instances with the
  3534.                                    specified product description.
  3535.  
  3536.        :type filters: dict
  3537.        :param filters: Optional filters that can be used to limit
  3538.                        the results returned.  Filters are provided
  3539.                        in the form of a dictionary consisting of
  3540.                        filter names as the key and filter values
  3541.                        as the value.  The set of allowable filter
  3542.                        names/values is dependent on the request
  3543.                        being performed.  Check the EC2 API guide
  3544.                        for details.
  3545.  
  3546.        :type instance_tenancy: string
  3547.        :param instance_tenancy: The tenancy of the Reserved Instance offering.
  3548.            A Reserved Instance with tenancy of dedicated will run on
  3549.            single-tenant hardware and can only be launched within a VPC.
  3550.  
  3551.        :type offering_type: string
  3552.        :param offering_type: The Reserved Instance offering type.  Valid
  3553.            Values: `"Heavy Utilization" | "Medium Utilization" | "Light
  3554.            Utilization"`
  3555.  
  3556.        :type include_marketplace: bool
  3557.        :param include_marketplace: Include Marketplace offerings in the
  3558.            response.
  3559.  
  3560.        :type min_duration: int :param min_duration: Minimum duration (in
  3561.            seconds) to filter when searching for offerings.
  3562.  
  3563.        :type max_duration: int
  3564.        :param max_duration: Maximum duration (in seconds) to filter when
  3565.            searching for offerings.
  3566.  
  3567.        :type max_instance_count: int
  3568.        :param max_instance_count: Maximum number of instances to filter when
  3569.            searching for offerings.
  3570.  
  3571.        :type next_token: string
  3572.        :param next_token: Token to use when requesting the next paginated set
  3573.            of offerings.
  3574.  
  3575.        :type max_results: int
  3576.        :param max_results: Maximum number of offerings to return per call.
  3577.  
  3578.        :type dry_run: bool
  3579.        :param dry_run: Set to True if the operation should not actually run.
  3580.  
  3581.        :rtype: list
  3582.        :return: A list of
  3583.            :class:`boto.ec2.reservedinstance.ReservedInstancesOffering`.
  3584.  
  3585.        """
  3586.         params = {}
  3587.         if reserved_instances_offering_ids is not None:
  3588.             self.build_list_params(params, reserved_instances_offering_ids,
  3589.                                    'ReservedInstancesOfferingId')
  3590.         if instance_type:
  3591.             params['InstanceType'] = instance_type
  3592.         if availability_zone:
  3593.             params['AvailabilityZone'] = availability_zone
  3594.         if product_description:
  3595.             params['ProductDescription'] = product_description
  3596.         if filters:
  3597.             self.build_filter_params(params, filters)
  3598.         if instance_tenancy is not None:
  3599.             params['InstanceTenancy'] = instance_tenancy
  3600.         if offering_type is not None:
  3601.             params['OfferingType'] = offering_type
  3602.         if include_marketplace is not None:
  3603.             if include_marketplace:
  3604.                 params['IncludeMarketplace'] = 'true'
  3605.             else:
  3606.                 params['IncludeMarketplace'] = 'false'
  3607.         if min_duration is not None:
  3608.             params['MinDuration'] = str(min_duration)
  3609.         if max_duration is not None:
  3610.             params['MaxDuration'] = str(max_duration)
  3611.         if max_instance_count is not None:
  3612.             params['MaxInstanceCount'] = str(max_instance_count)
  3613.         if next_token is not None:
  3614.             params['NextToken'] = next_token
  3615.         if max_results is not None:
  3616.             params['MaxResults'] = str(max_results)
  3617.         if dry_run:
  3618.             params['DryRun'] = 'true'
  3619.  
  3620.         return self.get_list('DescribeReservedInstancesOfferings',
  3621.                              params, [('item', ReservedInstancesOffering)],
  3622.                              verb='POST')
  3623.  
  3624.     def get_all_reserved_instances(self, reserved_instances_id=None,
  3625.                                    filters=None, dry_run=False):
  3626.         """
  3627.        Describes one or more of the Reserved Instances that you purchased.
  3628.  
  3629.        :type reserved_instance_ids: list
  3630.        :param reserved_instance_ids: A list of the reserved instance ids that
  3631.            will be returned. If not provided, all reserved instances
  3632.            will be returned.
  3633.  
  3634.        :type filters: dict
  3635.        :param filters: Optional filters that can be used to limit the
  3636.            results returned.  Filters are provided in the form of a
  3637.            dictionary consisting of filter names as the key and
  3638.            filter values as the value.  The set of allowable filter
  3639.            names/values is dependent on the request being performed.
  3640.            Check the EC2 API guide for details.
  3641.  
  3642.        :type dry_run: bool
  3643.        :param dry_run: Set to True if the operation should not actually run.
  3644.  
  3645.        :rtype: list
  3646.        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
  3647.        """
  3648.         params = {}
  3649.         if reserved_instances_id:
  3650.             self.build_list_params(params, reserved_instances_id,
  3651.                                    'ReservedInstancesId')
  3652.         if filters:
  3653.             self.build_filter_params(params, filters)
  3654.         if dry_run:
  3655.             params['DryRun'] = 'true'
  3656.         return self.get_list('DescribeReservedInstances',
  3657.                              params, [('item', ReservedInstance)], verb='POST')
  3658.  
  3659.     def purchase_reserved_instance_offering(self,
  3660.                                             reserved_instances_offering_id,
  3661.                                             instance_count=1, limit_price=None,
  3662.                                             dry_run=False):
  3663.         """
  3664.        Purchase a Reserved Instance for use with your account.
  3665.        ** CAUTION **
  3666.        This request can result in large amounts of money being charged to your
  3667.        AWS account.  Use with caution!
  3668.  
  3669.        :type reserved_instances_offering_id: string
  3670.        :param reserved_instances_offering_id: The offering ID of the Reserved
  3671.            Instance to purchase
  3672.  
  3673.        :type instance_count: int
  3674.        :param instance_count: The number of Reserved Instances to purchase.
  3675.            Default value is 1.
  3676.  
  3677.        :type limit_price: tuple
  3678.        :param instance_count: Limit the price on the total order.
  3679.            Must be a tuple of (amount, currency_code), for example:
  3680.            (100.0, 'USD').
  3681.  
  3682.        :type dry_run: bool
  3683.        :param dry_run: Set to True if the operation should not actually run.
  3684.  
  3685.        :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
  3686.        :return: The newly created Reserved Instance
  3687.        """
  3688.         params = {
  3689.             'ReservedInstancesOfferingId': reserved_instances_offering_id,
  3690.             'InstanceCount': instance_count}
  3691.         if limit_price is not None:
  3692.             params['LimitPrice.Amount'] = str(limit_price[0])
  3693.             params['LimitPrice.CurrencyCode'] = str(limit_price[1])
  3694.         if dry_run:
  3695.             params['DryRun'] = 'true'
  3696.         return self.get_object('PurchaseReservedInstancesOffering', params,
  3697.                                ReservedInstance, verb='POST')
  3698.  
  3699.     def create_reserved_instances_listing(self, reserved_instances_id,
  3700.                                           instance_count, price_schedules,
  3701.                                           client_token, dry_run=False):
  3702.         """Creates a new listing for Reserved Instances.
  3703.  
  3704.        Creates a new listing for Amazon EC2 Reserved Instances that will be
  3705.        sold in the Reserved Instance Marketplace. You can submit one Reserved
  3706.        Instance listing at a time.
  3707.  
  3708.        The Reserved Instance Marketplace matches sellers who want to resell
  3709.        Reserved Instance capacity that they no longer need with buyers who
  3710.        want to purchase additional capacity. Reserved Instances bought and
  3711.        sold through the Reserved Instance Marketplace work like any other
  3712.        Reserved Instances.
  3713.  
  3714.        If you want to sell your Reserved Instances, you must first register as
  3715.        a Seller in the Reserved Instance Marketplace. After completing the
  3716.        registration process, you can create a Reserved Instance Marketplace
  3717.        listing of some or all of your Reserved Instances, and specify the
  3718.        upfront price you want to receive for them. Your Reserved Instance
  3719.        listings then become available for purchase.
  3720.  
  3721.        :type reserved_instances_id: string
  3722.        :param reserved_instances_id: The ID of the Reserved Instance that
  3723.            will be listed.
  3724.  
  3725.        :type instance_count: int
  3726.        :param instance_count: The number of instances that are a part of a
  3727.            Reserved Instance account that will be listed in the Reserved
  3728.            Instance Marketplace. This number should be less than or equal to
  3729.            the instance count associated with the Reserved Instance ID
  3730.            specified in this call.
  3731.  
  3732.        :type price_schedules: List of tuples
  3733.        :param price_schedules: A list specifying the price of the Reserved
  3734.            Instance for each month remaining in the Reserved Instance term.
  3735.            Each tuple contains two elements, the price and the term.  For
  3736.            example, for an instance that 11 months remaining in its term,
  3737.            we can have a price schedule with an upfront price of $2.50.
  3738.            At 8 months remaining we can drop the price down to $2.00.
  3739.            This would be expressed as::
  3740.  
  3741.                price_schedules=[('2.50', 11), ('2.00', 8)]
  3742.  
  3743.        :type client_token: string
  3744.        :param client_token: Unique, case-sensitive identifier you provide
  3745.            to ensure idempotency of the request.  Maximum 64 ASCII characters.
  3746.  
  3747.        :type dry_run: bool
  3748.        :param dry_run: Set to True if the operation should not actually run.
  3749.  
  3750.        :rtype: list
  3751.        :return: A list of
  3752.            :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
  3753.  
  3754.        """
  3755.         params = {
  3756.             'ReservedInstancesId': reserved_instances_id,
  3757.             'InstanceCount': str(instance_count),
  3758.             'ClientToken': client_token,
  3759.         }
  3760.         for i, schedule in enumerate(price_schedules):
  3761.             price, term = schedule
  3762.             params['PriceSchedules.%s.Price' % i] = str(price)
  3763.             params['PriceSchedules.%s.Term' % i] = str(term)
  3764.         if dry_run:
  3765.             params['DryRun'] = 'true'
  3766.         return self.get_list('CreateReservedInstancesListing',
  3767.                              params, [('item', ReservedInstanceListing)], verb='POST')
  3768.  
  3769.     def cancel_reserved_instances_listing(self,
  3770.                                           reserved_instances_listing_ids=None,
  3771.                                           dry_run=False):
  3772.         """Cancels the specified Reserved Instance listing.
  3773.  
  3774.        :type reserved_instances_listing_ids: List of strings
  3775.        :param reserved_instances_listing_ids: The ID of the
  3776.            Reserved Instance listing to be cancelled.
  3777.  
  3778.        :type dry_run: bool
  3779.        :param dry_run: Set to True if the operation should not actually run.
  3780.  
  3781.        :rtype: list
  3782.        :return: A list of
  3783.            :class:`boto.ec2.reservedinstance.ReservedInstanceListing`
  3784.  
  3785.        """
  3786.         params = {}
  3787.         if reserved_instances_listing_ids is not None:
  3788.             self.build_list_params(params, reserved_instances_listing_ids,
  3789.                                    'ReservedInstancesListingId')
  3790.         if dry_run:
  3791.             params['DryRun'] = 'true'
  3792.         return self.get_list('CancelReservedInstancesListing',
  3793.                              params, [('item', ReservedInstanceListing)], verb='POST')
  3794.  
  3795.     def build_configurations_param_list(self, params, target_configurations):
  3796.         for offset, tc in enumerate(target_configurations):
  3797.             prefix = 'ReservedInstancesConfigurationSetItemType.%d.' % offset
  3798.             if tc.availability_zone is not None:
  3799.                 params[prefix + 'AvailabilityZone'] = tc.availability_zone
  3800.             if tc.platform is not None:
  3801.                 params[prefix + 'Platform'] = tc.platform
  3802.             if tc.instance_count is not None:
  3803.                 params[prefix + 'InstanceCount'] = tc.instance_count
  3804.             if tc.instance_type is not None:
  3805.                 params[prefix + 'InstanceType'] = tc.instance_type
  3806.  
  3807.     def modify_reserved_instances(self, client_token, reserved_instance_ids,
  3808.                                   target_configurations):
  3809.         """
  3810.        Modifies the specified Reserved Instances.
  3811.  
  3812.        :type client_token: string
  3813.        :param client_token: A unique, case-sensitive, token you provide to
  3814.                             ensure idempotency of your modification request.
  3815.  
  3816.        :type reserved_instance_ids: List of strings
  3817.        :param reserved_instance_ids: The IDs of the Reserved Instances to
  3818.                                      modify.
  3819.  
  3820.        :type target_configurations: List of :class:`boto.ec2.reservedinstance.ReservedInstancesConfiguration`
  3821.        :param target_configurations: The configuration settings for the
  3822.                                      modified Reserved Instances.
  3823.  
  3824.        :rtype: string
  3825.        :return: The unique ID for the submitted modification request.
  3826.        """
  3827.         params = {}
  3828.         if client_token is not None:
  3829.             params['ClientToken'] = client_token
  3830.         if reserved_instance_ids is not None:
  3831.             self.build_list_params(params, reserved_instance_ids,
  3832.                                    'ReservedInstancesId')
  3833.         if target_configurations is not None:
  3834.             self.build_configurations_param_list(params, target_configurations)
  3835.         mrir = self.get_object(
  3836.             'ModifyReservedInstances',
  3837.             params,
  3838.             ModifyReservedInstancesResult,
  3839.             verb='POST'
  3840.         )
  3841.         return mrir.modification_id
  3842.  
  3843.     def describe_reserved_instances_modifications(self,
  3844.             reserved_instances_modification_ids=None, next_token=None,
  3845.             filters=None):
  3846.         """
  3847.        A request to describe the modifications made to Reserved Instances in
  3848.        your account.
  3849.  
  3850.        :type reserved_instances_modification_ids: list
  3851.        :param reserved_instances_modification_ids: An optional list of
  3852.            Reserved Instances modification IDs to describe.
  3853.  
  3854.        :type next_token: str
  3855.        :param next_token: A string specifying the next paginated set
  3856.            of results to return.
  3857.  
  3858.        :type filters: dict
  3859.        :param filters: Optional filters that can be used to limit the
  3860.            results returned.  Filters are provided in the form of a
  3861.            dictionary consisting of filter names as the key and
  3862.            filter values as the value.  The set of allowable filter
  3863.            names/values is dependent on the request being performed.
  3864.            Check the EC2 API guide for details.
  3865.  
  3866.        :rtype: list
  3867.        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
  3868.        """
  3869.         params = {}
  3870.         if reserved_instances_modification_ids:
  3871.             self.build_list_params(params, reserved_instances_modification_ids,
  3872.                                    'ReservedInstancesModificationId')
  3873.         if next_token:
  3874.             params['NextToken'] = next_token
  3875.         if filters:
  3876.             self.build_filter_params(params, filters)
  3877.         return self.get_list('DescribeReservedInstancesModifications',
  3878.                              params, [('item', ReservedInstancesModification)],
  3879.                              verb='POST')
  3880.  
  3881.     #
  3882.     # Monitoring
  3883.     #
  3884.  
  3885.     def monitor_instances(self, instance_ids, dry_run=False):
  3886.         """
  3887.        Enable detailed CloudWatch monitoring for the supplied instances.
  3888.  
  3889.        :type instance_id: list of strings
  3890.        :param instance_id: The instance ids
  3891.  
  3892.        :type dry_run: bool
  3893.        :param dry_run: Set to True if the operation should not actually run.
  3894.  
  3895.        :rtype: list
  3896.        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
  3897.        """
  3898.         params = {}
  3899.         self.build_list_params(params, instance_ids, 'InstanceId')
  3900.         if dry_run:
  3901.             params['DryRun'] = 'true'
  3902.         return self.get_list('MonitorInstances', params,
  3903.                              [('item', InstanceInfo)], verb='POST')
  3904.  
  3905.     def monitor_instance(self, instance_id, dry_run=False):
  3906.         """
  3907.        Deprecated Version, maintained for backward compatibility.
  3908.        Enable detailed CloudWatch monitoring for the supplied instance.
  3909.  
  3910.        :type instance_id: string
  3911.        :param instance_id: The instance id
  3912.  
  3913.        :type dry_run: bool
  3914.        :param dry_run: Set to True if the operation should not actually run.
  3915.  
  3916.        :rtype: list
  3917.        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
  3918.        """
  3919.         return self.monitor_instances([instance_id], dry_run=dry_run)
  3920.  
  3921.     def unmonitor_instances(self, instance_ids, dry_run=False):
  3922.         """
  3923.        Disable CloudWatch monitoring for the supplied instance.
  3924.  
  3925.        :type instance_id: list of string
  3926.        :param instance_id: The instance id
  3927.  
  3928.        :type dry_run: bool
  3929.        :param dry_run: Set to True if the operation should not actually run.
  3930.  
  3931.        :rtype: list
  3932.        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
  3933.        """
  3934.         params = {}
  3935.         self.build_list_params(params, instance_ids, 'InstanceId')
  3936.         if dry_run:
  3937.             params['DryRun'] = 'true'
  3938.         return self.get_list('UnmonitorInstances', params,
  3939.                              [('item', InstanceInfo)], verb='POST')
  3940.  
  3941.     def unmonitor_instance(self, instance_id, dry_run=False):
  3942.         """
  3943.        Deprecated Version, maintained for backward compatibility.
  3944.        Disable detailed CloudWatch monitoring for the supplied instance.
  3945.  
  3946.        :type instance_id: string
  3947.        :param instance_id: The instance id
  3948.  
  3949.        :type dry_run: bool
  3950.        :param dry_run: Set to True if the operation should not actually run.
  3951.  
  3952.        :rtype: list
  3953.        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
  3954.        """
  3955.         return self.unmonitor_instances([instance_id], dry_run=dry_run)
  3956.  
  3957.     #
  3958.     # Bundle Windows Instances
  3959.     #
  3960.  
  3961.     def bundle_instance(self, instance_id,
  3962.                         s3_bucket,
  3963.                         s3_prefix,
  3964.                         s3_upload_policy, dry_run=False):
  3965.         """
  3966.        Bundle Windows instance.
  3967.  
  3968.        :type instance_id: string
  3969.        :param instance_id: The instance id
  3970.  
  3971.        :type s3_bucket: string
  3972.        :param s3_bucket: The bucket in which the AMI should be stored.
  3973.  
  3974.        :type s3_prefix: string
  3975.        :param s3_prefix: The beginning of the file name for the AMI.
  3976.  
  3977.        :type s3_upload_policy: string
  3978.        :param s3_upload_policy: Base64 encoded policy that specifies condition
  3979.                                 and permissions for Amazon EC2 to upload the
  3980.                                 user's image into Amazon S3.
  3981.  
  3982.        :type dry_run: bool
  3983.        :param dry_run: Set to True if the operation should not actually run.
  3984.  
  3985.        """
  3986.  
  3987.         params = {'InstanceId': instance_id,
  3988.                   'Storage.S3.Bucket': s3_bucket,
  3989.                   'Storage.S3.Prefix': s3_prefix,
  3990.                   'Storage.S3.UploadPolicy': s3_upload_policy}
  3991.         s3auth = boto.auth.get_auth_handler(None, boto.config,
  3992.                                             self.provider, ['s3'])
  3993.         params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
  3994.         signature = s3auth.sign_string(s3_upload_policy)
  3995.         params['Storage.S3.UploadPolicySignature'] = signature
  3996.         if dry_run:
  3997.             params['DryRun'] = 'true'
  3998.         return self.get_object('BundleInstance', params,
  3999.                                BundleInstanceTask, verb='POST')
  4000.  
  4001.     def get_all_bundle_tasks(self, bundle_ids=None, filters=None,
  4002.                              dry_run=False):
  4003.         """
  4004.        Retrieve current bundling tasks. If no bundle id is specified, all
  4005.        tasks are retrieved.
  4006.  
  4007.        :type bundle_ids: list
  4008.        :param bundle_ids: A list of strings containing identifiers for
  4009.                           previously created bundling tasks.
  4010.  
  4011.        :type filters: dict
  4012.        :param filters: Optional filters that can be used to limit
  4013.                        the results returned.  Filters are provided
  4014.                        in the form of a dictionary consisting of
  4015.                        filter names as the key and filter values
  4016.                        as the value.  The set of allowable filter
  4017.                        names/values is dependent on the request
  4018.                        being performed.  Check the EC2 API guide
  4019.                        for details.
  4020.  
  4021.        :type dry_run: bool
  4022.        :param dry_run: Set to True if the operation should not actually run.
  4023.  
  4024.        """
  4025.         params = {}
  4026.         if bundle_ids:
  4027.             self.build_list_params(params, bundle_ids, 'BundleId')
  4028.         if filters:
  4029.             self.build_filter_params(params, filters)
  4030.         if dry_run:
  4031.             params['DryRun'] = 'true'
  4032.         return self.get_list('DescribeBundleTasks', params,
  4033.                              [('item', BundleInstanceTask)], verb='POST')
  4034.  
  4035.     def cancel_bundle_task(self, bundle_id, dry_run=False):
  4036.         """
  4037.        Cancel a previously submitted bundle task
  4038.  
  4039.        :type bundle_id: string
  4040.        :param bundle_id: The identifier of the bundle task to cancel.
  4041.  
  4042.        :type dry_run: bool
  4043.        :param dry_run: Set to True if the operation should not actually run.
  4044.  
  4045.        """
  4046.         params = {'BundleId': bundle_id}
  4047.         if dry_run:
  4048.             params['DryRun'] = 'true'
  4049.         return self.get_object('CancelBundleTask', params,
  4050.                                BundleInstanceTask, verb='POST')
  4051.  
  4052.     def get_password_data(self, instance_id, dry_run=False):
  4053.         """
  4054.        Get encrypted administrator password for a Windows instance.
  4055.  
  4056.        :type instance_id: string
  4057.        :param instance_id: The identifier of the instance to retrieve the
  4058.                            password for.
  4059.  
  4060.        :type dry_run: bool
  4061.        :param dry_run: Set to True if the operation should not actually run.
  4062.  
  4063.        """
  4064.         params = {'InstanceId': instance_id}
  4065.         if dry_run:
  4066.             params['DryRun'] = 'true'
  4067.         rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST')
  4068.         return rs.passwordData
  4069.  
  4070.     #
  4071.     # Cluster Placement Groups
  4072.     #
  4073.  
  4074.     def get_all_placement_groups(self, groupnames=None, filters=None,
  4075.                                  dry_run=False):
  4076.         """
  4077.        Get all placement groups associated with your account in a region.
  4078.  
  4079.        :type groupnames: list
  4080.        :param groupnames: A list of the names of placement groups to retrieve.
  4081.                           If not provided, all placement groups will be
  4082.                           returned.
  4083.  
  4084.        :type filters: dict
  4085.        :param filters: Optional filters that can be used to limit
  4086.                        the results returned.  Filters are provided
  4087.                        in the form of a dictionary consisting of
  4088.                        filter names as the key and filter values
  4089.                        as the value.  The set of allowable filter
  4090.                        names/values is dependent on the request
  4091.                        being performed.  Check the EC2 API guide
  4092.                        for details.
  4093.  
  4094.        :type dry_run: bool
  4095.        :param dry_run: Set to True if the operation should not actually run.
  4096.  
  4097.        :rtype: list
  4098.        :return: A list of :class:`boto.ec2.placementgroup.PlacementGroup`
  4099.        """
  4100.         params = {}
  4101.         if groupnames:
  4102.             self.build_list_params(params, groupnames, 'GroupName')
  4103.         if filters:
  4104.             self.build_filter_params(params, filters)
  4105.         if dry_run:
  4106.             params['DryRun'] = 'true'
  4107.         return self.get_list('DescribePlacementGroups', params,
  4108.                              [('item', PlacementGroup)], verb='POST')
  4109.  
  4110.     def create_placement_group(self, name, strategy='cluster', dry_run=False):
  4111.         """
  4112.        Create a new placement group for your account.
  4113.        This will create the placement group within the region you
  4114.        are currently connected to.
  4115.  
  4116.        :type name: string
  4117.        :param name: The name of the new placement group
  4118.  
  4119.        :type strategy: string
  4120.        :param strategy: The placement strategy of the new placement group.
  4121.                         Currently, the only acceptable value is "cluster".
  4122.  
  4123.        :type dry_run: bool
  4124.        :param dry_run: Set to True if the operation should not actually run.
  4125.  
  4126.        :rtype: bool
  4127.        :return: True if successful
  4128.        """
  4129.         params = {'GroupName': name, 'Strategy': strategy}
  4130.         if dry_run:
  4131.             params['DryRun'] = 'true'
  4132.         group = self.get_status('CreatePlacementGroup', params, verb='POST')
  4133.         return group
  4134.  
  4135.     def delete_placement_group(self, name, dry_run=False):
  4136.         """
  4137.        Delete a placement group from your account.
  4138.  
  4139.        :type key_name: string
  4140.        :param key_name: The name of the keypair to delete
  4141.  
  4142.        :type dry_run: bool
  4143.        :param dry_run: Set to True if the operation should not actually run.
  4144.  
  4145.        """
  4146.         params = {'GroupName': name}
  4147.         if dry_run:
  4148.             params['DryRun'] = 'true'
  4149.         return self.get_status('DeletePlacementGroup', params, verb='POST')
  4150.  
  4151.     # Tag methods
  4152.  
  4153.     def build_tag_param_list(self, params, tags):
  4154.         keys = sorted(tags.keys())
  4155.         i = 1
  4156.         for key in keys:
  4157.             value = tags[key]
  4158.             params['Tag.%d.Key' % i] = key
  4159.             if value is not None:
  4160.                 params['Tag.%d.Value' % i] = value
  4161.             i += 1
  4162.  
  4163.     def get_all_tags(self, filters=None, dry_run=False, max_results=None):
  4164.         """
  4165.        Retrieve all the metadata tags associated with your account.
  4166.  
  4167.        :type filters: dict
  4168.        :param filters: Optional filters that can be used to limit
  4169.                        the results returned.  Filters are provided
  4170.                        in the form of a dictionary consisting of
  4171.                        filter names as the key and filter values
  4172.                        as the value.  The set of allowable filter
  4173.                        names/values is dependent on the request
  4174.                        being performed.  Check the EC2 API guide
  4175.                        for details.
  4176.  
  4177.        :type dry_run: bool
  4178.        :param dry_run: Set to True if the operation should not actually run.
  4179.  
  4180.        :type max_results: int
  4181.        :param max_results: The maximum number of paginated instance
  4182.            items per response.
  4183.  
  4184.        :rtype: list
  4185.        :return: A list of :class:`boto.ec2.tag.Tag` objects
  4186.        """
  4187.         params = {}
  4188.         if filters:
  4189.             self.build_filter_params(params, filters)
  4190.         if dry_run:
  4191.             params['DryRun'] = 'true'
  4192.         if max_results is not None:
  4193.             params['MaxResults'] = max_results
  4194.         return self.get_list('DescribeTags', params,
  4195.                              [('item', Tag)], verb='POST')
  4196.  
  4197.     def create_tags(self, resource_ids, tags, dry_run=False):
  4198.         """
  4199.        Create new metadata tags for the specified resource ids.
  4200.  
  4201.        :type resource_ids: list
  4202.        :param resource_ids: List of strings
  4203.  
  4204.        :type tags: dict
  4205.        :param tags: A dictionary containing the name/value pairs.
  4206.                     If you want to create only a tag name, the
  4207.                     value for that tag should be the empty string
  4208.                     (e.g. '').
  4209.  
  4210.        :type dry_run: bool
  4211.        :param dry_run: Set to True if the operation should not actually run.
  4212.  
  4213.        """
  4214.         params = {}
  4215.         self.build_list_params(params, resource_ids, 'ResourceId')
  4216.         self.build_tag_param_list(params, tags)
  4217.         if dry_run:
  4218.             params['DryRun'] = 'true'
  4219.         return self.get_status('CreateTags', params, verb='POST')
  4220.  
  4221.     def delete_tags(self, resource_ids, tags, dry_run=False):
  4222.         """
  4223.        Delete metadata tags for the specified resource ids.
  4224.  
  4225.        :type resource_ids: list
  4226.        :param resource_ids: List of strings
  4227.  
  4228.        :type tags: dict or list
  4229.        :param tags: Either a dictionary containing name/value pairs
  4230.                     or a list containing just tag names.
  4231.                     If you pass in a dictionary, the values must
  4232.                     match the actual tag values or the tag will
  4233.                     not be deleted.  If you pass in a value of None
  4234.                     for the tag value, all tags with that name will
  4235.                     be deleted.
  4236.  
  4237.        :type dry_run: bool
  4238.        :param dry_run: Set to True if the operation should not actually run.
  4239.  
  4240.        """
  4241.         if isinstance(tags, list):
  4242.             tags = {}.fromkeys(tags, None)
  4243.         params = {}
  4244.         self.build_list_params(params, resource_ids, 'ResourceId')
  4245.         self.build_tag_param_list(params, tags)
  4246.         if dry_run:
  4247.             params['DryRun'] = 'true'
  4248.         return self.get_status('DeleteTags', params, verb='POST')
  4249.  
  4250.     # Network Interface methods
  4251.  
  4252.     def get_all_network_interfaces(self, network_interface_ids=None, filters=None, dry_run=False):
  4253.         """
  4254.        Retrieve all of the Elastic Network Interfaces (ENI's)
  4255.        associated with your account.
  4256.  
  4257.        :type network_interface_ids: list
  4258.        :param network_interface_ids: a list of strings representing ENI IDs
  4259.  
  4260.        :type filters: dict
  4261.        :param filters: Optional filters that can be used to limit
  4262.                        the results returned.  Filters are provided
  4263.                        in the form of a dictionary consisting of
  4264.                        filter names as the key and filter values
  4265.                        as the value.  The set of allowable filter
  4266.                        names/values is dependent on the request
  4267.                        being performed.  Check the EC2 API guide
  4268.                        for details.
  4269.  
  4270.        :type dry_run: bool
  4271.        :param dry_run: Set to True if the operation should not actually run.
  4272.  
  4273.        :rtype: list
  4274.        :return: A list of :class:`boto.ec2.networkinterface.NetworkInterface`
  4275.        """
  4276.         params = {}
  4277.         if network_interface_ids:
  4278.             self.build_list_params(params, network_interface_ids, 'NetworkInterfaceId')
  4279.         if filters:
  4280.             self.build_filter_params(params, filters)
  4281.         if dry_run:
  4282.             params['DryRun'] = 'true'
  4283.         return self.get_list('DescribeNetworkInterfaces', params,
  4284.                              [('item', NetworkInterface)], verb='POST')
  4285.  
  4286.     def create_network_interface(self, subnet_id, private_ip_address=None,
  4287.                                  description=None, groups=None, dry_run=False):
  4288.         """
  4289.        Creates a network interface in the specified subnet.
  4290.  
  4291.        :type subnet_id: str
  4292.        :param subnet_id: The ID of the subnet to associate with the
  4293.            network interface.
  4294.  
  4295.        :type private_ip_address: str
  4296.        :param private_ip_address: The private IP address of the
  4297.            network interface.  If not supplied, one will be chosen
  4298.            for you.
  4299.  
  4300.        :type description: str
  4301.        :param description: The description of the network interface.
  4302.  
  4303.        :type groups: list
  4304.        :param groups: Lists the groups for use by the network interface.
  4305.            This can be either a list of group ID's or a list of
  4306.            :class:`boto.ec2.securitygroup.SecurityGroup` objects.
  4307.  
  4308.        :type dry_run: bool
  4309.        :param dry_run: Set to True if the operation should not actually run.
  4310.  
  4311.        :rtype: :class:`boto.ec2.networkinterface.NetworkInterface`
  4312.        :return: The newly created network interface.
  4313.        """
  4314.         params = {'SubnetId': subnet_id}
  4315.         if private_ip_address:
  4316.             params['PrivateIpAddress'] = private_ip_address
  4317.         if description:
  4318.             params['Description'] = description
  4319.         if groups:
  4320.             ids = []
  4321.             for group in groups:
  4322.                 if isinstance(group, SecurityGroup):
  4323.                     ids.append(group.id)
  4324.                 else:
  4325.                     ids.append(group)
  4326.             self.build_list_params(params, ids, 'SecurityGroupId')
  4327.         if dry_run:
  4328.             params['DryRun'] = 'true'
  4329.         return self.get_object('CreateNetworkInterface', params,
  4330.                                NetworkInterface, verb='POST')
  4331.  
  4332.     def attach_network_interface(self, network_interface_id,
  4333.                                  instance_id, device_index, dry_run=False):
  4334.         """
  4335.        Attaches a network interface to an instance.
  4336.  
  4337.        :type network_interface_id: str
  4338.        :param network_interface_id: The ID of the network interface to attach.
  4339.  
  4340.        :type instance_id: str
  4341.        :param instance_id: The ID of the instance that will be attached
  4342.            to the network interface.
  4343.  
  4344.        :type device_index: int
  4345.        :param device_index: The index of the device for the network
  4346.            interface attachment on the instance.
  4347.  
  4348.        :type dry_run: bool
  4349.        :param dry_run: Set to True if the operation should not actually run.
  4350.  
  4351.        """
  4352.         params = {'NetworkInterfaceId': network_interface_id,
  4353.                   'InstanceId': instance_id,
  4354.                   'DeviceIndex': device_index}
  4355.         if dry_run:
  4356.             params['DryRun'] = 'true'
  4357.         return self.get_status('AttachNetworkInterface', params, verb='POST')
  4358.  
  4359.     def detach_network_interface(self, attachment_id, force=False,
  4360.                                  dry_run=False):
  4361.         """
  4362.        Detaches a network interface from an instance.
  4363.  
  4364.        :type attachment_id: str
  4365.        :param attachment_id: The ID of the attachment.
  4366.  
  4367.        :type force: bool
  4368.        :param force: Set to true to force a detachment.
  4369.  
  4370.        :type dry_run: bool
  4371.        :param dry_run: Set to True if the operation should not actually run.
  4372.  
  4373.        """
  4374.         params = {'AttachmentId': attachment_id}
  4375.         if force:
  4376.             params['Force'] = 'true'
  4377.         if dry_run:
  4378.             params['DryRun'] = 'true'
  4379.         return self.get_status('DetachNetworkInterface', params, verb='POST')
  4380.  
  4381.     def delete_network_interface(self, network_interface_id, dry_run=False):
  4382.         """
  4383.        Delete the specified network interface.
  4384.  
  4385.        :type network_interface_id: str
  4386.        :param network_interface_id: The ID of the network interface to delete.
  4387.  
  4388.        :type dry_run: bool
  4389.        :param dry_run: Set to True if the operation should not actually run.
  4390.  
  4391.        """
  4392.         params = {'NetworkInterfaceId': network_interface_id}
  4393.         if dry_run:
  4394.             params['DryRun'] = 'true'
  4395.         return self.get_status('DeleteNetworkInterface', params, verb='POST')
  4396.  
  4397.     def get_all_instance_types(self):
  4398.         """
  4399.        Get all instance_types available on this cloud (eucalyptus specific)
  4400.  
  4401.        :rtype: list of :class:`boto.ec2.instancetype.InstanceType`
  4402.        :return: The requested InstanceType objects
  4403.        """
  4404.         params = {}
  4405.         return self.get_list('DescribeInstanceTypes', params, [('item', InstanceType)], verb='POST')
  4406.  
  4407.     def copy_image(self, source_region, source_image_id, name=None,
  4408.                    description=None, client_token=None, dry_run=False,
  4409.                    encrypted=None, kms_key_id=None):
  4410.         """
  4411.        :type dry_run: bool
  4412.        :param dry_run: Set to True if the operation should not actually run.
  4413.        :rtype: :class:`boto.ec2.image.CopyImage`
  4414.        :return: Object containing the image_id of the copied image.
  4415.        """
  4416.         params = {
  4417.             'SourceRegion': source_region,
  4418.             'SourceImageId': source_image_id,
  4419.         }
  4420.         if name is not None:
  4421.             params['Name'] = name
  4422.         if description is not None:
  4423.             params['Description'] = description
  4424.         if client_token is not None:
  4425.             params['ClientToken'] = client_token
  4426.         if encrypted is not None:
  4427.             params['Encrypted'] = 'true' if encrypted else 'false'
  4428.         if kms_key_id is not None:
  4429.             params['KmsKeyId'] = kms_key_id
  4430.         if dry_run:
  4431.             params['DryRun'] = 'true'
  4432.         return self.get_object('CopyImage', params, CopyImage,
  4433.                                verb='POST')
  4434.  
  4435.     def describe_account_attributes(self, attribute_names=None, dry_run=False):
  4436.         """
  4437.        :type dry_run: bool
  4438.        :param dry_run: Set to True if the operation should not actually run.
  4439.  
  4440.        """
  4441.         params = {}
  4442.         if attribute_names is not None:
  4443.             self.build_list_params(params, attribute_names, 'AttributeName')
  4444.         if dry_run:
  4445.             params['DryRun'] = 'true'
  4446.         return self.get_list('DescribeAccountAttributes', params,
  4447.                              [('item', AccountAttribute)], verb='POST')
  4448.  
  4449.     def describe_vpc_attribute(self, vpc_id, attribute=None, dry_run=False):
  4450.         """
  4451.        :type dry_run: bool
  4452.        :param dry_run: Set to True if the operation should not actually run.
  4453.  
  4454.        """
  4455.         params = {
  4456.             'VpcId': vpc_id
  4457.         }
  4458.         if attribute is not None:
  4459.             params['Attribute'] = attribute
  4460.         if dry_run:
  4461.             params['DryRun'] = 'true'
  4462.         return self.get_object('DescribeVpcAttribute', params,
  4463.                                VPCAttribute, verb='POST')
  4464.  
  4465.     def modify_vpc_attribute(self, vpc_id, enable_dns_support=None,
  4466.                              enable_dns_hostnames=None, dry_run=False):
  4467.         """
  4468.        :type dry_run: bool
  4469.        :param dry_run: Set to True if the operation should not actually run.
  4470.  
  4471.        """
  4472.         params = {
  4473.             'VpcId': vpc_id
  4474.         }
  4475.         if enable_dns_support is not None:
  4476.             params['EnableDnsSupport.Value'] = (
  4477.                 'true' if enable_dns_support else 'false')
  4478.         if enable_dns_hostnames is not None:
  4479.             params['EnableDnsHostnames.Value'] = (
  4480.                 'true' if enable_dns_hostnames else 'false')
  4481.         if dry_run:
  4482.             params['DryRun'] = 'true'
  4483.         return self.get_status('ModifyVpcAttribute', params, verb='POST')
  4484.  
  4485.     def get_all_classic_link_instances(self, instance_ids=None, filters=None,
  4486.                                        dry_run=False, max_results=None,
  4487.                                        next_token=None):
  4488.         """
  4489.        Get all of your linked EC2-Classic instances. This request only
  4490.        returns information about EC2-Classic instances linked  to
  4491.        a VPC through ClassicLink
  4492.  
  4493.        :type instance_ids: list
  4494.        :param instance_ids: A list of strings of instance IDs. Must be
  4495.            instances linked to a VPC through ClassicLink.
  4496.  
  4497.        :type filters: dict
  4498.        :param filters: Optional filters that can be used to limit the
  4499.            results returned.  Filters are provided in the form of a
  4500.            dictionary consisting of filter names as the key and
  4501.            filter values as the value.  The set of allowable filter
  4502.            names/values is dependent on the request being performed.
  4503.            Check the EC2 API guide for details.
  4504.  
  4505.        :type dry_run: bool
  4506.        :param dry_run: Set to True if the operation should not actually run.
  4507.  
  4508.        :type max_results: int
  4509.        :param max_results: The maximum number of paginated instance
  4510.            items per response.
  4511.  
  4512.        :rtype: list
  4513.        :return: A list of  :class:`boto.ec2.instance.Instance`
  4514.        """
  4515.         params = {}
  4516.         if instance_ids:
  4517.             self.build_list_params(params, instance_ids, 'InstanceId')
  4518.         if filters:
  4519.             self.build_filter_params(params, filters)
  4520.         if dry_run:
  4521.             params['DryRun'] = 'true'
  4522.         if max_results is not None:
  4523.             params['MaxResults'] = max_results
  4524.         if next_token:
  4525.             params['NextToken'] = next_token
  4526.         return self.get_list('DescribeClassicLinkInstances', params,
  4527.                              [('item', Instance)], verb='POST')
Add Comment
Please, Sign In to add comment