Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: third_party/gsutil/boto/ec2/connection.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698