OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. |
| 3 # Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved |
| 4 # |
| 5 # Permission is hereby granted, free of charge, to any person obtaining a |
| 6 # copy of this software and associated documentation files (the |
| 7 # "Software"), to deal in the Software without restriction, including |
| 8 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 9 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 10 # persons to whom the Software is furnished to do so, subject to the fol- |
| 11 # lowing conditions: |
| 12 # |
| 13 # The above copyright notice and this permission notice shall be included |
| 14 # in all copies or substantial portions of the Software. |
| 15 # |
| 16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 22 # IN THE SOFTWARE. |
| 23 |
| 24 """ |
| 25 Represents a connection to the EC2 service. |
| 26 """ |
| 27 |
| 28 import base64 |
| 29 import warnings |
| 30 from datetime import datetime |
| 31 from datetime import timedelta |
| 32 |
| 33 import boto |
| 34 from boto.connection import AWSQueryConnection |
| 35 from boto.resultset import ResultSet |
| 36 from boto.ec2.image import Image, ImageAttribute |
| 37 from boto.ec2.instance import Reservation, Instance |
| 38 from boto.ec2.instance import ConsoleOutput, InstanceAttribute |
| 39 from boto.ec2.keypair import KeyPair |
| 40 from boto.ec2.address import Address |
| 41 from boto.ec2.volume import Volume, VolumeAttribute |
| 42 from boto.ec2.snapshot import Snapshot |
| 43 from boto.ec2.snapshot import SnapshotAttribute |
| 44 from boto.ec2.zone import Zone |
| 45 from boto.ec2.securitygroup import SecurityGroup |
| 46 from boto.ec2.regioninfo import RegionInfo |
| 47 from boto.ec2.instanceinfo import InstanceInfo |
| 48 from boto.ec2.reservedinstance import ReservedInstancesOffering |
| 49 from boto.ec2.reservedinstance import ReservedInstance |
| 50 from boto.ec2.reservedinstance import ReservedInstanceListing |
| 51 from boto.ec2.spotinstancerequest import SpotInstanceRequest |
| 52 from boto.ec2.spotpricehistory import SpotPriceHistory |
| 53 from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription |
| 54 from boto.ec2.bundleinstance import BundleInstanceTask |
| 55 from boto.ec2.placementgroup import PlacementGroup |
| 56 from boto.ec2.tag import Tag |
| 57 from boto.ec2.vmtype import VmType |
| 58 from boto.ec2.instancestatus import InstanceStatusSet |
| 59 from boto.ec2.volumestatus import VolumeStatusSet |
| 60 from boto.ec2.networkinterface import NetworkInterface |
| 61 from boto.exception import EC2ResponseError |
| 62 |
| 63 #boto.set_stream_logger('ec2') |
| 64 |
| 65 |
| 66 class EC2Connection(AWSQueryConnection): |
| 67 |
| 68 APIVersion = boto.config.get('Boto', 'ec2_version', '2012-12-01') |
| 69 DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1') |
| 70 DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint', |
| 71 'ec2.us-east-1.amazonaws.com') |
| 72 ResponseError = EC2ResponseError |
| 73 |
| 74 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, |
| 75 is_secure=True, host=None, port=None, |
| 76 proxy=None, proxy_port=None, |
| 77 proxy_user=None, proxy_pass=None, debug=0, |
| 78 https_connection_factory=None, region=None, path='/', |
| 79 api_version=None, security_token=None, |
| 80 validate_certs=True): |
| 81 """ |
| 82 Init method to create a new connection to EC2. |
| 83 """ |
| 84 if not region: |
| 85 region = RegionInfo(self, self.DefaultRegionName, |
| 86 self.DefaultRegionEndpoint) |
| 87 self.region = region |
| 88 AWSQueryConnection.__init__(self, aws_access_key_id, |
| 89 aws_secret_access_key, |
| 90 is_secure, port, proxy, proxy_port, |
| 91 proxy_user, proxy_pass, |
| 92 self.region.endpoint, debug, |
| 93 https_connection_factory, path, |
| 94 security_token, |
| 95 validate_certs=validate_certs) |
| 96 if api_version: |
| 97 self.APIVersion = api_version |
| 98 |
| 99 def _required_auth_capability(self): |
| 100 return ['ec2'] |
| 101 |
| 102 def get_params(self): |
| 103 """ |
| 104 Returns a dictionary containing the value of of all of the keyword |
| 105 arguments passed when constructing this connection. |
| 106 """ |
| 107 param_names = ['aws_access_key_id', 'aws_secret_access_key', |
| 108 'is_secure', 'port', 'proxy', 'proxy_port', |
| 109 'proxy_user', 'proxy_pass', |
| 110 'debug', 'https_connection_factory'] |
| 111 params = {} |
| 112 for name in param_names: |
| 113 params[name] = getattr(self, name) |
| 114 return params |
| 115 |
| 116 def build_filter_params(self, params, filters): |
| 117 i = 1 |
| 118 for name in filters: |
| 119 aws_name = name |
| 120 if not aws_name.startswith('tag:'): |
| 121 aws_name = name.replace('_', '-') |
| 122 params['Filter.%d.Name' % i] = aws_name |
| 123 value = filters[name] |
| 124 if not isinstance(value, list): |
| 125 value = [value] |
| 126 j = 1 |
| 127 for v in value: |
| 128 params['Filter.%d.Value.%d' % (i, j)] = v |
| 129 j += 1 |
| 130 i += 1 |
| 131 |
| 132 # Image methods |
| 133 |
| 134 def get_all_images(self, image_ids=None, owners=None, |
| 135 executable_by=None, filters=None): |
| 136 """ |
| 137 Retrieve all the EC2 images available on your account. |
| 138 |
| 139 :type image_ids: list |
| 140 :param image_ids: A list of strings with the image IDs wanted |
| 141 |
| 142 :type owners: list |
| 143 :param owners: A list of owner IDs |
| 144 |
| 145 :type executable_by: list |
| 146 :param executable_by: Returns AMIs for which the specified |
| 147 user ID has explicit launch permissions |
| 148 |
| 149 :type filters: dict |
| 150 :param filters: Optional filters that can be used to limit |
| 151 the results returned. Filters are provided |
| 152 in the form of a dictionary consisting of |
| 153 filter names as the key and filter values |
| 154 as the value. The set of allowable filter |
| 155 names/values is dependent on the request |
| 156 being performed. Check the EC2 API guide |
| 157 for details. |
| 158 |
| 159 :rtype: list |
| 160 :return: A list of :class:`boto.ec2.image.Image` |
| 161 """ |
| 162 params = {} |
| 163 if image_ids: |
| 164 self.build_list_params(params, image_ids, 'ImageId') |
| 165 if owners: |
| 166 self.build_list_params(params, owners, 'Owner') |
| 167 if executable_by: |
| 168 self.build_list_params(params, executable_by, 'ExecutableBy') |
| 169 if filters: |
| 170 self.build_filter_params(params, filters) |
| 171 return self.get_list('DescribeImages', params, |
| 172 [('item', Image)], verb='POST') |
| 173 |
| 174 def get_all_kernels(self, kernel_ids=None, owners=None): |
| 175 """ |
| 176 Retrieve all the EC2 kernels available on your account. |
| 177 Constructs a filter to allow the processing to happen server side. |
| 178 |
| 179 :type kernel_ids: list |
| 180 :param kernel_ids: A list of strings with the image IDs wanted |
| 181 |
| 182 :type owners: list |
| 183 :param owners: A list of owner IDs |
| 184 |
| 185 :rtype: list |
| 186 :return: A list of :class:`boto.ec2.image.Image` |
| 187 """ |
| 188 params = {} |
| 189 if kernel_ids: |
| 190 self.build_list_params(params, kernel_ids, 'ImageId') |
| 191 if owners: |
| 192 self.build_list_params(params, owners, 'Owner') |
| 193 filter = {'image-type': 'kernel'} |
| 194 self.build_filter_params(params, filter) |
| 195 return self.get_list('DescribeImages', params, |
| 196 [('item', Image)], verb='POST') |
| 197 |
| 198 def get_all_ramdisks(self, ramdisk_ids=None, owners=None): |
| 199 """ |
| 200 Retrieve all the EC2 ramdisks available on your account. |
| 201 Constructs a filter to allow the processing to happen server side. |
| 202 |
| 203 :type ramdisk_ids: list |
| 204 :param ramdisk_ids: A list of strings with the image IDs wanted |
| 205 |
| 206 :type owners: list |
| 207 :param owners: A list of owner IDs |
| 208 |
| 209 :rtype: list |
| 210 :return: A list of :class:`boto.ec2.image.Image` |
| 211 """ |
| 212 params = {} |
| 213 if ramdisk_ids: |
| 214 self.build_list_params(params, ramdisk_ids, 'ImageId') |
| 215 if owners: |
| 216 self.build_list_params(params, owners, 'Owner') |
| 217 filter = {'image-type': 'ramdisk'} |
| 218 self.build_filter_params(params, filter) |
| 219 return self.get_list('DescribeImages', params, |
| 220 [('item', Image)], verb='POST') |
| 221 |
| 222 def get_image(self, image_id): |
| 223 """ |
| 224 Shortcut method to retrieve a specific image (AMI). |
| 225 |
| 226 :type image_id: string |
| 227 :param image_id: the ID of the Image to retrieve |
| 228 |
| 229 :rtype: :class:`boto.ec2.image.Image` |
| 230 :return: The EC2 Image specified or None if the image is not found |
| 231 """ |
| 232 try: |
| 233 return self.get_all_images(image_ids=[image_id])[0] |
| 234 except IndexError: # None of those images available |
| 235 return None |
| 236 |
| 237 def register_image(self, name=None, description=None, image_location=None, |
| 238 architecture=None, kernel_id=None, ramdisk_id=None, |
| 239 root_device_name=None, block_device_map=None): |
| 240 """ |
| 241 Register an image. |
| 242 |
| 243 :type name: string |
| 244 :param name: The name of the AMI. Valid only for EBS-based images. |
| 245 |
| 246 :type description: string |
| 247 :param description: The description of the AMI. |
| 248 |
| 249 :type image_location: string |
| 250 :param image_location: Full path to your AMI manifest in |
| 251 Amazon S3 storage. Only used for S3-based AMI's. |
| 252 |
| 253 :type architecture: string |
| 254 :param architecture: The architecture of the AMI. Valid choices are: |
| 255 * i386 |
| 256 * x86_64 |
| 257 |
| 258 :type kernel_id: string |
| 259 :param kernel_id: The ID of the kernel with which to launch |
| 260 the instances |
| 261 |
| 262 :type root_device_name: string |
| 263 :param root_device_name: The root device name (e.g. /dev/sdh) |
| 264 |
| 265 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM
apping` |
| 266 :param block_device_map: A BlockDeviceMapping data structure |
| 267 describing the EBS volumes associated with the Image. |
| 268 |
| 269 :rtype: string |
| 270 :return: The new image id |
| 271 """ |
| 272 params = {} |
| 273 if name: |
| 274 params['Name'] = name |
| 275 if description: |
| 276 params['Description'] = description |
| 277 if architecture: |
| 278 params['Architecture'] = architecture |
| 279 if kernel_id: |
| 280 params['KernelId'] = kernel_id |
| 281 if ramdisk_id: |
| 282 params['RamdiskId'] = ramdisk_id |
| 283 if image_location: |
| 284 params['ImageLocation'] = image_location |
| 285 if root_device_name: |
| 286 params['RootDeviceName'] = root_device_name |
| 287 if block_device_map: |
| 288 block_device_map.build_list_params(params) |
| 289 rs = self.get_object('RegisterImage', params, ResultSet, verb='POST') |
| 290 image_id = getattr(rs, 'imageId', None) |
| 291 return image_id |
| 292 |
| 293 def deregister_image(self, image_id, delete_snapshot=False): |
| 294 """ |
| 295 Unregister an AMI. |
| 296 |
| 297 :type image_id: string |
| 298 :param image_id: the ID of the Image to unregister |
| 299 |
| 300 :type delete_snapshot: bool |
| 301 :param delete_snapshot: Set to True if we should delete the |
| 302 snapshot associated with an EBS volume |
| 303 mounted at /dev/sda1 |
| 304 |
| 305 :rtype: bool |
| 306 :return: True if successful |
| 307 """ |
| 308 snapshot_id = None |
| 309 if delete_snapshot: |
| 310 image = self.get_image(image_id) |
| 311 for key in image.block_device_mapping: |
| 312 if key == "/dev/sda1": |
| 313 snapshot_id = image.block_device_mapping[key].snapshot_id |
| 314 break |
| 315 |
| 316 result = self.get_status('DeregisterImage', |
| 317 {'ImageId':image_id}, verb='POST') |
| 318 if result and snapshot_id: |
| 319 return result and self.delete_snapshot(snapshot_id) |
| 320 return result |
| 321 |
| 322 def create_image(self, instance_id, name, |
| 323 description=None, no_reboot=False): |
| 324 """ |
| 325 Will create an AMI from the instance in the running or stopped |
| 326 state. |
| 327 |
| 328 :type instance_id: string |
| 329 :param instance_id: the ID of the instance to image. |
| 330 |
| 331 :type name: string |
| 332 :param name: The name of the new image |
| 333 |
| 334 :type description: string |
| 335 :param description: An optional human-readable string describing |
| 336 the contents and purpose of the AMI. |
| 337 |
| 338 :type no_reboot: bool |
| 339 :param no_reboot: An optional flag indicating that the bundling process |
| 340 should not attempt to shutdown the instance before |
| 341 bundling. If this flag is True, the responsibility |
| 342 of maintaining file system integrity is left to the |
| 343 owner of the instance. |
| 344 |
| 345 :rtype: string |
| 346 :return: The new image id |
| 347 """ |
| 348 params = {'InstanceId': instance_id, |
| 349 'Name': name} |
| 350 if description: |
| 351 params['Description'] = description |
| 352 if no_reboot: |
| 353 params['NoReboot'] = 'true' |
| 354 img = self.get_object('CreateImage', params, Image, verb='POST') |
| 355 return img.id |
| 356 |
| 357 # ImageAttribute methods |
| 358 |
| 359 def get_image_attribute(self, image_id, attribute='launchPermission'): |
| 360 """ |
| 361 Gets an attribute from an image. |
| 362 |
| 363 :type image_id: string |
| 364 :param image_id: The Amazon image id for which you want info about |
| 365 |
| 366 :type attribute: string |
| 367 :param attribute: The attribute you need information about. |
| 368 Valid choices are: |
| 369 * launchPermission |
| 370 * productCodes |
| 371 * blockDeviceMapping |
| 372 |
| 373 :rtype: :class:`boto.ec2.image.ImageAttribute` |
| 374 :return: An ImageAttribute object representing the value of the |
| 375 attribute requested |
| 376 """ |
| 377 params = {'ImageId': image_id, |
| 378 'Attribute': attribute} |
| 379 return self.get_object('DescribeImageAttribute', params, |
| 380 ImageAttribute, verb='POST') |
| 381 |
| 382 def modify_image_attribute(self, image_id, attribute='launchPermission', |
| 383 operation='add', user_ids=None, groups=None, |
| 384 product_codes=None): |
| 385 """ |
| 386 Changes an attribute of an image. |
| 387 |
| 388 :type image_id: string |
| 389 :param image_id: The image id you wish to change |
| 390 |
| 391 :type attribute: string |
| 392 :param attribute: The attribute you wish to change |
| 393 |
| 394 :type operation: string |
| 395 :param operation: Either add or remove (this is required for changing |
| 396 launchPermissions) |
| 397 |
| 398 :type user_ids: list |
| 399 :param user_ids: The Amazon IDs of users to add/remove attributes |
| 400 |
| 401 :type groups: list |
| 402 :param groups: The groups to add/remove attributes |
| 403 |
| 404 :type product_codes: list |
| 405 :param product_codes: Amazon DevPay product code. Currently only one |
| 406 product code can be associated with an AMI. Once |
| 407 set, the product code cannot be changed or reset. |
| 408 """ |
| 409 params = {'ImageId': image_id, |
| 410 'Attribute': attribute, |
| 411 'OperationType': operation} |
| 412 if user_ids: |
| 413 self.build_list_params(params, user_ids, 'UserId') |
| 414 if groups: |
| 415 self.build_list_params(params, groups, 'UserGroup') |
| 416 if product_codes: |
| 417 self.build_list_params(params, product_codes, 'ProductCode') |
| 418 return self.get_status('ModifyImageAttribute', params, verb='POST') |
| 419 |
| 420 def reset_image_attribute(self, image_id, attribute='launchPermission'): |
| 421 """ |
| 422 Resets an attribute of an AMI to its default value. |
| 423 |
| 424 :type image_id: string |
| 425 :param image_id: ID of the AMI for which an attribute will be described |
| 426 |
| 427 :type attribute: string |
| 428 :param attribute: The attribute to reset |
| 429 |
| 430 :rtype: bool |
| 431 :return: Whether the operation succeeded or not |
| 432 """ |
| 433 params = {'ImageId': image_id, |
| 434 'Attribute': attribute} |
| 435 return self.get_status('ResetImageAttribute', params, verb='POST') |
| 436 |
| 437 # Instance methods |
| 438 |
| 439 def get_all_instances(self, instance_ids=None, filters=None): |
| 440 """ |
| 441 Retrieve all the instances associated with your account. |
| 442 |
| 443 :type instance_ids: list |
| 444 :param instance_ids: A list of strings of instance IDs |
| 445 |
| 446 :type filters: dict |
| 447 :param filters: Optional filters that can be used to limit the |
| 448 results returned. Filters are provided in the form of a |
| 449 dictionary consisting of filter names as the key and |
| 450 filter values as the value. The set of allowable filter |
| 451 names/values is dependent on the request being performed. |
| 452 Check the EC2 API guide for details. |
| 453 |
| 454 :rtype: list |
| 455 :return: A list of :class:`boto.ec2.instance.Reservation` |
| 456 """ |
| 457 params = {} |
| 458 if instance_ids: |
| 459 self.build_list_params(params, instance_ids, 'InstanceId') |
| 460 if filters: |
| 461 if 'group-id' in filters: |
| 462 gid = filters.get('group-id') |
| 463 if not gid.startswith('sg-') or len(gid) != 11: |
| 464 warnings.warn( |
| 465 "The group-id filter now requires a security group " |
| 466 "identifier (sg-*) instead of a group name. To filter " |
| 467 "by group name use the 'group-name' filter instead.", |
| 468 UserWarning) |
| 469 self.build_filter_params(params, filters) |
| 470 return self.get_list('DescribeInstances', params, |
| 471 [('item', Reservation)], verb='POST') |
| 472 |
| 473 def get_all_instance_status(self, instance_ids=None, |
| 474 max_results=None, next_token=None, |
| 475 filters=None): |
| 476 """ |
| 477 Retrieve all the instances in your account scheduled for maintenance. |
| 478 |
| 479 :type instance_ids: list |
| 480 :param instance_ids: A list of strings of instance IDs |
| 481 |
| 482 :type max_results: int |
| 483 :param max_results: The maximum number of paginated instance |
| 484 items per response. |
| 485 |
| 486 :type next_token: str |
| 487 :param next_token: A string specifying the next paginated set |
| 488 of results to return. |
| 489 |
| 490 :type filters: dict |
| 491 :param filters: Optional filters that can be used to limit |
| 492 the results returned. Filters are provided |
| 493 in the form of a dictionary consisting of |
| 494 filter names as the key and filter values |
| 495 as the value. The set of allowable filter |
| 496 names/values is dependent on the request |
| 497 being performed. Check the EC2 API guide |
| 498 for details. |
| 499 |
| 500 :rtype: list |
| 501 :return: A list of instances that have maintenance scheduled. |
| 502 """ |
| 503 params = {} |
| 504 if instance_ids: |
| 505 self.build_list_params(params, instance_ids, 'InstanceId') |
| 506 if max_results: |
| 507 params['MaxResults'] = max_results |
| 508 if next_token: |
| 509 params['NextToken'] = next_token |
| 510 if filters: |
| 511 self.build_filter_params(params, filters) |
| 512 return self.get_object('DescribeInstanceStatus', params, |
| 513 InstanceStatusSet, verb='POST') |
| 514 |
| 515 def run_instances(self, image_id, min_count=1, max_count=1, |
| 516 key_name=None, security_groups=None, |
| 517 user_data=None, addressing_type=None, |
| 518 instance_type='m1.small', placement=None, |
| 519 kernel_id=None, ramdisk_id=None, |
| 520 monitoring_enabled=False, subnet_id=None, |
| 521 block_device_map=None, |
| 522 disable_api_termination=False, |
| 523 instance_initiated_shutdown_behavior=None, |
| 524 private_ip_address=None, |
| 525 placement_group=None, client_token=None, |
| 526 security_group_ids=None, |
| 527 additional_info=None, instance_profile_name=None, |
| 528 instance_profile_arn=None, tenancy=None, |
| 529 ebs_optimized=False, network_interfaces=None): |
| 530 """ |
| 531 Runs an image on EC2. |
| 532 |
| 533 :type image_id: string |
| 534 :param image_id: The ID of the image to run. |
| 535 |
| 536 :type min_count: int |
| 537 :param min_count: The minimum number of instances to launch. |
| 538 |
| 539 :type max_count: int |
| 540 :param max_count: The maximum number of instances to launch. |
| 541 |
| 542 :type key_name: string |
| 543 :param key_name: The name of the key pair with which to |
| 544 launch instances. |
| 545 |
| 546 :type security_groups: list of strings |
| 547 :param security_groups: The names of the security groups with which to |
| 548 associate instances |
| 549 |
| 550 :type user_data: string |
| 551 :param user_data: The user data passed to the launched instances |
| 552 |
| 553 :type instance_type: string |
| 554 :param instance_type: The type of instance to run: |
| 555 |
| 556 * t1.micro |
| 557 * m1.small |
| 558 * m1.medium |
| 559 * m1.large |
| 560 * m1.xlarge |
| 561 * c1.medium |
| 562 * c1.xlarge |
| 563 * m2.xlarge |
| 564 * m2.2xlarge |
| 565 * m2.4xlarge |
| 566 * cc1.4xlarge |
| 567 * cg1.4xlarge |
| 568 * cc2.8xlarge |
| 569 |
| 570 :type placement: string |
| 571 :param placement: The availability zone in which to launch |
| 572 the instances. |
| 573 |
| 574 :type kernel_id: string |
| 575 :param kernel_id: The ID of the kernel with which to launch the |
| 576 instances. |
| 577 |
| 578 :type ramdisk_id: string |
| 579 :param ramdisk_id: The ID of the RAM disk with which to launch the |
| 580 instances. |
| 581 |
| 582 :type monitoring_enabled: bool |
| 583 :param monitoring_enabled: Enable CloudWatch monitoring on |
| 584 the instance. |
| 585 |
| 586 :type subnet_id: string |
| 587 :param subnet_id: The subnet ID within which to launch the instances |
| 588 for VPC. |
| 589 |
| 590 :type private_ip_address: string |
| 591 :param private_ip_address: If you're using VPC, you can |
| 592 optionally use this parameter to assign the instance a |
| 593 specific available IP address from the subnet (e.g., |
| 594 10.0.0.25). |
| 595 |
| 596 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM
apping` |
| 597 :param block_device_map: A BlockDeviceMapping data structure |
| 598 describing the EBS volumes associated with the Image. |
| 599 |
| 600 :type disable_api_termination: bool |
| 601 :param disable_api_termination: If True, the instances will be locked |
| 602 and will not be able to be terminated via the API. |
| 603 |
| 604 :type instance_initiated_shutdown_behavior: string |
| 605 :param instance_initiated_shutdown_behavior: Specifies whether the |
| 606 instance stops or terminates on instance-initiated shutdown. |
| 607 Valid values are: |
| 608 |
| 609 * stop |
| 610 * terminate |
| 611 |
| 612 :type placement_group: string |
| 613 :param placement_group: If specified, this is the name of the placement |
| 614 group in which the instance(s) will be launched. |
| 615 |
| 616 :type client_token: string |
| 617 :param client_token: Unique, case-sensitive identifier you provide |
| 618 to ensure idempotency of the request. Maximum 64 ASCII characters. |
| 619 |
| 620 :type security_group_ids: list of strings |
| 621 :param security_group_ids: The ID of the VPC security groups with |
| 622 which to associate instances. |
| 623 |
| 624 :type additional_info: string |
| 625 :param additional_info: Specifies additional information to make |
| 626 available to the instance(s). |
| 627 |
| 628 :type tenancy: string |
| 629 :param tenancy: The tenancy of the instance you want to |
| 630 launch. An instance with a tenancy of 'dedicated' runs on |
| 631 single-tenant hardware and can only be launched into a |
| 632 VPC. Valid values are:"default" or "dedicated". |
| 633 NOTE: To use dedicated tenancy you MUST specify a VPC |
| 634 subnet-ID as well. |
| 635 |
| 636 :type instance_profile_arn: string |
| 637 :param instance_profile_arn: The Amazon resource name (ARN) of |
| 638 the IAM Instance Profile (IIP) to associate with the instances. |
| 639 |
| 640 :type instance_profile_name: string |
| 641 :param instance_profile_name: The name of |
| 642 the IAM Instance Profile (IIP) to associate with the instances. |
| 643 |
| 644 :type ebs_optimized: bool |
| 645 :param ebs_optimized: Whether the instance is optimized for |
| 646 EBS I/O. This optimization provides dedicated throughput |
| 647 to Amazon EBS and an optimized configuration stack to |
| 648 provide optimal EBS I/O performance. This optimization |
| 649 isn't available with all instance types. |
| 650 |
| 651 :type network_interfaces: list |
| 652 :param network_interfaces: A list of |
| 653 :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification` |
| 654 |
| 655 :rtype: Reservation |
| 656 :return: The :class:`boto.ec2.instance.Reservation` associated with |
| 657 the request for machines |
| 658 """ |
| 659 params = {'ImageId': image_id, |
| 660 'MinCount': min_count, |
| 661 'MaxCount': max_count} |
| 662 if key_name: |
| 663 params['KeyName'] = key_name |
| 664 if security_group_ids: |
| 665 l = [] |
| 666 for group in security_group_ids: |
| 667 if isinstance(group, SecurityGroup): |
| 668 l.append(group.id) |
| 669 else: |
| 670 l.append(group) |
| 671 self.build_list_params(params, l, 'SecurityGroupId') |
| 672 if security_groups: |
| 673 l = [] |
| 674 for group in security_groups: |
| 675 if isinstance(group, SecurityGroup): |
| 676 l.append(group.name) |
| 677 else: |
| 678 l.append(group) |
| 679 self.build_list_params(params, l, 'SecurityGroup') |
| 680 if user_data: |
| 681 params['UserData'] = base64.b64encode(user_data) |
| 682 if addressing_type: |
| 683 params['AddressingType'] = addressing_type |
| 684 if instance_type: |
| 685 params['InstanceType'] = instance_type |
| 686 if placement: |
| 687 params['Placement.AvailabilityZone'] = placement |
| 688 if placement_group: |
| 689 params['Placement.GroupName'] = placement_group |
| 690 if tenancy: |
| 691 params['Placement.Tenancy'] = tenancy |
| 692 if kernel_id: |
| 693 params['KernelId'] = kernel_id |
| 694 if ramdisk_id: |
| 695 params['RamdiskId'] = ramdisk_id |
| 696 if monitoring_enabled: |
| 697 params['Monitoring.Enabled'] = 'true' |
| 698 if subnet_id: |
| 699 params['SubnetId'] = subnet_id |
| 700 if private_ip_address: |
| 701 params['PrivateIpAddress'] = private_ip_address |
| 702 if block_device_map: |
| 703 block_device_map.build_list_params(params) |
| 704 if disable_api_termination: |
| 705 params['DisableApiTermination'] = 'true' |
| 706 if instance_initiated_shutdown_behavior: |
| 707 val = instance_initiated_shutdown_behavior |
| 708 params['InstanceInitiatedShutdownBehavior'] = val |
| 709 if client_token: |
| 710 params['ClientToken'] = client_token |
| 711 if additional_info: |
| 712 params['AdditionalInfo'] = additional_info |
| 713 if instance_profile_name: |
| 714 params['IamInstanceProfile.Name'] = instance_profile_name |
| 715 if instance_profile_arn: |
| 716 params['IamInstanceProfile.Arn'] = instance_profile_arn |
| 717 if ebs_optimized: |
| 718 params['EbsOptimized'] = 'true' |
| 719 if network_interfaces: |
| 720 network_interfaces.build_list_params(params) |
| 721 return self.get_object('RunInstances', params, Reservation, |
| 722 verb='POST') |
| 723 |
| 724 def terminate_instances(self, instance_ids=None): |
| 725 """ |
| 726 Terminate the instances specified |
| 727 |
| 728 :type instance_ids: list |
| 729 :param instance_ids: A list of strings of the Instance IDs to terminate |
| 730 |
| 731 :rtype: list |
| 732 :return: A list of the instances terminated |
| 733 """ |
| 734 params = {} |
| 735 if instance_ids: |
| 736 self.build_list_params(params, instance_ids, 'InstanceId') |
| 737 return self.get_list('TerminateInstances', params, |
| 738 [('item', Instance)], verb='POST') |
| 739 |
| 740 def stop_instances(self, instance_ids=None, force=False): |
| 741 """ |
| 742 Stop the instances specified |
| 743 |
| 744 :type instance_ids: list |
| 745 :param instance_ids: A list of strings of the Instance IDs to stop |
| 746 |
| 747 :type force: bool |
| 748 :param force: Forces the instance to stop |
| 749 |
| 750 :rtype: list |
| 751 :return: A list of the instances stopped |
| 752 """ |
| 753 params = {} |
| 754 if force: |
| 755 params['Force'] = 'true' |
| 756 if instance_ids: |
| 757 self.build_list_params(params, instance_ids, 'InstanceId') |
| 758 return self.get_list('StopInstances', params, |
| 759 [('item', Instance)], verb='POST') |
| 760 |
| 761 def start_instances(self, instance_ids=None): |
| 762 """ |
| 763 Start the instances specified |
| 764 |
| 765 :type instance_ids: list |
| 766 :param instance_ids: A list of strings of the Instance IDs to start |
| 767 |
| 768 :rtype: list |
| 769 :return: A list of the instances started |
| 770 """ |
| 771 params = {} |
| 772 if instance_ids: |
| 773 self.build_list_params(params, instance_ids, 'InstanceId') |
| 774 return self.get_list('StartInstances', params, |
| 775 [('item', Instance)], verb='POST') |
| 776 |
| 777 def get_console_output(self, instance_id): |
| 778 """ |
| 779 Retrieves the console output for the specified instance. |
| 780 |
| 781 :type instance_id: string |
| 782 :param instance_id: The instance ID of a running instance on the cloud. |
| 783 |
| 784 :rtype: :class:`boto.ec2.instance.ConsoleOutput` |
| 785 :return: The console output as a ConsoleOutput object |
| 786 """ |
| 787 params = {} |
| 788 self.build_list_params(params, [instance_id], 'InstanceId') |
| 789 return self.get_object('GetConsoleOutput', params, |
| 790 ConsoleOutput, verb='POST') |
| 791 |
| 792 def reboot_instances(self, instance_ids=None): |
| 793 """ |
| 794 Reboot the specified instances. |
| 795 |
| 796 :type instance_ids: list |
| 797 :param instance_ids: The instances to terminate and reboot |
| 798 """ |
| 799 params = {} |
| 800 if instance_ids: |
| 801 self.build_list_params(params, instance_ids, 'InstanceId') |
| 802 return self.get_status('RebootInstances', params) |
| 803 |
| 804 def confirm_product_instance(self, product_code, instance_id): |
| 805 params = {'ProductCode': product_code, |
| 806 'InstanceId': instance_id} |
| 807 rs = self.get_object('ConfirmProductInstance', params, |
| 808 ResultSet, verb='POST') |
| 809 return (rs.status, rs.ownerId) |
| 810 |
| 811 # InstanceAttribute methods |
| 812 |
| 813 def get_instance_attribute(self, instance_id, attribute): |
| 814 """ |
| 815 Gets an attribute from an instance. |
| 816 |
| 817 :type instance_id: string |
| 818 :param instance_id: The Amazon id of the instance |
| 819 |
| 820 :type attribute: string |
| 821 :param attribute: The attribute you need information about |
| 822 Valid choices are: |
| 823 |
| 824 * instanceType |
| 825 * kernel |
| 826 * ramdisk |
| 827 * userData |
| 828 * disableApiTermination |
| 829 * instanceInitiatedShutdownBehavior |
| 830 * rootDeviceName |
| 831 * blockDeviceMapping |
| 832 * productCodes |
| 833 * sourceDestCheck |
| 834 * groupSet |
| 835 * ebsOptimized |
| 836 |
| 837 :rtype: :class:`boto.ec2.image.InstanceAttribute` |
| 838 :return: An InstanceAttribute object representing the value of the |
| 839 attribute requested |
| 840 """ |
| 841 params = {'InstanceId': instance_id} |
| 842 if attribute: |
| 843 params['Attribute'] = attribute |
| 844 return self.get_object('DescribeInstanceAttribute', params, |
| 845 InstanceAttribute, verb='POST') |
| 846 |
| 847 def modify_instance_attribute(self, instance_id, attribute, value): |
| 848 """ |
| 849 Changes an attribute of an instance |
| 850 |
| 851 :type instance_id: string |
| 852 :param instance_id: The instance id you wish to change |
| 853 |
| 854 :type attribute: string |
| 855 :param attribute: The attribute you wish to change. |
| 856 |
| 857 * instanceType - A valid instance type (m1.small) |
| 858 * kernel - Kernel ID (None) |
| 859 * ramdisk - Ramdisk ID (None) |
| 860 * userData - Base64 encoded String (None) |
| 861 * disableApiTermination - Boolean (true) |
| 862 * instanceInitiatedShutdownBehavior - stop|terminate |
| 863 * blockDeviceMapping - List of strings - ie: ['/dev/sda=false'] |
| 864 * sourceDestCheck - Boolean (true) |
| 865 * groupSet - Set of Security Groups or IDs |
| 866 * ebsOptimized - Boolean (false) |
| 867 |
| 868 :type value: string |
| 869 :param value: The new value for the attribute |
| 870 |
| 871 :rtype: bool |
| 872 :return: Whether the operation succeeded or not |
| 873 """ |
| 874 # Allow a bool to be passed in for value of disableApiTermination |
| 875 bool_reqs = ('disableapitermination', |
| 876 'sourcedestcheck', |
| 877 'ebsoptimized') |
| 878 if attribute.lower() in bool_reqs: |
| 879 if isinstance(value, bool): |
| 880 if value: |
| 881 value = 'true' |
| 882 else: |
| 883 value = 'false' |
| 884 |
| 885 params = {'InstanceId': instance_id} |
| 886 |
| 887 # groupSet is handled differently from other arguments |
| 888 if attribute.lower() == 'groupset': |
| 889 for idx, sg in enumerate(value): |
| 890 if isinstance(sg, SecurityGroup): |
| 891 sg = sg.id |
| 892 params['GroupId.%s' % (idx + 1)] = sg |
| 893 elif attribute.lower() == 'blockdevicemapping': |
| 894 for idx, kv in enumerate(value): |
| 895 dev_name, _, flag = kv.partition('=') |
| 896 pre = 'BlockDeviceMapping.%d' % (idx + 1) |
| 897 params['%s.DeviceName' % pre] = dev_name |
| 898 params['%s.Ebs.DeleteOnTermination' % pre] = flag or 'true' |
| 899 else: |
| 900 # for backwards compatibility handle lowercase first letter |
| 901 attribute = attribute[0].upper() + attribute[1:] |
| 902 params['%s.Value' % attribute] = value |
| 903 |
| 904 return self.get_status('ModifyInstanceAttribute', params, verb='POST') |
| 905 |
| 906 def reset_instance_attribute(self, instance_id, attribute): |
| 907 """ |
| 908 Resets an attribute of an instance to its default value. |
| 909 |
| 910 :type instance_id: string |
| 911 :param instance_id: ID of the instance |
| 912 |
| 913 :type attribute: string |
| 914 :param attribute: The attribute to reset. Valid values are: |
| 915 kernel|ramdisk |
| 916 |
| 917 :rtype: bool |
| 918 :return: Whether the operation succeeded or not |
| 919 """ |
| 920 params = {'InstanceId': instance_id, |
| 921 'Attribute': attribute} |
| 922 return self.get_status('ResetInstanceAttribute', params, verb='POST') |
| 923 |
| 924 # Spot Instances |
| 925 |
| 926 def get_all_spot_instance_requests(self, request_ids=None, |
| 927 filters=None): |
| 928 """ |
| 929 Retrieve all the spot instances requests associated with your account. |
| 930 |
| 931 :type request_ids: list |
| 932 :param request_ids: A list of strings of spot instance request IDs |
| 933 |
| 934 :type filters: dict |
| 935 :param filters: Optional filters that can be used to limit the |
| 936 results returned. Filters are provided in the form of a |
| 937 dictionary consisting of filter names as the key and |
| 938 filter values as the value. The set of allowable filter |
| 939 names/values is dependent on the request being performed. |
| 940 Check the EC2 API guide for details. |
| 941 |
| 942 :rtype: list |
| 943 :return: A list of |
| 944 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest` |
| 945 """ |
| 946 params = {} |
| 947 if request_ids: |
| 948 self.build_list_params(params, request_ids, 'SpotInstanceRequestId') |
| 949 if filters: |
| 950 if 'launch.group-id' in filters: |
| 951 lgid = filters.get('launch.group-id') |
| 952 if not lgid.startswith('sg-') or len(lgid) != 11: |
| 953 warnings.warn( |
| 954 "The 'launch.group-id' filter now requires a security " |
| 955 "group id (sg-*) and no longer supports filtering by " |
| 956 "group name. Please update your filters accordingly.", |
| 957 UserWarning) |
| 958 self.build_filter_params(params, filters) |
| 959 return self.get_list('DescribeSpotInstanceRequests', params, |
| 960 [('item', SpotInstanceRequest)], verb='POST') |
| 961 |
| 962 def get_spot_price_history(self, start_time=None, end_time=None, |
| 963 instance_type=None, product_description=None, |
| 964 availability_zone=None): |
| 965 """ |
| 966 Retrieve the recent history of spot instances pricing. |
| 967 |
| 968 :type start_time: str |
| 969 :param start_time: An indication of how far back to provide price |
| 970 changes for. An ISO8601 DateTime string. |
| 971 |
| 972 :type end_time: str |
| 973 :param end_time: An indication of how far forward to provide price |
| 974 changes for. An ISO8601 DateTime string. |
| 975 |
| 976 :type instance_type: str |
| 977 :param instance_type: Filter responses to a particular instance type. |
| 978 |
| 979 :type product_description: str |
| 980 :param product_description: Filter responses to a particular platform. |
| 981 Valid values are currently: |
| 982 |
| 983 * Linux/UNIX |
| 984 * SUSE Linux |
| 985 * Windows |
| 986 * Linux/UNIX (Amazon VPC) |
| 987 * SUSE Linux (Amazon VPC) |
| 988 * Windows (Amazon VPC) |
| 989 |
| 990 :type availability_zone: str |
| 991 :param availability_zone: The availability zone for which prices |
| 992 should be returned. If not specified, data for all |
| 993 availability zones will be returned. |
| 994 |
| 995 :rtype: list |
| 996 :return: A list tuples containing price and timestamp. |
| 997 """ |
| 998 params = {} |
| 999 if start_time: |
| 1000 params['StartTime'] = start_time |
| 1001 if end_time: |
| 1002 params['EndTime'] = end_time |
| 1003 if instance_type: |
| 1004 params['InstanceType'] = instance_type |
| 1005 if product_description: |
| 1006 params['ProductDescription'] = product_description |
| 1007 if availability_zone: |
| 1008 params['AvailabilityZone'] = availability_zone |
| 1009 return self.get_list('DescribeSpotPriceHistory', params, |
| 1010 [('item', SpotPriceHistory)], verb='POST') |
| 1011 |
| 1012 def request_spot_instances(self, price, image_id, count=1, type='one-time', |
| 1013 valid_from=None, valid_until=None, |
| 1014 launch_group=None, availability_zone_group=None, |
| 1015 key_name=None, security_groups=None, |
| 1016 user_data=None, addressing_type=None, |
| 1017 instance_type='m1.small', placement=None, |
| 1018 kernel_id=None, ramdisk_id=None, |
| 1019 monitoring_enabled=False, subnet_id=None, |
| 1020 placement_group=None, |
| 1021 block_device_map=None, |
| 1022 instance_profile_arn=None, |
| 1023 instance_profile_name=None, |
| 1024 security_group_ids=None, |
| 1025 ebs_optimized=False, |
| 1026 network_interfaces=None): |
| 1027 """ |
| 1028 Request instances on the spot market at a particular price. |
| 1029 |
| 1030 :type price: str |
| 1031 :param price: The maximum price of your bid |
| 1032 |
| 1033 :type image_id: string |
| 1034 :param image_id: The ID of the image to run |
| 1035 |
| 1036 :type count: int |
| 1037 :param count: The of instances to requested |
| 1038 |
| 1039 :type type: str |
| 1040 :param type: Type of request. Can be 'one-time' or 'persistent'. |
| 1041 Default is one-time. |
| 1042 |
| 1043 :type valid_from: str |
| 1044 :param valid_from: Start date of the request. An ISO8601 time string. |
| 1045 |
| 1046 :type valid_until: str |
| 1047 :param valid_until: End date of the request. An ISO8601 time string. |
| 1048 |
| 1049 :type launch_group: str |
| 1050 :param launch_group: If supplied, all requests will be fulfilled |
| 1051 as a group. |
| 1052 |
| 1053 :type availability_zone_group: str |
| 1054 :param availability_zone_group: If supplied, all requests will be |
| 1055 fulfilled within a single availability zone. |
| 1056 |
| 1057 :type key_name: string |
| 1058 :param key_name: The name of the key pair with which to |
| 1059 launch instances |
| 1060 |
| 1061 :type security_groups: list of strings |
| 1062 :param security_groups: The names of the security groups with which to |
| 1063 associate instances |
| 1064 |
| 1065 :type user_data: string |
| 1066 :param user_data: The user data passed to the launched instances |
| 1067 |
| 1068 :type instance_type: string |
| 1069 :param instance_type: The type of instance to run: |
| 1070 |
| 1071 * m1.small |
| 1072 * m1.large |
| 1073 * m1.xlarge |
| 1074 * c1.medium |
| 1075 * c1.xlarge |
| 1076 * m2.xlarge |
| 1077 * m2.2xlarge |
| 1078 * m2.4xlarge |
| 1079 * cc1.4xlarge |
| 1080 * t1.micro |
| 1081 |
| 1082 :type placement: string |
| 1083 :param placement: The availability zone in which to launch |
| 1084 the instances |
| 1085 |
| 1086 :type kernel_id: string |
| 1087 :param kernel_id: The ID of the kernel with which to launch the |
| 1088 instances |
| 1089 |
| 1090 :type ramdisk_id: string |
| 1091 :param ramdisk_id: The ID of the RAM disk with which to launch the |
| 1092 instances |
| 1093 |
| 1094 :type monitoring_enabled: bool |
| 1095 :param monitoring_enabled: Enable CloudWatch monitoring on |
| 1096 the instance. |
| 1097 |
| 1098 :type subnet_id: string |
| 1099 :param subnet_id: The subnet ID within which to launch the instances |
| 1100 for VPC. |
| 1101 |
| 1102 :type placement_group: string |
| 1103 :param placement_group: If specified, this is the name of the placement |
| 1104 group in which the instance(s) will be launched. |
| 1105 |
| 1106 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM
apping` |
| 1107 :param block_device_map: A BlockDeviceMapping data structure |
| 1108 describing the EBS volumes associated with the Image. |
| 1109 |
| 1110 :type security_group_ids: list of strings |
| 1111 :param security_group_ids: The ID of the VPC security groups with |
| 1112 which to associate instances. |
| 1113 |
| 1114 :type instance_profile_arn: string |
| 1115 :param instance_profile_arn: The Amazon resource name (ARN) of |
| 1116 the IAM Instance Profile (IIP) to associate with the instances. |
| 1117 |
| 1118 :type instance_profile_name: string |
| 1119 :param instance_profile_name: The name of |
| 1120 the IAM Instance Profile (IIP) to associate with the instances. |
| 1121 |
| 1122 :type ebs_optimized: bool |
| 1123 :param ebs_optimized: Whether the instance is optimized for |
| 1124 EBS I/O. This optimization provides dedicated throughput |
| 1125 to Amazon EBS and an optimized configuration stack to |
| 1126 provide optimal EBS I/O performance. This optimization |
| 1127 isn't available with all instance types. |
| 1128 |
| 1129 :type network_interfaces: list |
| 1130 :param network_interfaces: A list of |
| 1131 :class:`boto.ec2.networkinterface.NetworkInterfaceSpecification` |
| 1132 |
| 1133 :rtype: Reservation |
| 1134 :return: The :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest` |
| 1135 associated with the request for machines |
| 1136 """ |
| 1137 ls = 'LaunchSpecification' |
| 1138 params = {'%s.ImageId' % ls: image_id, |
| 1139 'Type': type, |
| 1140 'SpotPrice': price} |
| 1141 if count: |
| 1142 params['InstanceCount'] = count |
| 1143 if valid_from: |
| 1144 params['ValidFrom'] = valid_from |
| 1145 if valid_until: |
| 1146 params['ValidUntil'] = valid_until |
| 1147 if launch_group: |
| 1148 params['LaunchGroup'] = launch_group |
| 1149 if availability_zone_group: |
| 1150 params['AvailabilityZoneGroup'] = availability_zone_group |
| 1151 if key_name: |
| 1152 params['%s.KeyName' % ls] = key_name |
| 1153 if security_group_ids: |
| 1154 l = [] |
| 1155 for group in security_group_ids: |
| 1156 if isinstance(group, SecurityGroup): |
| 1157 l.append(group.id) |
| 1158 else: |
| 1159 l.append(group) |
| 1160 self.build_list_params(params, l, |
| 1161 '%s.SecurityGroupId' % ls) |
| 1162 if security_groups: |
| 1163 l = [] |
| 1164 for group in security_groups: |
| 1165 if isinstance(group, SecurityGroup): |
| 1166 l.append(group.name) |
| 1167 else: |
| 1168 l.append(group) |
| 1169 self.build_list_params(params, l, '%s.SecurityGroup' % ls) |
| 1170 if user_data: |
| 1171 params['%s.UserData' % ls] = base64.b64encode(user_data) |
| 1172 if addressing_type: |
| 1173 params['%s.AddressingType' % ls] = addressing_type |
| 1174 if instance_type: |
| 1175 params['%s.InstanceType' % ls] = instance_type |
| 1176 if placement: |
| 1177 params['%s.Placement.AvailabilityZone' % ls] = placement |
| 1178 if kernel_id: |
| 1179 params['%s.KernelId' % ls] = kernel_id |
| 1180 if ramdisk_id: |
| 1181 params['%s.RamdiskId' % ls] = ramdisk_id |
| 1182 if monitoring_enabled: |
| 1183 params['%s.Monitoring.Enabled' % ls] = 'true' |
| 1184 if subnet_id: |
| 1185 params['%s.SubnetId' % ls] = subnet_id |
| 1186 if placement_group: |
| 1187 params['%s.Placement.GroupName' % ls] = placement_group |
| 1188 if block_device_map: |
| 1189 block_device_map.build_list_params(params, '%s.' % ls) |
| 1190 if instance_profile_name: |
| 1191 params['%s.IamInstanceProfile.Name' % ls] = instance_profile_name |
| 1192 if instance_profile_arn: |
| 1193 params['%s.IamInstanceProfile.Arn' % ls] = instance_profile_arn |
| 1194 if ebs_optimized: |
| 1195 params['%s.EbsOptimized' % ls] = 'true' |
| 1196 if network_interfaces: |
| 1197 network_interfaces.build_list_params(params, prefix=ls + '.') |
| 1198 return self.get_list('RequestSpotInstances', params, |
| 1199 [('item', SpotInstanceRequest)], |
| 1200 verb='POST') |
| 1201 |
| 1202 def cancel_spot_instance_requests(self, request_ids): |
| 1203 """ |
| 1204 Cancel the specified Spot Instance Requests. |
| 1205 |
| 1206 :type request_ids: list |
| 1207 :param request_ids: A list of strings of the Request IDs to terminate |
| 1208 |
| 1209 :rtype: list |
| 1210 :return: A list of the instances terminated |
| 1211 """ |
| 1212 params = {} |
| 1213 if request_ids: |
| 1214 self.build_list_params(params, request_ids, 'SpotInstanceRequestId') |
| 1215 return self.get_list('CancelSpotInstanceRequests', params, |
| 1216 [('item', Instance)], verb='POST') |
| 1217 |
| 1218 def get_spot_datafeed_subscription(self): |
| 1219 """ |
| 1220 Return the current spot instance data feed subscription |
| 1221 associated with this account, if any. |
| 1222 |
| 1223 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti
on` |
| 1224 :return: The datafeed subscription object or None |
| 1225 """ |
| 1226 return self.get_object('DescribeSpotDatafeedSubscription', |
| 1227 None, SpotDatafeedSubscription, verb='POST') |
| 1228 |
| 1229 def create_spot_datafeed_subscription(self, bucket, prefix): |
| 1230 """ |
| 1231 Create a spot instance datafeed subscription for this account. |
| 1232 |
| 1233 :type bucket: str or unicode |
| 1234 :param bucket: The name of the bucket where spot instance data |
| 1235 will be written. The account issuing this request |
| 1236 must have FULL_CONTROL access to the bucket |
| 1237 specified in the request. |
| 1238 |
| 1239 :type prefix: str or unicode |
| 1240 :param prefix: An optional prefix that will be pre-pended to all |
| 1241 data files written to the bucket. |
| 1242 |
| 1243 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti
on` |
| 1244 :return: The datafeed subscription object or None |
| 1245 """ |
| 1246 params = {'Bucket': bucket} |
| 1247 if prefix: |
| 1248 params['Prefix'] = prefix |
| 1249 return self.get_object('CreateSpotDatafeedSubscription', |
| 1250 params, SpotDatafeedSubscription, verb='POST') |
| 1251 |
| 1252 def delete_spot_datafeed_subscription(self): |
| 1253 """ |
| 1254 Delete the current spot instance data feed subscription |
| 1255 associated with this account |
| 1256 |
| 1257 :rtype: bool |
| 1258 :return: True if successful |
| 1259 """ |
| 1260 return self.get_status('DeleteSpotDatafeedSubscription', |
| 1261 None, verb='POST') |
| 1262 |
| 1263 # Zone methods |
| 1264 |
| 1265 def get_all_zones(self, zones=None, filters=None): |
| 1266 """ |
| 1267 Get all Availability Zones associated with the current region. |
| 1268 |
| 1269 :type zones: list |
| 1270 :param zones: Optional list of zones. If this list is present, |
| 1271 only the Zones associated with these zone names |
| 1272 will be returned. |
| 1273 |
| 1274 :type filters: dict |
| 1275 :param filters: Optional filters that can be used to limit |
| 1276 the results returned. Filters are provided |
| 1277 in the form of a dictionary consisting of |
| 1278 filter names as the key and filter values |
| 1279 as the value. The set of allowable filter |
| 1280 names/values is dependent on the request |
| 1281 being performed. Check the EC2 API guide |
| 1282 for details. |
| 1283 |
| 1284 :rtype: list of :class:`boto.ec2.zone.Zone` |
| 1285 :return: The requested Zone objects |
| 1286 """ |
| 1287 params = {} |
| 1288 if zones: |
| 1289 self.build_list_params(params, zones, 'ZoneName') |
| 1290 if filters: |
| 1291 self.build_filter_params(params, filters) |
| 1292 return self.get_list('DescribeAvailabilityZones', params, |
| 1293 [('item', Zone)], verb='POST') |
| 1294 |
| 1295 # Address methods |
| 1296 |
| 1297 def get_all_addresses(self, addresses=None, filters=None, allocation_ids=Non
e): |
| 1298 """ |
| 1299 Get all EIP's associated with the current credentials. |
| 1300 |
| 1301 :type addresses: list |
| 1302 :param addresses: Optional list of addresses. If this list is present, |
| 1303 only the Addresses associated with these addresses |
| 1304 will be returned. |
| 1305 |
| 1306 :type filters: dict |
| 1307 :param filters: Optional filters that can be used to limit |
| 1308 the results returned. Filters are provided |
| 1309 in the form of a dictionary consisting of |
| 1310 filter names as the key and filter values |
| 1311 as the value. The set of allowable filter |
| 1312 names/values is dependent on the request |
| 1313 being performed. Check the EC2 API guide |
| 1314 for details. |
| 1315 |
| 1316 :type allocation_ids: list |
| 1317 :param allocation_ids: Optional list of allocation IDs. If this list is |
| 1318 present, only the Addresses associated with the given |
| 1319 allocation IDs will be returned. |
| 1320 |
| 1321 :rtype: list of :class:`boto.ec2.address.Address` |
| 1322 :return: The requested Address objects |
| 1323 """ |
| 1324 params = {} |
| 1325 if addresses: |
| 1326 self.build_list_params(params, addresses, 'PublicIp') |
| 1327 if allocation_ids: |
| 1328 self.build_list_params(params, allocation_ids, 'AllocationId') |
| 1329 if filters: |
| 1330 self.build_filter_params(params, filters) |
| 1331 return self.get_list('DescribeAddresses', params, [('item', Address)], v
erb='POST') |
| 1332 |
| 1333 def allocate_address(self, domain=None): |
| 1334 """ |
| 1335 Allocate a new Elastic IP address and associate it with your account. |
| 1336 |
| 1337 :type domain: string |
| 1338 :param domain: Optional string. If domain is set to "vpc" the address |
| 1339 will be allocated to VPC . Will return address |
| 1340 object with allocation_id. |
| 1341 |
| 1342 :rtype: :class:`boto.ec2.address.Address` |
| 1343 :return: The newly allocated Address |
| 1344 """ |
| 1345 params = {} |
| 1346 |
| 1347 if domain is not None: |
| 1348 params['Domain'] = domain |
| 1349 |
| 1350 return self.get_object('AllocateAddress', params, Address, verb='POST') |
| 1351 |
| 1352 def assign_private_ip_addresses(self, network_interface_id=None, |
| 1353 private_ip_addresses=None, |
| 1354 secondary_private_ip_address_count=None, |
| 1355 allow_reassignment=False): |
| 1356 """ |
| 1357 Assigns one or more secondary private IP addresses to a network |
| 1358 interface in Amazon VPC. |
| 1359 |
| 1360 :type network_interface_id: string |
| 1361 :param network_interface_id: The network interface to which the IP |
| 1362 address will be assigned. |
| 1363 |
| 1364 :type private_ip_addresses: list |
| 1365 :param private_ip_addresses: Assigns the specified IP addresses as |
| 1366 secondary IP addresses to the network interface. |
| 1367 |
| 1368 :type secondary_private_ip_address_count: int |
| 1369 :param secondary_private_ip_address_count: The number of secondary IP |
| 1370 addresses to assign to the network interface. You cannot specify |
| 1371 this parameter when also specifying private_ip_addresses. |
| 1372 |
| 1373 :type allow_reassignment: bool |
| 1374 :param allow_reassignment: Specifies whether to allow an IP address |
| 1375 that is already assigned to another network interface or instance |
| 1376 to be reassigned to the specified network interface. |
| 1377 |
| 1378 :rtype: bool |
| 1379 :return: True if successful |
| 1380 """ |
| 1381 params = {} |
| 1382 |
| 1383 if network_interface_id is not None: |
| 1384 params['NetworkInterfaceId'] = network_interface_id |
| 1385 |
| 1386 if private_ip_addresses is not None: |
| 1387 self.build_list_params(params, private_ip_addresses, |
| 1388 'PrivateIpAddress') |
| 1389 elif secondary_private_ip_address_count is not None: |
| 1390 params['SecondaryPrivateIpAddressCount'] = \ |
| 1391 secondary_private_ip_address_count |
| 1392 |
| 1393 if allow_reassignment: |
| 1394 params['AllowReassignment'] = 'true' |
| 1395 |
| 1396 return self.get_status('AssignPrivateIpAddresses', params, verb='POST') |
| 1397 |
| 1398 def associate_address(self, instance_id=None, public_ip=None, |
| 1399 allocation_id=None, network_interface_id=None, |
| 1400 private_ip_address=None, allow_reassociation=False): |
| 1401 """ |
| 1402 Associate an Elastic IP address with a currently running instance. |
| 1403 This requires one of ``public_ip`` or ``allocation_id`` depending |
| 1404 on if you're associating a VPC address or a plain EC2 address. |
| 1405 |
| 1406 When using an Allocation ID, make sure to pass ``None`` for ``public_ip`
` |
| 1407 as EC2 expects a single parameter and if ``public_ip`` is passed boto |
| 1408 will preference that instead of ``allocation_id``. |
| 1409 |
| 1410 :type instance_id: string |
| 1411 :param instance_id: The ID of the instance |
| 1412 |
| 1413 :type public_ip: string |
| 1414 :param public_ip: The public IP address for EC2 based allocations. |
| 1415 |
| 1416 :type allocation_id: string |
| 1417 :param allocation_id: The allocation ID for a VPC-based elastic IP. |
| 1418 |
| 1419 :type network_interface_id: string |
| 1420 :param network_interface_id: The network interface ID to which |
| 1421 elastic IP is to be assigned to |
| 1422 |
| 1423 :type private_ip_address: string |
| 1424 :param private_ip_address: The primary or secondary private IP address |
| 1425 to associate with the Elastic IP address. |
| 1426 |
| 1427 :type allow_reassociation: bool |
| 1428 :param allow_reassociation: Specify this option to allow an Elastic IP |
| 1429 address that is already associated with another network interface |
| 1430 or instance to be re-associated with the specified instance or |
| 1431 interface. |
| 1432 |
| 1433 :rtype: bool |
| 1434 :return: True if successful |
| 1435 """ |
| 1436 params = {} |
| 1437 if instance_id is not None: |
| 1438 params['InstanceId'] = instance_id |
| 1439 elif network_interface_id is not None: |
| 1440 params['NetworkInterfaceId'] = network_interface_id |
| 1441 |
| 1442 if public_ip is not None: |
| 1443 params['PublicIp'] = public_ip |
| 1444 elif allocation_id is not None: |
| 1445 params['AllocationId'] = allocation_id |
| 1446 |
| 1447 if private_ip_address is not None: |
| 1448 params['PrivateIpAddress'] = private_ip_address |
| 1449 |
| 1450 if allow_reassociation: |
| 1451 params['AllowReassociation'] = 'true' |
| 1452 |
| 1453 return self.get_status('AssociateAddress', params, verb='POST') |
| 1454 |
| 1455 def disassociate_address(self, public_ip=None, association_id=None): |
| 1456 """ |
| 1457 Disassociate an Elastic IP address from a currently running instance. |
| 1458 |
| 1459 :type public_ip: string |
| 1460 :param public_ip: The public IP address for EC2 elastic IPs. |
| 1461 |
| 1462 :type association_id: string |
| 1463 :param association_id: The association ID for a VPC based elastic ip. |
| 1464 |
| 1465 :rtype: bool |
| 1466 :return: True if successful |
| 1467 """ |
| 1468 params = {} |
| 1469 |
| 1470 if public_ip is not None: |
| 1471 params['PublicIp'] = public_ip |
| 1472 elif association_id is not None: |
| 1473 params['AssociationId'] = association_id |
| 1474 |
| 1475 return self.get_status('DisassociateAddress', params, verb='POST') |
| 1476 |
| 1477 def release_address(self, public_ip=None, allocation_id=None): |
| 1478 """ |
| 1479 Free up an Elastic IP address. Pass a public IP address to |
| 1480 release an EC2 Elastic IP address and an AllocationId to |
| 1481 release a VPC Elastic IP address. You should only pass |
| 1482 one value. |
| 1483 |
| 1484 This requires one of ``public_ip`` or ``allocation_id`` depending |
| 1485 on if you're associating a VPC address or a plain EC2 address. |
| 1486 |
| 1487 When using an Allocation ID, make sure to pass ``None`` for ``public_ip`
` |
| 1488 as EC2 expects a single parameter and if ``public_ip`` is passed boto |
| 1489 will preference that instead of ``allocation_id``. |
| 1490 |
| 1491 :type public_ip: string |
| 1492 :param public_ip: The public IP address for EC2 elastic IPs. |
| 1493 |
| 1494 :type allocation_id: string |
| 1495 :param allocation_id: The Allocation ID for VPC elastic IPs. |
| 1496 |
| 1497 :rtype: bool |
| 1498 :return: True if successful |
| 1499 """ |
| 1500 params = {} |
| 1501 |
| 1502 if public_ip is not None: |
| 1503 params['PublicIp'] = public_ip |
| 1504 elif allocation_id is not None: |
| 1505 params['AllocationId'] = allocation_id |
| 1506 |
| 1507 return self.get_status('ReleaseAddress', params, verb='POST') |
| 1508 |
| 1509 def unassign_private_ip_addresses(self, network_interface_id=None, |
| 1510 private_ip_addresses=None): |
| 1511 """ |
| 1512 Unassigns one or more secondary private IP addresses from a network |
| 1513 interface in Amazon VPC. |
| 1514 |
| 1515 :type network_interface_id: string |
| 1516 :param network_interface_id: The network interface from which the |
| 1517 secondary private IP address will be unassigned. |
| 1518 |
| 1519 :type private_ip_addresses: list |
| 1520 :param private_ip_addresses: Specifies the secondary private IP |
| 1521 addresses that you want to unassign from the network interface. |
| 1522 |
| 1523 :rtype: bool |
| 1524 :return: True if successful |
| 1525 """ |
| 1526 params = {} |
| 1527 |
| 1528 if network_interface_id is not None: |
| 1529 params['NetworkInterfaceId'] = network_interface_id |
| 1530 |
| 1531 if private_ip_addresses is not None: |
| 1532 self.build_list_params(params, private_ip_addresses, |
| 1533 'PrivateIpAddress') |
| 1534 |
| 1535 return self.get_status('UnassignPrivateIpAddresses', params, |
| 1536 verb='POST') |
| 1537 |
| 1538 # Volume methods |
| 1539 |
| 1540 def get_all_volumes(self, volume_ids=None, filters=None): |
| 1541 """ |
| 1542 Get all Volumes associated with the current credentials. |
| 1543 |
| 1544 :type volume_ids: list |
| 1545 :param volume_ids: Optional list of volume ids. If this list |
| 1546 is present, only the volumes associated with |
| 1547 these volume ids will be returned. |
| 1548 |
| 1549 :type filters: dict |
| 1550 :param filters: Optional filters that can be used to limit |
| 1551 the results returned. Filters are provided |
| 1552 in the form of a dictionary consisting of |
| 1553 filter names as the key and filter values |
| 1554 as the value. The set of allowable filter |
| 1555 names/values is dependent on the request |
| 1556 being performed. Check the EC2 API guide |
| 1557 for details. |
| 1558 |
| 1559 :rtype: list of :class:`boto.ec2.volume.Volume` |
| 1560 :return: The requested Volume objects |
| 1561 """ |
| 1562 params = {} |
| 1563 if volume_ids: |
| 1564 self.build_list_params(params, volume_ids, 'VolumeId') |
| 1565 if filters: |
| 1566 self.build_filter_params(params, filters) |
| 1567 return self.get_list('DescribeVolumes', params, |
| 1568 [('item', Volume)], verb='POST') |
| 1569 |
| 1570 def get_all_volume_status(self, volume_ids=None, |
| 1571 max_results=None, next_token=None, |
| 1572 filters=None): |
| 1573 """ |
| 1574 Retrieve the status of one or more volumes. |
| 1575 |
| 1576 :type volume_ids: list |
| 1577 :param volume_ids: A list of strings of volume IDs |
| 1578 |
| 1579 :type max_results: int |
| 1580 :param max_results: The maximum number of paginated instance |
| 1581 items per response. |
| 1582 |
| 1583 :type next_token: str |
| 1584 :param next_token: A string specifying the next paginated set |
| 1585 of results to return. |
| 1586 |
| 1587 :type filters: dict |
| 1588 :param filters: Optional filters that can be used to limit |
| 1589 the results returned. Filters are provided |
| 1590 in the form of a dictionary consisting of |
| 1591 filter names as the key and filter values |
| 1592 as the value. The set of allowable filter |
| 1593 names/values is dependent on the request |
| 1594 being performed. Check the EC2 API guide |
| 1595 for details. |
| 1596 |
| 1597 :rtype: list |
| 1598 :return: A list of volume status. |
| 1599 """ |
| 1600 params = {} |
| 1601 if volume_ids: |
| 1602 self.build_list_params(params, volume_ids, 'VolumeId') |
| 1603 if max_results: |
| 1604 params['MaxResults'] = max_results |
| 1605 if next_token: |
| 1606 params['NextToken'] = next_token |
| 1607 if filters: |
| 1608 self.build_filter_params(params, filters) |
| 1609 return self.get_object('DescribeVolumeStatus', params, |
| 1610 VolumeStatusSet, verb='POST') |
| 1611 |
| 1612 def enable_volume_io(self, volume_id): |
| 1613 """ |
| 1614 Enables I/O operations for a volume that had I/O operations |
| 1615 disabled because the data on the volume was potentially inconsistent. |
| 1616 |
| 1617 :type volume_id: str |
| 1618 :param volume_id: The ID of the volume. |
| 1619 |
| 1620 :rtype: bool |
| 1621 :return: True if successful |
| 1622 """ |
| 1623 params = {'VolumeId': volume_id} |
| 1624 return self.get_status('EnableVolumeIO', params, verb='POST') |
| 1625 |
| 1626 def get_volume_attribute(self, volume_id, |
| 1627 attribute='autoEnableIO'): |
| 1628 """ |
| 1629 Describes attribute of the volume. |
| 1630 |
| 1631 :type volume_id: str |
| 1632 :param volume_id: The ID of the volume. |
| 1633 |
| 1634 :type attribute: str |
| 1635 :param attribute: The requested attribute. Valid values are: |
| 1636 |
| 1637 * autoEnableIO |
| 1638 |
| 1639 :rtype: list of :class:`boto.ec2.volume.VolumeAttribute` |
| 1640 :return: The requested Volume attribute |
| 1641 """ |
| 1642 params = {'VolumeId': volume_id, 'Attribute': attribute} |
| 1643 return self.get_object('DescribeVolumeAttribute', params, |
| 1644 VolumeAttribute, verb='POST') |
| 1645 |
| 1646 def modify_volume_attribute(self, volume_id, attribute, new_value): |
| 1647 """ |
| 1648 Changes an attribute of an Volume. |
| 1649 |
| 1650 :type volume_id: string |
| 1651 :param volume_id: The volume id you wish to change |
| 1652 |
| 1653 :type attribute: string |
| 1654 :param attribute: The attribute you wish to change. Valid values are: |
| 1655 AutoEnableIO. |
| 1656 |
| 1657 :type new_value: string |
| 1658 :param new_value: The new value of the attribute. |
| 1659 """ |
| 1660 params = {'VolumeId': volume_id} |
| 1661 if attribute == 'AutoEnableIO': |
| 1662 params['AutoEnableIO.Value'] = new_value |
| 1663 return self.get_status('ModifyVolumeAttribute', params, verb='POST') |
| 1664 |
| 1665 def create_volume(self, size, zone, snapshot=None, |
| 1666 volume_type=None, iops=None): |
| 1667 """ |
| 1668 Create a new EBS Volume. |
| 1669 |
| 1670 :type size: int |
| 1671 :param size: The size of the new volume, in GiB |
| 1672 |
| 1673 :type zone: string or :class:`boto.ec2.zone.Zone` |
| 1674 :param zone: The availability zone in which the Volume will be created. |
| 1675 |
| 1676 :type snapshot: string or :class:`boto.ec2.snapshot.Snapshot` |
| 1677 :param snapshot: The snapshot from which the new Volume will be |
| 1678 created. |
| 1679 |
| 1680 :type volume_type: string |
| 1681 :param volume_type: The type of the volume. (optional). Valid |
| 1682 values are: standard | io1. |
| 1683 |
| 1684 :type iops: int |
| 1685 :param iops: The provisioned IOPs you want to associate with |
| 1686 this volume. (optional) |
| 1687 """ |
| 1688 if isinstance(zone, Zone): |
| 1689 zone = zone.name |
| 1690 params = {'AvailabilityZone': zone} |
| 1691 if size: |
| 1692 params['Size'] = size |
| 1693 if snapshot: |
| 1694 if isinstance(snapshot, Snapshot): |
| 1695 snapshot = snapshot.id |
| 1696 params['SnapshotId'] = snapshot |
| 1697 if volume_type: |
| 1698 params['VolumeType'] = volume_type |
| 1699 if iops: |
| 1700 params['Iops'] = str(iops) |
| 1701 return self.get_object('CreateVolume', params, Volume, verb='POST') |
| 1702 |
| 1703 def delete_volume(self, volume_id): |
| 1704 """ |
| 1705 Delete an EBS volume. |
| 1706 |
| 1707 :type volume_id: str |
| 1708 :param volume_id: The ID of the volume to be delete. |
| 1709 |
| 1710 :rtype: bool |
| 1711 :return: True if successful |
| 1712 """ |
| 1713 params = {'VolumeId': volume_id} |
| 1714 return self.get_status('DeleteVolume', params, verb='POST') |
| 1715 |
| 1716 def attach_volume(self, volume_id, instance_id, device): |
| 1717 """ |
| 1718 Attach an EBS volume to an EC2 instance. |
| 1719 |
| 1720 :type volume_id: str |
| 1721 :param volume_id: The ID of the EBS volume to be attached. |
| 1722 |
| 1723 :type instance_id: str |
| 1724 :param instance_id: The ID of the EC2 instance to which it will |
| 1725 be attached. |
| 1726 |
| 1727 :type device: str |
| 1728 :param device: The device on the instance through which the |
| 1729 volume will be exposted (e.g. /dev/sdh) |
| 1730 |
| 1731 :rtype: bool |
| 1732 :return: True if successful |
| 1733 """ |
| 1734 params = {'InstanceId': instance_id, |
| 1735 'VolumeId': volume_id, |
| 1736 'Device': device} |
| 1737 return self.get_status('AttachVolume', params, verb='POST') |
| 1738 |
| 1739 def detach_volume(self, volume_id, instance_id=None, |
| 1740 device=None, force=False): |
| 1741 """ |
| 1742 Detach an EBS volume from an EC2 instance. |
| 1743 |
| 1744 :type volume_id: str |
| 1745 :param volume_id: The ID of the EBS volume to be attached. |
| 1746 |
| 1747 :type instance_id: str |
| 1748 :param instance_id: The ID of the EC2 instance from which it will |
| 1749 be detached. |
| 1750 |
| 1751 :type device: str |
| 1752 :param device: The device on the instance through which the |
| 1753 volume is exposted (e.g. /dev/sdh) |
| 1754 |
| 1755 :type force: bool |
| 1756 :param force: Forces detachment if the previous detachment |
| 1757 attempt did not occur cleanly. This option can lead to |
| 1758 data loss or a corrupted file system. Use this option only |
| 1759 as a last resort to detach a volume from a failed |
| 1760 instance. The instance will not have an opportunity to |
| 1761 flush file system caches nor file system meta data. If you |
| 1762 use this option, you must perform file system check and |
| 1763 repair procedures. |
| 1764 |
| 1765 :rtype: bool |
| 1766 :return: True if successful |
| 1767 """ |
| 1768 params = {'VolumeId': volume_id} |
| 1769 if instance_id: |
| 1770 params['InstanceId'] = instance_id |
| 1771 if device: |
| 1772 params['Device'] = device |
| 1773 if force: |
| 1774 params['Force'] = 'true' |
| 1775 return self.get_status('DetachVolume', params, verb='POST') |
| 1776 |
| 1777 # Snapshot methods |
| 1778 |
| 1779 def get_all_snapshots(self, snapshot_ids=None, |
| 1780 owner=None, restorable_by=None, |
| 1781 filters=None): |
| 1782 """ |
| 1783 Get all EBS Snapshots associated with the current credentials. |
| 1784 |
| 1785 :type snapshot_ids: list |
| 1786 :param snapshot_ids: Optional list of snapshot ids. If this list is |
| 1787 present, only the Snapshots associated with |
| 1788 these snapshot ids will be returned. |
| 1789 |
| 1790 :type owner: str |
| 1791 :param owner: If present, only the snapshots owned by the specified user |
| 1792 will be returned. Valid values are: |
| 1793 |
| 1794 * self |
| 1795 * amazon |
| 1796 * AWS Account ID |
| 1797 |
| 1798 :type restorable_by: str |
| 1799 :param restorable_by: If present, only the snapshots that are restorable |
| 1800 by the specified account id will be returned. |
| 1801 |
| 1802 :type filters: dict |
| 1803 :param filters: Optional filters that can be used to limit |
| 1804 the results returned. Filters are provided |
| 1805 in the form of a dictionary consisting of |
| 1806 filter names as the key and filter values |
| 1807 as the value. The set of allowable filter |
| 1808 names/values is dependent on the request |
| 1809 being performed. Check the EC2 API guide |
| 1810 for details. |
| 1811 |
| 1812 :rtype: list of :class:`boto.ec2.snapshot.Snapshot` |
| 1813 :return: The requested Snapshot objects |
| 1814 """ |
| 1815 params = {} |
| 1816 if snapshot_ids: |
| 1817 self.build_list_params(params, snapshot_ids, 'SnapshotId') |
| 1818 if owner: |
| 1819 params['Owner'] = owner |
| 1820 if restorable_by: |
| 1821 params['RestorableBy'] = restorable_by |
| 1822 if filters: |
| 1823 self.build_filter_params(params, filters) |
| 1824 return self.get_list('DescribeSnapshots', params, |
| 1825 [('item', Snapshot)], verb='POST') |
| 1826 |
| 1827 def create_snapshot(self, volume_id, description=None): |
| 1828 """ |
| 1829 Create a snapshot of an existing EBS Volume. |
| 1830 |
| 1831 :type volume_id: str |
| 1832 :param volume_id: The ID of the volume to be snapshot'ed |
| 1833 |
| 1834 :type description: str |
| 1835 :param description: A description of the snapshot. |
| 1836 Limited to 255 characters. |
| 1837 |
| 1838 :rtype: :class:`boto.ec2.snapshot.Snapshot` |
| 1839 :return: The created Snapshot object |
| 1840 """ |
| 1841 params = {'VolumeId': volume_id} |
| 1842 if description: |
| 1843 params['Description'] = description[0:255] |
| 1844 snapshot = self.get_object('CreateSnapshot', params, |
| 1845 Snapshot, verb='POST') |
| 1846 volume = self.get_all_volumes([volume_id])[0] |
| 1847 volume_name = volume.tags.get('Name') |
| 1848 if volume_name: |
| 1849 snapshot.add_tag('Name', volume_name) |
| 1850 return snapshot |
| 1851 |
| 1852 def delete_snapshot(self, snapshot_id): |
| 1853 params = {'SnapshotId': snapshot_id} |
| 1854 return self.get_status('DeleteSnapshot', params, verb='POST') |
| 1855 |
| 1856 def copy_snapshot(self, source_region, source_snapshot_id, |
| 1857 description=None): |
| 1858 """ |
| 1859 Copies a point-in-time snapshot of an Amazon Elastic Block Store |
| 1860 (Amazon EBS) volume and stores it in Amazon Simple Storage Service |
| 1861 (Amazon S3). You can copy the snapshot within the same region or from |
| 1862 one region to another. You can use the snapshot to create new Amazon |
| 1863 EBS volumes or Amazon Machine Images (AMIs). |
| 1864 |
| 1865 |
| 1866 :type source_region: str |
| 1867 :param source_region: The ID of the AWS region that contains the |
| 1868 snapshot to be copied (e.g 'us-east-1', 'us-west-2', etc.). |
| 1869 |
| 1870 :type source_snapshot_id: str |
| 1871 :param source_snapshot_id: The ID of the Amazon EBS snapshot to copy |
| 1872 |
| 1873 :type description: str |
| 1874 :param description: A description of the new Amazon EBS snapshot. |
| 1875 |
| 1876 :rtype: str |
| 1877 :return: The snapshot ID |
| 1878 |
| 1879 """ |
| 1880 params = { |
| 1881 'SourceRegion': source_region, |
| 1882 'SourceSnapshotId': source_snapshot_id, |
| 1883 } |
| 1884 if description is not None: |
| 1885 params['Description'] = description |
| 1886 snapshot = self.get_object('CopySnapshot', params, Snapshot, |
| 1887 verb='POST') |
| 1888 return snapshot.id |
| 1889 |
| 1890 def trim_snapshots(self, hourly_backups=8, daily_backups=7, |
| 1891 weekly_backups=4): |
| 1892 """ |
| 1893 Trim excess snapshots, based on when they were taken. More current |
| 1894 snapshots are retained, with the number retained decreasing as you |
| 1895 move back in time. |
| 1896 |
| 1897 If ebs volumes have a 'Name' tag with a value, their snapshots |
| 1898 will be assigned the same tag when they are created. The values |
| 1899 of the 'Name' tags for snapshots are used by this function to |
| 1900 group snapshots taken from the same volume (or from a series |
| 1901 of like-named volumes over time) for trimming. |
| 1902 |
| 1903 For every group of like-named snapshots, this function retains |
| 1904 the newest and oldest snapshots, as well as, by default, the |
| 1905 first snapshots taken in each of the last eight hours, the first |
| 1906 snapshots taken in each of the last seven days, the first snapshots |
| 1907 taken in the last 4 weeks (counting Midnight Sunday morning as |
| 1908 the start of the week), and the first snapshot from the first |
| 1909 Sunday of each month forever. |
| 1910 |
| 1911 :type hourly_backups: int |
| 1912 :param hourly_backups: How many recent hourly backups should be saved. |
| 1913 |
| 1914 :type daily_backups: int |
| 1915 :param daily_backups: How many recent daily backups should be saved. |
| 1916 |
| 1917 :type weekly_backups: int |
| 1918 :param weekly_backups: How many recent weekly backups should be saved. |
| 1919 """ |
| 1920 |
| 1921 # This function first builds up an ordered list of target times |
| 1922 # that snapshots should be saved for (last 8 hours, last 7 days, etc.). |
| 1923 # Then a map of snapshots is constructed, with the keys being |
| 1924 # the snapshot / volume names and the values being arrays of |
| 1925 # chronologically sorted snapshots. |
| 1926 # Finally, for each array in the map, we go through the snapshot |
| 1927 # array and the target time array in an interleaved fashion, |
| 1928 # deleting snapshots whose start_times don't immediately follow a |
| 1929 # target time (we delete a snapshot if there's another snapshot |
| 1930 # that was made closer to the preceding target time). |
| 1931 |
| 1932 now = datetime.utcnow() |
| 1933 last_hour = datetime(now.year, now.month, now.day, now.hour) |
| 1934 last_midnight = datetime(now.year, now.month, now.day) |
| 1935 last_sunday = datetime(now.year, now.month, now.day) - timedelta(days =
(now.weekday() + 1) % 7) |
| 1936 start_of_month = datetime(now.year, now.month, 1) |
| 1937 |
| 1938 target_backup_times = [] |
| 1939 |
| 1940 # there are no snapshots older than 1/1/2007 |
| 1941 oldest_snapshot_date = datetime(2007, 1, 1) |
| 1942 |
| 1943 for hour in range(0, hourly_backups): |
| 1944 target_backup_times.append(last_hour - timedelta(hours = hour)) |
| 1945 |
| 1946 for day in range(0, daily_backups): |
| 1947 target_backup_times.append(last_midnight - timedelta(days = day)) |
| 1948 |
| 1949 for week in range(0, weekly_backups): |
| 1950 target_backup_times.append(last_sunday - timedelta(weeks = week)) |
| 1951 |
| 1952 one_day = timedelta(days = 1) |
| 1953 while start_of_month > oldest_snapshot_date: |
| 1954 # append the start of the month to the list of |
| 1955 # snapshot dates to save: |
| 1956 target_backup_times.append(start_of_month) |
| 1957 # there's no timedelta setting for one month, so instead: |
| 1958 # decrement the day by one, so we go to the final day of |
| 1959 # the previous month... |
| 1960 start_of_month -= one_day |
| 1961 # ... and then go to the first day of that previous month: |
| 1962 start_of_month = datetime(start_of_month.year, |
| 1963 start_of_month.month, 1) |
| 1964 |
| 1965 temp = [] |
| 1966 |
| 1967 for t in target_backup_times: |
| 1968 if temp.__contains__(t) == False: |
| 1969 temp.append(t) |
| 1970 |
| 1971 # sort to make the oldest dates first, and make sure the month start |
| 1972 # and last four week's start are in the proper order |
| 1973 target_backup_times = sorted(temp) |
| 1974 |
| 1975 # get all the snapshots, sort them by date and time, and |
| 1976 # organize them into one array for each volume: |
| 1977 all_snapshots = self.get_all_snapshots(owner = 'self') |
| 1978 all_snapshots.sort(cmp = lambda x, y: cmp(x.start_time, y.start_time)) |
| 1979 snaps_for_each_volume = {} |
| 1980 for snap in all_snapshots: |
| 1981 # the snapshot name and the volume name are the same. |
| 1982 # The snapshot name is set from the volume |
| 1983 # name at the time the snapshot is taken |
| 1984 volume_name = snap.tags.get('Name') |
| 1985 if volume_name: |
| 1986 # only examine snapshots that have a volume name |
| 1987 snaps_for_volume = snaps_for_each_volume.get(volume_name) |
| 1988 if not snaps_for_volume: |
| 1989 snaps_for_volume = [] |
| 1990 snaps_for_each_volume[volume_name] = snaps_for_volume |
| 1991 snaps_for_volume.append(snap) |
| 1992 |
| 1993 # Do a running comparison of snapshot dates to desired time |
| 1994 #periods, keeping the oldest snapshot in each |
| 1995 # time period and deleting the rest: |
| 1996 for volume_name in snaps_for_each_volume: |
| 1997 snaps = snaps_for_each_volume[volume_name] |
| 1998 snaps = snaps[:-1] # never delete the newest snapshot |
| 1999 time_period_number = 0 |
| 2000 snap_found_for_this_time_period = False |
| 2001 for snap in snaps: |
| 2002 check_this_snap = True |
| 2003 while check_this_snap and time_period_number < target_backup_tim
es.__len__(): |
| 2004 snap_date = datetime.strptime(snap.start_time, |
| 2005 '%Y-%m-%dT%H:%M:%S.000Z') |
| 2006 if snap_date < target_backup_times[time_period_number]: |
| 2007 # the snap date is before the cutoff date. |
| 2008 # Figure out if it's the first snap in this |
| 2009 # date range and act accordingly (since both |
| 2010 #date the date ranges and the snapshots |
| 2011 # are sorted chronologically, we know this |
| 2012 #snapshot isn't in an earlier date range): |
| 2013 if snap_found_for_this_time_period == True: |
| 2014 if not snap.tags.get('preserve_snapshot'): |
| 2015 # as long as the snapshot wasn't marked |
| 2016 # with the 'preserve_snapshot' tag, delete it: |
| 2017 try: |
| 2018 self.delete_snapshot(snap.id) |
| 2019 boto.log.info('Trimmed snapshot %s (%s)' % (
snap.tags['Name'], snap.start_time)) |
| 2020 except EC2ResponseError: |
| 2021 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)) |
| 2022 # go on and look at the next snapshot, |
| 2023 #leaving the time period alone |
| 2024 else: |
| 2025 # this was the first snapshot found for this |
| 2026 #time period. Leave it alone and look at the |
| 2027 # next snapshot: |
| 2028 snap_found_for_this_time_period = True |
| 2029 check_this_snap = False |
| 2030 else: |
| 2031 # the snap is after the cutoff date. Check it |
| 2032 # against the next cutoff date |
| 2033 time_period_number += 1 |
| 2034 snap_found_for_this_time_period = False |
| 2035 |
| 2036 def get_snapshot_attribute(self, snapshot_id, |
| 2037 attribute='createVolumePermission'): |
| 2038 """ |
| 2039 Get information about an attribute of a snapshot. Only one attribute |
| 2040 can be specified per call. |
| 2041 |
| 2042 :type snapshot_id: str |
| 2043 :param snapshot_id: The ID of the snapshot. |
| 2044 |
| 2045 :type attribute: str |
| 2046 :param attribute: The requested attribute. Valid values are: |
| 2047 |
| 2048 * createVolumePermission |
| 2049 |
| 2050 :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute` |
| 2051 :return: The requested Snapshot attribute |
| 2052 """ |
| 2053 params = {'Attribute': attribute} |
| 2054 if snapshot_id: |
| 2055 params['SnapshotId'] = snapshot_id |
| 2056 return self.get_object('DescribeSnapshotAttribute', params, |
| 2057 SnapshotAttribute, verb='POST') |
| 2058 |
| 2059 def modify_snapshot_attribute(self, snapshot_id, |
| 2060 attribute='createVolumePermission', |
| 2061 operation='add', user_ids=None, groups=None): |
| 2062 """ |
| 2063 Changes an attribute of an image. |
| 2064 |
| 2065 :type snapshot_id: string |
| 2066 :param snapshot_id: The snapshot id you wish to change |
| 2067 |
| 2068 :type attribute: string |
| 2069 :param attribute: The attribute you wish to change. Valid values are: |
| 2070 createVolumePermission |
| 2071 |
| 2072 :type operation: string |
| 2073 :param operation: Either add or remove (this is required for changing |
| 2074 snapshot ermissions) |
| 2075 |
| 2076 :type user_ids: list |
| 2077 :param user_ids: The Amazon IDs of users to add/remove attributes |
| 2078 |
| 2079 :type groups: list |
| 2080 :param groups: The groups to add/remove attributes. The only valid |
| 2081 value at this time is 'all'. |
| 2082 |
| 2083 """ |
| 2084 params = {'SnapshotId': snapshot_id, |
| 2085 'Attribute': attribute, |
| 2086 'OperationType': operation} |
| 2087 if user_ids: |
| 2088 self.build_list_params(params, user_ids, 'UserId') |
| 2089 if groups: |
| 2090 self.build_list_params(params, groups, 'UserGroup') |
| 2091 return self.get_status('ModifySnapshotAttribute', params, verb='POST') |
| 2092 |
| 2093 def reset_snapshot_attribute(self, snapshot_id, |
| 2094 attribute='createVolumePermission'): |
| 2095 """ |
| 2096 Resets an attribute of a snapshot to its default value. |
| 2097 |
| 2098 :type snapshot_id: string |
| 2099 :param snapshot_id: ID of the snapshot |
| 2100 |
| 2101 :type attribute: string |
| 2102 :param attribute: The attribute to reset |
| 2103 |
| 2104 :rtype: bool |
| 2105 :return: Whether the operation succeeded or not |
| 2106 """ |
| 2107 params = {'SnapshotId': snapshot_id, |
| 2108 'Attribute': attribute} |
| 2109 return self.get_status('ResetSnapshotAttribute', params, verb='POST') |
| 2110 |
| 2111 # Keypair methods |
| 2112 |
| 2113 def get_all_key_pairs(self, keynames=None, filters=None): |
| 2114 """ |
| 2115 Get all key pairs associated with your account. |
| 2116 |
| 2117 :type keynames: list |
| 2118 :param keynames: A list of the names of keypairs to retrieve. |
| 2119 If not provided, all key pairs will be returned. |
| 2120 |
| 2121 :type filters: dict |
| 2122 :param filters: Optional filters that can be used to limit the |
| 2123 results returned. Filters are provided in the form of a |
| 2124 dictionary consisting of filter names as the key and |
| 2125 filter values as the value. The set of allowable filter |
| 2126 names/values is dependent on the request being performed. |
| 2127 Check the EC2 API guide for details. |
| 2128 |
| 2129 :rtype: list |
| 2130 :return: A list of :class:`boto.ec2.keypair.KeyPair` |
| 2131 """ |
| 2132 params = {} |
| 2133 if keynames: |
| 2134 self.build_list_params(params, keynames, 'KeyName') |
| 2135 if filters: |
| 2136 self.build_filter_params(params, filters) |
| 2137 return self.get_list('DescribeKeyPairs', params, |
| 2138 [('item', KeyPair)], verb='POST') |
| 2139 |
| 2140 def get_key_pair(self, keyname): |
| 2141 """ |
| 2142 Convenience method to retrieve a specific keypair (KeyPair). |
| 2143 |
| 2144 :type image_id: string |
| 2145 :param image_id: the ID of the Image to retrieve |
| 2146 |
| 2147 :rtype: :class:`boto.ec2.keypair.KeyPair` |
| 2148 :return: The KeyPair specified or None if it is not found |
| 2149 """ |
| 2150 try: |
| 2151 return self.get_all_key_pairs(keynames=[keyname])[0] |
| 2152 except self.ResponseError, e: |
| 2153 if e.code == 'InvalidKeyPair.NotFound': |
| 2154 return None |
| 2155 else: |
| 2156 raise |
| 2157 |
| 2158 def create_key_pair(self, key_name): |
| 2159 """ |
| 2160 Create a new key pair for your account. |
| 2161 This will create the key pair within the region you |
| 2162 are currently connected to. |
| 2163 |
| 2164 :type key_name: string |
| 2165 :param key_name: The name of the new keypair |
| 2166 |
| 2167 :rtype: :class:`boto.ec2.keypair.KeyPair` |
| 2168 :return: The newly created :class:`boto.ec2.keypair.KeyPair`. |
| 2169 The material attribute of the new KeyPair object |
| 2170 will contain the the unencrypted PEM encoded RSA private key. |
| 2171 """ |
| 2172 params = {'KeyName': key_name} |
| 2173 return self.get_object('CreateKeyPair', params, KeyPair, verb='POST') |
| 2174 |
| 2175 def delete_key_pair(self, key_name): |
| 2176 """ |
| 2177 Delete a key pair from your account. |
| 2178 |
| 2179 :type key_name: string |
| 2180 :param key_name: The name of the keypair to delete |
| 2181 """ |
| 2182 params = {'KeyName': key_name} |
| 2183 return self.get_status('DeleteKeyPair', params, verb='POST') |
| 2184 |
| 2185 def import_key_pair(self, key_name, public_key_material): |
| 2186 """ |
| 2187 mports the public key from an RSA key pair that you created |
| 2188 with a third-party tool. |
| 2189 |
| 2190 Supported formats: |
| 2191 |
| 2192 * OpenSSH public key format (e.g., the format |
| 2193 in ~/.ssh/authorized_keys) |
| 2194 |
| 2195 * Base64 encoded DER format |
| 2196 |
| 2197 * SSH public key file format as specified in RFC4716 |
| 2198 |
| 2199 DSA keys are not supported. Make sure your key generator is |
| 2200 set up to create RSA keys. |
| 2201 |
| 2202 Supported lengths: 1024, 2048, and 4096. |
| 2203 |
| 2204 :type key_name: string |
| 2205 :param key_name: The name of the new keypair |
| 2206 |
| 2207 :type public_key_material: string |
| 2208 :param public_key_material: The public key. You must base64 encode |
| 2209 the public key material before sending |
| 2210 it to AWS. |
| 2211 |
| 2212 :rtype: :class:`boto.ec2.keypair.KeyPair` |
| 2213 :return: The newly created :class:`boto.ec2.keypair.KeyPair`. |
| 2214 The material attribute of the new KeyPair object |
| 2215 will contain the the unencrypted PEM encoded RSA private key. |
| 2216 """ |
| 2217 public_key_material = base64.b64encode(public_key_material) |
| 2218 params = {'KeyName': key_name, |
| 2219 'PublicKeyMaterial': public_key_material} |
| 2220 return self.get_object('ImportKeyPair', params, KeyPair, verb='POST') |
| 2221 |
| 2222 # SecurityGroup methods |
| 2223 |
| 2224 def get_all_security_groups(self, groupnames=None, group_ids=None, |
| 2225 filters=None): |
| 2226 """ |
| 2227 Get all security groups associated with your account in a region. |
| 2228 |
| 2229 :type groupnames: list |
| 2230 :param groupnames: A list of the names of security groups to retrieve. |
| 2231 If not provided, all security groups will be |
| 2232 returned. |
| 2233 |
| 2234 :type group_ids: list |
| 2235 :param group_ids: A list of IDs of security groups to retrieve for |
| 2236 security groups within a VPC. |
| 2237 |
| 2238 :type filters: dict |
| 2239 :param filters: Optional filters that can be used to limit |
| 2240 the results returned. Filters are provided |
| 2241 in the form of a dictionary consisting of |
| 2242 filter names as the key and filter values |
| 2243 as the value. The set of allowable filter |
| 2244 names/values is dependent on the request |
| 2245 being performed. Check the EC2 API guide |
| 2246 for details. |
| 2247 |
| 2248 :rtype: list |
| 2249 :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup` |
| 2250 """ |
| 2251 params = {} |
| 2252 if groupnames is not None: |
| 2253 self.build_list_params(params, groupnames, 'GroupName') |
| 2254 if group_ids is not None: |
| 2255 self.build_list_params(params, group_ids, 'GroupId') |
| 2256 if filters is not None: |
| 2257 self.build_filter_params(params, filters) |
| 2258 |
| 2259 return self.get_list('DescribeSecurityGroups', params, |
| 2260 [('item', SecurityGroup)], verb='POST') |
| 2261 |
| 2262 def create_security_group(self, name, description, vpc_id=None): |
| 2263 """ |
| 2264 Create a new security group for your account. |
| 2265 This will create the security group within the region you |
| 2266 are currently connected to. |
| 2267 |
| 2268 :type name: string |
| 2269 :param name: The name of the new security group |
| 2270 |
| 2271 :type description: string |
| 2272 :param description: The description of the new security group |
| 2273 |
| 2274 :type vpc_id: string |
| 2275 :param vpc_id: The ID of the VPC to create the security group in, |
| 2276 if any. |
| 2277 |
| 2278 :rtype: :class:`boto.ec2.securitygroup.SecurityGroup` |
| 2279 :return: The newly created :class:`boto.ec2.securitygroup.SecurityGroup`
. |
| 2280 """ |
| 2281 params = {'GroupName': name, |
| 2282 'GroupDescription': description} |
| 2283 |
| 2284 if vpc_id is not None: |
| 2285 params['VpcId'] = vpc_id |
| 2286 |
| 2287 group = self.get_object('CreateSecurityGroup', params, |
| 2288 SecurityGroup, verb='POST') |
| 2289 group.name = name |
| 2290 group.description = description |
| 2291 if vpc_id is not None: |
| 2292 group.vpc_id = vpc_id |
| 2293 return group |
| 2294 |
| 2295 def delete_security_group(self, name=None, group_id=None): |
| 2296 """ |
| 2297 Delete a security group from your account. |
| 2298 |
| 2299 :type name: string |
| 2300 :param name: The name of the security group to delete. |
| 2301 |
| 2302 :type group_id: string |
| 2303 :param group_id: The ID of the security group to delete within |
| 2304 a VPC. |
| 2305 |
| 2306 :rtype: bool |
| 2307 :return: True if successful. |
| 2308 """ |
| 2309 params = {} |
| 2310 |
| 2311 if name is not None: |
| 2312 params['GroupName'] = name |
| 2313 elif group_id is not None: |
| 2314 params['GroupId'] = group_id |
| 2315 |
| 2316 return self.get_status('DeleteSecurityGroup', params, verb='POST') |
| 2317 |
| 2318 def authorize_security_group_deprecated(self, group_name, |
| 2319 src_security_group_name=None, |
| 2320 src_security_group_owner_id=None, |
| 2321 ip_protocol=None, |
| 2322 from_port=None, to_port=None, |
| 2323 cidr_ip=None): |
| 2324 """ |
| 2325 NOTE: This method uses the old-style request parameters |
| 2326 that did not allow a port to be specified when |
| 2327 authorizing a group. |
| 2328 |
| 2329 :type group_name: string |
| 2330 :param group_name: The name of the security group you are adding |
| 2331 the rule to. |
| 2332 |
| 2333 :type src_security_group_name: string |
| 2334 :param src_security_group_name: The name of the security group you are |
| 2335 granting access to. |
| 2336 |
| 2337 :type src_security_group_owner_id: string |
| 2338 :param src_security_group_owner_id: The ID of the owner of the security |
| 2339 group you are granting access to. |
| 2340 |
| 2341 :type ip_protocol: string |
| 2342 :param ip_protocol: Either tcp | udp | icmp |
| 2343 |
| 2344 :type from_port: int |
| 2345 :param from_port: The beginning port number you are enabling |
| 2346 |
| 2347 :type to_port: int |
| 2348 :param to_port: The ending port number you are enabling |
| 2349 |
| 2350 :type to_port: string |
| 2351 :param to_port: The CIDR block you are providing access to. |
| 2352 See http://goo.gl/Yj5QC |
| 2353 |
| 2354 :rtype: bool |
| 2355 :return: True if successful. |
| 2356 """ |
| 2357 params = {'GroupName':group_name} |
| 2358 if src_security_group_name: |
| 2359 params['SourceSecurityGroupName'] = src_security_group_name |
| 2360 if src_security_group_owner_id: |
| 2361 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id |
| 2362 if ip_protocol: |
| 2363 params['IpProtocol'] = ip_protocol |
| 2364 if from_port: |
| 2365 params['FromPort'] = from_port |
| 2366 if to_port: |
| 2367 params['ToPort'] = to_port |
| 2368 if cidr_ip: |
| 2369 params['CidrIp'] = cidr_ip |
| 2370 return self.get_status('AuthorizeSecurityGroupIngress', params) |
| 2371 |
| 2372 def authorize_security_group(self, group_name=None, |
| 2373 src_security_group_name=None, |
| 2374 src_security_group_owner_id=None, |
| 2375 ip_protocol=None, |
| 2376 from_port=None, to_port=None, |
| 2377 cidr_ip=None, group_id=None, |
| 2378 src_security_group_group_id=None): |
| 2379 """ |
| 2380 Add a new rule to an existing security group. |
| 2381 You need to pass in either src_security_group_name and |
| 2382 src_security_group_owner_id OR ip_protocol, from_port, to_port, |
| 2383 and cidr_ip. In other words, either you are authorizing another |
| 2384 group or you are authorizing some ip-based rule. |
| 2385 |
| 2386 :type group_name: string |
| 2387 :param group_name: The name of the security group you are adding |
| 2388 the rule to. |
| 2389 |
| 2390 :type src_security_group_name: string |
| 2391 :param src_security_group_name: The name of the security group you are |
| 2392 granting access to. |
| 2393 |
| 2394 :type src_security_group_owner_id: string |
| 2395 :param src_security_group_owner_id: The ID of the owner of the security |
| 2396 group you are granting access to. |
| 2397 |
| 2398 :type ip_protocol: string |
| 2399 :param ip_protocol: Either tcp | udp | icmp |
| 2400 |
| 2401 :type from_port: int |
| 2402 :param from_port: The beginning port number you are enabling |
| 2403 |
| 2404 :type to_port: int |
| 2405 :param to_port: The ending port number you are enabling |
| 2406 |
| 2407 :type cidr_ip: string or list of strings |
| 2408 :param cidr_ip: The CIDR block you are providing access to. |
| 2409 See http://goo.gl/Yj5QC |
| 2410 |
| 2411 :type group_id: string |
| 2412 :param group_id: ID of the EC2 or VPC security group to |
| 2413 modify. This is required for VPC security groups and can |
| 2414 be used instead of group_name for EC2 security groups. |
| 2415 |
| 2416 :type src_security_group_group_id: string |
| 2417 :param src_security_group_group_id: The ID of the security |
| 2418 group you are granting access to. Can be used instead of |
| 2419 src_security_group_name |
| 2420 |
| 2421 :rtype: bool |
| 2422 :return: True if successful. |
| 2423 """ |
| 2424 if src_security_group_name: |
| 2425 if from_port is None and to_port is None and ip_protocol is None: |
| 2426 return self.authorize_security_group_deprecated( |
| 2427 group_name, src_security_group_name, |
| 2428 src_security_group_owner_id) |
| 2429 |
| 2430 params = {} |
| 2431 |
| 2432 if group_name: |
| 2433 params['GroupName'] = group_name |
| 2434 if group_id: |
| 2435 params['GroupId'] = group_id |
| 2436 if src_security_group_name: |
| 2437 param_name = 'IpPermissions.1.Groups.1.GroupName' |
| 2438 params[param_name] = src_security_group_name |
| 2439 if src_security_group_owner_id: |
| 2440 param_name = 'IpPermissions.1.Groups.1.UserId' |
| 2441 params[param_name] = src_security_group_owner_id |
| 2442 if src_security_group_group_id: |
| 2443 param_name = 'IpPermissions.1.Groups.1.GroupId' |
| 2444 params[param_name] = src_security_group_group_id |
| 2445 if ip_protocol: |
| 2446 params['IpPermissions.1.IpProtocol'] = ip_protocol |
| 2447 if from_port is not None: |
| 2448 params['IpPermissions.1.FromPort'] = from_port |
| 2449 if to_port is not None: |
| 2450 params['IpPermissions.1.ToPort'] = to_port |
| 2451 if cidr_ip: |
| 2452 if not isinstance(cidr_ip, list): |
| 2453 cidr_ip = [cidr_ip] |
| 2454 for i, single_cidr_ip in enumerate(cidr_ip): |
| 2455 params['IpPermissions.1.IpRanges.%d.CidrIp' % (i+1)] = \ |
| 2456 single_cidr_ip |
| 2457 |
| 2458 return self.get_status('AuthorizeSecurityGroupIngress', |
| 2459 params, verb='POST') |
| 2460 |
| 2461 def authorize_security_group_egress(self, |
| 2462 group_id, |
| 2463 ip_protocol, |
| 2464 from_port=None, |
| 2465 to_port=None, |
| 2466 src_group_id=None, |
| 2467 cidr_ip=None): |
| 2468 """ |
| 2469 The action adds one or more egress rules to a VPC security |
| 2470 group. Specifically, this action permits instances in a |
| 2471 security group to send traffic to one or more destination |
| 2472 CIDR IP address ranges, or to one or more destination |
| 2473 security groups in the same VPC. |
| 2474 """ |
| 2475 params = { |
| 2476 'GroupId': group_id, |
| 2477 'IpPermissions.1.IpProtocol': ip_protocol |
| 2478 } |
| 2479 |
| 2480 if from_port is not None: |
| 2481 params['IpPermissions.1.FromPort'] = from_port |
| 2482 if to_port is not None: |
| 2483 params['IpPermissions.1.ToPort'] = to_port |
| 2484 if src_group_id is not None: |
| 2485 params['IpPermissions.1.Groups.1.GroupId'] = src_group_id |
| 2486 if cidr_ip is not None: |
| 2487 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip |
| 2488 |
| 2489 return self.get_status('AuthorizeSecurityGroupEgress', |
| 2490 params, verb='POST') |
| 2491 |
| 2492 def revoke_security_group_deprecated(self, group_name, |
| 2493 src_security_group_name=None, |
| 2494 src_security_group_owner_id=None, |
| 2495 ip_protocol=None, |
| 2496 from_port=None, to_port=None, |
| 2497 cidr_ip=None): |
| 2498 """ |
| 2499 NOTE: This method uses the old-style request parameters |
| 2500 that did not allow a port to be specified when |
| 2501 authorizing a group. |
| 2502 |
| 2503 Remove an existing rule from an existing security group. |
| 2504 You need to pass in either src_security_group_name and |
| 2505 src_security_group_owner_id OR ip_protocol, from_port, to_port, |
| 2506 and cidr_ip. In other words, either you are revoking another |
| 2507 group or you are revoking some ip-based rule. |
| 2508 |
| 2509 :type group_name: string |
| 2510 :param group_name: The name of the security group you are removing |
| 2511 the rule from. |
| 2512 |
| 2513 :type src_security_group_name: string |
| 2514 :param src_security_group_name: The name of the security group you are |
| 2515 revoking access to. |
| 2516 |
| 2517 :type src_security_group_owner_id: string |
| 2518 :param src_security_group_owner_id: The ID of the owner of the security |
| 2519 group you are revoking access to. |
| 2520 |
| 2521 :type ip_protocol: string |
| 2522 :param ip_protocol: Either tcp | udp | icmp |
| 2523 |
| 2524 :type from_port: int |
| 2525 :param from_port: The beginning port number you are disabling |
| 2526 |
| 2527 :type to_port: int |
| 2528 :param to_port: The ending port number you are disabling |
| 2529 |
| 2530 :type to_port: string |
| 2531 :param to_port: The CIDR block you are revoking access to. |
| 2532 http://goo.gl/Yj5QC |
| 2533 |
| 2534 :rtype: bool |
| 2535 :return: True if successful. |
| 2536 """ |
| 2537 params = {'GroupName':group_name} |
| 2538 if src_security_group_name: |
| 2539 params['SourceSecurityGroupName'] = src_security_group_name |
| 2540 if src_security_group_owner_id: |
| 2541 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id |
| 2542 if ip_protocol: |
| 2543 params['IpProtocol'] = ip_protocol |
| 2544 if from_port: |
| 2545 params['FromPort'] = from_port |
| 2546 if to_port: |
| 2547 params['ToPort'] = to_port |
| 2548 if cidr_ip: |
| 2549 params['CidrIp'] = cidr_ip |
| 2550 return self.get_status('RevokeSecurityGroupIngress', params) |
| 2551 |
| 2552 def revoke_security_group(self, group_name=None, |
| 2553 src_security_group_name=None, |
| 2554 src_security_group_owner_id=None, |
| 2555 ip_protocol=None, from_port=None, to_port=None, |
| 2556 cidr_ip=None, group_id=None, |
| 2557 src_security_group_group_id=None): |
| 2558 """ |
| 2559 Remove an existing rule from an existing security group. |
| 2560 You need to pass in either src_security_group_name and |
| 2561 src_security_group_owner_id OR ip_protocol, from_port, to_port, |
| 2562 and cidr_ip. In other words, either you are revoking another |
| 2563 group or you are revoking some ip-based rule. |
| 2564 |
| 2565 :type group_name: string |
| 2566 :param group_name: The name of the security group you are removing |
| 2567 the rule from. |
| 2568 |
| 2569 :type src_security_group_name: string |
| 2570 :param src_security_group_name: The name of the security group you are |
| 2571 revoking access to. |
| 2572 |
| 2573 :type src_security_group_owner_id: string |
| 2574 :param src_security_group_owner_id: The ID of the owner of the security |
| 2575 group you are revoking access to. |
| 2576 |
| 2577 :type ip_protocol: string |
| 2578 :param ip_protocol: Either tcp | udp | icmp |
| 2579 |
| 2580 :type from_port: int |
| 2581 :param from_port: The beginning port number you are disabling |
| 2582 |
| 2583 :type to_port: int |
| 2584 :param to_port: The ending port number you are disabling |
| 2585 |
| 2586 :type cidr_ip: string |
| 2587 :param cidr_ip: The CIDR block you are revoking access to. |
| 2588 See http://goo.gl/Yj5QC |
| 2589 |
| 2590 :type group_id: string |
| 2591 :param group_id: ID of the EC2 or VPC security group to |
| 2592 modify. This is required for VPC security groups and can |
| 2593 be used instead of group_name for EC2 security groups. |
| 2594 |
| 2595 :type src_security_group_group_id: string |
| 2596 :param src_security_group_group_id: The ID of the security group |
| 2597 for which you are revoking access. Can be used instead |
| 2598 of src_security_group_name |
| 2599 |
| 2600 :rtype: bool |
| 2601 :return: True if successful. |
| 2602 """ |
| 2603 if src_security_group_name: |
| 2604 if from_port is None and to_port is None and ip_protocol is None: |
| 2605 return self.revoke_security_group_deprecated( |
| 2606 group_name, src_security_group_name, |
| 2607 src_security_group_owner_id) |
| 2608 params = {} |
| 2609 if group_name is not None: |
| 2610 params['GroupName'] = group_name |
| 2611 if group_id is not None: |
| 2612 params['GroupId'] = group_id |
| 2613 if src_security_group_name: |
| 2614 param_name = 'IpPermissions.1.Groups.1.GroupName' |
| 2615 params[param_name] = src_security_group_name |
| 2616 if src_security_group_group_id: |
| 2617 param_name = 'IpPermissions.1.Groups.1.GroupId' |
| 2618 params[param_name] = src_security_group_group_id |
| 2619 if src_security_group_owner_id: |
| 2620 param_name = 'IpPermissions.1.Groups.1.UserId' |
| 2621 params[param_name] = src_security_group_owner_id |
| 2622 if ip_protocol: |
| 2623 params['IpPermissions.1.IpProtocol'] = ip_protocol |
| 2624 if from_port is not None: |
| 2625 params['IpPermissions.1.FromPort'] = from_port |
| 2626 if to_port is not None: |
| 2627 params['IpPermissions.1.ToPort'] = to_port |
| 2628 if cidr_ip: |
| 2629 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip |
| 2630 return self.get_status('RevokeSecurityGroupIngress', |
| 2631 params, verb='POST') |
| 2632 |
| 2633 def revoke_security_group_egress(self, |
| 2634 group_id, |
| 2635 ip_protocol, |
| 2636 from_port=None, |
| 2637 to_port=None, |
| 2638 src_group_id=None, |
| 2639 cidr_ip=None): |
| 2640 """ |
| 2641 Remove an existing egress rule from an existing VPC security |
| 2642 group. You need to pass in an ip_protocol, from_port and |
| 2643 to_port range only if the protocol you are using is |
| 2644 port-based. You also need to pass in either a src_group_id or |
| 2645 cidr_ip. |
| 2646 |
| 2647 :type group_name: string |
| 2648 :param group_id: The name of the security group you are removing |
| 2649 the rule from. |
| 2650 |
| 2651 :type ip_protocol: string |
| 2652 :param ip_protocol: Either tcp | udp | icmp | -1 |
| 2653 |
| 2654 :type from_port: int |
| 2655 :param from_port: The beginning port number you are disabling |
| 2656 |
| 2657 :type to_port: int |
| 2658 :param to_port: The ending port number you are disabling |
| 2659 |
| 2660 :type src_group_id: src_group_id |
| 2661 :param src_group_id: The source security group you are |
| 2662 revoking access to. |
| 2663 |
| 2664 :type cidr_ip: string |
| 2665 :param cidr_ip: The CIDR block you are revoking access to. |
| 2666 See http://goo.gl/Yj5QC |
| 2667 |
| 2668 :rtype: bool |
| 2669 :return: True if successful. |
| 2670 """ |
| 2671 |
| 2672 params = {} |
| 2673 if group_id: |
| 2674 params['GroupId'] = group_id |
| 2675 if ip_protocol: |
| 2676 params['IpPermissions.1.IpProtocol'] = ip_protocol |
| 2677 if from_port is not None: |
| 2678 params['IpPermissions.1.FromPort'] = from_port |
| 2679 if to_port is not None: |
| 2680 params['IpPermissions.1.ToPort'] = to_port |
| 2681 if src_group_id is not None: |
| 2682 params['IpPermissions.1.Groups.1.GroupId'] = src_group_id |
| 2683 if cidr_ip: |
| 2684 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip |
| 2685 return self.get_status('RevokeSecurityGroupEgress', |
| 2686 params, verb='POST') |
| 2687 |
| 2688 # |
| 2689 # Regions |
| 2690 # |
| 2691 |
| 2692 def get_all_regions(self, region_names=None, filters=None): |
| 2693 """ |
| 2694 Get all available regions for the EC2 service. |
| 2695 |
| 2696 :type region_names: list of str |
| 2697 :param region_names: Names of regions to limit output |
| 2698 |
| 2699 :type filters: dict |
| 2700 :param filters: Optional filters that can be used to limit |
| 2701 the results returned. Filters are provided |
| 2702 in the form of a dictionary consisting of |
| 2703 filter names as the key and filter values |
| 2704 as the value. The set of allowable filter |
| 2705 names/values is dependent on the request |
| 2706 being performed. Check the EC2 API guide |
| 2707 for details. |
| 2708 |
| 2709 :rtype: list |
| 2710 :return: A list of :class:`boto.ec2.regioninfo.RegionInfo` |
| 2711 """ |
| 2712 params = {} |
| 2713 if region_names: |
| 2714 self.build_list_params(params, region_names, 'RegionName') |
| 2715 if filters: |
| 2716 self.build_filter_params(params, filters) |
| 2717 regions = self.get_list('DescribeRegions', params, |
| 2718 [('item', RegionInfo)], verb='POST') |
| 2719 for region in regions: |
| 2720 region.connection_cls = EC2Connection |
| 2721 return regions |
| 2722 |
| 2723 # |
| 2724 # Reservation methods |
| 2725 # |
| 2726 |
| 2727 def get_all_reserved_instances_offerings(self, |
| 2728 reserved_instances_offering_ids=Non
e, |
| 2729 instance_type=None, |
| 2730 availability_zone=None, |
| 2731 product_description=None, |
| 2732 filters=None, |
| 2733 instance_tenancy=None, |
| 2734 offering_type=None, |
| 2735 include_marketplace=None, |
| 2736 min_duration=None, |
| 2737 max_duration=None, |
| 2738 max_instance_count=None, |
| 2739 next_token=None, |
| 2740 max_results=None): |
| 2741 """ |
| 2742 Describes Reserved Instance offerings that are available for purchase. |
| 2743 |
| 2744 :type reserved_instances_offering_ids: list |
| 2745 :param reserved_instances_id: One or more Reserved Instances |
| 2746 offering IDs. |
| 2747 |
| 2748 :type instance_type: str |
| 2749 :param instance_type: Displays Reserved Instances of the specified |
| 2750 instance type. |
| 2751 |
| 2752 :type availability_zone: str |
| 2753 :param availability_zone: Displays Reserved Instances within the |
| 2754 specified Availability Zone. |
| 2755 |
| 2756 :type product_description: str |
| 2757 :param product_description: Displays Reserved Instances with the |
| 2758 specified product description. |
| 2759 |
| 2760 :type filters: dict |
| 2761 :param filters: Optional filters that can be used to limit |
| 2762 the results returned. Filters are provided |
| 2763 in the form of a dictionary consisting of |
| 2764 filter names as the key and filter values |
| 2765 as the value. The set of allowable filter |
| 2766 names/values is dependent on the request |
| 2767 being performed. Check the EC2 API guide |
| 2768 for details. |
| 2769 |
| 2770 :type instance_tenancy: string |
| 2771 :param instance_tenancy: The tenancy of the Reserved Instance offering. |
| 2772 A Reserved Instance with tenancy of dedicated will run on |
| 2773 single-tenant hardware and can only be launched within a VPC. |
| 2774 |
| 2775 :type offering_type: string |
| 2776 :param offering_type: The Reserved Instance offering type. Valid |
| 2777 Values: `"Heavy Utilization" | "Medium Utilization" | "Light |
| 2778 Utilization"` |
| 2779 |
| 2780 :type include_marketplace: bool |
| 2781 :param include_marketplace: Include Marketplace offerings in the |
| 2782 response. |
| 2783 |
| 2784 :type min_duration: int :param min_duration: Minimum duration (in |
| 2785 seconds) to filter when searching for offerings. |
| 2786 |
| 2787 :type max_duration: int |
| 2788 :param max_duration: Maximum duration (in seconds) to filter when |
| 2789 searching for offerings. |
| 2790 |
| 2791 :type max_instance_count: int |
| 2792 :param max_instance_count: Maximum number of instances to filter when |
| 2793 searching for offerings. |
| 2794 |
| 2795 :type next_token: string |
| 2796 :param next_token: Token to use when requesting the next paginated set |
| 2797 of offerings. |
| 2798 |
| 2799 :type max_results: int |
| 2800 :param max_results: Maximum number of offerings to return per call. |
| 2801 |
| 2802 :rtype: list |
| 2803 :return: A list of |
| 2804 :class:`boto.ec2.reservedinstance.ReservedInstancesOffering`. |
| 2805 |
| 2806 """ |
| 2807 params = {} |
| 2808 if reserved_instances_offering_ids is not None: |
| 2809 self.build_list_params(params, reserved_instances_offering_ids, |
| 2810 'ReservedInstancesOfferingId') |
| 2811 if instance_type: |
| 2812 params['InstanceType'] = instance_type |
| 2813 if availability_zone: |
| 2814 params['AvailabilityZone'] = availability_zone |
| 2815 if product_description: |
| 2816 params['ProductDescription'] = product_description |
| 2817 if filters: |
| 2818 self.build_filter_params(params, filters) |
| 2819 if instance_tenancy is not None: |
| 2820 params['InstanceTenancy'] = instance_tenancy |
| 2821 if offering_type is not None: |
| 2822 params['OfferingType'] = offering_type |
| 2823 if include_marketplace is not None: |
| 2824 if include_marketplace: |
| 2825 params['IncludeMarketplace'] = 'true' |
| 2826 else: |
| 2827 params['IncludeMarketplace'] = 'false' |
| 2828 if min_duration is not None: |
| 2829 params['MinDuration'] = str(min_duration) |
| 2830 if max_duration is not None: |
| 2831 params['MaxDuration'] = str(max_duration) |
| 2832 if max_instance_count is not None: |
| 2833 params['MaxInstanceCount'] = str(max_instance_count) |
| 2834 if next_token is not None: |
| 2835 params['NextToken'] = next_token |
| 2836 if max_results is not None: |
| 2837 params['MaxResults'] = str(max_results) |
| 2838 |
| 2839 return self.get_list('DescribeReservedInstancesOfferings', |
| 2840 params, [('item', ReservedInstancesOffering)], |
| 2841 verb='POST') |
| 2842 |
| 2843 def get_all_reserved_instances(self, reserved_instances_id=None, |
| 2844 filters=None): |
| 2845 """ |
| 2846 Describes one or more of the Reserved Instances that you purchased. |
| 2847 |
| 2848 :type reserved_instance_ids: list |
| 2849 :param reserved_instance_ids: A list of the reserved instance ids that |
| 2850 will be returned. If not provided, all reserved instances |
| 2851 will be returned. |
| 2852 |
| 2853 :type filters: dict |
| 2854 :param filters: Optional filters that can be used to limit the |
| 2855 results returned. Filters are provided in the form of a |
| 2856 dictionary consisting of filter names as the key and |
| 2857 filter values as the value. The set of allowable filter |
| 2858 names/values is dependent on the request being performed. |
| 2859 Check the EC2 API guide for details. |
| 2860 |
| 2861 :rtype: list |
| 2862 :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance` |
| 2863 """ |
| 2864 params = {} |
| 2865 if reserved_instances_id: |
| 2866 self.build_list_params(params, reserved_instances_id, |
| 2867 'ReservedInstancesId') |
| 2868 if filters: |
| 2869 self.build_filter_params(params, filters) |
| 2870 return self.get_list('DescribeReservedInstances', |
| 2871 params, [('item', ReservedInstance)], verb='POST') |
| 2872 |
| 2873 def purchase_reserved_instance_offering(self, |
| 2874 reserved_instances_offering_id, |
| 2875 instance_count=1, limit_price=None): |
| 2876 """ |
| 2877 Purchase a Reserved Instance for use with your account. |
| 2878 ** CAUTION ** |
| 2879 This request can result in large amounts of money being charged to your |
| 2880 AWS account. Use with caution! |
| 2881 |
| 2882 :type reserved_instances_offering_id: string |
| 2883 :param reserved_instances_offering_id: The offering ID of the Reserved |
| 2884 Instance to purchase |
| 2885 |
| 2886 :type instance_count: int |
| 2887 :param instance_count: The number of Reserved Instances to purchase. |
| 2888 Default value is 1. |
| 2889 |
| 2890 :type limit_price: tuple |
| 2891 :param instance_count: Limit the price on the total order. |
| 2892 Must be a tuple of (amount, currency_code), for example: |
| 2893 (100.0, 'USD'). |
| 2894 |
| 2895 :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance` |
| 2896 :return: The newly created Reserved Instance |
| 2897 """ |
| 2898 params = { |
| 2899 'ReservedInstancesOfferingId': reserved_instances_offering_id, |
| 2900 'InstanceCount': instance_count} |
| 2901 if limit_price is not None: |
| 2902 params['LimitPrice.Amount'] = str(limit_price[0]) |
| 2903 params['LimitPrice.CurrencyCode'] = str(limit_price[1]) |
| 2904 return self.get_object('PurchaseReservedInstancesOffering', params, |
| 2905 ReservedInstance, verb='POST') |
| 2906 |
| 2907 def create_reserved_instances_listing(self, reserved_instances_id, instance_
count, |
| 2908 price_schedules, client_token): |
| 2909 """Creates a new listing for Reserved Instances. |
| 2910 |
| 2911 Creates a new listing for Amazon EC2 Reserved Instances that will be |
| 2912 sold in the Reserved Instance Marketplace. You can submit one Reserved |
| 2913 Instance listing at a time. |
| 2914 |
| 2915 The Reserved Instance Marketplace matches sellers who want to resell |
| 2916 Reserved Instance capacity that they no longer need with buyers who |
| 2917 want to purchase additional capacity. Reserved Instances bought and |
| 2918 sold through the Reserved Instance Marketplace work like any other |
| 2919 Reserved Instances. |
| 2920 |
| 2921 If you want to sell your Reserved Instances, you must first register as |
| 2922 a Seller in the Reserved Instance Marketplace. After completing the |
| 2923 registration process, you can create a Reserved Instance Marketplace |
| 2924 listing of some or all of your Reserved Instances, and specify the |
| 2925 upfront price you want to receive for them. Your Reserved Instance |
| 2926 listings then become available for purchase. |
| 2927 |
| 2928 :type reserved_instances_id: string |
| 2929 :param reserved_instances_id: The ID of the Reserved Instance that |
| 2930 will be listed. |
| 2931 |
| 2932 :type instance_count: int |
| 2933 :param instance_count: The number of instances that are a part of a |
| 2934 Reserved Instance account that will be listed in the Reserved |
| 2935 Instance Marketplace. This number should be less than or equal to |
| 2936 the instance count associated with the Reserved Instance ID |
| 2937 specified in this call. |
| 2938 |
| 2939 :type price_schedules: List of tuples |
| 2940 :param price_schedules: A list specifying the price of the Reserved |
| 2941 Instance for each month remaining in the Reserved Instance term. |
| 2942 Each tuple contains two elements, the price and the term. For |
| 2943 example, for an instance that 11 months remaining in its term, |
| 2944 we can have a price schedule with an upfront price of $2.50. |
| 2945 At 8 months remaining we can drop the price down to $2.00. |
| 2946 This would be expressed as:: |
| 2947 |
| 2948 price_schedules=[('2.50', 11), ('2.00', 8)] |
| 2949 |
| 2950 :type client_token: string |
| 2951 :param client_token: Unique, case-sensitive identifier you provide |
| 2952 to ensure idempotency of the request. Maximum 64 ASCII characters. |
| 2953 |
| 2954 :rtype: list |
| 2955 :return: A list of |
| 2956 :class:`boto.ec2.reservedinstance.ReservedInstanceListing` |
| 2957 |
| 2958 """ |
| 2959 params = { |
| 2960 'ReservedInstancesId': reserved_instances_id, |
| 2961 'InstanceCount': str(instance_count), |
| 2962 'ClientToken': client_token, |
| 2963 } |
| 2964 for i, schedule in enumerate(price_schedules): |
| 2965 price, term = schedule |
| 2966 params['PriceSchedules.%s.Price' % i] = str(price) |
| 2967 params['PriceSchedules.%s.Term' % i] = str(term) |
| 2968 return self.get_list('CreateReservedInstancesListing', |
| 2969 params, [('item', ReservedInstanceListing)], verb='
POST') |
| 2970 |
| 2971 def cancel_reserved_instances_listing( |
| 2972 self, reserved_instances_listing_ids=None): |
| 2973 """Cancels the specified Reserved Instance listing. |
| 2974 |
| 2975 :type reserved_instances_listing_ids: List of strings |
| 2976 :param reserved_instances_listing_ids: The ID of the |
| 2977 Reserved Instance listing to be cancelled. |
| 2978 |
| 2979 :rtype: list |
| 2980 :return: A list of |
| 2981 :class:`boto.ec2.reservedinstance.ReservedInstanceListing` |
| 2982 |
| 2983 """ |
| 2984 params = {} |
| 2985 if reserved_instances_listing_ids is not None: |
| 2986 self.build_list_params(params, reserved_instances_listing_ids, |
| 2987 'ReservedInstancesListingId') |
| 2988 return self.get_list('CancelReservedInstancesListing', |
| 2989 params, [('item', ReservedInstanceListing)], verb='
POST') |
| 2990 |
| 2991 # |
| 2992 # Monitoring |
| 2993 # |
| 2994 |
| 2995 def monitor_instances(self, instance_ids): |
| 2996 """ |
| 2997 Enable CloudWatch monitoring for the supplied instances. |
| 2998 |
| 2999 :type instance_id: list of strings |
| 3000 :param instance_id: The instance ids |
| 3001 |
| 3002 :rtype: list |
| 3003 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` |
| 3004 """ |
| 3005 params = {} |
| 3006 self.build_list_params(params, instance_ids, 'InstanceId') |
| 3007 return self.get_list('MonitorInstances', params, |
| 3008 [('item', InstanceInfo)], verb='POST') |
| 3009 |
| 3010 def monitor_instance(self, instance_id): |
| 3011 """ |
| 3012 Deprecated Version, maintained for backward compatibility. |
| 3013 Enable CloudWatch monitoring for the supplied instance. |
| 3014 |
| 3015 :type instance_id: string |
| 3016 :param instance_id: The instance id |
| 3017 |
| 3018 :rtype: list |
| 3019 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` |
| 3020 """ |
| 3021 return self.monitor_instances([instance_id]) |
| 3022 |
| 3023 def unmonitor_instances(self, instance_ids): |
| 3024 """ |
| 3025 Disable CloudWatch monitoring for the supplied instance. |
| 3026 |
| 3027 :type instance_id: list of string |
| 3028 :param instance_id: The instance id |
| 3029 |
| 3030 :rtype: list |
| 3031 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` |
| 3032 """ |
| 3033 params = {} |
| 3034 self.build_list_params(params, instance_ids, 'InstanceId') |
| 3035 return self.get_list('UnmonitorInstances', params, |
| 3036 [('item', InstanceInfo)], verb='POST') |
| 3037 |
| 3038 def unmonitor_instance(self, instance_id): |
| 3039 """ |
| 3040 Deprecated Version, maintained for backward compatibility. |
| 3041 Disable CloudWatch monitoring for the supplied instance. |
| 3042 |
| 3043 :type instance_id: string |
| 3044 :param instance_id: The instance id |
| 3045 |
| 3046 :rtype: list |
| 3047 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` |
| 3048 """ |
| 3049 return self.unmonitor_instances([instance_id]) |
| 3050 |
| 3051 # |
| 3052 # Bundle Windows Instances |
| 3053 # |
| 3054 |
| 3055 def bundle_instance(self, instance_id, |
| 3056 s3_bucket, |
| 3057 s3_prefix, |
| 3058 s3_upload_policy): |
| 3059 """ |
| 3060 Bundle Windows instance. |
| 3061 |
| 3062 :type instance_id: string |
| 3063 :param instance_id: The instance id |
| 3064 |
| 3065 :type s3_bucket: string |
| 3066 :param s3_bucket: The bucket in which the AMI should be stored. |
| 3067 |
| 3068 :type s3_prefix: string |
| 3069 :param s3_prefix: The beginning of the file name for the AMI. |
| 3070 |
| 3071 :type s3_upload_policy: string |
| 3072 :param s3_upload_policy: Base64 encoded policy that specifies condition |
| 3073 and permissions for Amazon EC2 to upload the |
| 3074 user's image into Amazon S3. |
| 3075 """ |
| 3076 |
| 3077 params = {'InstanceId': instance_id, |
| 3078 'Storage.S3.Bucket': s3_bucket, |
| 3079 'Storage.S3.Prefix': s3_prefix, |
| 3080 'Storage.S3.UploadPolicy': s3_upload_policy} |
| 3081 s3auth = boto.auth.get_auth_handler(None, boto.config, |
| 3082 self.provider, ['s3']) |
| 3083 params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id |
| 3084 signature = s3auth.sign_string(s3_upload_policy) |
| 3085 params['Storage.S3.UploadPolicySignature'] = signature |
| 3086 return self.get_object('BundleInstance', params, |
| 3087 BundleInstanceTask, verb='POST') |
| 3088 |
| 3089 def get_all_bundle_tasks(self, bundle_ids=None, filters=None): |
| 3090 """ |
| 3091 Retrieve current bundling tasks. If no bundle id is specified, all |
| 3092 tasks are retrieved. |
| 3093 |
| 3094 :type bundle_ids: list |
| 3095 :param bundle_ids: A list of strings containing identifiers for |
| 3096 previously created bundling tasks. |
| 3097 |
| 3098 :type filters: dict |
| 3099 :param filters: Optional filters that can be used to limit |
| 3100 the results returned. Filters are provided |
| 3101 in the form of a dictionary consisting of |
| 3102 filter names as the key and filter values |
| 3103 as the value. The set of allowable filter |
| 3104 names/values is dependent on the request |
| 3105 being performed. Check the EC2 API guide |
| 3106 for details. |
| 3107 |
| 3108 """ |
| 3109 |
| 3110 params = {} |
| 3111 if bundle_ids: |
| 3112 self.build_list_params(params, bundle_ids, 'BundleId') |
| 3113 if filters: |
| 3114 self.build_filter_params(params, filters) |
| 3115 return self.get_list('DescribeBundleTasks', params, |
| 3116 [('item', BundleInstanceTask)], verb='POST') |
| 3117 |
| 3118 def cancel_bundle_task(self, bundle_id): |
| 3119 """ |
| 3120 Cancel a previously submitted bundle task |
| 3121 |
| 3122 :type bundle_id: string |
| 3123 :param bundle_id: The identifier of the bundle task to cancel. |
| 3124 """ |
| 3125 |
| 3126 params = {'BundleId': bundle_id} |
| 3127 return self.get_object('CancelBundleTask', params, |
| 3128 BundleInstanceTask, verb='POST') |
| 3129 |
| 3130 def get_password_data(self, instance_id): |
| 3131 """ |
| 3132 Get encrypted administrator password for a Windows instance. |
| 3133 |
| 3134 :type instance_id: string |
| 3135 :param instance_id: The identifier of the instance to retrieve the |
| 3136 password for. |
| 3137 """ |
| 3138 |
| 3139 params = {'InstanceId': instance_id} |
| 3140 rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST') |
| 3141 return rs.passwordData |
| 3142 |
| 3143 # |
| 3144 # Cluster Placement Groups |
| 3145 # |
| 3146 |
| 3147 def get_all_placement_groups(self, groupnames=None, filters=None): |
| 3148 """ |
| 3149 Get all placement groups associated with your account in a region. |
| 3150 |
| 3151 :type groupnames: list |
| 3152 :param groupnames: A list of the names of placement groups to retrieve. |
| 3153 If not provided, all placement groups will be |
| 3154 returned. |
| 3155 |
| 3156 :type filters: dict |
| 3157 :param filters: Optional filters that can be used to limit |
| 3158 the results returned. Filters are provided |
| 3159 in the form of a dictionary consisting of |
| 3160 filter names as the key and filter values |
| 3161 as the value. The set of allowable filter |
| 3162 names/values is dependent on the request |
| 3163 being performed. Check the EC2 API guide |
| 3164 for details. |
| 3165 |
| 3166 :rtype: list |
| 3167 :return: A list of :class:`boto.ec2.placementgroup.PlacementGroup` |
| 3168 """ |
| 3169 params = {} |
| 3170 if groupnames: |
| 3171 self.build_list_params(params, groupnames, 'GroupName') |
| 3172 if filters: |
| 3173 self.build_filter_params(params, filters) |
| 3174 return self.get_list('DescribePlacementGroups', params, |
| 3175 [('item', PlacementGroup)], verb='POST') |
| 3176 |
| 3177 def create_placement_group(self, name, strategy='cluster'): |
| 3178 """ |
| 3179 Create a new placement group for your account. |
| 3180 This will create the placement group within the region you |
| 3181 are currently connected to. |
| 3182 |
| 3183 :type name: string |
| 3184 :param name: The name of the new placement group |
| 3185 |
| 3186 :type strategy: string |
| 3187 :param strategy: The placement strategy of the new placement group. |
| 3188 Currently, the only acceptable value is "cluster". |
| 3189 |
| 3190 :rtype: bool |
| 3191 :return: True if successful |
| 3192 """ |
| 3193 params = {'GroupName':name, 'Strategy':strategy} |
| 3194 group = self.get_status('CreatePlacementGroup', params, verb='POST') |
| 3195 return group |
| 3196 |
| 3197 def delete_placement_group(self, name): |
| 3198 """ |
| 3199 Delete a placement group from your account. |
| 3200 |
| 3201 :type key_name: string |
| 3202 :param key_name: The name of the keypair to delete |
| 3203 """ |
| 3204 params = {'GroupName':name} |
| 3205 return self.get_status('DeletePlacementGroup', params, verb='POST') |
| 3206 |
| 3207 # Tag methods |
| 3208 |
| 3209 def build_tag_param_list(self, params, tags): |
| 3210 keys = sorted(tags.keys()) |
| 3211 i = 1 |
| 3212 for key in keys: |
| 3213 value = tags[key] |
| 3214 params['Tag.%d.Key'%i] = key |
| 3215 if value is not None: |
| 3216 params['Tag.%d.Value'%i] = value |
| 3217 i += 1 |
| 3218 |
| 3219 def get_all_tags(self, filters=None): |
| 3220 """ |
| 3221 Retrieve all the metadata tags associated with your account. |
| 3222 |
| 3223 :type filters: dict |
| 3224 :param filters: Optional filters that can be used to limit |
| 3225 the results returned. Filters are provided |
| 3226 in the form of a dictionary consisting of |
| 3227 filter names as the key and filter values |
| 3228 as the value. The set of allowable filter |
| 3229 names/values is dependent on the request |
| 3230 being performed. Check the EC2 API guide |
| 3231 for details. |
| 3232 |
| 3233 :rtype: dict |
| 3234 :return: A dictionary containing metadata tags |
| 3235 """ |
| 3236 params = {} |
| 3237 if filters: |
| 3238 self.build_filter_params(params, filters) |
| 3239 return self.get_list('DescribeTags', params, |
| 3240 [('item', Tag)], verb='POST') |
| 3241 |
| 3242 def create_tags(self, resource_ids, tags): |
| 3243 """ |
| 3244 Create new metadata tags for the specified resource ids. |
| 3245 |
| 3246 :type resource_ids: list |
| 3247 :param resource_ids: List of strings |
| 3248 |
| 3249 :type tags: dict |
| 3250 :param tags: A dictionary containing the name/value pairs. |
| 3251 If you want to create only a tag name, the |
| 3252 value for that tag should be the empty string |
| 3253 (e.g. ''). |
| 3254 |
| 3255 """ |
| 3256 params = {} |
| 3257 self.build_list_params(params, resource_ids, 'ResourceId') |
| 3258 self.build_tag_param_list(params, tags) |
| 3259 return self.get_status('CreateTags', params, verb='POST') |
| 3260 |
| 3261 def delete_tags(self, resource_ids, tags): |
| 3262 """ |
| 3263 Delete metadata tags for the specified resource ids. |
| 3264 |
| 3265 :type resource_ids: list |
| 3266 :param resource_ids: List of strings |
| 3267 |
| 3268 :type tags: dict or list |
| 3269 :param tags: Either a dictionary containing name/value pairs |
| 3270 or a list containing just tag names. |
| 3271 If you pass in a dictionary, the values must |
| 3272 match the actual tag values or the tag will |
| 3273 not be deleted. If you pass in a value of None |
| 3274 for the tag value, all tags with that name will |
| 3275 be deleted. |
| 3276 |
| 3277 """ |
| 3278 if isinstance(tags, list): |
| 3279 tags = {}.fromkeys(tags, None) |
| 3280 params = {} |
| 3281 self.build_list_params(params, resource_ids, 'ResourceId') |
| 3282 self.build_tag_param_list(params, tags) |
| 3283 return self.get_status('DeleteTags', params, verb='POST') |
| 3284 |
| 3285 # Network Interface methods |
| 3286 |
| 3287 def get_all_network_interfaces(self, filters=None): |
| 3288 """ |
| 3289 Retrieve all of the Elastic Network Interfaces (ENI's) |
| 3290 associated with your account. |
| 3291 |
| 3292 :type filters: dict |
| 3293 :param filters: Optional filters that can be used to limit |
| 3294 the results returned. Filters are provided |
| 3295 in the form of a dictionary consisting of |
| 3296 filter names as the key and filter values |
| 3297 as the value. The set of allowable filter |
| 3298 names/values is dependent on the request |
| 3299 being performed. Check the EC2 API guide |
| 3300 for details. |
| 3301 |
| 3302 :rtype: list |
| 3303 :return: A list of :class:`boto.ec2.networkinterface.NetworkInterface` |
| 3304 """ |
| 3305 params = {} |
| 3306 if filters: |
| 3307 self.build_filter_params(params, filters) |
| 3308 return self.get_list('DescribeNetworkInterfaces', params, |
| 3309 [('item', NetworkInterface)], verb='POST') |
| 3310 |
| 3311 def create_network_interface(self, subnet_id, private_ip_address=None, |
| 3312 description=None, groups=None): |
| 3313 """ |
| 3314 Creates a network interface in the specified subnet. |
| 3315 |
| 3316 :type subnet_id: str |
| 3317 :param subnet_id: The ID of the subnet to associate with the |
| 3318 network interface. |
| 3319 |
| 3320 :type private_ip_address: str |
| 3321 :param private_ip_address: The private IP address of the |
| 3322 network interface. If not supplied, one will be chosen |
| 3323 for you. |
| 3324 |
| 3325 :type description: str |
| 3326 :param description: The description of the network interface. |
| 3327 |
| 3328 :type groups: list |
| 3329 :param groups: Lists the groups for use by the network interface. |
| 3330 This can be either a list of group ID's or a list of |
| 3331 :class:`boto.ec2.securitygroup.SecurityGroup` objects. |
| 3332 |
| 3333 :rtype: :class:`boto.ec2.networkinterface.NetworkInterface` |
| 3334 :return: The newly created network interface. |
| 3335 """ |
| 3336 params = {'SubnetId': subnet_id} |
| 3337 if private_ip_address: |
| 3338 params['PrivateIpAddress'] = private_ip_address |
| 3339 if description: |
| 3340 params['Description'] = description |
| 3341 if groups: |
| 3342 ids = [] |
| 3343 for group in groups: |
| 3344 if isinstance(group, SecurityGroup): |
| 3345 ids.append(group.id) |
| 3346 else: |
| 3347 ids.append(group) |
| 3348 self.build_list_params(params, ids, 'SecurityGroupId') |
| 3349 return self.get_object('CreateNetworkInterface', params, |
| 3350 NetworkInterface, verb='POST') |
| 3351 |
| 3352 def attach_network_interface(self, network_interface_id, |
| 3353 instance_id, device_index): |
| 3354 """ |
| 3355 Attaches a network interface to an instance. |
| 3356 |
| 3357 :type network_interface_id: str |
| 3358 :param network_interface_id: The ID of the network interface to attach. |
| 3359 |
| 3360 :type instance_id: str |
| 3361 :param instance_id: The ID of the instance that will be attached |
| 3362 to the network interface. |
| 3363 |
| 3364 :type device_index: int |
| 3365 :param device_index: The index of the device for the network |
| 3366 interface attachment on the instance. |
| 3367 """ |
| 3368 params = {'NetworkInterfaceId': network_interface_id, |
| 3369 'InstanceId': instance_id, |
| 3370 'DeviceIndex': device_index} |
| 3371 return self.get_status('AttachNetworkInterface', params, verb='POST') |
| 3372 |
| 3373 def detach_network_interface(self, attachement_id, force=False): |
| 3374 """ |
| 3375 Detaches a network interface from an instance. |
| 3376 |
| 3377 :type attachment_id: str |
| 3378 :param attachment_id: The ID of the attachment. |
| 3379 |
| 3380 :type force: bool |
| 3381 :param force: Set to true to force a detachment. |
| 3382 |
| 3383 """ |
| 3384 params = {'AttachmentId': network_interface_id} |
| 3385 if force: |
| 3386 params['Force'] = 'true' |
| 3387 return self.get_status('DetachNetworkInterface', params, verb='POST') |
| 3388 |
| 3389 def delete_network_interface(self, network_interface_id): |
| 3390 """ |
| 3391 Delete the specified network interface. |
| 3392 |
| 3393 :type network_interface_id: str |
| 3394 :param network_interface_id: The ID of the network interface to delete. |
| 3395 |
| 3396 """ |
| 3397 params = {'NetworkInterfaceId': network_interface_id} |
| 3398 return self.get_status('DeleteNetworkInterface', params, verb='POST') |
| 3399 |
| 3400 def get_all_vmtypes(self): |
| 3401 """ |
| 3402 Get all vmtypes available on this cloud (eucalyptus specific) |
| 3403 |
| 3404 :rtype: list of :class:`boto.ec2.vmtype.VmType` |
| 3405 :return: The requested VmType objects |
| 3406 """ |
| 3407 params = {} |
| 3408 return self.get_list('DescribeVmTypes', params, [('euca:item', VmType)],
verb='POST') |
| 3409 |
OLD | NEW |