~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/boto/boto/ec2/connection.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
 
2
#
 
3
# Permission is hereby granted, free of charge, to any person obtaining a
 
4
# copy of this software and associated documentation files (the
 
5
# "Software"), to deal in the Software without restriction, including
 
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
 
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
 
8
# persons to whom the Software is furnished to do so, subject to the fol-
 
9
# lowing conditions:
 
10
#
 
11
# The above copyright notice and this permission notice shall be included
 
12
# in all copies or substantial portions of the Software.
 
13
#
 
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
20
# IN THE SOFTWARE.
 
21
 
 
22
"""
 
23
Represents a connection to the EC2 service.
 
24
"""
 
25
 
 
26
import urllib
 
27
import base64
 
28
import hmac
 
29
import boto
 
30
from hashlib import sha1 as sha
 
31
from boto.connection import AWSQueryConnection
 
32
from boto.resultset import ResultSet
 
33
from boto.ec2.image import Image, ImageAttribute
 
34
from boto.ec2.instance import Reservation, Instance, ConsoleOutput, InstanceAttribute
 
35
from boto.ec2.keypair import KeyPair
 
36
from boto.ec2.address import Address
 
37
from boto.ec2.volume import Volume
 
38
from boto.ec2.snapshot import Snapshot
 
39
from boto.ec2.snapshot import SnapshotAttribute
 
40
from boto.ec2.zone import Zone
 
41
from boto.ec2.securitygroup import SecurityGroup
 
42
from boto.ec2.regioninfo import RegionInfo
 
43
from boto.ec2.instanceinfo import InstanceInfo
 
44
from boto.ec2.reservedinstance import ReservedInstancesOffering, ReservedInstance
 
45
from boto.ec2.spotinstancerequest import SpotInstanceRequest
 
46
from boto.ec2.spotpricehistory import SpotPriceHistory
 
47
from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
 
48
from boto.ec2.bundleinstance import BundleInstanceTask
 
49
from boto.exception import EC2ResponseError
 
50
 
 
51
#boto.set_stream_logger('ec2')
 
52
 
 
53
class EC2Connection(AWSQueryConnection):
 
54
 
 
55
    APIVersion = boto.config.get('Boto', 'ec2_version', '2009-11-30')
 
56
    DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
 
57
    DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
 
58
                                            'ec2.amazonaws.com')
 
59
    SignatureVersion = '2'
 
60
    ResponseError = EC2ResponseError
 
61
 
 
62
    def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
 
63
                 is_secure=True, host=None, port=None, proxy=None, proxy_port=None,
 
64
                 proxy_user=None, proxy_pass=None, debug=0,
 
65
                 https_connection_factory=None, region=None, path='/'):
 
66
        """
 
67
        Init method to create a new connection to EC2.
 
68
 
 
69
        B{Note:} The host argument is overridden by the host specified in the boto configuration file.
 
70
        """
 
71
        if not region:
 
72
            region = RegionInfo(self, self.DefaultRegionName, self.DefaultRegionEndpoint)
 
73
        self.region = region
 
74
        AWSQueryConnection.__init__(self, aws_access_key_id,
 
75
                                    aws_secret_access_key,
 
76
                                    is_secure, port, proxy, proxy_port,
 
77
                                    proxy_user, proxy_pass,
 
78
                                    self.region.endpoint, debug,
 
79
                                    https_connection_factory, path)
 
80
 
 
81
    def get_params(self):
 
82
        """
 
83
        Returns a dictionary containing the value of of all of the keyword
 
84
        arguments passed when constructing this connection.
 
85
        """
 
86
        param_names = ['aws_access_key_id', 'aws_secret_access_key', 'is_secure',
 
87
                       'port', 'proxy', 'proxy_port', 'proxy_user', 'proxy_pass',
 
88
                       'debug', 'https_connection_factory']
 
89
        params = {}
 
90
        for name in param_names:
 
91
            params[name] = getattr(self, name)
 
92
        return params
 
93
 
 
94
    # Image methods
 
95
 
 
96
    def get_all_images(self, image_ids=None, owners=None, executable_by=None):
 
97
        """
 
98
        Retrieve all the EC2 images available on your account.
 
99
 
 
100
        :type image_ids: list
 
101
        :param image_ids: A list of strings with the image IDs wanted
 
102
 
 
103
        :type owners: list
 
104
        :param owners: A list of owner IDs
 
105
 
 
106
        :type executable_by:
 
107
        :param executable_by:
 
108
 
 
109
        :rtype: list
 
110
        :return: A list of :class:`boto.ec2.image.Image`
 
111
        """
 
112
        params = {}
 
113
        if image_ids:
 
114
            self.build_list_params(params, image_ids, 'ImageId')
 
115
        if owners:
 
116
            self.build_list_params(params, owners, 'Owner')
 
117
        if executable_by:
 
118
            self.build_list_params(params, executable_by, 'ExecutableBy')
 
119
        return self.get_list('DescribeImages', params, [('item', Image)])
 
120
 
 
121
    def get_all_kernels(self, kernel_ids=None, owners=None):
 
122
        """
 
123
        Retrieve all the EC2 kernels available on your account.  Simply filters the list returned
 
124
        by get_all_images because EC2 does not provide a way to filter server-side.
 
125
 
 
126
        :type kernel_ids: list
 
127
        :param kernel_ids: A list of strings with the image IDs wanted
 
128
 
 
129
        :type owners: list
 
130
        :param owners: A list of owner IDs
 
131
 
 
132
        :rtype: list
 
133
        :return: A list of :class:`boto.ec2.image.Image`
 
134
        """
 
135
        rs = self.get_all_images(kernel_ids, owners)
 
136
        kernels = []
 
137
        for image in rs:
 
138
            if image.type == 'kernel':
 
139
                kernels.append(image)
 
140
        return kernels
 
141
 
 
142
    def get_all_ramdisks(self, ramdisk_ids=None, owners=None):
 
143
        """
 
144
        Retrieve all the EC2 ramdisks available on your account.
 
145
        Simply filters the list returned by get_all_images because
 
146
        EC2 does not provide a way to filter server-side.
 
147
 
 
148
        :type ramdisk_ids: list
 
149
        :param ramdisk_ids: A list of strings with the image IDs wanted
 
150
 
 
151
        :type owners: list
 
152
        :param owners: A list of owner IDs
 
153
 
 
154
        :rtype: list
 
155
        :return: A list of :class:`boto.ec2.image.Image`
 
156
        """
 
157
        rs = self.get_all_images(ramdisk_ids, owners)
 
158
        ramdisks = []
 
159
        for image in rs:
 
160
            if image.type == 'ramdisk':
 
161
                ramdisks.append(image)
 
162
        return ramdisks
 
163
 
 
164
    def get_image(self, image_id):
 
165
        """
 
166
        Shortcut method to retrieve a specific image (AMI).
 
167
 
 
168
        :type image_id: string
 
169
        :param image_id: the ID of the Image to retrieve
 
170
 
 
171
        :rtype: :class:`boto.ec2.image.Image`
 
172
        :return: The EC2 Image specified or None if the image is not found
 
173
        """
 
174
        try:
 
175
            return self.get_all_images(image_ids=[image_id])[0]
 
176
        except IndexError: # None of those images available
 
177
            return None
 
178
 
 
179
    def register_image(self, name=None, description=None, image_location=None,
 
180
                       architecture=None, kernel_id=None, ramdisk_id=None,
 
181
                       root_device_name=None, block_device_map=None):
 
182
        """
 
183
        Register an image.
 
184
 
 
185
        :type name: string
 
186
        :param name: The name of the AMI.  Valid only for EBS-based images.
 
187
 
 
188
        :type description: string
 
189
        :param description: The description of the AMI.
 
190
 
 
191
        :type image_location: string
 
192
        :param image_location: Full path to your AMI manifest in Amazon S3 storage.
 
193
                               Only used for S3-based AMI's.
 
194
 
 
195
        :type architecture: string
 
196
        :param architecture: The architecture of the AMI.  Valid choices are:
 
197
                             i386 | x86_64
 
198
 
 
199
        :type kernel_id: string
 
200
        :param kernel_id: The ID of the kernel with which to launch the instances
 
201
 
 
202
        :type root_device_name: string
 
203
        :param root_device_name: The root device name (e.g. /dev/sdh)
 
204
 
 
205
        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
 
206
        :param block_device_map: A BlockDeviceMapping data structure
 
207
                                 describing the EBS volumes associated
 
208
                                 with the Image.
 
209
 
 
210
        :rtype: string
 
211
        :return: The new image id
 
212
        """
 
213
        params = {}
 
214
        if name:
 
215
            params['Name'] = name
 
216
        if description:
 
217
            params['Description'] = description
 
218
        if architecture:
 
219
            params['Architecture'] = architecture
 
220
        if kernel_id:
 
221
            params['KernelId'] = kernel_id
 
222
        if ramdisk_id:
 
223
            params['RamdiskId'] = ramdisk_id
 
224
        if image_location:
 
225
            params['ImageLocation'] = image_location
 
226
        if root_device_name:
 
227
            params['RootDeviceName'] = root_device_name
 
228
        if block_device_map:
 
229
            block_device_map.build_list_params(params)
 
230
        rs = self.get_object('RegisterImage', params, ResultSet)
 
231
        image_id = getattr(rs, 'imageId', None)
 
232
        return image_id
 
233
 
 
234
    def deregister_image(self, image_id):
 
235
        """
 
236
        Unregister an AMI.
 
237
 
 
238
        :type image_id: string
 
239
        :param image_id: the ID of the Image to unregister
 
240
 
 
241
        :rtype: bool
 
242
        :return: True if successful
 
243
        """
 
244
        return self.get_status('DeregisterImage', {'ImageId':image_id})
 
245
 
 
246
    def create_image(self, instance_id, name, description=None, no_reboot=False):
 
247
        """
 
248
        Will create an AMI from the instance in the running or stopped
 
249
        state.
 
250
        
 
251
        :type instance_id: string
 
252
        :param instance_id: the ID of the instance to image.
 
253
 
 
254
        :type name: string
 
255
        :param name: The name of the new image
 
256
 
 
257
        :type description: string
 
258
        :param description: An optional human-readable string describing
 
259
                            the contents and purpose of the AMI.
 
260
 
 
261
        :type no_reboot: bool
 
262
        :param no_reboot: An optional flag indicating that the bundling process
 
263
                          should not attempt to shutdown the instance before
 
264
                          bundling.  If this flag is True, the responsibility
 
265
                          of maintaining file system integrity is left to the
 
266
                          owner of the instance.
 
267
        
 
268
        :rtype: string
 
269
        :return: The new image id
 
270
        """
 
271
        params = {'InstanceId' : instance_id,
 
272
                  'Name' : name}
 
273
        if description:
 
274
            params['Description'] = description
 
275
        if no_reboot:
 
276
            params['NoReboot'] = 'true'
 
277
        rs = self.get_object('CreateImage', params, Image)
 
278
        image_id = getattr(rs, 'imageId', None)
 
279
        if not image_id:
 
280
            image_id = getattr(rs, 'ImageId', None)
 
281
        return image_id
 
282
        
 
283
    # ImageAttribute methods
 
284
 
 
285
    def get_image_attribute(self, image_id, attribute='launchPermission'):
 
286
        """
 
287
        Gets an attribute from an image.
 
288
        See http://docs.amazonwebservices.com/AWSEC2/2008-02-01/DeveloperGuide/ApiReference-Query-DescribeImageAttribute.html
 
289
 
 
290
        :type image_id: string
 
291
        :param image_id: The Amazon image id for which you want info about
 
292
 
 
293
        :type attribute: string
 
294
        :param attribute: The attribute you need information about.
 
295
                          Valid choices are:
 
296
                          * launchPermission
 
297
                          * productCodes
 
298
                          * blockDeviceMapping
 
299
 
 
300
        :rtype: :class:`boto.ec2.image.ImageAttribute`
 
301
        :return: An ImageAttribute object representing the value of the attribute requested
 
302
        """
 
303
        params = {'ImageId' : image_id,
 
304
                  'Attribute' : attribute}
 
305
        return self.get_object('DescribeImageAttribute', params, ImageAttribute)
 
306
 
 
307
    def modify_image_attribute(self, image_id, attribute='launchPermission',
 
308
                               operation='add', user_ids=None, groups=None,
 
309
                               product_codes=None):
 
310
        """
 
311
        Changes an attribute of an image.
 
312
        See http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyImageAttribute.html
 
313
 
 
314
        :type image_id: string
 
315
        :param image_id: The image id you wish to change
 
316
 
 
317
        :type attribute: string
 
318
        :param attribute: The attribute you wish to change
 
319
 
 
320
        :type operation: string
 
321
        :param operation: Either add or remove (this is required for changing launchPermissions)
 
322
 
 
323
        :type user_ids: list
 
324
        :param user_ids: The Amazon IDs of users to add/remove attributes
 
325
 
 
326
        :type groups: list
 
327
        :param groups: The groups to add/remove attributes
 
328
 
 
329
        :type product_codes: list
 
330
        :param product_codes: Amazon DevPay product code. Currently only one
 
331
                              product code can be associated with an AMI. Once
 
332
                              set, the product code cannot be changed or reset.
 
333
        """
 
334
        params = {'ImageId' : image_id,
 
335
                  'Attribute' : attribute,
 
336
                  'OperationType' : operation}
 
337
        if user_ids:
 
338
            self.build_list_params(params, user_ids, 'UserId')
 
339
        if groups:
 
340
            self.build_list_params(params, groups, 'UserGroup')
 
341
        if product_codes:
 
342
            self.build_list_params(params, product_codes, 'ProductCode')
 
343
        return self.get_status('ModifyImageAttribute', params)
 
344
 
 
345
    def reset_image_attribute(self, image_id, attribute='launchPermission'):
 
346
        """
 
347
        Resets an attribute of an AMI to its default value.
 
348
        See http://docs.amazonwebservices.com/AWSEC2/2008-02-01/DeveloperGuide/ApiReference-Query-ResetImageAttribute.html
 
349
 
 
350
        :type image_id: string
 
351
        :param image_id: ID of the AMI for which an attribute will be described
 
352
 
 
353
        :type attribute: string
 
354
        :param attribute: The attribute to reset
 
355
 
 
356
        :rtype: bool
 
357
        :return: Whether the operation succeeded or not
 
358
        """
 
359
        params = {'ImageId' : image_id,
 
360
                  'Attribute' : attribute}
 
361
        return self.get_status('ResetImageAttribute', params)
 
362
 
 
363
    # Instance methods
 
364
 
 
365
    def get_all_instances(self, instance_ids=None):
 
366
        """
 
367
        Retrieve all the instances associated with your account.
 
368
 
 
369
        :type instance_ids: list
 
370
        :param instance_ids: A list of strings of instance IDs
 
371
 
 
372
        :rtype: list
 
373
        :return: A list of  :class:`boto.ec2.instance.Reservation`
 
374
        """
 
375
        params = {}
 
376
        if instance_ids:
 
377
            self.build_list_params(params, instance_ids, 'InstanceId')
 
378
        return self.get_list('DescribeInstances', params, [('item', Reservation)])
 
379
 
 
380
    def run_instances(self, image_id, min_count=1, max_count=1,
 
381
                      key_name=None, security_groups=None,
 
382
                      user_data=None, addressing_type=None,
 
383
                      instance_type='m1.small', placement=None,
 
384
                      kernel_id=None, ramdisk_id=None,
 
385
                      monitoring_enabled=False, subnet_id=None,
 
386
                      block_device_map=None,
 
387
                      instance_initiated_shutdown_behavior=None):
 
388
        """
 
389
        Runs an image on EC2.
 
390
 
 
391
        :type image_id: string
 
392
        :param image_id: The ID of the image to run
 
393
 
 
394
        :type min_count: int
 
395
        :param min_count: The minimum number of instances to launch
 
396
 
 
397
        :type max_count: int
 
398
        :param max_count: The maximum number of instances to launch
 
399
 
 
400
        :type key_name: string
 
401
        :param key_name: The name of the key pair with which to launch instances
 
402
 
 
403
        :type security_groups: list of strings
 
404
        :param security_groups: The names of the security groups with which to associate instances
 
405
 
 
406
        :type user_data: string
 
407
        :param user_data: The user data passed to the launched instances
 
408
 
 
409
        :type instance_type: string
 
410
        :param instance_type: The type of instance to run (m1.small, m1.large, m1.xlarge)
 
411
 
 
412
        :type placement: string
 
413
        :param placement: The availability zone in which to launch the instances
 
414
 
 
415
        :type kernel_id: string
 
416
        :param kernel_id: The ID of the kernel with which to launch the instances
 
417
 
 
418
        :type ramdisk_id: string
 
419
        :param ramdisk_id: The ID of the RAM disk with which to launch the instances
 
420
 
 
421
        :type monitoring_enabled: bool
 
422
        :param monitoring_enabled: Enable CloudWatch monitoring on the instance.
 
423
 
 
424
        :type subnet_id: string
 
425
        :param subnet_id: The subnet ID within which to launch the instances for VPC.
 
426
 
 
427
        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
 
428
        :param block_device_map: A BlockDeviceMapping data structure
 
429
                                 describing the EBS volumes associated
 
430
                                 with the Image.
 
431
 
 
432
        :type instance_initiated_shutdown_behavior: string
 
433
        :param instance_initiated_shutdown_behavior: Specifies whether the instance's
 
434
                                                     EBS volues are stopped (i.e. detached)
 
435
                                                     or terminated (i.e. deleted) when
 
436
                                                     the instance is shutdown by the
 
437
                                                     owner.  Valid values are:
 
438
                                                     stop | terminate
 
439
 
 
440
        :rtype: Reservation
 
441
        :return: The :class:`boto.ec2.instance.Reservation` associated with the request for machines
 
442
        """
 
443
        params = {'ImageId':image_id,
 
444
                  'MinCount':min_count,
 
445
                  'MaxCount': max_count}
 
446
        if key_name:
 
447
            params['KeyName'] = key_name
 
448
        if security_groups:
 
449
            l = []
 
450
            for group in security_groups:
 
451
                if isinstance(group, SecurityGroup):
 
452
                    l.append(group.name)
 
453
                else:
 
454
                    l.append(group)
 
455
            self.build_list_params(params, l, 'SecurityGroup')
 
456
        if user_data:
 
457
            params['UserData'] = base64.b64encode(user_data)
 
458
        if addressing_type:
 
459
            params['AddressingType'] = addressing_type
 
460
        if instance_type:
 
461
            params['InstanceType'] = instance_type
 
462
        if placement:
 
463
            params['Placement.AvailabilityZone'] = placement
 
464
        if kernel_id:
 
465
            params['KernelId'] = kernel_id
 
466
        if ramdisk_id:
 
467
            params['RamdiskId'] = ramdisk_id
 
468
        if monitoring_enabled:
 
469
            params['Monitoring.Enabled'] = 'true'
 
470
        if subnet_id:
 
471
            params['SubnetId'] = subnet_id
 
472
        if block_device_map:
 
473
            block_device_map.build_list_params(params)
 
474
        if instance_initiated_shutdown_behavior:
 
475
            val = instance_initiated_shutdown_behavior
 
476
            params['InstanceInitiatedShutdownBehavior'] = val
 
477
        return self.get_object('RunInstances', params, Reservation, verb='POST')
 
478
 
 
479
    def terminate_instances(self, instance_ids=None):
 
480
        """
 
481
        Terminate the instances specified
 
482
 
 
483
        :type instance_ids: list
 
484
        :param instance_ids: A list of strings of the Instance IDs to terminate
 
485
 
 
486
        :rtype: list
 
487
        :return: A list of the instances terminated
 
488
        """
 
489
        params = {}
 
490
        if instance_ids:
 
491
            self.build_list_params(params, instance_ids, 'InstanceId')
 
492
        return self.get_list('TerminateInstances', params, [('item', Instance)])
 
493
 
 
494
    def stop_instances(self, instance_ids=None, force=False):
 
495
        """
 
496
        Stop the instances specified
 
497
        
 
498
        :type instance_ids: list
 
499
        :param instance_ids: A list of strings of the Instance IDs to stop
 
500
 
 
501
        :type force: bool
 
502
        :param force: Forces the instance to stop
 
503
        
 
504
        :rtype: list
 
505
        :return: A list of the instances stopped
 
506
        """
 
507
        params = {}
 
508
        if force:
 
509
            params['Force'] = 'true'
 
510
        if instance_ids:
 
511
            self.build_list_params(params, instance_ids, 'InstanceId')
 
512
        return self.get_list('StopInstances', params, [('item', Instance)])
 
513
 
 
514
    def start_instances(self, instance_ids=None):
 
515
        """
 
516
        Start the instances specified
 
517
        
 
518
        :type instance_ids: list
 
519
        :param instance_ids: A list of strings of the Instance IDs to start
 
520
        
 
521
        :rtype: list
 
522
        :return: A list of the instances started
 
523
        """
 
524
        params = {}
 
525
        if instance_ids:
 
526
            self.build_list_params(params, instance_ids, 'InstanceId')
 
527
        return self.get_list('StartInstances', params, [('item', Instance)])
 
528
 
 
529
    def get_console_output(self, instance_id):
 
530
        """
 
531
        Retrieves the console output for the specified instance.
 
532
        See http://docs.amazonwebservices.com/AWSEC2/2008-02-01/DeveloperGuide/ApiReference-Query-GetConsoleOutput.html
 
533
 
 
534
        :type instance_id: string
 
535
        :param instance_id: The instance ID of a running instance on the cloud.
 
536
 
 
537
        :rtype: :class:`boto.ec2.instance.ConsoleOutput`
 
538
        :return: The console output as a ConsoleOutput object
 
539
        """
 
540
        params = {}
 
541
        self.build_list_params(params, [instance_id], 'InstanceId')
 
542
        return self.get_object('GetConsoleOutput', params, ConsoleOutput)
 
543
 
 
544
    def reboot_instances(self, instance_ids=None):
 
545
        """
 
546
        Reboot the specified instances.
 
547
 
 
548
        :type instance_ids: list
 
549
        :param instance_ids: The instances to terminate and reboot
 
550
        """
 
551
        params = {}
 
552
        if instance_ids:
 
553
            self.build_list_params(params, instance_ids, 'InstanceId')
 
554
        return self.get_status('RebootInstances', params)
 
555
 
 
556
    def confirm_product_instance(self, product_code, instance_id):
 
557
        params = {'ProductCode' : product_code,
 
558
                  'InstanceId' : instance_id}
 
559
        rs = self.get_object('ConfirmProductInstance', params, ResultSet)
 
560
        return (rs.status, rs.ownerId)
 
561
 
 
562
    # InstanceAttribute methods
 
563
 
 
564
    def get_instance_attribute(self, instance_id, attribute):
 
565
        """
 
566
        Gets an attribute from an instance.
 
567
 
 
568
        :type instance_id: string
 
569
        :param instance_id: The Amazon id of the instance
 
570
 
 
571
        :type attribute: string
 
572
        :param attribute: The attribute you need information about
 
573
                          Valid choices are:
 
574
                          instanceType|kernel|ramdisk|userData|
 
575
                          disableApiTermination|
 
576
                          instanceInitiatedShutdownBehavior|
 
577
                          rootDeviceName|blockDeviceMapping
 
578
 
 
579
        :rtype: :class:`boto.ec2.image.ImageAttribute`
 
580
        :return: An ImageAttribute object representing the value of the attribute requested
 
581
        """
 
582
        params = {'InstanceId' : instance_id}
 
583
        if attribute:
 
584
            params['Attribute'] = attribute
 
585
        return self.get_object('DescribeInstanceAttribute', params, InstanceAttribute)
 
586
 
 
587
    def modify_instance_attribute(self, instance_id, attribute, value):
 
588
        """
 
589
        Changes an attribute of an instance
 
590
 
 
591
        :type instance_id: string
 
592
        :param instance_id: The instance id you wish to change
 
593
 
 
594
        :type attribute: string
 
595
        :param attribute: The attribute you wish to change.
 
596
                          AttributeName - Expected value (default)
 
597
                          instanceType - A valid instance type (m1.small)
 
598
                          kernel - Kernel ID (None)
 
599
                          ramdisk - Ramdisk ID (None)
 
600
                          userData - Base64 encoded String (None)
 
601
                          disableApiTermination - Boolean (true)
 
602
                          instanceInitiatedShutdownBehavior - stop|terminate
 
603
                          rootDeviceName - device name (None)
 
604
 
 
605
        :type value: string
 
606
        :param value: The new value for the attribute
 
607
 
 
608
        :rtype: bool
 
609
        :return: Whether the operation succeeded or not
 
610
        """
 
611
        params = {'InstanceId' : instance_id,
 
612
                  'Attribute' : attribute,
 
613
                  'Value' : value}
 
614
        return self.get_status('ModifyInstanceAttribute', params)
 
615
 
 
616
    def reset_instance_attribute(self, instance_id, attribute):
 
617
        """
 
618
        Resets an attribute of an instance to its default value.
 
619
 
 
620
        :type instance_id: string
 
621
        :param instance_id: ID of the instance
 
622
 
 
623
        :type attribute: string
 
624
        :param attribute: The attribute to reset. Valid values are:
 
625
                          kernel|ramdisk
 
626
 
 
627
        :rtype: bool
 
628
        :return: Whether the operation succeeded or not
 
629
        """
 
630
        params = {'InstanceId' : instance_id,
 
631
                  'Attribute' : attribute}
 
632
        return self.get_status('ResetInstanceAttribute', params)
 
633
 
 
634
    # Spot Instances
 
635
 
 
636
    def get_all_spot_instance_requests(self, request_ids=None):
 
637
        """
 
638
        Retrieve all the spot instances requests associated with your account.
 
639
        
 
640
        @type request_ids: list
 
641
        @param request_ids: A list of strings of spot instance request IDs
 
642
        
 
643
        @rtype: list
 
644
        @return: A list of
 
645
                 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
 
646
        """
 
647
        params = {}
 
648
        if request_ids:
 
649
            self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
 
650
        return self.get_list('DescribeSpotInstanceRequests', params,
 
651
                             [('item', SpotInstanceRequest)])
 
652
 
 
653
    def get_spot_price_history(self, start_time=None, end_time=None,
 
654
                               instance_type=None, product_description=None):
 
655
        """
 
656
        Retrieve the recent history of spot instances pricing.
 
657
        
 
658
        @type start_time: str
 
659
        @param start_time: An indication of how far back to provide price
 
660
                           changes for. An ISO8601 DateTime string.
 
661
        
 
662
        @type end_time: str
 
663
        @param end_time: An indication of how far forward to provide price
 
664
                         changes for.  An ISO8601 DateTime string.
 
665
        
 
666
        @type instance_type: str
 
667
        @param instance_type: Filter responses to a particular instance type.
 
668
        
 
669
        @type product_description: str
 
670
        @param product_descripton: Filter responses to a particular platform.
 
671
                                   Valid values are currently: Linux
 
672
        
 
673
        @rtype: list
 
674
        @return: A list tuples containing price and timestamp.
 
675
        """
 
676
        params = {}
 
677
        if start_time:
 
678
            params['StartTime'] = start_time
 
679
        if end_time:
 
680
            params['EndTime'] = end_time
 
681
        if instance_type:
 
682
            params['InstanceType'] = instance_type
 
683
        if product_description:
 
684
            params['ProductDescription'] = product_description
 
685
        return self.get_list('DescribeSpotPriceHistory', params, [('item', SpotPriceHistory)])
 
686
 
 
687
    def request_spot_instances(self, price, image_id, count=1, type=None,
 
688
                               valid_from=None, valid_until=None,
 
689
                               launch_group=None, availability_zone_group=None,
 
690
                               key_name=None, security_groups=None,
 
691
                               user_data=None, addressing_type=None,
 
692
                               instance_type='m1.small', placement=None,
 
693
                               kernel_id=None, ramdisk_id=None,
 
694
                               monitoring_enabled=False, subnet_id=None,
 
695
                               block_device_map=None):
 
696
        """
 
697
        Request instances on the spot market at a particular price.
 
698
 
 
699
        :type price: str
 
700
        :param price: The maximum price of your bid
 
701
        
 
702
        :type image_id: string
 
703
        :param image_id: The ID of the image to run
 
704
 
 
705
        :type count: int
 
706
        :param count: The of instances to requested
 
707
        
 
708
        :type type: str
 
709
        :param type: Type of request. Can be 'one-time' or 'persistent'.
 
710
                     Default is one-time.
 
711
 
 
712
        :type valid_from: str
 
713
        :param valid_from: Start date of the request. An ISO8601 time string.
 
714
 
 
715
        :type valid_until: str
 
716
        :param valid_until: End date of the request.  An ISO8601 time string.
 
717
 
 
718
        :type launch_group: str
 
719
        :param launch_group: If supplied, all requests will be fulfilled
 
720
                             as a group.
 
721
                             
 
722
        :type availability_zone_group: str
 
723
        :param availability_zone_group: If supplied, all requests will be fulfilled
 
724
                                        within a single availability zone.
 
725
                             
 
726
        :type key_name: string
 
727
        :param key_name: The name of the key pair with which to launch instances
 
728
 
 
729
        :type security_groups: list of strings
 
730
        :param security_groups: The names of the security groups with which to associate instances
 
731
 
 
732
        :type user_data: string
 
733
        :param user_data: The user data passed to the launched instances
 
734
 
 
735
        :type instance_type: string
 
736
        :param instance_type: The type of instance to run (m1.small, m1.large, m1.xlarge)
 
737
 
 
738
        :type placement: string
 
739
        :param placement: The availability zone in which to launch the instances
 
740
 
 
741
        :type kernel_id: string
 
742
        :param kernel_id: The ID of the kernel with which to launch the instances
 
743
 
 
744
        :type ramdisk_id: string
 
745
        :param ramdisk_id: The ID of the RAM disk with which to launch the instances
 
746
 
 
747
        :type monitoring_enabled: bool
 
748
        :param monitoring_enabled: Enable CloudWatch monitoring on the instance.
 
749
 
 
750
        :type subnet_id: string
 
751
        :param subnet_id: The subnet ID within which to launch the instances for VPC.
 
752
 
 
753
        :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
 
754
        :param block_device_map: A BlockDeviceMapping data structure
 
755
                                 describing the EBS volumes associated
 
756
                                 with the Image.
 
757
 
 
758
        :rtype: Reservation
 
759
        :return: The :class:`boto.ec2.instance.Reservation` associated with the request for machines
 
760
        """
 
761
        params = {'LaunchSpecification.ImageId':image_id,
 
762
                  'SpotPrice' : price}
 
763
        if count:
 
764
            params['InstanceCount'] = count
 
765
        if valid_from:
 
766
            params['ValidFrom'] = valid_from
 
767
        if valid_until:
 
768
            params['ValidUntil'] = valid_until
 
769
        if launch_group:
 
770
            params['LaunchGroup'] = launch_group
 
771
        if availability_zone_group:
 
772
            params['AvailabilityZoneGroup'] = availability_zone_group
 
773
        if key_name:
 
774
            params['LaunchSpecification.KeyName'] = key_name
 
775
        if security_groups:
 
776
            l = []
 
777
            for group in security_groups:
 
778
                if isinstance(group, SecurityGroup):
 
779
                    l.append(group.name)
 
780
                else:
 
781
                    l.append(group)
 
782
            self.build_list_params(params, l,
 
783
                                   'LaunchSpecification.SecurityGroup')
 
784
        if user_data:
 
785
            params['LaunchSpecification.UserData'] = base64.b64encode(user_data)
 
786
        if addressing_type:
 
787
            params['LaunchSpecification.AddressingType'] = addressing_type
 
788
        if instance_type:
 
789
            params['LaunchSpecification.InstanceType'] = instance_type
 
790
        if placement:
 
791
            params['LaunchSpecification.Placement.AvailabilityZone'] = placement
 
792
        if kernel_id:
 
793
            params['LaunchSpecification.KernelId'] = kernel_id
 
794
        if ramdisk_id:
 
795
            params['LaunchSpecification.RamdiskId'] = ramdisk_id
 
796
        if monitoring_enabled:
 
797
            params['LaunchSpecification.Monitoring.Enabled'] = 'true'
 
798
        if subnet_id:
 
799
            params['LaunchSpecification.SubnetId'] = subnet_id
 
800
        if block_device_map:
 
801
            block_device_map.build_list_params(params, 'LaunchSpecification.')
 
802
        return self.get_list('RequestSpotInstances', params,
 
803
                             [('item', SpotInstanceRequest)],
 
804
                             verb='POST')
 
805
 
 
806
        
 
807
    def cancel_spot_instance_requests(self, request_ids):
 
808
        """
 
809
        Cancel the specified Spot Instance Requests.
 
810
        
 
811
        :type request_ids: list
 
812
        :param request_ids: A list of strings of the Request IDs to terminate
 
813
        
 
814
        :rtype: list
 
815
        :return: A list of the instances terminated
 
816
        """
 
817
        params = {}
 
818
        if request_ids:
 
819
            self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
 
820
        return self.get_list('CancelSpotInstanceRequests', params, [('item', Instance)])
 
821
 
 
822
    def get_spot_datafeed_subscription(self):
 
823
        """
 
824
        Return the current spot instance data feed subscription
 
825
        associated with this account, if any.
 
826
        
 
827
        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
 
828
        :return: The datafeed subscription object or None
 
829
        """
 
830
        return self.get_object('DescribeSpotDatafeedSubscription',
 
831
                               None, SpotDatafeedSubscription)
 
832
 
 
833
    def create_spot_datafeed_subscription(self, bucket, prefix):
 
834
        """
 
835
        Create a spot instance datafeed subscription for this account.
 
836
 
 
837
        :type bucket: str or unicode
 
838
        :param bucket: The name of the bucket where spot instance data
 
839
                       will be written.  The account issuing this request
 
840
                       must have FULL_CONTROL access to the bucket
 
841
                       specified in the request.
 
842
 
 
843
        :type prefix: str or unicode
 
844
        :param prefix: An optional prefix that will be pre-pended to all
 
845
                       data files written to the bucket.
 
846
                       
 
847
        :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
 
848
        :return: The datafeed subscription object or None
 
849
        """
 
850
        params = {'Bucket' : bucket}
 
851
        if prefix:
 
852
            params['Prefix'] = prefix
 
853
        return self.get_object('CreateSpotDatafeedSubscription',
 
854
                               params, SpotDatafeedSubscription)
 
855
 
 
856
    def delete_spot_datafeed_subscription(self):
 
857
        """
 
858
        Delete the current spot instance data feed subscription
 
859
        associated with this account
 
860
        
 
861
        :rtype: bool
 
862
        :return: True if successful
 
863
        """
 
864
        return self.get_status('DeleteSpotDatafeedSubscription', None)
 
865
 
 
866
    # Zone methods
 
867
 
 
868
    def get_all_zones(self, zones=None):
 
869
        """
 
870
        Get all Availability Zones associated with the current region.
 
871
 
 
872
        :type zones: list
 
873
        :param zones: Optional list of zones.  If this list is present,
 
874
                      only the Zones associated with these zone names
 
875
                      will be returned.
 
876
 
 
877
        :rtype: list of L{boto.ec2.zone.Zone}
 
878
        :return: The requested Zone objects
 
879
        """
 
880
        params = {}
 
881
        if zones:
 
882
            self.build_list_params(params, zones, 'ZoneName')
 
883
        return self.get_list('DescribeAvailabilityZones', params, [('item', Zone)])
 
884
 
 
885
    # Address methods
 
886
 
 
887
    def get_all_addresses(self, addresses=None):
 
888
        """
 
889
        Get all EIP's associated with the current credentials.
 
890
 
 
891
        :type addresses: list
 
892
        :param addresses: Optional list of addresses.  If this list is present,
 
893
                           only the Addresses associated with these addresses
 
894
                           will be returned.
 
895
 
 
896
        :rtype: list of L{boto.ec2.address.Address}
 
897
        :return: The requested Address objects
 
898
        """
 
899
        params = {}
 
900
        if addresses:
 
901
            self.build_list_params(params, addresses, 'PublicIp')
 
902
        return self.get_list('DescribeAddresses', params, [('item', Address)])
 
903
 
 
904
    def allocate_address(self):
 
905
        """
 
906
        Allocate a new Elastic IP address and associate it with your account.
 
907
 
 
908
        :rtype: L{boto.ec2.address.Address}
 
909
        :return: The newly allocated Address
 
910
        """
 
911
        return self.get_object('AllocateAddress', None, Address)
 
912
 
 
913
    def associate_address(self, instance_id, public_ip):
 
914
        """
 
915
        Associate an Elastic IP address with a currently running instance.
 
916
 
 
917
        :type instance_id: string
 
918
        :param instance_id: The ID of the instance
 
919
 
 
920
        :type public_ip: string
 
921
        :param public_ip: The public IP address
 
922
 
 
923
        :rtype: bool
 
924
        :return: True if successful
 
925
        """
 
926
        params = {'InstanceId' : instance_id, 'PublicIp' : public_ip}
 
927
        return self.get_status('AssociateAddress', params)
 
928
 
 
929
    def disassociate_address(self, public_ip):
 
930
        """
 
931
        Disassociate an Elastic IP address from a currently running instance.
 
932
 
 
933
        :type public_ip: string
 
934
        :param public_ip: The public IP address
 
935
 
 
936
        :rtype: bool
 
937
        :return: True if successful
 
938
        """
 
939
        params = {'PublicIp' : public_ip}
 
940
        return self.get_status('DisassociateAddress', params)
 
941
 
 
942
    def release_address(self, public_ip):
 
943
        """
 
944
        Free up an Elastic IP address
 
945
 
 
946
        :type public_ip: string
 
947
        :param public_ip: The public IP address
 
948
 
 
949
        :rtype: bool
 
950
        :return: True if successful
 
951
        """
 
952
        params = {'PublicIp' : public_ip}
 
953
        return self.get_status('ReleaseAddress', params)
 
954
 
 
955
    # Volume methods
 
956
 
 
957
    def get_all_volumes(self, volume_ids=None):
 
958
        """
 
959
        Get all Volumes associated with the current credentials.
 
960
 
 
961
        :type volume_ids: list
 
962
        :param volume_ids: Optional list of volume ids.  If this list is present,
 
963
                           only the volumes associated with these volume ids
 
964
                           will be returned.
 
965
 
 
966
        :rtype: list of L{boto.ec2.volume.Volume}
 
967
        :return: The requested Volume objects
 
968
        """
 
969
        params = {}
 
970
        if volume_ids:
 
971
            self.build_list_params(params, volume_ids, 'VolumeId')
 
972
        return self.get_list('DescribeVolumes', params, [('item', Volume)])
 
973
 
 
974
    def create_volume(self, size, zone, snapshot=None):
 
975
        """
 
976
        Create a new EBS Volume.
 
977
 
 
978
        :type size: int
 
979
        :param size: The size of the new volume, in GiB
 
980
 
 
981
        :type zone: string or L{boto.ec2.zone.Zone}
 
982
        :param zone: The availability zone in which the Volume will be created.
 
983
 
 
984
        :type snapshot: string or L{boto.ec2.snapshot.Snapshot}
 
985
        :param snapshot: The snapshot from which the new Volume will be created.
 
986
        """
 
987
        if isinstance(zone, Zone):
 
988
            zone = zone.name
 
989
        params = {'AvailabilityZone' : zone}
 
990
        if size:
 
991
            params['Size'] = size
 
992
        if snapshot:
 
993
            if isinstance(snapshot, Snapshot):
 
994
                snapshot = snapshot.id
 
995
            params['SnapshotId'] = snapshot
 
996
        return self.get_object('CreateVolume', params, Volume)
 
997
 
 
998
    def delete_volume(self, volume_id):
 
999
        """
 
1000
        Delete an EBS volume.
 
1001
 
 
1002
        :type volume_id: str
 
1003
        :param volume_id: The ID of the volume to be delete.
 
1004
 
 
1005
        :rtype: bool
 
1006
        :return: True if successful
 
1007
        """
 
1008
        params = {'VolumeId': volume_id}
 
1009
        return self.get_status('DeleteVolume', params)
 
1010
 
 
1011
    def attach_volume(self, volume_id, instance_id, device):
 
1012
        """
 
1013
        Attach an EBS volume to an EC2 instance.
 
1014
 
 
1015
        :type volume_id: str
 
1016
        :param volume_id: The ID of the EBS volume to be attached.
 
1017
 
 
1018
        :type instance_id: str
 
1019
        :param instance_id: The ID of the EC2 instance to which it will
 
1020
                            be attached.
 
1021
 
 
1022
        :type device: str
 
1023
        :param device: The device on the instance through which the
 
1024
                       volume will be exposted (e.g. /dev/sdh)
 
1025
 
 
1026
        :rtype: bool
 
1027
        :return: True if successful
 
1028
        """
 
1029
        params = {'InstanceId' : instance_id,
 
1030
                  'VolumeId' : volume_id,
 
1031
                  'Device' : device}
 
1032
        return self.get_status('AttachVolume', params)
 
1033
 
 
1034
    def detach_volume(self, volume_id, instance_id=None, device=None, force=False):
 
1035
        """
 
1036
        Detach an EBS volume from an EC2 instance.
 
1037
 
 
1038
        :type volume_id: str
 
1039
        :param volume_id: The ID of the EBS volume to be attached.
 
1040
 
 
1041
        :type instance_id: str
 
1042
        :param instance_id: The ID of the EC2 instance from which it will
 
1043
                            be detached.
 
1044
 
 
1045
        :type device: str
 
1046
        :param device: The device on the instance through which the
 
1047
                       volume is exposted (e.g. /dev/sdh)
 
1048
 
 
1049
        :type force: bool
 
1050
        :param force: Forces detachment if the previous detachment attempt did
 
1051
                      not occur cleanly.  This option can lead to data loss or
 
1052
                      a corrupted file system. Use this option only as a last
 
1053
                      resort to detach a volume from a failed instance. The
 
1054
                      instance will not have an opportunity to flush file system
 
1055
                      caches nor file system meta data. If you use this option,
 
1056
                      you must perform file system check and repair procedures.
 
1057
 
 
1058
        :rtype: bool
 
1059
        :return: True if successful
 
1060
        """
 
1061
        params = {'VolumeId' : volume_id}
 
1062
        if instance_id:
 
1063
            params['InstanceId'] = instance_id
 
1064
        if device:
 
1065
            params['Device'] = device
 
1066
        if force:
 
1067
            params['Force'] = 'true'
 
1068
        return self.get_status('DetachVolume', params)
 
1069
 
 
1070
    # Snapshot methods
 
1071
 
 
1072
    def get_all_snapshots(self, snapshot_ids=None, owner=None, restorable_by=None):
 
1073
        """
 
1074
        Get all EBS Snapshots associated with the current credentials.
 
1075
 
 
1076
        :type snapshot_ids: list
 
1077
        :param snapshot_ids: Optional list of snapshot ids.  If this list is present,
 
1078
                           only the Snapshots associated with these snapshot ids
 
1079
                           will be returned.
 
1080
 
 
1081
        :type owner: str
 
1082
        :param owner: If present, only the snapshots owned by the specified user
 
1083
                      will be returned.  Valid values are:
 
1084
                      self | amazon | AWS Account ID
 
1085
 
 
1086
        :type restorable_by: str
 
1087
        :param restorable_by: If present, only the snapshots that are restorable
 
1088
                              by the specified account id will be returned.
 
1089
 
 
1090
        :rtype: list of L{boto.ec2.snapshot.Snapshot}
 
1091
        :return: The requested Snapshot objects
 
1092
        """
 
1093
        params = {}
 
1094
        if snapshot_ids:
 
1095
            self.build_list_params(params, snapshot_ids, 'SnapshotId')
 
1096
        if owner:
 
1097
            params['Owner'] = owner
 
1098
        if restorable_by:
 
1099
            params['RestorableBy'] = restorable_by
 
1100
        return self.get_list('DescribeSnapshots', params, [('item', Snapshot)])
 
1101
 
 
1102
    def create_snapshot(self, volume_id, description=None):
 
1103
        """
 
1104
        Create a snapshot of an existing EBS Volume.
 
1105
 
 
1106
        :type volume_id: str
 
1107
        :param volume_id: The ID of the volume to be snapshot'ed
 
1108
 
 
1109
        :type description: str
 
1110
        :param description: A description of the snapshot.  Limited to 255 characters.
 
1111
 
 
1112
        :rtype: bool
 
1113
        :return: True if successful
 
1114
        """
 
1115
        params = {'VolumeId' : volume_id}
 
1116
        if description:
 
1117
            params['Description'] = description[0:255]
 
1118
        return self.get_object('CreateSnapshot', params, Snapshot)
 
1119
 
 
1120
    def delete_snapshot(self, snapshot_id):
 
1121
        params = {'SnapshotId': snapshot_id}
 
1122
        return self.get_status('DeleteSnapshot', params)
 
1123
 
 
1124
    def get_snapshot_attribute(self, snapshot_id, attribute='createVolumePermission'):
 
1125
        """
 
1126
        Get information about an attribute of a snapshot.  Only one attribute can be
 
1127
        specified per call.
 
1128
 
 
1129
        :type snapshot_id: str
 
1130
        :param snapshot_id: The ID of the snapshot.
 
1131
 
 
1132
        :type attribute: str
 
1133
        :param attribute: The requested attribute.  Valid values are:
 
1134
                          createVolumePermission
 
1135
 
 
1136
        :rtype: list of L{boto.ec2.snapshotattribute.SnapshotAttribute}
 
1137
        :return: The requested Snapshot attribute
 
1138
        """
 
1139
        params = {'Attribute' : attribute}
 
1140
        if snapshot_id:
 
1141
            params['SnapshotId'] = snapshot_id
 
1142
        return self.get_object('DescribeSnapshotAttribute', params, SnapshotAttribute)
 
1143
 
 
1144
    def modify_snapshot_attribute(self, snapshot_id, attribute='createVolumePermission',
 
1145
                                  operation='add', user_ids=None, groups=None):
 
1146
        """
 
1147
        Changes an attribute of an image.
 
1148
 
 
1149
        :type snapshot_id: string
 
1150
        :param snapshot_id: The snapshot id you wish to change
 
1151
 
 
1152
        :type attribute: string
 
1153
        :param attribute: The attribute you wish to change.  Valid values are:
 
1154
                          createVolumePermission
 
1155
 
 
1156
        :type operation: string
 
1157
        :param operation: Either add or remove (this is required for changing
 
1158
                          snapshot ermissions)
 
1159
 
 
1160
        :type user_ids: list
 
1161
        :param user_ids: The Amazon IDs of users to add/remove attributes
 
1162
 
 
1163
        :type groups: list
 
1164
        :param groups: The groups to add/remove attributes.  The only valid
 
1165
                       value at this time is 'all'.
 
1166
 
 
1167
        """
 
1168
        params = {'SnapshotId' : snapshot_id,
 
1169
                  'Attribute' : attribute,
 
1170
                  'OperationType' : operation}
 
1171
        if user_ids:
 
1172
            self.build_list_params(params, user_ids, 'UserId')
 
1173
        if groups:
 
1174
            self.build_list_params(params, groups, 'UserGroup')
 
1175
        return self.get_status('ModifySnapshotAttribute', params)
 
1176
 
 
1177
    def reset_snapshot_attribute(self, snapshot_id, attribute='createVolumePermission'):
 
1178
        """
 
1179
        Resets an attribute of a snapshot to its default value.
 
1180
 
 
1181
        :type snapshot_id: string
 
1182
        :param snapshot_id: ID of the snapshot
 
1183
 
 
1184
        :type attribute: string
 
1185
        :param attribute: The attribute to reset
 
1186
 
 
1187
        :rtype: bool
 
1188
        :return: Whether the operation succeeded or not
 
1189
        """
 
1190
        params = {'SnapshotId' : snapshot_id,
 
1191
                  'Attribute' : attribute}
 
1192
        return self.get_status('ResetSnapshotAttribute', params)
 
1193
 
 
1194
    # Keypair methods
 
1195
 
 
1196
    def get_all_key_pairs(self, keynames=None):
 
1197
        """
 
1198
        Get all key pairs associated with your account.
 
1199
 
 
1200
        :type keynames: list
 
1201
        :param keynames: A list of the names of keypairs to retrieve.
 
1202
                         If not provided, all key pairs will be returned.
 
1203
 
 
1204
        :rtype: list
 
1205
        :return: A list of :class:`boto.ec2.keypair.KeyPair`
 
1206
        """
 
1207
        params = {}
 
1208
        if keynames:
 
1209
            self.build_list_params(params, keynames, 'KeyName')
 
1210
        return self.get_list('DescribeKeyPairs', params, [('item', KeyPair)])
 
1211
 
 
1212
    def get_key_pair(self, keyname):
 
1213
        """
 
1214
        Convenience method to retrieve a specific keypair (KeyPair).
 
1215
 
 
1216
        :type image_id: string
 
1217
        :param image_id: the ID of the Image to retrieve
 
1218
 
 
1219
        :rtype: :class:`boto.ec2.keypair.KeyPair`
 
1220
        :return: The KeyPair specified or None if it is not found
 
1221
        """
 
1222
        try:
 
1223
            return self.get_all_key_pairs(keynames=[keyname])[0]
 
1224
        except IndexError: # None of those key pairs available
 
1225
            return None
 
1226
 
 
1227
    def create_key_pair(self, key_name):
 
1228
        """
 
1229
        Create a new key pair for your account.
 
1230
        This will create the key pair within the region you
 
1231
        are currently connected to.
 
1232
 
 
1233
        :type key_name: string
 
1234
        :param key_name: The name of the new keypair
 
1235
 
 
1236
        :rtype: :class:`boto.ec2.keypair.KeyPair`
 
1237
        :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
 
1238
                 The material attribute of the new KeyPair object
 
1239
                 will contain the the unencrypted PEM encoded RSA private key.
 
1240
        """
 
1241
        params = {'KeyName':key_name}
 
1242
        return self.get_object('CreateKeyPair', params, KeyPair)
 
1243
 
 
1244
    def delete_key_pair(self, key_name):
 
1245
        """
 
1246
        Delete a key pair from your account.
 
1247
 
 
1248
        :type key_name: string
 
1249
        :param key_name: The name of the keypair to delete
 
1250
        """
 
1251
        params = {'KeyName':key_name}
 
1252
        return self.get_status('DeleteKeyPair', params)
 
1253
 
 
1254
    # SecurityGroup methods
 
1255
 
 
1256
    def get_all_security_groups(self, groupnames=None):
 
1257
        """
 
1258
        Get all security groups associated with your account in a region.
 
1259
 
 
1260
        :type groupnames: list
 
1261
        :param groupnames: A list of the names of security groups to retrieve.
 
1262
                           If not provided, all security groups will be returned.
 
1263
 
 
1264
        :rtype: list
 
1265
        :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
 
1266
        """
 
1267
        params = {}
 
1268
        if groupnames:
 
1269
            self.build_list_params(params, groupnames, 'GroupName')
 
1270
        return self.get_list('DescribeSecurityGroups', params, [('item', SecurityGroup)])
 
1271
 
 
1272
    def create_security_group(self, name, description):
 
1273
        """
 
1274
        Create a new security group for your account.
 
1275
        This will create the security group within the region you
 
1276
        are currently connected to.
 
1277
 
 
1278
        :type name: string
 
1279
        :param name: The name of the new security group
 
1280
 
 
1281
        :type description: string
 
1282
        :param description: The description of the new security group
 
1283
 
 
1284
        :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
 
1285
        :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
 
1286
        """
 
1287
        params = {'GroupName':name, 'GroupDescription':description}
 
1288
        group = self.get_object('CreateSecurityGroup', params, SecurityGroup)
 
1289
        group.name = name
 
1290
        group.description = description
 
1291
        return group
 
1292
 
 
1293
    def delete_security_group(self, name):
 
1294
        """
 
1295
        Delete a security group from your account.
 
1296
 
 
1297
        :type key_name: string
 
1298
        :param key_name: The name of the keypair to delete
 
1299
        """
 
1300
        params = {'GroupName':name}
 
1301
        return self.get_status('DeleteSecurityGroup', params)
 
1302
 
 
1303
    def authorize_security_group(self, group_name, src_security_group_name=None,
 
1304
                                 src_security_group_owner_id=None,
 
1305
                                 ip_protocol=None, from_port=None, to_port=None,
 
1306
                                 cidr_ip=None):
 
1307
        """
 
1308
        Add a new rule to an existing security group.
 
1309
        You need to pass in either src_security_group_name and
 
1310
        src_security_group_owner_id OR ip_protocol, from_port, to_port,
 
1311
        and cidr_ip.  In other words, either you are authorizing another
 
1312
        group or you are authorizing some ip-based rule.
 
1313
 
 
1314
        :type group_name: string
 
1315
        :param group_name: The name of the security group you are adding
 
1316
                           the rule to.
 
1317
 
 
1318
        :type src_security_group_name: string
 
1319
        :param src_security_group_name: The name of the security group you are
 
1320
                                        granting access to.
 
1321
 
 
1322
        :type src_security_group_owner_id: string
 
1323
        :param src_security_group_owner_id: The ID of the owner of the security group you are
 
1324
                                            granting access to.
 
1325
 
 
1326
        :type ip_protocol: string
 
1327
        :param ip_protocol: Either tcp | udp | icmp
 
1328
 
 
1329
        :type from_port: int
 
1330
        :param from_port: The beginning port number you are enabling
 
1331
 
 
1332
        :type to_port: int
 
1333
        :param to_port: The ending port number you are enabling
 
1334
 
 
1335
        :type to_port: string
 
1336
        :param to_port: The CIDR block you are providing access to.
 
1337
                        See http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
 
1338
 
 
1339
        :rtype: bool
 
1340
        :return: True if successful.
 
1341
        """
 
1342
        params = {'GroupName':group_name}
 
1343
        if src_security_group_name:
 
1344
            params['SourceSecurityGroupName'] = src_security_group_name
 
1345
        if src_security_group_owner_id:
 
1346
            params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
 
1347
        if ip_protocol:
 
1348
            params['IpProtocol'] = ip_protocol
 
1349
        if from_port:
 
1350
            params['FromPort'] = from_port
 
1351
        if to_port:
 
1352
            params['ToPort'] = to_port
 
1353
        if cidr_ip:
 
1354
            params['CidrIp'] = urllib.quote(cidr_ip)
 
1355
        return self.get_status('AuthorizeSecurityGroupIngress', params)
 
1356
 
 
1357
    def revoke_security_group(self, group_name, src_security_group_name=None,
 
1358
                              src_security_group_owner_id=None,
 
1359
                              ip_protocol=None, from_port=None, to_port=None,
 
1360
                              cidr_ip=None):
 
1361
        """
 
1362
        Remove an existing rule from an existing security group.
 
1363
        You need to pass in either src_security_group_name and
 
1364
        src_security_group_owner_id OR ip_protocol, from_port, to_port,
 
1365
        and cidr_ip.  In other words, either you are revoking another
 
1366
        group or you are revoking some ip-based rule.
 
1367
 
 
1368
        :type group_name: string
 
1369
        :param group_name: The name of the security group you are removing
 
1370
                           the rule from.
 
1371
 
 
1372
        :type src_security_group_name: string
 
1373
        :param src_security_group_name: The name of the security group you are
 
1374
                                        revoking access to.
 
1375
 
 
1376
        :type src_security_group_owner_id: string
 
1377
        :param src_security_group_owner_id: The ID of the owner of the security group you are
 
1378
                                            revoking access to.
 
1379
 
 
1380
        :type ip_protocol: string
 
1381
        :param ip_protocol: Either tcp | udp | icmp
 
1382
 
 
1383
        :type from_port: int
 
1384
        :param from_port: The beginning port number you are disabling
 
1385
 
 
1386
        :type to_port: int
 
1387
        :param to_port: The ending port number you are disabling
 
1388
 
 
1389
        :type to_port: string
 
1390
        :param to_port: The CIDR block you are revoking access to.
 
1391
                        See http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
 
1392
 
 
1393
        :rtype: bool
 
1394
        :return: True if successful.
 
1395
        """
 
1396
        params = {'GroupName':group_name}
 
1397
        if src_security_group_name:
 
1398
            params['SourceSecurityGroupName'] = src_security_group_name
 
1399
        if src_security_group_owner_id:
 
1400
            params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
 
1401
        if ip_protocol:
 
1402
            params['IpProtocol'] = ip_protocol
 
1403
        if from_port:
 
1404
            params['FromPort'] = from_port
 
1405
        if to_port:
 
1406
            params['ToPort'] = to_port
 
1407
        if cidr_ip:
 
1408
            params['CidrIp'] = cidr_ip
 
1409
        return self.get_status('RevokeSecurityGroupIngress', params)
 
1410
 
 
1411
    #
 
1412
    # Regions
 
1413
    #
 
1414
 
 
1415
    def get_all_regions(self):
 
1416
        """
 
1417
        Get all available regions for the EC2 service.
 
1418
 
 
1419
        :rtype: list
 
1420
        :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
 
1421
        """
 
1422
        return self.get_list('DescribeRegions', None, [('item', RegionInfo)])
 
1423
 
 
1424
    #
 
1425
    # Reservation methods
 
1426
    #
 
1427
 
 
1428
    def get_all_reserved_instances_offerings(self, reserved_instances_id=None,
 
1429
                                             instance_type=None,
 
1430
                                             availability_zone=None,
 
1431
                                             product_description=None):
 
1432
        """
 
1433
        Describes Reserved Instance offerings that are available for purchase.
 
1434
 
 
1435
        :type reserved_instances_id: str
 
1436
        :param reserved_instances_id: Displays Reserved Instances with the specified offering IDs.
 
1437
 
 
1438
        :type instance_type: str
 
1439
        :param instance_type: Displays Reserved Instances of the specified instance type.
 
1440
 
 
1441
        :type availability_zone: str
 
1442
        :param availability_zone: Displays Reserved Instances within the specified Availability Zone.
 
1443
 
 
1444
        :type product_description: str
 
1445
        :param product_description: Displays Reserved Instances with the specified product description.
 
1446
 
 
1447
        :rtype: list
 
1448
        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstancesOffering`
 
1449
        """
 
1450
        params = {}
 
1451
        if reserved_instances_id:
 
1452
            params['ReservedInstancesId'] = reserved_instances_id
 
1453
        if instance_type:
 
1454
            params['InstanceType'] = instance_type
 
1455
        if availability_zone:
 
1456
            params['AvailabilityZone'] = availability_zone
 
1457
        if product_description:
 
1458
            params['ProductDescription'] = product_description
 
1459
 
 
1460
        return self.get_list('DescribeReservedInstancesOfferings',
 
1461
                             params, [('item', ReservedInstancesOffering)])
 
1462
 
 
1463
    def get_all_reserved_instances(self, reserved_instances_id=None):
 
1464
        """
 
1465
        Describes Reserved Instance offerings that are available for purchase.
 
1466
 
 
1467
        :type reserved_instance_ids: list
 
1468
        :param reserved_instance_ids: A list of the reserved instance ids that will be returned.
 
1469
                                      If not provided, all reserved instances will be returned.
 
1470
 
 
1471
        :rtype: list
 
1472
        :return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
 
1473
        """
 
1474
        params = {}
 
1475
        if reserved_instances_id:
 
1476
            self.build_list_params(params, reserved_instances_id, 'ReservedInstancesId')
 
1477
        return self.get_list('DescribeReservedInstances',
 
1478
                             params, [('item', ReservedInstance)])
 
1479
 
 
1480
    def purchase_reserved_instance_offering(self, reserved_instances_offering_id,
 
1481
                                            instance_count=1):
 
1482
        """
 
1483
        Purchase a Reserved Instance for use with your account.
 
1484
        ** CAUTION **
 
1485
        This request can result in large amounts of money being charged to your
 
1486
        AWS account.  Use with caution!
 
1487
 
 
1488
        :type reserved_instances_offering_id: string
 
1489
        :param reserved_instances_offering_id: The offering ID of the Reserved
 
1490
                                               Instance to purchase
 
1491
 
 
1492
        :type instance_count: int
 
1493
        :param instance_count: The number of Reserved Instances to purchase.
 
1494
                               Default value is 1.
 
1495
 
 
1496
        :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
 
1497
        :return: The newly created Reserved Instance
 
1498
        """
 
1499
        params = {'ReservedInstancesOfferingId' : reserved_instances_offering_id,
 
1500
                  'InstanceCount' : instance_count}
 
1501
        return self.get_object('PurchaseReservedInstancesOffering', params, ReservedInstance)
 
1502
 
 
1503
    #
 
1504
    # Monitoring
 
1505
    #
 
1506
 
 
1507
    def monitor_instance(self, instance_id):
 
1508
        """
 
1509
        Enable CloudWatch monitoring for the supplied instance.
 
1510
 
 
1511
        :type instance_id: string
 
1512
        :param instance_id: The instance id
 
1513
 
 
1514
        :rtype: list
 
1515
        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
 
1516
        """
 
1517
        params = {'InstanceId' : instance_id}
 
1518
        return self.get_list('MonitorInstances', params, [('item', InstanceInfo)])
 
1519
 
 
1520
    def unmonitor_instance(self, instance_id):
 
1521
        """
 
1522
        Disable CloudWatch monitoring for the supplied instance.
 
1523
 
 
1524
        :type instance_id: string
 
1525
        :param instance_id: The instance id
 
1526
 
 
1527
        :rtype: list
 
1528
        :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
 
1529
        """
 
1530
        params = {'InstanceId' : instance_id}
 
1531
        return self.get_list('UnmonitorInstances', params, [('item', InstanceInfo)])
 
1532
 
 
1533
    # 
 
1534
    # Bundle Windows Instances
 
1535
    #
 
1536
 
 
1537
    def bundle_instance(self, instance_id,
 
1538
                        s3_bucket, 
 
1539
                        s3_prefix,
 
1540
                        s3_upload_policy):
 
1541
        """
 
1542
        Bundle Windows instance.
 
1543
 
 
1544
        :type instance_id: string
 
1545
        :param instance_id: The instance id
 
1546
 
 
1547
        :type s3_bucket: string
 
1548
        :param s3_bucket: The bucket in which the AMI should be stored.
 
1549
 
 
1550
        :type s3_prefix: string
 
1551
        :param s3_prefix: The beginning of the file name for the AMI.
 
1552
 
 
1553
        :type s3_upload_policy: string
 
1554
        :param s3_upload_policy: Base64 encoded policy that specifies condition and permissions
 
1555
                                 for Amazon EC2 to upload the user's image into Amazon S3.
 
1556
        """
 
1557
 
 
1558
        params = {'InstanceId' : instance_id,
 
1559
                  'Storage.S3.Bucket' : s3_bucket,
 
1560
                  'Storage.S3.Prefix' : s3_prefix,
 
1561
                  'Storage.S3.UploadPolicy' : s3_upload_policy}
 
1562
        params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
 
1563
        local_hmac = self.hmac.copy()
 
1564
        local_hmac.update(s3_upload_policy)
 
1565
        s3_upload_policy_signature = base64.b64encode(local_hmac.digest())
 
1566
        params['Storage.S3.UploadPolicySignature'] = s3_upload_policy_signature
 
1567
        return self.get_object('BundleInstance', params, BundleInstanceTask) 
 
1568
 
 
1569
    def get_all_bundle_tasks(self, bundle_ids=None):
 
1570
        """
 
1571
        Retrieve current bundling tasks. If no bundle id is specified, all tasks are retrieved.
 
1572
 
 
1573
        :type bundle_ids: list
 
1574
        :param bundle_ids: A list of strings containing identifiers for 
 
1575
                           previously created bundling tasks. 
 
1576
        """
 
1577
 
 
1578
        params = {}
 
1579
        if bundle_ids:
 
1580
            self.build_list_params(params, bundle_ids, 'BundleId')
 
1581
        return self.get_list('DescribeBundleTasks', params, [('item', BundleInstanceTask)])
 
1582
 
 
1583
    def cancel_bundle_task(self, bundle_id):
 
1584
        """
 
1585
        Cancel a previously submitted bundle task
 
1586
 
 
1587
        :type bundle_id: string
 
1588
        :param bundle_id: The identifier of the bundle task to cancel.
 
1589
        """                        
 
1590
 
 
1591
        params = {'BundleId' : bundle_id}
 
1592
        return self.get_object('CancelBundleTask', params, BundleInstanceTask)
 
1593
 
 
1594
    def get_password_data(self, instance_id):
 
1595
        """
 
1596
        Get encrypted administrator password for a Windows instance.
 
1597
 
 
1598
        :type instance_id: string
 
1599
        :param instance_id: The identifier of the instance to retrieve the password for.
 
1600
        """
 
1601
 
 
1602
        params = {'InstanceId' : instance_id}
 
1603
        rs = self.get_object('GetPasswordData', params, ResultSet)
 
1604
        return rs.passwordData
 
1605