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