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