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

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

Issue 8386013: Merging in latest boto. (Closed) Base URL: svn://svn.chromium.org/boto
Patch Set: Redoing vendor drop by deleting and then merging. Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « boto/ec2/cloudwatch/metric.py ('k') | boto/ec2/ec2object.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. 2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
3 # 3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a 4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the 5 # copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including 6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish, dis- 7 # without limitation the rights to use, copy, modify, merge, publish, dis-
8 # tribute, sublicense, and/or sell copies of the Software, and to permit 8 # tribute, sublicense, and/or sell copies of the Software, and to permit
9 # persons to whom the Software is furnished to do so, subject to the fol- 9 # persons to whom the Software is furnished to do so, subject to the fol-
10 # lowing conditions: 10 # lowing conditions:
(...skipping 14 matching lines...) Expand all
25 """ 25 """
26 26
27 import base64 27 import base64
28 import warnings 28 import warnings
29 from datetime import datetime 29 from datetime import datetime
30 from datetime import timedelta 30 from datetime import timedelta
31 import boto 31 import boto
32 from boto.connection import AWSQueryConnection 32 from boto.connection import AWSQueryConnection
33 from boto.resultset import ResultSet 33 from boto.resultset import ResultSet
34 from boto.ec2.image import Image, ImageAttribute 34 from boto.ec2.image import Image, ImageAttribute
35 from boto.ec2.instance import Reservation, Instance, ConsoleOutput, InstanceAttr ibute 35 from boto.ec2.instance import Reservation, Instance
36 from boto.ec2.instance import ConsoleOutput, InstanceAttribute
36 from boto.ec2.keypair import KeyPair 37 from boto.ec2.keypair import KeyPair
37 from boto.ec2.address import Address 38 from boto.ec2.address import Address
38 from boto.ec2.volume import Volume 39 from boto.ec2.volume import Volume
39 from boto.ec2.snapshot import Snapshot 40 from boto.ec2.snapshot import Snapshot
40 from boto.ec2.snapshot import SnapshotAttribute 41 from boto.ec2.snapshot import SnapshotAttribute
41 from boto.ec2.zone import Zone 42 from boto.ec2.zone import Zone
42 from boto.ec2.securitygroup import SecurityGroup 43 from boto.ec2.securitygroup import SecurityGroup
43 from boto.ec2.regioninfo import RegionInfo 44 from boto.ec2.regioninfo import RegionInfo
44 from boto.ec2.instanceinfo import InstanceInfo 45 from boto.ec2.instanceinfo import InstanceInfo
45 from boto.ec2.reservedinstance import ReservedInstancesOffering, ReservedInstanc e 46 from boto.ec2.reservedinstance import ReservedInstancesOffering
47 from boto.ec2.reservedinstance import ReservedInstance
46 from boto.ec2.spotinstancerequest import SpotInstanceRequest 48 from boto.ec2.spotinstancerequest import SpotInstanceRequest
47 from boto.ec2.spotpricehistory import SpotPriceHistory 49 from boto.ec2.spotpricehistory import SpotPriceHistory
48 from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription 50 from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
49 from boto.ec2.bundleinstance import BundleInstanceTask 51 from boto.ec2.bundleinstance import BundleInstanceTask
50 from boto.ec2.placementgroup import PlacementGroup 52 from boto.ec2.placementgroup import PlacementGroup
51 from boto.ec2.tag import Tag 53 from boto.ec2.tag import Tag
52 from boto.exception import EC2ResponseError 54 from boto.exception import EC2ResponseError
53 55
54 #boto.set_stream_logger('ec2') 56 #boto.set_stream_logger('ec2')
55 57
56 class EC2Connection(AWSQueryConnection): 58 class EC2Connection(AWSQueryConnection):
57 59
58 APIVersion = boto.config.get('Boto', 'ec2_version', '2010-08-31') 60 APIVersion = boto.config.get('Boto', 'ec2_version', '2011-01-01')
59 DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1') 61 DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
60 DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint', 62 DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
61 'ec2.amazonaws.com') 63 'ec2.amazonaws.com')
62 ResponseError = EC2ResponseError 64 ResponseError = EC2ResponseError
63 65
64 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, 66 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
65 is_secure=True, host=None, port=None, proxy=None, proxy_port=No ne, 67 is_secure=True, host=None, port=None,
68 proxy=None, proxy_port=None,
66 proxy_user=None, proxy_pass=None, debug=0, 69 proxy_user=None, proxy_pass=None, debug=0,
67 https_connection_factory=None, region=None, path='/'): 70 https_connection_factory=None, region=None, path='/',
71 api_version=None, security_token=None):
68 """ 72 """
69 Init method to create a new connection to EC2. 73 Init method to create a new connection to EC2.
70 74
71 B{Note:} The host argument is overridden by the host specified in the 75 B{Note:} The host argument is overridden by the host specified in the
72 boto configuration file. 76 boto configuration file.
73 """ 77 """
74 if not region: 78 if not region:
75 region = RegionInfo(self, self.DefaultRegionName, 79 region = RegionInfo(self, self.DefaultRegionName,
76 self.DefaultRegionEndpoint) 80 self.DefaultRegionEndpoint)
77 self.region = region 81 self.region = region
78 AWSQueryConnection.__init__(self, aws_access_key_id, 82 AWSQueryConnection.__init__(self, aws_access_key_id,
79 aws_secret_access_key, 83 aws_secret_access_key,
80 is_secure, port, proxy, proxy_port, 84 is_secure, port, proxy, proxy_port,
81 proxy_user, proxy_pass, 85 proxy_user, proxy_pass,
82 self.region.endpoint, debug, 86 self.region.endpoint, debug,
83 https_connection_factory, path) 87 https_connection_factory, path,
88 security_token)
89 if api_version:
90 self.APIVersion = api_version
84 91
85 def _required_auth_capability(self): 92 def _required_auth_capability(self):
86 return ['ec2'] 93 return ['ec2']
87 94
88 def get_params(self): 95 def get_params(self):
89 """ 96 """
90 Returns a dictionary containing the value of of all of the keyword 97 Returns a dictionary containing the value of of all of the keyword
91 arguments passed when constructing this connection. 98 arguments passed when constructing this connection.
92 """ 99 """
93 param_names = ['aws_access_key_id', 'aws_secret_access_key', 'is_secure' , 100 param_names = ['aws_access_key_id', 'aws_secret_access_key',
94 'port', 'proxy', 'proxy_port', 'proxy_user', 'proxy_pass' , 101 'is_secure', 'port', 'proxy', 'proxy_port',
102 'proxy_user', 'proxy_pass',
95 'debug', 'https_connection_factory'] 103 'debug', 'https_connection_factory']
96 params = {} 104 params = {}
97 for name in param_names: 105 for name in param_names:
98 params[name] = getattr(self, name) 106 params[name] = getattr(self, name)
99 return params 107 return params
100 108
101 def build_filter_params(self, params, filters): 109 def build_filter_params(self, params, filters):
102 i = 1 110 i = 1
103 for name in filters: 111 for name in filters:
104 aws_name = name.replace('_', '-') 112 aws_name = name
113 if not aws_name.startswith('tag:'):
114 aws_name = name.replace('_', '-')
105 params['Filter.%d.Name' % i] = aws_name 115 params['Filter.%d.Name' % i] = aws_name
106 value = filters[name] 116 value = filters[name]
107 if not isinstance(value, list): 117 if not isinstance(value, list):
108 value = [value] 118 value = [value]
109 j = 1 119 j = 1
110 for v in value: 120 for v in value:
111 params['Filter.%d.Value.%d' % (i,j)] = v 121 params['Filter.%d.Value.%d' % (i,j)] = v
112 j += 1 122 j += 1
113 i += 1 123 i += 1
114 124
(...skipping 29 matching lines...) Expand all
144 """ 154 """
145 params = {} 155 params = {}
146 if image_ids: 156 if image_ids:
147 self.build_list_params(params, image_ids, 'ImageId') 157 self.build_list_params(params, image_ids, 'ImageId')
148 if owners: 158 if owners:
149 self.build_list_params(params, owners, 'Owner') 159 self.build_list_params(params, owners, 'Owner')
150 if executable_by: 160 if executable_by:
151 self.build_list_params(params, executable_by, 'ExecutableBy') 161 self.build_list_params(params, executable_by, 'ExecutableBy')
152 if filters: 162 if filters:
153 self.build_filter_params(params, filters) 163 self.build_filter_params(params, filters)
154 return self.get_list('DescribeImages', params, [('item', Image)], verb=' POST') 164 return self.get_list('DescribeImages', params,
165 [('item', Image)], verb='POST')
155 166
156 def get_all_kernels(self, kernel_ids=None, owners=None): 167 def get_all_kernels(self, kernel_ids=None, owners=None):
157 """ 168 """
158 Retrieve all the EC2 kernels available on your account. 169 Retrieve all the EC2 kernels available on your account.
159 Constructs a filter to allow the processing to happen server side. 170 Constructs a filter to allow the processing to happen server side.
160 171
161 :type kernel_ids: list 172 :type kernel_ids: list
162 :param kernel_ids: A list of strings with the image IDs wanted 173 :param kernel_ids: A list of strings with the image IDs wanted
163 174
164 :type owners: list 175 :type owners: list
165 :param owners: A list of owner IDs 176 :param owners: A list of owner IDs
166 177
167 :rtype: list 178 :rtype: list
168 :return: A list of :class:`boto.ec2.image.Image` 179 :return: A list of :class:`boto.ec2.image.Image`
169 """ 180 """
170 params = {} 181 params = {}
171 if kernel_ids: 182 if kernel_ids:
172 self.build_list_params(params, kernel_ids, 'ImageId') 183 self.build_list_params(params, kernel_ids, 'ImageId')
173 if owners: 184 if owners:
174 self.build_list_params(params, owners, 'Owner') 185 self.build_list_params(params, owners, 'Owner')
175 filter = {'image-type' : 'kernel'} 186 filter = {'image-type' : 'kernel'}
176 self.build_filter_params(params, filter) 187 self.build_filter_params(params, filter)
177 return self.get_list('DescribeImages', params, [('item', Image)], verb=' POST') 188 return self.get_list('DescribeImages', params,
189 [('item', Image)], verb='POST')
178 190
179 def get_all_ramdisks(self, ramdisk_ids=None, owners=None): 191 def get_all_ramdisks(self, ramdisk_ids=None, owners=None):
180 """ 192 """
181 Retrieve all the EC2 ramdisks available on your account. 193 Retrieve all the EC2 ramdisks available on your account.
182 Constructs a filter to allow the processing to happen server side. 194 Constructs a filter to allow the processing to happen server side.
183 195
184 :type ramdisk_ids: list 196 :type ramdisk_ids: list
185 :param ramdisk_ids: A list of strings with the image IDs wanted 197 :param ramdisk_ids: A list of strings with the image IDs wanted
186 198
187 :type owners: list 199 :type owners: list
188 :param owners: A list of owner IDs 200 :param owners: A list of owner IDs
189 201
190 :rtype: list 202 :rtype: list
191 :return: A list of :class:`boto.ec2.image.Image` 203 :return: A list of :class:`boto.ec2.image.Image`
192 """ 204 """
193 params = {} 205 params = {}
194 if ramdisk_ids: 206 if ramdisk_ids:
195 self.build_list_params(params, ramdisk_ids, 'ImageId') 207 self.build_list_params(params, ramdisk_ids, 'ImageId')
196 if owners: 208 if owners:
197 self.build_list_params(params, owners, 'Owner') 209 self.build_list_params(params, owners, 'Owner')
198 filter = {'image-type' : 'ramdisk'} 210 filter = {'image-type' : 'ramdisk'}
199 self.build_filter_params(params, filter) 211 self.build_filter_params(params, filter)
200 return self.get_list('DescribeImages', params, [('item', Image)], verb=' POST') 212 return self.get_list('DescribeImages', params,
213 [('item', Image)], verb='POST')
201 214
202 def get_image(self, image_id): 215 def get_image(self, image_id):
203 """ 216 """
204 Shortcut method to retrieve a specific image (AMI). 217 Shortcut method to retrieve a specific image (AMI).
205 218
206 :type image_id: string 219 :type image_id: string
207 :param image_id: the ID of the Image to retrieve 220 :param image_id: the ID of the Image to retrieve
208 221
209 :rtype: :class:`boto.ec2.image.Image` 222 :rtype: :class:`boto.ec2.image.Image`
210 :return: The EC2 Image specified or None if the image is not found 223 :return: The EC2 Image specified or None if the image is not found
211 """ 224 """
212 try: 225 try:
213 return self.get_all_images(image_ids=[image_id])[0] 226 return self.get_all_images(image_ids=[image_id])[0]
214 except IndexError: # None of those images available 227 except IndexError: # None of those images available
215 return None 228 return None
216 229
217 def register_image(self, name=None, description=None, image_location=None, 230 def register_image(self, name=None, description=None, image_location=None,
218 architecture=None, kernel_id=None, ramdisk_id=None, 231 architecture=None, kernel_id=None, ramdisk_id=None,
219 root_device_name=None, block_device_map=None): 232 root_device_name=None, block_device_map=None):
220 """ 233 """
221 Register an image. 234 Register an image.
222 235
223 :type name: string 236 :type name: string
224 :param name: The name of the AMI. Valid only for EBS-based images. 237 :param name: The name of the AMI. Valid only for EBS-based images.
225 238
226 :type description: string 239 :type description: string
227 :param description: The description of the AMI. 240 :param description: The description of the AMI.
228 241
229 :type image_location: string 242 :type image_location: string
230 :param image_location: Full path to your AMI manifest in Amazon S3 stora ge. 243 :param image_location: Full path to your AMI manifest in
244 Amazon S3 storage.
231 Only used for S3-based AMI's. 245 Only used for S3-based AMI's.
232 246
233 :type architecture: string 247 :type architecture: string
234 :param architecture: The architecture of the AMI. Valid choices are: 248 :param architecture: The architecture of the AMI. Valid choices are:
235 i386 | x86_64 249 i386 | x86_64
236 250
237 :type kernel_id: string 251 :type kernel_id: string
238 :param kernel_id: The ID of the kernel with which to launch the instance s 252 :param kernel_id: The ID of the kernel with which to launch
253 the instances
239 254
240 :type root_device_name: string 255 :type root_device_name: string
241 :param root_device_name: The root device name (e.g. /dev/sdh) 256 :param root_device_name: The root device name (e.g. /dev/sdh)
242 257
243 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM apping` 258 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM apping`
244 :param block_device_map: A BlockDeviceMapping data structure 259 :param block_device_map: A BlockDeviceMapping data structure
245 describing the EBS volumes associated 260 describing the EBS volumes associated
246 with the Image. 261 with the Image.
247 262
248 :rtype: string 263 :rtype: string
(...skipping 13 matching lines...) Expand all
262 if image_location: 277 if image_location:
263 params['ImageLocation'] = image_location 278 params['ImageLocation'] = image_location
264 if root_device_name: 279 if root_device_name:
265 params['RootDeviceName'] = root_device_name 280 params['RootDeviceName'] = root_device_name
266 if block_device_map: 281 if block_device_map:
267 block_device_map.build_list_params(params) 282 block_device_map.build_list_params(params)
268 rs = self.get_object('RegisterImage', params, ResultSet, verb='POST') 283 rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
269 image_id = getattr(rs, 'imageId', None) 284 image_id = getattr(rs, 'imageId', None)
270 return image_id 285 return image_id
271 286
272 def deregister_image(self, image_id): 287 def deregister_image(self, image_id, delete_snapshot=False):
273 """ 288 """
274 Unregister an AMI. 289 Unregister an AMI.
275 290
276 :type image_id: string 291 :type image_id: string
277 :param image_id: the ID of the Image to unregister 292 :param image_id: the ID of the Image to unregister
278 293
294 :type delete_snapshot: bool
295 :param delete_snapshot: Set to True if we should delete the
296 snapshot associated with an EBS volume
297 mounted at /dev/sda1
298
279 :rtype: bool 299 :rtype: bool
280 :return: True if successful 300 :return: True if successful
281 """ 301 """
282 return self.get_status('DeregisterImage', {'ImageId':image_id}, verb='PO ST') 302 snapshot_id = None
303 if delete_snapshot:
304 image = self.get_image(image_id)
305 for key in image.block_device_mapping:
306 if key == "/dev/sda1":
307 snapshot_id = image.block_device_mapping[key].snapshot_id
308 break
283 309
284 def create_image(self, instance_id, name, description=None, no_reboot=False) : 310 result = self.get_status('DeregisterImage',
311 {'ImageId':image_id}, verb='POST')
312 if result and snapshot_id:
313 return result and self.delete_snapshot(snapshot_id)
314 return result
315
316 def create_image(self, instance_id, name,
317 description=None, no_reboot=False):
285 """ 318 """
286 Will create an AMI from the instance in the running or stopped 319 Will create an AMI from the instance in the running or stopped
287 state. 320 state.
288 321
289 :type instance_id: string 322 :type instance_id: string
290 :param instance_id: the ID of the instance to image. 323 :param instance_id: the ID of the instance to image.
291 324
292 :type name: string 325 :type name: string
293 :param name: The name of the new image 326 :param name: The name of the new image
294 327
295 :type description: string 328 :type description: string
296 :param description: An optional human-readable string describing 329 :param description: An optional human-readable string describing
297 the contents and purpose of the AMI. 330 the contents and purpose of the AMI.
298 331
299 :type no_reboot: bool 332 :type no_reboot: bool
300 :param no_reboot: An optional flag indicating that the bundling process 333 :param no_reboot: An optional flag indicating that the bundling process
301 should not attempt to shutdown the instance before 334 should not attempt to shutdown the instance before
302 bundling. If this flag is True, the responsibility 335 bundling. If this flag is True, the responsibility
303 of maintaining file system integrity is left to the 336 of maintaining file system integrity is left to the
304 owner of the instance. 337 owner of the instance.
305 338
306 :rtype: string 339 :rtype: string
307 :return: The new image id 340 :return: The new image id
308 """ 341 """
309 params = {'InstanceId' : instance_id, 342 params = {'InstanceId' : instance_id,
310 'Name' : name} 343 'Name' : name}
311 if description: 344 if description:
312 params['Description'] = description 345 params['Description'] = description
313 if no_reboot: 346 if no_reboot:
314 params['NoReboot'] = 'true' 347 params['NoReboot'] = 'true'
315 img = self.get_object('CreateImage', params, Image, verb='POST') 348 img = self.get_object('CreateImage', params, Image, verb='POST')
316 return img.id 349 return img.id
317 350
318 # ImageAttribute methods 351 # ImageAttribute methods
319 352
320 def get_image_attribute(self, image_id, attribute='launchPermission'): 353 def get_image_attribute(self, image_id, attribute='launchPermission'):
321 """ 354 """
322 Gets an attribute from an image. 355 Gets an attribute from an image.
323 356
324 :type image_id: string 357 :type image_id: string
325 :param image_id: The Amazon image id for which you want info about 358 :param image_id: The Amazon image id for which you want info about
326 359
327 :type attribute: string 360 :type attribute: string
328 :param attribute: The attribute you need information about. 361 :param attribute: The attribute you need information about.
329 Valid choices are: 362 Valid choices are:
330 * launchPermission 363 * launchPermission
331 * productCodes 364 * productCodes
332 * blockDeviceMapping 365 * blockDeviceMapping
333 366
334 :rtype: :class:`boto.ec2.image.ImageAttribute` 367 :rtype: :class:`boto.ec2.image.ImageAttribute`
335 :return: An ImageAttribute object representing the value of the 368 :return: An ImageAttribute object representing the value of the
336 attribute requested 369 attribute requested
337 """ 370 """
338 params = {'ImageId' : image_id, 371 params = {'ImageId' : image_id,
339 'Attribute' : attribute} 372 'Attribute' : attribute}
340 return self.get_object('DescribeImageAttribute', params, ImageAttribute, verb='POST') 373 return self.get_object('DescribeImageAttribute', params,
374 ImageAttribute, verb='POST')
341 375
342 def modify_image_attribute(self, image_id, attribute='launchPermission', 376 def modify_image_attribute(self, image_id, attribute='launchPermission',
343 operation='add', user_ids=None, groups=None, 377 operation='add', user_ids=None, groups=None,
344 product_codes=None): 378 product_codes=None):
345 """ 379 """
346 Changes an attribute of an image. 380 Changes an attribute of an image.
347 381
348 :type image_id: string 382 :type image_id: string
349 :param image_id: The image id you wish to change 383 :param image_id: The image id you wish to change
350 384
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 being performed. Check the EC2 API guide 447 being performed. Check the EC2 API guide
414 for details. 448 for details.
415 449
416 :rtype: list 450 :rtype: list
417 :return: A list of :class:`boto.ec2.instance.Reservation` 451 :return: A list of :class:`boto.ec2.instance.Reservation`
418 """ 452 """
419 params = {} 453 params = {}
420 if instance_ids: 454 if instance_ids:
421 self.build_list_params(params, instance_ids, 'InstanceId') 455 self.build_list_params(params, instance_ids, 'InstanceId')
422 if filters: 456 if filters:
457 if 'group-id' in filters:
458 warnings.warn("The group-id filter now requires a security "
459 "group identifier (sg-*) instead of a group "
460 "name. To filter by group name use the "
461 "'group-name' filter instead.", UserWarning)
423 self.build_filter_params(params, filters) 462 self.build_filter_params(params, filters)
424 return self.get_list('DescribeInstances', params, 463 return self.get_list('DescribeInstances', params,
425 [('item', Reservation)], verb='POST') 464 [('item', Reservation)], verb='POST')
426 465
427 def run_instances(self, image_id, min_count=1, max_count=1, 466 def run_instances(self, image_id, min_count=1, max_count=1,
428 key_name=None, security_groups=None, 467 key_name=None, security_groups=None,
429 user_data=None, addressing_type=None, 468 user_data=None, addressing_type=None,
430 instance_type='m1.small', placement=None, 469 instance_type='m1.small', placement=None,
431 kernel_id=None, ramdisk_id=None, 470 kernel_id=None, ramdisk_id=None,
432 monitoring_enabled=False, subnet_id=None, 471 monitoring_enabled=False, subnet_id=None,
433 block_device_map=None, 472 block_device_map=None,
434 disable_api_termination=False, 473 disable_api_termination=False,
435 instance_initiated_shutdown_behavior=None, 474 instance_initiated_shutdown_behavior=None,
436 private_ip_address=None, 475 private_ip_address=None,
437 placement_group=None, client_token=None): 476 placement_group=None, client_token=None,
477 security_group_ids=None):
438 """ 478 """
439 Runs an image on EC2. 479 Runs an image on EC2.
440 480
441 :type image_id: string 481 :type image_id: string
442 :param image_id: The ID of the image to run 482 :param image_id: The ID of the image to run
443 483
444 :type min_count: int 484 :type min_count: int
445 :param min_count: The minimum number of instances to launch 485 :param min_count: The minimum number of instances to launch
446 486
447 :type max_count: int 487 :type max_count: int
448 :param max_count: The maximum number of instances to launch 488 :param max_count: The maximum number of instances to launch
449 489
450 :type key_name: string 490 :type key_name: string
451 :param key_name: The name of the key pair with which to launch instances 491 :param key_name: The name of the key pair with which to launch instances
452 492
453 :type security_groups: list of strings 493 :type security_groups: list of strings
454 :param security_groups: The names of the security groups with which to 494 :param security_groups: The names of the security groups with which to
455 associate instances 495 associate instances
456 496
457 :type user_data: string 497 :type user_data: string
458 :param user_data: The user data passed to the launched instances 498 :param user_data: The user data passed to the launched instances
459 499
460 :type instance_type: string 500 :type instance_type: string
461 :param instance_type: The type of instance to run: 501 :param instance_type: The type of instance to run:
462 502
463 * m1.small 503 * m1.small
464 * m1.large 504 * m1.large
465 * m1.xlarge 505 * m1.xlarge
466 * c1.medium 506 * c1.medium
467 * c1.xlarge 507 * c1.xlarge
468 * m2.xlarge 508 * m2.xlarge
469 * m2.2xlarge 509 * m2.2xlarge
470 * m2.4xlarge 510 * m2.4xlarge
471 * cc1.4xlarge 511 * cc1.4xlarge
472 * t1.micro 512 * t1.micro
(...skipping 27 matching lines...) Expand all
500 describing the EBS volumes associated 540 describing the EBS volumes associated
501 with the Image. 541 with the Image.
502 542
503 :type disable_api_termination: bool 543 :type disable_api_termination: bool
504 :param disable_api_termination: If True, the instances will be locked 544 :param disable_api_termination: If True, the instances will be locked
505 and will not be able to be terminated 545 and will not be able to be terminated
506 via the API. 546 via the API.
507 547
508 :type instance_initiated_shutdown_behavior: string 548 :type instance_initiated_shutdown_behavior: string
509 :param instance_initiated_shutdown_behavior: Specifies whether the 549 :param instance_initiated_shutdown_behavior: Specifies whether the
510 instance's EBS volumes are 550 instance stops or
511 stopped (i.e. detached) or 551 terminates on
512 terminated (i.e. deleted) 552 instance-initiated
513 when the instance is 553 shutdown.
514 shutdown by the 554 Valid values are:
515 owner. Valid values are: 555
516
517 * stop 556 * stop
518 * terminate 557 * terminate
519 558
520 :type placement_group: string 559 :type placement_group: string
521 :param placement_group: If specified, this is the name of the placement 560 :param placement_group: If specified, this is the name of the placement
522 group in which the instance(s) will be launched. 561 group in which the instance(s) will be launched.
523 562
524 :type client_token: string 563 :type client_token: string
525 :param client_token: Unique, case-sensitive identifier you provide 564 :param client_token: Unique, case-sensitive identifier you provide
526 to ensure idempotency of the request. 565 to ensure idempotency of the request.
527 Maximum 64 ASCII characters 566 Maximum 64 ASCII characters
528 567
529 :rtype: Reservation 568 :rtype: Reservation
530 :return: The :class:`boto.ec2.instance.Reservation` associated with 569 :return: The :class:`boto.ec2.instance.Reservation` associated with
531 the request for machines 570 the request for machines
571
572 :type security_group_ids: list of strings
573 :param security_group_ids: The ID of the VPC security groups with
574 which to associate instances
532 """ 575 """
533 params = {'ImageId':image_id, 576 params = {'ImageId':image_id,
534 'MinCount':min_count, 577 'MinCount':min_count,
535 'MaxCount': max_count} 578 'MaxCount': max_count}
536 if key_name: 579 if key_name:
537 params['KeyName'] = key_name 580 params['KeyName'] = key_name
581 if security_group_ids:
582 l = []
583 for group in security_group_ids:
584 if isinstance(group, SecurityGroup):
585 l.append(group.name)
586 else:
587 l.append(group)
588 self.build_list_params(params, l, 'SecurityGroupId')
538 if security_groups: 589 if security_groups:
539 l = [] 590 l = []
540 for group in security_groups: 591 for group in security_groups:
541 if isinstance(group, SecurityGroup): 592 if isinstance(group, SecurityGroup):
542 l.append(group.name) 593 l.append(group.name)
543 else: 594 else:
544 l.append(group) 595 l.append(group)
545 self.build_list_params(params, l, 'SecurityGroup') 596 self.build_list_params(params, l, 'SecurityGroup')
546 if user_data: 597 if user_data:
547 params['UserData'] = base64.b64encode(user_data) 598 params['UserData'] = base64.b64encode(user_data)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 631
581 :type instance_ids: list 632 :type instance_ids: list
582 :param instance_ids: A list of strings of the Instance IDs to terminate 633 :param instance_ids: A list of strings of the Instance IDs to terminate
583 634
584 :rtype: list 635 :rtype: list
585 :return: A list of the instances terminated 636 :return: A list of the instances terminated
586 """ 637 """
587 params = {} 638 params = {}
588 if instance_ids: 639 if instance_ids:
589 self.build_list_params(params, instance_ids, 'InstanceId') 640 self.build_list_params(params, instance_ids, 'InstanceId')
590 return self.get_list('TerminateInstances', params, [('item', Instance)], verb='POST') 641 return self.get_list('TerminateInstances', params,
642 [('item', Instance)], verb='POST')
591 643
592 def stop_instances(self, instance_ids=None, force=False): 644 def stop_instances(self, instance_ids=None, force=False):
593 """ 645 """
594 Stop the instances specified 646 Stop the instances specified
595 647
596 :type instance_ids: list 648 :type instance_ids: list
597 :param instance_ids: A list of strings of the Instance IDs to stop 649 :param instance_ids: A list of strings of the Instance IDs to stop
598 650
599 :type force: bool 651 :type force: bool
600 :param force: Forces the instance to stop 652 :param force: Forces the instance to stop
601 653
602 :rtype: list 654 :rtype: list
603 :return: A list of the instances stopped 655 :return: A list of the instances stopped
604 """ 656 """
605 params = {} 657 params = {}
606 if force: 658 if force:
607 params['Force'] = 'true' 659 params['Force'] = 'true'
608 if instance_ids: 660 if instance_ids:
609 self.build_list_params(params, instance_ids, 'InstanceId') 661 self.build_list_params(params, instance_ids, 'InstanceId')
610 return self.get_list('StopInstances', params, [('item', Instance)], verb ='POST') 662 return self.get_list('StopInstances', params,
663 [('item', Instance)], verb='POST')
611 664
612 def start_instances(self, instance_ids=None): 665 def start_instances(self, instance_ids=None):
613 """ 666 """
614 Start the instances specified 667 Start the instances specified
615 668
616 :type instance_ids: list 669 :type instance_ids: list
617 :param instance_ids: A list of strings of the Instance IDs to start 670 :param instance_ids: A list of strings of the Instance IDs to start
618 671
619 :rtype: list 672 :rtype: list
620 :return: A list of the instances started 673 :return: A list of the instances started
621 """ 674 """
622 params = {} 675 params = {}
623 if instance_ids: 676 if instance_ids:
624 self.build_list_params(params, instance_ids, 'InstanceId') 677 self.build_list_params(params, instance_ids, 'InstanceId')
625 return self.get_list('StartInstances', params, [('item', Instance)], ver b='POST') 678 return self.get_list('StartInstances', params,
679 [('item', Instance)], verb='POST')
626 680
627 def get_console_output(self, instance_id): 681 def get_console_output(self, instance_id):
628 """ 682 """
629 Retrieves the console output for the specified instance. 683 Retrieves the console output for the specified instance.
630 684
631 :type instance_id: string 685 :type instance_id: string
632 :param instance_id: The instance ID of a running instance on the cloud. 686 :param instance_id: The instance ID of a running instance on the cloud.
633 687
634 :rtype: :class:`boto.ec2.instance.ConsoleOutput` 688 :rtype: :class:`boto.ec2.instance.ConsoleOutput`
635 :return: The console output as a ConsoleOutput object 689 :return: The console output as a ConsoleOutput object
636 """ 690 """
637 params = {} 691 params = {}
638 self.build_list_params(params, [instance_id], 'InstanceId') 692 self.build_list_params(params, [instance_id], 'InstanceId')
639 return self.get_object('GetConsoleOutput', params, ConsoleOutput, verb=' POST') 693 return self.get_object('GetConsoleOutput', params,
694 ConsoleOutput, verb='POST')
640 695
641 def reboot_instances(self, instance_ids=None): 696 def reboot_instances(self, instance_ids=None):
642 """ 697 """
643 Reboot the specified instances. 698 Reboot the specified instances.
644 699
645 :type instance_ids: list 700 :type instance_ids: list
646 :param instance_ids: The instances to terminate and reboot 701 :param instance_ids: The instances to terminate and reboot
647 """ 702 """
648 params = {} 703 params = {}
649 if instance_ids: 704 if instance_ids:
650 self.build_list_params(params, instance_ids, 'InstanceId') 705 self.build_list_params(params, instance_ids, 'InstanceId')
651 return self.get_status('RebootInstances', params) 706 return self.get_status('RebootInstances', params)
652 707
653 def confirm_product_instance(self, product_code, instance_id): 708 def confirm_product_instance(self, product_code, instance_id):
654 params = {'ProductCode' : product_code, 709 params = {'ProductCode' : product_code,
655 'InstanceId' : instance_id} 710 'InstanceId' : instance_id}
656 rs = self.get_object('ConfirmProductInstance', params, ResultSet, verb=' POST') 711 rs = self.get_object('ConfirmProductInstance', params,
712 ResultSet, verb='POST')
657 return (rs.status, rs.ownerId) 713 return (rs.status, rs.ownerId)
658 714
659 # InstanceAttribute methods 715 # InstanceAttribute methods
660 716
661 def get_instance_attribute(self, instance_id, attribute): 717 def get_instance_attribute(self, instance_id, attribute):
662 """ 718 """
663 Gets an attribute from an instance. 719 Gets an attribute from an instance.
664 720
665 :type instance_id: string 721 :type instance_id: string
666 :param instance_id: The Amazon id of the instance 722 :param instance_id: The Amazon id of the instance
667 723
668 :type attribute: string 724 :type attribute: string
669 :param attribute: The attribute you need information about 725 :param attribute: The attribute you need information about
670 Valid choices are: 726 Valid choices are:
671 727
672 * instanceType|kernel|ramdisk|userData| 728 * instanceType|kernel|ramdisk|userData|
673 * disableApiTermination| 729 * disableApiTermination|
674 * instanceInitiatedShutdownBehavior| 730 * instanceInitiatedShutdownBehavior|
675 * rootDeviceName|blockDeviceMapping 731 * rootDeviceName|blockDeviceMapping
676 732
677 :rtype: :class:`boto.ec2.image.InstanceAttribute` 733 :rtype: :class:`boto.ec2.image.InstanceAttribute`
678 :return: An InstanceAttribute object representing the value of the 734 :return: An InstanceAttribute object representing the value of the
679 attribute requested 735 attribute requested
680 """ 736 """
681 params = {'InstanceId' : instance_id} 737 params = {'InstanceId' : instance_id}
682 if attribute: 738 if attribute:
683 params['Attribute'] = attribute 739 params['Attribute'] = attribute
684 return self.get_object('DescribeInstanceAttribute', params, 740 return self.get_object('DescribeInstanceAttribute', params,
685 InstanceAttribute, verb='POST') 741 InstanceAttribute, verb='POST')
686 742
687 def modify_instance_attribute(self, instance_id, attribute, value): 743 def modify_instance_attribute(self, instance_id, attribute, value):
688 """ 744 """
689 Changes an attribute of an instance 745 Changes an attribute of an instance
690 746
691 :type instance_id: string 747 :type instance_id: string
692 :param instance_id: The instance id you wish to change 748 :param instance_id: The instance id you wish to change
693 749
694 :type attribute: string 750 :type attribute: string
695 :param attribute: The attribute you wish to change. 751 :param attribute: The attribute you wish to change.
696 752
697 * AttributeName - Expected value (default) 753 * AttributeName - Expected value (default)
698 * instanceType - A valid instance type (m1.small) 754 * instanceType - A valid instance type (m1.small)
699 * kernel - Kernel ID (None) 755 * kernel - Kernel ID (None)
700 * ramdisk - Ramdisk ID (None) 756 * ramdisk - Ramdisk ID (None)
701 * userData - Base64 encoded String (None) 757 * userData - Base64 encoded String (None)
702 * disableApiTermination - Boolean (true) 758 * disableApiTermination - Boolean (true)
703 * instanceInitiatedShutdownBehavior - stop|terminate 759 * instanceInitiatedShutdownBehavior - stop|terminate
704 * rootDeviceName - device name (None) 760 * rootDeviceName - device name (None)
705 761
706 :type value: string 762 :type value: string
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 params = {'InstanceId' : instance_id, 794 params = {'InstanceId' : instance_id,
739 'Attribute' : attribute} 795 'Attribute' : attribute}
740 return self.get_status('ResetInstanceAttribute', params, verb='POST') 796 return self.get_status('ResetInstanceAttribute', params, verb='POST')
741 797
742 # Spot Instances 798 # Spot Instances
743 799
744 def get_all_spot_instance_requests(self, request_ids=None, 800 def get_all_spot_instance_requests(self, request_ids=None,
745 filters=None): 801 filters=None):
746 """ 802 """
747 Retrieve all the spot instances requests associated with your account. 803 Retrieve all the spot instances requests associated with your account.
748 804
749 :type request_ids: list 805 :type request_ids: list
750 :param request_ids: A list of strings of spot instance request IDs 806 :param request_ids: A list of strings of spot instance request IDs
751 807
752 :type filters: dict 808 :type filters: dict
753 :param filters: Optional filters that can be used to limit 809 :param filters: Optional filters that can be used to limit
754 the results returned. Filters are provided 810 the results returned. Filters are provided
755 in the form of a dictionary consisting of 811 in the form of a dictionary consisting of
756 filter names as the key and filter values 812 filter names as the key and filter values
757 as the value. The set of allowable filter 813 as the value. The set of allowable filter
758 names/values is dependent on the request 814 names/values is dependent on the request
759 being performed. Check the EC2 API guide 815 being performed. Check the EC2 API guide
760 for details. 816 for details.
761 817
762 :rtype: list 818 :rtype: list
763 :return: A list of 819 :return: A list of
764 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest` 820 :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
765 """ 821 """
766 params = {} 822 params = {}
767 if request_ids: 823 if request_ids:
768 self.build_list_params(params, request_ids, 'SpotInstanceRequestId') 824 self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
769 if filters: 825 if filters:
826 if 'launch.group-id' in filters:
827 warnings.warn("The 'launch.group-id' filter now requires a "
828 "security group id (sg-*) and no longer supports "
829 "filtering by group name. Please update your "
830 "filters accordingly.", UserWarning)
770 self.build_filter_params(params, filters) 831 self.build_filter_params(params, filters)
771 return self.get_list('DescribeSpotInstanceRequests', params, 832 return self.get_list('DescribeSpotInstanceRequests', params,
772 [('item', SpotInstanceRequest)], verb='POST') 833 [('item', SpotInstanceRequest)], verb='POST')
773 834
774 def get_spot_price_history(self, start_time=None, end_time=None, 835 def get_spot_price_history(self, start_time=None, end_time=None,
775 instance_type=None, product_description=None): 836 instance_type=None, product_description=None,
837 availability_zone=None):
776 """ 838 """
777 Retrieve the recent history of spot instances pricing. 839 Retrieve the recent history of spot instances pricing.
778 840
779 :type start_time: str 841 :type start_time: str
780 :param start_time: An indication of how far back to provide price 842 :param start_time: An indication of how far back to provide price
781 changes for. An ISO8601 DateTime string. 843 changes for. An ISO8601 DateTime string.
782 844
783 :type end_time: str 845 :type end_time: str
784 :param end_time: An indication of how far forward to provide price 846 :param end_time: An indication of how far forward to provide price
785 changes for. An ISO8601 DateTime string. 847 changes for. An ISO8601 DateTime string.
786 848
787 :type instance_type: str 849 :type instance_type: str
788 :param instance_type: Filter responses to a particular instance type. 850 :param instance_type: Filter responses to a particular instance type.
789 851
790 :type product_description: str 852 :type product_description: str
791 :param product_descripton: Filter responses to a particular platform. 853 :param product_description: Filter responses to a particular platform.
792 Valid values are currently: Linux 854 Valid values are currently: "Linux/UNIX",
793 855 "SUSE Linux", and "Windows"
856
857 :type availability_zone: str
858 :param availability_zone: The availability zone for which prices
859 should be returned
860
794 :rtype: list 861 :rtype: list
795 :return: A list tuples containing price and timestamp. 862 :return: A list tuples containing price and timestamp.
796 """ 863 """
797 params = {} 864 params = {}
798 if start_time: 865 if start_time:
799 params['StartTime'] = start_time 866 params['StartTime'] = start_time
800 if end_time: 867 if end_time:
801 params['EndTime'] = end_time 868 params['EndTime'] = end_time
802 if instance_type: 869 if instance_type:
803 params['InstanceType'] = instance_type 870 params['InstanceType'] = instance_type
804 if product_description: 871 if product_description:
805 params['ProductDescription'] = product_description 872 params['ProductDescription'] = product_description
873 if availability_zone:
874 params['AvailabilityZone'] = availability_zone
806 return self.get_list('DescribeSpotPriceHistory', params, 875 return self.get_list('DescribeSpotPriceHistory', params,
807 [('item', SpotPriceHistory)], verb='POST') 876 [('item', SpotPriceHistory)], verb='POST')
808 877
809 def request_spot_instances(self, price, image_id, count=1, type='one-time', 878 def request_spot_instances(self, price, image_id, count=1, type='one-time',
810 valid_from=None, valid_until=None, 879 valid_from=None, valid_until=None,
811 launch_group=None, availability_zone_group=None, 880 launch_group=None, availability_zone_group=None,
812 key_name=None, security_groups=None, 881 key_name=None, security_groups=None,
813 user_data=None, addressing_type=None, 882 user_data=None, addressing_type=None,
814 instance_type='m1.small', placement=None, 883 instance_type='m1.small', placement=None,
815 kernel_id=None, ramdisk_id=None, 884 kernel_id=None, ramdisk_id=None,
816 monitoring_enabled=False, subnet_id=None, 885 monitoring_enabled=False, subnet_id=None,
817 block_device_map=None): 886 block_device_map=None):
818 """ 887 """
819 Request instances on the spot market at a particular price. 888 Request instances on the spot market at a particular price.
820 889
821 :type price: str 890 :type price: str
822 :param price: The maximum price of your bid 891 :param price: The maximum price of your bid
823 892
824 :type image_id: string 893 :type image_id: string
825 :param image_id: The ID of the image to run 894 :param image_id: The ID of the image to run
826 895
827 :type count: int 896 :type count: int
828 :param count: The of instances to requested 897 :param count: The of instances to requested
829 898
830 :type type: str 899 :type type: str
831 :param type: Type of request. Can be 'one-time' or 'persistent'. 900 :param type: Type of request. Can be 'one-time' or 'persistent'.
832 Default is one-time. 901 Default is one-time.
833 902
834 :type valid_from: str 903 :type valid_from: str
835 :param valid_from: Start date of the request. An ISO8601 time string. 904 :param valid_from: Start date of the request. An ISO8601 time string.
836 905
837 :type valid_until: str 906 :type valid_until: str
838 :param valid_until: End date of the request. An ISO8601 time string. 907 :param valid_until: End date of the request. An ISO8601 time string.
839 908
840 :type launch_group: str 909 :type launch_group: str
841 :param launch_group: If supplied, all requests will be fulfilled 910 :param launch_group: If supplied, all requests will be fulfilled
842 as a group. 911 as a group.
843 912
844 :type availability_zone_group: str 913 :type availability_zone_group: str
845 :param availability_zone_group: If supplied, all requests will be 914 :param availability_zone_group: If supplied, all requests will be
846 fulfilled within a single 915 fulfilled within a single
847 availability zone. 916 availability zone.
848 917
849 :type key_name: string 918 :type key_name: string
850 :param key_name: The name of the key pair with which to launch instances 919 :param key_name: The name of the key pair with which to launch instances
851 920
852 :type security_groups: list of strings 921 :type security_groups: list of strings
853 :param security_groups: The names of the security groups with which to 922 :param security_groups: The names of the security groups with which to
854 associate instances 923 associate instances
855 924
856 :type user_data: string 925 :type user_data: string
857 :param user_data: The user data passed to the launched instances 926 :param user_data: The user data passed to the launched instances
858 927
859 :type instance_type: string 928 :type instance_type: string
860 :param instance_type: The type of instance to run: 929 :param instance_type: The type of instance to run:
861 930
862 * m1.small 931 * m1.small
863 * m1.large 932 * m1.large
864 * m1.xlarge 933 * m1.xlarge
865 * c1.medium 934 * c1.medium
866 * c1.xlarge 935 * c1.xlarge
867 * m2.xlarge 936 * m2.xlarge
868 * m2.2xlarge 937 * m2.2xlarge
869 * m2.4xlarge 938 * m2.4xlarge
870 * cc1.4xlarge 939 * cc1.4xlarge
871 * t1.micro 940 * t1.micro
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 if monitoring_enabled: 1005 if monitoring_enabled:
937 params['LaunchSpecification.Monitoring.Enabled'] = 'true' 1006 params['LaunchSpecification.Monitoring.Enabled'] = 'true'
938 if subnet_id: 1007 if subnet_id:
939 params['LaunchSpecification.SubnetId'] = subnet_id 1008 params['LaunchSpecification.SubnetId'] = subnet_id
940 if block_device_map: 1009 if block_device_map:
941 block_device_map.build_list_params(params, 'LaunchSpecification.') 1010 block_device_map.build_list_params(params, 'LaunchSpecification.')
942 return self.get_list('RequestSpotInstances', params, 1011 return self.get_list('RequestSpotInstances', params,
943 [('item', SpotInstanceRequest)], 1012 [('item', SpotInstanceRequest)],
944 verb='POST') 1013 verb='POST')
945 1014
946 1015
947 def cancel_spot_instance_requests(self, request_ids): 1016 def cancel_spot_instance_requests(self, request_ids):
948 """ 1017 """
949 Cancel the specified Spot Instance Requests. 1018 Cancel the specified Spot Instance Requests.
950 1019
951 :type request_ids: list 1020 :type request_ids: list
952 :param request_ids: A list of strings of the Request IDs to terminate 1021 :param request_ids: A list of strings of the Request IDs to terminate
953 1022
954 :rtype: list 1023 :rtype: list
955 :return: A list of the instances terminated 1024 :return: A list of the instances terminated
956 """ 1025 """
957 params = {} 1026 params = {}
958 if request_ids: 1027 if request_ids:
959 self.build_list_params(params, request_ids, 'SpotInstanceRequestId') 1028 self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
960 return self.get_list('CancelSpotInstanceRequests', params, 1029 return self.get_list('CancelSpotInstanceRequests', params,
961 [('item', Instance)], verb='POST') 1030 [('item', Instance)], verb='POST')
962 1031
963 def get_spot_datafeed_subscription(self): 1032 def get_spot_datafeed_subscription(self):
964 """ 1033 """
965 Return the current spot instance data feed subscription 1034 Return the current spot instance data feed subscription
966 associated with this account, if any. 1035 associated with this account, if any.
967 1036
968 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti on` 1037 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti on`
969 :return: The datafeed subscription object or None 1038 :return: The datafeed subscription object or None
970 """ 1039 """
971 return self.get_object('DescribeSpotDatafeedSubscription', 1040 return self.get_object('DescribeSpotDatafeedSubscription',
972 None, SpotDatafeedSubscription, verb='POST') 1041 None, SpotDatafeedSubscription, verb='POST')
973 1042
974 def create_spot_datafeed_subscription(self, bucket, prefix): 1043 def create_spot_datafeed_subscription(self, bucket, prefix):
975 """ 1044 """
976 Create a spot instance datafeed subscription for this account. 1045 Create a spot instance datafeed subscription for this account.
977 1046
978 :type bucket: str or unicode 1047 :type bucket: str or unicode
979 :param bucket: The name of the bucket where spot instance data 1048 :param bucket: The name of the bucket where spot instance data
980 will be written. The account issuing this request 1049 will be written. The account issuing this request
981 must have FULL_CONTROL access to the bucket 1050 must have FULL_CONTROL access to the bucket
982 specified in the request. 1051 specified in the request.
983 1052
984 :type prefix: str or unicode 1053 :type prefix: str or unicode
985 :param prefix: An optional prefix that will be pre-pended to all 1054 :param prefix: An optional prefix that will be pre-pended to all
986 data files written to the bucket. 1055 data files written to the bucket.
987 1056
988 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti on` 1057 :rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscripti on`
989 :return: The datafeed subscription object or None 1058 :return: The datafeed subscription object or None
990 """ 1059 """
991 params = {'Bucket' : bucket} 1060 params = {'Bucket' : bucket}
992 if prefix: 1061 if prefix:
993 params['Prefix'] = prefix 1062 params['Prefix'] = prefix
994 return self.get_object('CreateSpotDatafeedSubscription', 1063 return self.get_object('CreateSpotDatafeedSubscription',
995 params, SpotDatafeedSubscription, verb='POST') 1064 params, SpotDatafeedSubscription, verb='POST')
996 1065
997 def delete_spot_datafeed_subscription(self): 1066 def delete_spot_datafeed_subscription(self):
998 """ 1067 """
999 Delete the current spot instance data feed subscription 1068 Delete the current spot instance data feed subscription
1000 associated with this account 1069 associated with this account
1001 1070
1002 :rtype: bool 1071 :rtype: bool
1003 :return: True if successful 1072 :return: True if successful
1004 """ 1073 """
1005 return self.get_status('DeleteSpotDatafeedSubscription', None, verb='POS T') 1074 return self.get_status('DeleteSpotDatafeedSubscription',
1075 None, verb='POST')
1006 1076
1007 # Zone methods 1077 # Zone methods
1008 1078
1009 def get_all_zones(self, zones=None, filters=None): 1079 def get_all_zones(self, zones=None, filters=None):
1010 """ 1080 """
1011 Get all Availability Zones associated with the current region. 1081 Get all Availability Zones associated with the current region.
1012 1082
1013 :type zones: list 1083 :type zones: list
1014 :param zones: Optional list of zones. If this list is present, 1084 :param zones: Optional list of zones. If this list is present,
1015 only the Zones associated with these zone names 1085 only the Zones associated with these zone names
(...skipping 10 matching lines...) Expand all
1026 for details. 1096 for details.
1027 1097
1028 :rtype: list of :class:`boto.ec2.zone.Zone` 1098 :rtype: list of :class:`boto.ec2.zone.Zone`
1029 :return: The requested Zone objects 1099 :return: The requested Zone objects
1030 """ 1100 """
1031 params = {} 1101 params = {}
1032 if zones: 1102 if zones:
1033 self.build_list_params(params, zones, 'ZoneName') 1103 self.build_list_params(params, zones, 'ZoneName')
1034 if filters: 1104 if filters:
1035 self.build_filter_params(params, filters) 1105 self.build_filter_params(params, filters)
1036 return self.get_list('DescribeAvailabilityZones', params, [('item', Zone )], verb='POST') 1106 return self.get_list('DescribeAvailabilityZones', params,
1107 [('item', Zone)], verb='POST')
1037 1108
1038 # Address methods 1109 # Address methods
1039 1110
1040 def get_all_addresses(self, addresses=None, filters=None): 1111 def get_all_addresses(self, addresses=None, filters=None, allocation_ids=Non e):
1041 """ 1112 """
1042 Get all EIP's associated with the current credentials. 1113 Get all EIP's associated with the current credentials.
1043 1114
1044 :type addresses: list 1115 :type addresses: list
1045 :param addresses: Optional list of addresses. If this list is present, 1116 :param addresses: Optional list of addresses. If this list is present,
1046 only the Addresses associated with these addresses 1117 only the Addresses associated with these addresses
1047 will be returned. 1118 will be returned.
1048 1119
1049 :type filters: dict 1120 :type filters: dict
1050 :param filters: Optional filters that can be used to limit 1121 :param filters: Optional filters that can be used to limit
1051 the results returned. Filters are provided 1122 the results returned. Filters are provided
1052 in the form of a dictionary consisting of 1123 in the form of a dictionary consisting of
1053 filter names as the key and filter values 1124 filter names as the key and filter values
1054 as the value. The set of allowable filter 1125 as the value. The set of allowable filter
1055 names/values is dependent on the request 1126 names/values is dependent on the request
1056 being performed. Check the EC2 API guide 1127 being performed. Check the EC2 API guide
1057 for details. 1128 for details.
1058 1129
1130 :type allocation_ids: list
1131 :param allocation_ids: Optional list of allocation IDs. If this list is
1132 present, only the Addresses associated with the given
1133 allocation IDs will be returned.
1134
1059 :rtype: list of :class:`boto.ec2.address.Address` 1135 :rtype: list of :class:`boto.ec2.address.Address`
1060 :return: The requested Address objects 1136 :return: The requested Address objects
1061 """ 1137 """
1062 params = {} 1138 params = {}
1063 if addresses: 1139 if addresses:
1064 self.build_list_params(params, addresses, 'PublicIp') 1140 self.build_list_params(params, addresses, 'PublicIp')
1141 if allocation_ids:
1142 self.build_list_params(params, allocation_ids, 'AllocationId')
1065 if filters: 1143 if filters:
1066 self.build_filter_params(params, filters) 1144 self.build_filter_params(params, filters)
1067 return self.get_list('DescribeAddresses', params, [('item', Address)], v erb='POST') 1145 return self.get_list('DescribeAddresses', params, [('item', Address)], v erb='POST')
1068 1146
1069 def allocate_address(self): 1147 def allocate_address(self, domain=None):
1070 """ 1148 """
1071 Allocate a new Elastic IP address and associate it with your account. 1149 Allocate a new Elastic IP address and associate it with your account.
1072 1150
1073 :rtype: :class:`boto.ec2.address.Address` 1151 :rtype: :class:`boto.ec2.address.Address`
1074 :return: The newly allocated Address 1152 :return: The newly allocated Address
1075 """ 1153 """
1076 return self.get_object('AllocateAddress', {}, Address, verb='POST') 1154 params = {}
1077 1155
1078 def associate_address(self, instance_id, public_ip): 1156 if domain is not None:
1157 params['Domain'] = domain
1158
1159 return self.get_object('AllocateAddress', params, Address, verb='POST')
1160
1161 def associate_address(self, instance_id, public_ip=None, allocation_id=None) :
1079 """ 1162 """
1080 Associate an Elastic IP address with a currently running instance. 1163 Associate an Elastic IP address with a currently running instance.
1164 This requires one of ``public_ip`` or ``allocation_id`` depending
1165 on if you're associating a VPC address or a plain EC2 address.
1081 1166
1082 :type instance_id: string 1167 :type instance_id: string
1083 :param instance_id: The ID of the instance 1168 :param instance_id: The ID of the instance
1084 1169
1085 :type public_ip: string 1170 :type public_ip: string
1086 :param public_ip: The public IP address 1171 :param public_ip: The public IP address for EC2 based allocations.
1172
1173 :type allocation_id: string
1174 :param allocation_id: The allocation ID for a VPC-based elastic IP.
1087 1175
1088 :rtype: bool 1176 :rtype: bool
1089 :return: True if successful 1177 :return: True if successful
1090 """ 1178 """
1091 params = {'InstanceId' : instance_id, 'PublicIp' : public_ip} 1179 params = { 'InstanceId' : instance_id }
1180
1181 if public_ip is not None:
1182 params['PublicIp'] = public_ip
1183 elif allocation_id is not None:
1184 params['AllocationId'] = allocation_id
1185
1092 return self.get_status('AssociateAddress', params, verb='POST') 1186 return self.get_status('AssociateAddress', params, verb='POST')
1093 1187
1094 def disassociate_address(self, public_ip): 1188 def disassociate_address(self, public_ip=None, association_id=None):
1095 """ 1189 """
1096 Disassociate an Elastic IP address from a currently running instance. 1190 Disassociate an Elastic IP address from a currently running instance.
1097 1191
1098 :type public_ip: string 1192 :type public_ip: string
1099 :param public_ip: The public IP address 1193 :param public_ip: The public IP address for EC2 elastic IPs.
1194
1195 :type association_id: string
1196 :param association_id: The association ID for a VPC based elastic ip.
1100 1197
1101 :rtype: bool 1198 :rtype: bool
1102 :return: True if successful 1199 :return: True if successful
1103 """ 1200 """
1104 params = {'PublicIp' : public_ip} 1201 params = {}
1202
1203 if public_ip is not None:
1204 params['PublicIp'] = public_ip
1205 elif association_id is not None:
1206 params['AssociationId'] = association_id
1207
1105 return self.get_status('DisassociateAddress', params, verb='POST') 1208 return self.get_status('DisassociateAddress', params, verb='POST')
1106 1209
1107 def release_address(self, public_ip): 1210 def release_address(self, public_ip=None, allocation_id=None):
1108 """ 1211 """
1109 Free up an Elastic IP address 1212 Free up an Elastic IP address.
1110 1213
1111 :type public_ip: string 1214 :type public_ip: string
1112 :param public_ip: The public IP address 1215 :param public_ip: The public IP address for EC2 elastic IPs.
1216
1217 :type allocation_id: string
1218 :param allocation_id: The ID for VPC elastic IPs.
1113 1219
1114 :rtype: bool 1220 :rtype: bool
1115 :return: True if successful 1221 :return: True if successful
1116 """ 1222 """
1117 params = {'PublicIp' : public_ip} 1223 params = {}
1224
1225 if public_ip is not None:
1226 params['PublicIp'] = public_ip
1227 elif allocation_id is not None:
1228 params['AllocationId'] = allocation_id
1229
1118 return self.get_status('ReleaseAddress', params, verb='POST') 1230 return self.get_status('ReleaseAddress', params, verb='POST')
1119 1231
1120 # Volume methods 1232 # Volume methods
1121 1233
1122 def get_all_volumes(self, volume_ids=None, filters=None): 1234 def get_all_volumes(self, volume_ids=None, filters=None):
1123 """ 1235 """
1124 Get all Volumes associated with the current credentials. 1236 Get all Volumes associated with the current credentials.
1125 1237
1126 :type volume_ids: list 1238 :type volume_ids: list
1127 :param volume_ids: Optional list of volume ids. If this list is present , 1239 :param volume_ids: Optional list of volume ids. If this list
1128 only the volumes associated with these volume ids 1240 is present, only the volumes associated with
1129 will be returned. 1241 these volume ids will be returned.
1130 1242
1131 :type filters: dict 1243 :type filters: dict
1132 :param filters: Optional filters that can be used to limit 1244 :param filters: Optional filters that can be used to limit
1133 the results returned. Filters are provided 1245 the results returned. Filters are provided
1134 in the form of a dictionary consisting of 1246 in the form of a dictionary consisting of
1135 filter names as the key and filter values 1247 filter names as the key and filter values
1136 as the value. The set of allowable filter 1248 as the value. The set of allowable filter
1137 names/values is dependent on the request 1249 names/values is dependent on the request
1138 being performed. Check the EC2 API guide 1250 being performed. Check the EC2 API guide
1139 for details. 1251 for details.
1140 1252
1141 :rtype: list of :class:`boto.ec2.volume.Volume` 1253 :rtype: list of :class:`boto.ec2.volume.Volume`
1142 :return: The requested Volume objects 1254 :return: The requested Volume objects
1143 """ 1255 """
1144 params = {} 1256 params = {}
1145 if volume_ids: 1257 if volume_ids:
1146 self.build_list_params(params, volume_ids, 'VolumeId') 1258 self.build_list_params(params, volume_ids, 'VolumeId')
1147 if filters: 1259 if filters:
1148 self.build_filter_params(params, filters) 1260 self.build_filter_params(params, filters)
1149 return self.get_list('DescribeVolumes', params, [('item', Volume)], verb ='POST') 1261 return self.get_list('DescribeVolumes', params,
1262 [('item', Volume)], verb='POST')
1150 1263
1151 def create_volume(self, size, zone, snapshot=None): 1264 def create_volume(self, size, zone, snapshot=None):
1152 """ 1265 """
1153 Create a new EBS Volume. 1266 Create a new EBS Volume.
1154 1267
1155 :type size: int 1268 :type size: int
1156 :param size: The size of the new volume, in GiB 1269 :param size: The size of the new volume, in GiB
1157 1270
1158 :type zone: string or :class:`boto.ec2.zone.Zone` 1271 :type zone: string or :class:`boto.ec2.zone.Zone`
1159 :param zone: The availability zone in which the Volume will be created. 1272 :param zone: The availability zone in which the Volume will be created.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 Get all EBS Snapshots associated with the current credentials. 1367 Get all EBS Snapshots associated with the current credentials.
1255 1368
1256 :type snapshot_ids: list 1369 :type snapshot_ids: list
1257 :param snapshot_ids: Optional list of snapshot ids. If this list is 1370 :param snapshot_ids: Optional list of snapshot ids. If this list is
1258 present, only the Snapshots associated with 1371 present, only the Snapshots associated with
1259 these snapshot ids will be returned. 1372 these snapshot ids will be returned.
1260 1373
1261 :type owner: str 1374 :type owner: str
1262 :param owner: If present, only the snapshots owned by the specified user 1375 :param owner: If present, only the snapshots owned by the specified user
1263 will be returned. Valid values are: 1376 will be returned. Valid values are:
1264 1377
1265 * self 1378 * self
1266 * amazon 1379 * amazon
1267 * AWS Account ID 1380 * AWS Account ID
1268 1381
1269 :type restorable_by: str 1382 :type restorable_by: str
1270 :param restorable_by: If present, only the snapshots that are restorable 1383 :param restorable_by: If present, only the snapshots that are restorable
1271 by the specified account id will be returned. 1384 by the specified account id will be returned.
1272 1385
1273 :type filters: dict 1386 :type filters: dict
1274 :param filters: Optional filters that can be used to limit 1387 :param filters: Optional filters that can be used to limit
(...skipping 10 matching lines...) Expand all
1285 """ 1398 """
1286 params = {} 1399 params = {}
1287 if snapshot_ids: 1400 if snapshot_ids:
1288 self.build_list_params(params, snapshot_ids, 'SnapshotId') 1401 self.build_list_params(params, snapshot_ids, 'SnapshotId')
1289 if owner: 1402 if owner:
1290 params['Owner'] = owner 1403 params['Owner'] = owner
1291 if restorable_by: 1404 if restorable_by:
1292 params['RestorableBy'] = restorable_by 1405 params['RestorableBy'] = restorable_by
1293 if filters: 1406 if filters:
1294 self.build_filter_params(params, filters) 1407 self.build_filter_params(params, filters)
1295 return self.get_list('DescribeSnapshots', params, [('item', Snapshot)], verb='POST') 1408 return self.get_list('DescribeSnapshots', params,
1409 [('item', Snapshot)], verb='POST')
1296 1410
1297 def create_snapshot(self, volume_id, description=None): 1411 def create_snapshot(self, volume_id, description=None):
1298 """ 1412 """
1299 Create a snapshot of an existing EBS Volume. 1413 Create a snapshot of an existing EBS Volume.
1300 1414
1301 :type volume_id: str 1415 :type volume_id: str
1302 :param volume_id: The ID of the volume to be snapshot'ed 1416 :param volume_id: The ID of the volume to be snapshot'ed
1303 1417
1304 :type description: str 1418 :type description: str
1305 :param description: A description of the snapshot. 1419 :param description: A description of the snapshot.
1306 Limited to 255 characters. 1420 Limited to 255 characters.
1307 1421
1308 :rtype: bool 1422 :rtype: bool
1309 :return: True if successful 1423 :return: True if successful
1310 """ 1424 """
1311 params = {'VolumeId' : volume_id} 1425 params = {'VolumeId' : volume_id}
1312 if description: 1426 if description:
1313 params['Description'] = description[0:255] 1427 params['Description'] = description[0:255]
1314 snapshot = self.get_object('CreateSnapshot', params, Snapshot, verb='POS T') 1428 snapshot = self.get_object('CreateSnapshot', params,
1429 Snapshot, verb='POST')
1315 volume = self.get_all_volumes([volume_id])[0] 1430 volume = self.get_all_volumes([volume_id])[0]
1316 volume_name = volume.tags.get('Name') 1431 volume_name = volume.tags.get('Name')
1317 if volume_name: 1432 if volume_name:
1318 snapshot.add_tag('Name', volume_name) 1433 snapshot.add_tag('Name', volume_name)
1319 return snapshot 1434 return snapshot
1320 1435
1321 def delete_snapshot(self, snapshot_id): 1436 def delete_snapshot(self, snapshot_id):
1322 params = {'SnapshotId': snapshot_id} 1437 params = {'SnapshotId': snapshot_id}
1323 return self.get_status('DeleteSnapshot', params, verb='POST') 1438 return self.get_status('DeleteSnapshot', params, verb='POST')
1324 1439
1325 def trim_snapshots(self, hourly_backups = 8, daily_backups = 7, weekly_backu ps = 4): 1440 def trim_snapshots(self, hourly_backups = 8, daily_backups = 7,
1441 weekly_backups = 4):
1326 """ 1442 """
1327 Trim excess snapshots, based on when they were taken. More current snaps hots are 1443 Trim excess snapshots, based on when they were taken. More current
1328 retained, with the number retained decreasing as you move back in time. 1444 snapshots are retained, with the number retained decreasing as you
1445 move back in time.
1329 1446
1330 If ebs volumes have a 'Name' tag with a value, their snapshots will be a ssigned the same 1447 If ebs volumes have a 'Name' tag with a value, their snapshots
1331 tag when they are created. The values of the 'Name' tags for snapshots a re used by this 1448 will be assigned the same tag when they are created. The values
1332 function to group snapshots taken from the same volume (or from a series of like-named 1449 of the 'Name' tags for snapshots are used by this function to
1333 volumes over time) for trimming. 1450 group snapshots taken from the same volume (or from a series
1451 of like-named volumes over time) for trimming.
1334 1452
1335 For every group of like-named snapshots, this function retains the newes t and oldest 1453 For every group of like-named snapshots, this function retains
1336 snapshots, as well as, by default, the first snapshots taken in each of the last eight 1454 the newest and oldest snapshots, as well as, by default, the
1337 hours, the first snapshots taken in each of the last seven days, the fir st snapshots 1455 first snapshots taken in each of the last eight hours, the first
1338 taken in the last 4 weeks (counting Midnight Sunday morning as the start of the week), 1456 snapshots taken in each of the last seven days, the first snapshots
1339 and the first snapshot from the first Sunday of each month forever. 1457 taken in the last 4 weeks (counting Midnight Sunday morning as
1458 the start of the week), and the first snapshot from the first
1459 Sunday of each month forever.
1340 1460
1341 :type hourly_backups: int 1461 :type hourly_backups: int
1342 :param hourly_backups: How many recent hourly backups should be saved. 1462 :param hourly_backups: How many recent hourly backups should be saved.
1343 1463
1344 :type daily_backups: int 1464 :type daily_backups: int
1345 :param daily_backups: How many recent daily backups should be saved. 1465 :param daily_backups: How many recent daily backups should be saved.
1346 1466
1347 :type weekly_backups: int 1467 :type weekly_backups: int
1348 :param weekly_backups: How many recent weekly backups should be saved. 1468 :param weekly_backups: How many recent weekly backups should be saved.
1349 """ 1469 """
1350 1470
1351 # This function first builds up an ordered list of target times that sna pshots should be saved for 1471 # This function first builds up an ordered list of target times
1352 # (last 8 hours, last 7 days, etc.). Then a map of snapshots is construc ted, with the keys being 1472 # that snapshots should be saved for (last 8 hours, last 7 days, etc.).
1353 # the snapshot / volume names and the values being arrays of chornologic ally sorted snapshots. 1473 # Then a map of snapshots is constructed, with the keys being
1354 # Finally, for each array in the map, we go through the snapshot array a nd the target time array 1474 # the snapshot / volume names and the values being arrays of
1355 # in an interleaved fashion, deleting snapshots whose start_times don't immediately follow a 1475 # chronologically sorted snapshots.
1356 # target time (we delete a snapshot if there's another snapshot that was made closer to the 1476 # Finally, for each array in the map, we go through the snapshot
1357 # preceding target time). 1477 # array and the target time array in an interleaved fashion,
1478 # deleting snapshots whose start_times don't immediately follow a
1479 # target time (we delete a snapshot if there's another snapshot
1480 # that was made closer to the preceding target time).
1358 1481
1359 now = datetime.utcnow() # work with UTC time, which is what the snapshot start time is reported in 1482 now = datetime.utcnow()
1360 last_hour = datetime(now.year, now.month, now.day, now.hour) 1483 last_hour = datetime(now.year, now.month, now.day, now.hour)
1361 last_midnight = datetime(now.year, now.month, now.day) 1484 last_midnight = datetime(now.year, now.month, now.day)
1362 last_sunday = datetime(now.year, now.month, now.day) - timedelta(days = (now.weekday() + 1) % 7) 1485 last_sunday = datetime(now.year, now.month, now.day) - timedelta(days = (now.weekday() + 1) % 7)
1363 start_of_month = datetime(now.year, now.month, 1) 1486 start_of_month = datetime(now.year, now.month, 1)
1364 1487
1365 target_backup_times = [] 1488 target_backup_times = []
1366 1489
1367 oldest_snapshot_date = datetime(2007, 1, 1) # there are no snapshots old er than 1/1/2007 1490 # there are no snapshots older than 1/1/2007
1491 oldest_snapshot_date = datetime(2007, 1, 1)
1368 1492
1369 for hour in range(0, hourly_backups): 1493 for hour in range(0, hourly_backups):
1370 target_backup_times.append(last_hour - timedelta(hours = hour)) 1494 target_backup_times.append(last_hour - timedelta(hours = hour))
1371 1495
1372 for day in range(0, daily_backups): 1496 for day in range(0, daily_backups):
1373 target_backup_times.append(last_midnight - timedelta(days = day)) 1497 target_backup_times.append(last_midnight - timedelta(days = day))
1374 1498
1375 for week in range(0, weekly_backups): 1499 for week in range(0, weekly_backups):
1376 target_backup_times.append(last_sunday - timedelta(weeks = week)) 1500 target_backup_times.append(last_sunday - timedelta(weeks = week))
1377 1501
1378 one_day = timedelta(days = 1) 1502 one_day = timedelta(days = 1)
1379 while start_of_month > oldest_snapshot_date: 1503 while start_of_month > oldest_snapshot_date:
1380 # append the start of the month to the list of snapshot dates to sav e: 1504 # append the start of the month to the list of
1505 # snapshot dates to save:
1381 target_backup_times.append(start_of_month) 1506 target_backup_times.append(start_of_month)
1382 # there's no timedelta setting for one month, so instead: 1507 # there's no timedelta setting for one month, so instead:
1383 # decrement the day by one, so we go to the final day of the previou s month... 1508 # decrement the day by one, so we go to the final day of
1509 # the previous month...
1384 start_of_month -= one_day 1510 start_of_month -= one_day
1385 # ... and then go to the first day of that previous month: 1511 # ... and then go to the first day of that previous month:
1386 start_of_month = datetime(start_of_month.year, start_of_month.month, 1) 1512 start_of_month = datetime(start_of_month.year,
1513 start_of_month.month, 1)
1387 1514
1388 temp = [] 1515 temp = []
1389 1516
1390 for t in target_backup_times: 1517 for t in target_backup_times:
1391 if temp.__contains__(t) == False: 1518 if temp.__contains__(t) == False:
1392 temp.append(t) 1519 temp.append(t)
1393 1520
1394 target_backup_times = temp 1521 target_backup_times = temp
1395 target_backup_times.reverse() # make the oldest date first 1522 # make the oldeest dates first, and make sure the month start
1523 # and last four week's start are in the proper order
1524 target_backup_times.sort()
1396 1525
1397 # get all the snapshots, sort them by date and time, and organize them i nto one array for each volume: 1526 # get all the snapshots, sort them by date and time, and
1527 # organize them into one array for each volume:
1398 all_snapshots = self.get_all_snapshots(owner = 'self') 1528 all_snapshots = self.get_all_snapshots(owner = 'self')
1399 all_snapshots.sort(cmp = lambda x, y: cmp(x.start_time, y.start_time)) # oldest first 1529 all_snapshots.sort(cmp = lambda x, y: cmp(x.start_time, y.start_time))
1400 snaps_for_each_volume = {} 1530 snaps_for_each_volume = {}
1401 for snap in all_snapshots: 1531 for snap in all_snapshots:
1402 # the snapshot name and the volume name are the same. The snapshot n ame is set from the volume 1532 # the snapshot name and the volume name are the same.
1533 # The snapshot name is set from the volume
1403 # name at the time the snapshot is taken 1534 # name at the time the snapshot is taken
1404 volume_name = snap.tags.get('Name') 1535 volume_name = snap.tags.get('Name')
1405 if volume_name: 1536 if volume_name:
1406 # only examine snapshots that have a volume name 1537 # only examine snapshots that have a volume name
1407 snaps_for_volume = snaps_for_each_volume.get(volume_name) 1538 snaps_for_volume = snaps_for_each_volume.get(volume_name)
1408 if not snaps_for_volume: 1539 if not snaps_for_volume:
1409 snaps_for_volume = [] 1540 snaps_for_volume = []
1410 snaps_for_each_volume[volume_name] = snaps_for_volume 1541 snaps_for_each_volume[volume_name] = snaps_for_volume
1411 snaps_for_volume.append(snap) 1542 snaps_for_volume.append(snap)
1412 1543
1413 # Do a running comparison of snapshot dates to desired time periods, kee ping the oldest snapshot in each 1544 # Do a running comparison of snapshot dates to desired time
1545 #periods, keeping the oldest snapshot in each
1414 # time period and deleting the rest: 1546 # time period and deleting the rest:
1415 for volume_name in snaps_for_each_volume: 1547 for volume_name in snaps_for_each_volume:
1416 snaps = snaps_for_each_volume[volume_name] 1548 snaps = snaps_for_each_volume[volume_name]
1417 snaps = snaps[:-1] # never delete the newest snapshot, so remove it from consideration 1549 snaps = snaps[:-1] # never delete the newest snapshot
1418 time_period_number = 0 1550 time_period_number = 0
1419 snap_found_for_this_time_period = False 1551 snap_found_for_this_time_period = False
1420 for snap in snaps: 1552 for snap in snaps:
1421 check_this_snap = True 1553 check_this_snap = True
1422 while check_this_snap and time_period_number < target_backup_tim es.__len__(): 1554 while check_this_snap and time_period_number < target_backup_tim es.__len__():
1423 snap_date = datetime.strptime(snap.start_time, '%Y-%m-%dT%H: %M:%S.000Z') 1555 snap_date = datetime.strptime(snap.start_time,
1556 '%Y-%m-%dT%H:%M:%S.000Z')
1424 if snap_date < target_backup_times[time_period_number]: 1557 if snap_date < target_backup_times[time_period_number]:
1425 # the snap date is before the cutoff date. Figure out if it's the first snap in this 1558 # the snap date is before the cutoff date.
1426 # date range and act accordingly (since both date the da te ranges and the snapshots 1559 # Figure out if it's the first snap in this
1427 # are sorted chronologically, we know this snapshot isn' t in an earlier date range): 1560 # date range and act accordingly (since both
1561 #date the date ranges and the snapshots
1562 # are sorted chronologically, we know this
1563 #snapshot isn't in an earlier date range):
1428 if snap_found_for_this_time_period == True: 1564 if snap_found_for_this_time_period == True:
1429 if not snap.tags.get('preserve_snapshot'): 1565 if not snap.tags.get('preserve_snapshot'):
1430 # as long as the snapshot wasn't marked with the 'preserve_snapshot' tag, delete it: 1566 # as long as the snapshot wasn't marked
1431 self.delete_snapshot(snap.id) 1567 # with the 'preserve_snapshot' tag, delete it:
1432 boto.log.info('Trimmed snapshot %s (%s)' % (snap .tags['Name'], snap.start_time)) 1568 try:
1433 # go on and look at the next snapshot, leaving the t ime period alone 1569 self.delete_snapshot(snap.id)
1570 boto.log.info('Trimmed snapshot %s (%s)' % ( snap.tags['Name'], snap.start_time))
1571 except EC2ResponseError:
1572 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))
1573 # go on and look at the next snapshot,
1574 #leaving the time period alone
1434 else: 1575 else:
1435 # this was the first snapshot found for this time pe riod. Leave it alone and look at the 1576 # this was the first snapshot found for this
1577 #time period. Leave it alone and look at the
1436 # next snapshot: 1578 # next snapshot:
1437 snap_found_for_this_time_period = True 1579 snap_found_for_this_time_period = True
1438 check_this_snap = False 1580 check_this_snap = False
1439 else: 1581 else:
1440 # the snap is after the cutoff date. Check it against th e next cutoff date 1582 # the snap is after the cutoff date. Check it
1583 # against the next cutoff date
1441 time_period_number += 1 1584 time_period_number += 1
1442 snap_found_for_this_time_period = False 1585 snap_found_for_this_time_period = False
1443 1586
1444 1587
1445 def get_snapshot_attribute(self, snapshot_id, 1588 def get_snapshot_attribute(self, snapshot_id,
1446 attribute='createVolumePermission'): 1589 attribute='createVolumePermission'):
1447 """ 1590 """
1448 Get information about an attribute of a snapshot. Only one attribute 1591 Get information about an attribute of a snapshot. Only one attribute
1449 can be specified per call. 1592 can be specified per call.
1450 1593
1451 :type snapshot_id: str 1594 :type snapshot_id: str
1452 :param snapshot_id: The ID of the snapshot. 1595 :param snapshot_id: The ID of the snapshot.
1453 1596
1454 :type attribute: str 1597 :type attribute: str
1455 :param attribute: The requested attribute. Valid values are: 1598 :param attribute: The requested attribute. Valid values are:
1456 1599
1457 * createVolumePermission 1600 * createVolumePermission
1458 1601
1459 :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute` 1602 :rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute`
1460 :return: The requested Snapshot attribute 1603 :return: The requested Snapshot attribute
1461 """ 1604 """
1462 params = {'Attribute' : attribute} 1605 params = {'Attribute' : attribute}
1463 if snapshot_id: 1606 if snapshot_id:
1464 params['SnapshotId'] = snapshot_id 1607 params['SnapshotId'] = snapshot_id
1465 return self.get_object('DescribeSnapshotAttribute', params, 1608 return self.get_object('DescribeSnapshotAttribute', params,
1466 SnapshotAttribute, verb='POST') 1609 SnapshotAttribute, verb='POST')
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 for details. 1681 for details.
1539 1682
1540 :rtype: list 1683 :rtype: list
1541 :return: A list of :class:`boto.ec2.keypair.KeyPair` 1684 :return: A list of :class:`boto.ec2.keypair.KeyPair`
1542 """ 1685 """
1543 params = {} 1686 params = {}
1544 if keynames: 1687 if keynames:
1545 self.build_list_params(params, keynames, 'KeyName') 1688 self.build_list_params(params, keynames, 'KeyName')
1546 if filters: 1689 if filters:
1547 self.build_filter_params(params, filters) 1690 self.build_filter_params(params, filters)
1548 return self.get_list('DescribeKeyPairs', params, [('item', KeyPair)], ve rb='POST') 1691 return self.get_list('DescribeKeyPairs', params,
1692 [('item', KeyPair)], verb='POST')
1549 1693
1550 def get_key_pair(self, keyname): 1694 def get_key_pair(self, keyname):
1551 """ 1695 """
1552 Convenience method to retrieve a specific keypair (KeyPair). 1696 Convenience method to retrieve a specific keypair (KeyPair).
1553 1697
1554 :type image_id: string 1698 :type image_id: string
1555 :param image_id: the ID of the Image to retrieve 1699 :param image_id: the ID of the Image to retrieve
1556 1700
1557 :rtype: :class:`boto.ec2.keypair.KeyPair` 1701 :rtype: :class:`boto.ec2.keypair.KeyPair`
1558 :return: The KeyPair specified or None if it is not found 1702 :return: The KeyPair specified or None if it is not found
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 :type public_key_material: string 1758 :type public_key_material: string
1615 :param public_key_material: The public key. You must base64 encode 1759 :param public_key_material: The public key. You must base64 encode
1616 the public key material before sending 1760 the public key material before sending
1617 it to AWS. 1761 it to AWS.
1618 1762
1619 :rtype: :class:`boto.ec2.keypair.KeyPair` 1763 :rtype: :class:`boto.ec2.keypair.KeyPair`
1620 :return: The newly created :class:`boto.ec2.keypair.KeyPair`. 1764 :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
1621 The material attribute of the new KeyPair object 1765 The material attribute of the new KeyPair object
1622 will contain the the unencrypted PEM encoded RSA private key. 1766 will contain the the unencrypted PEM encoded RSA private key.
1623 """ 1767 """
1768 public_key_material = base64.b64encode(public_key_material)
1624 params = {'KeyName' : key_name, 1769 params = {'KeyName' : key_name,
1625 'PublicKeyMaterial' : public_key_material} 1770 'PublicKeyMaterial' : public_key_material}
1626 return self.get_object('ImportKeyPair', params, KeyPair, verb='POST') 1771 return self.get_object('ImportKeyPair', params, KeyPair, verb='POST')
1627 1772
1628 # SecurityGroup methods 1773 # SecurityGroup methods
1629 1774
1630 def get_all_security_groups(self, groupnames=None, filters=None): 1775 def get_all_security_groups(self, groupnames=None, group_ids=None, filters=N one):
1631 """ 1776 """
1632 Get all security groups associated with your account in a region. 1777 Get all security groups associated with your account in a region.
1633 1778
1634 :type groupnames: list 1779 :type groupnames: list
1635 :param groupnames: A list of the names of security groups to retrieve. 1780 :param groupnames: A list of the names of security groups to retrieve.
1636 If not provided, all security groups will be 1781 If not provided, all security groups will be
1637 returned. 1782 returned.
1638 1783
1784 :type group_ids: list
1785 :param group_ids: A list of IDs of security groups to retrieve for
1786 security groups within a VPC.
1787
1639 :type filters: dict 1788 :type filters: dict
1640 :param filters: Optional filters that can be used to limit 1789 :param filters: Optional filters that can be used to limit
1641 the results returned. Filters are provided 1790 the results returned. Filters are provided
1642 in the form of a dictionary consisting of 1791 in the form of a dictionary consisting of
1643 filter names as the key and filter values 1792 filter names as the key and filter values
1644 as the value. The set of allowable filter 1793 as the value. The set of allowable filter
1645 names/values is dependent on the request 1794 names/values is dependent on the request
1646 being performed. Check the EC2 API guide 1795 being performed. Check the EC2 API guide
1647 for details. 1796 for details.
1648 1797
1649 :rtype: list 1798 :rtype: list
1650 :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup` 1799 :return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
1651 """ 1800 """
1652 params = {} 1801 params = {}
1653 if groupnames: 1802 if groupnames is not None:
1654 self.build_list_params(params, groupnames, 'GroupName') 1803 self.build_list_params(params, groupnames, 'GroupName')
1655 if filters: 1804 if group_ids is not None:
1805 self.build_list_params(params, group_ids, 'GroupId')
1806 if filters is not None:
1656 self.build_filter_params(params, filters) 1807 self.build_filter_params(params, filters)
1808
1657 return self.get_list('DescribeSecurityGroups', params, 1809 return self.get_list('DescribeSecurityGroups', params,
1658 [('item', SecurityGroup)], verb='POST') 1810 [('item', SecurityGroup)], verb='POST')
1659 1811
1660 def create_security_group(self, name, description): 1812 def create_security_group(self, name, description, vpc_id=None):
1661 """ 1813 """
1662 Create a new security group for your account. 1814 Create a new security group for your account.
1663 This will create the security group within the region you 1815 This will create the security group within the region you
1664 are currently connected to. 1816 are currently connected to.
1665 1817
1666 :type name: string 1818 :type name: string
1667 :param name: The name of the new security group 1819 :param name: The name of the new security group
1668 1820
1669 :type description: string 1821 :type description: string
1670 :param description: The description of the new security group 1822 :param description: The description of the new security group
1671 1823
1824 :type vpc_id: string
1825 :param vpc_id: The ID of the VPC to create the security group in,
1826 if any.
1827
1672 :rtype: :class:`boto.ec2.securitygroup.SecurityGroup` 1828 :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
1673 :return: The newly created :class:`boto.ec2.keypair.KeyPair`. 1829 :return: The newly created :class:`boto.ec2.keypair.KeyPair`.
1674 """ 1830 """
1675 params = {'GroupName':name, 'GroupDescription':description} 1831 params = {
1676 group = self.get_object('CreateSecurityGroup', params, SecurityGroup, ve rb='POST') 1832 'GroupName': name,
1833 'GroupDescription': description
1834 }
1835
1836 if vpc_id is not None:
1837 params['VpcId'] = vpc_id
1838
1839 group = self.get_object('CreateSecurityGroup', params,
1840 SecurityGroup, verb='POST')
1677 group.name = name 1841 group.name = name
1678 group.description = description 1842 group.description = description
1679 return group 1843 return group
1680 1844
1681 def delete_security_group(self, name): 1845 def delete_security_group(self, name=None, group_id=None):
1682 """ 1846 """
1683 Delete a security group from your account. 1847 Delete a security group from your account.
1684 1848
1685 :type key_name: string 1849 :type name: string
1686 :param key_name: The name of the keypair to delete 1850 :param name: The name of the security group to delete.
1851
1852 :type group_id: string
1853 :param group_id: The ID of the security group to delete within
1854 a VPC.
1855
1856 :rtype: bool
1857 :return: True if successful.
1687 """ 1858 """
1688 params = {'GroupName':name} 1859 params = {}
1860
1861 if name is not None:
1862 params['GroupName'] = name
1863 elif group_id is not None:
1864 params['GroupId'] = group_id
1865
1689 return self.get_status('DeleteSecurityGroup', params, verb='POST') 1866 return self.get_status('DeleteSecurityGroup', params, verb='POST')
1690 1867
1691 def _authorize_deprecated(self, group_name, src_security_group_name=None, 1868 def authorize_security_group_deprecated(self, group_name,
1692 src_security_group_owner_id=None): 1869 src_security_group_name=None,
1870 src_security_group_owner_id=None,
1871 ip_protocol=None,
1872 from_port=None, to_port=None,
1873 cidr_ip=None):
1693 """ 1874 """
1694 This method is called only when someone tries to authorize a group 1875 NOTE: This method uses the old-style request parameters
1695 without specifying a from_port or to_port. Until recently, that was 1876 that did not allow a port to be specified when
1696 the only way to do group authorization but the EC2 API has been 1877 authorizing a group.
1697 changed to now require a from_port and to_port when specifying a
1698 group. This is a much better approach but I don't want to break
1699 existing boto applications that depend on the old behavior, hence
1700 this kludge.
1701 1878
1702 :type group_name: string 1879 :type group_name: string
1703 :param group_name: The name of the security group you are adding 1880 :param group_name: The name of the security group you are adding
1704 the rule to. 1881 the rule to.
1705 1882
1706 :type src_security_group_name: string 1883 :type src_security_group_name: string
1707 :param src_security_group_name: The name of the security group you are 1884 :param src_security_group_name: The name of the security group you are
1708 granting access to. 1885 granting access to.
1709 1886
1710 :type src_security_group_owner_id: string 1887 :type src_security_group_owner_id: string
1711 :param src_security_group_owner_id: The ID of the owner of the security 1888 :param src_security_group_owner_id: The ID of the owner of the security
1712 group you are granting access to. 1889 group you are granting access to.
1713 1890
1891 :type ip_protocol: string
1892 :param ip_protocol: Either tcp | udp | icmp
1893
1894 :type from_port: int
1895 :param from_port: The beginning port number you are enabling
1896
1897 :type to_port: int
1898 :param to_port: The ending port number you are enabling
1899
1900 :type to_port: string
1901 :param to_port: The CIDR block you are providing access to.
1902 See http://goo.gl/Yj5QC
1903
1714 :rtype: bool 1904 :rtype: bool
1715 :return: True if successful. 1905 :return: True if successful.
1716 """ 1906 """
1717 warnings.warn('FromPort and ToPort now required for group authorization' ,
1718 DeprecationWarning)
1719 params = {'GroupName':group_name} 1907 params = {'GroupName':group_name}
1720 if src_security_group_name: 1908 if src_security_group_name:
1721 params['SourceSecurityGroupName'] = src_security_group_name 1909 params['SourceSecurityGroupName'] = src_security_group_name
1722 if src_security_group_owner_id: 1910 if src_security_group_owner_id:
1723 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id 1911 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
1724 return self.get_status('AuthorizeSecurityGroupIngress', params, verb='PO ST') 1912 if ip_protocol:
1913 params['IpProtocol'] = ip_protocol
1914 if from_port:
1915 params['FromPort'] = from_port
1916 if to_port:
1917 params['ToPort'] = to_port
1918 if cidr_ip:
1919 params['CidrIp'] = cidr_ip
1920 return self.get_status('AuthorizeSecurityGroupIngress', params)
1725 1921
1726 def authorize_security_group(self, group_name, src_security_group_name=None, 1922 def authorize_security_group(self, group_name=None,
1923 src_security_group_name=None,
1727 src_security_group_owner_id=None, 1924 src_security_group_owner_id=None,
1728 ip_protocol=None, from_port=None, to_port=None, 1925 ip_protocol=None, from_port=None, to_port=None,
1729 cidr_ip=None): 1926 cidr_ip=None, group_id=None,
1927 src_security_group_group_id=None):
1730 """ 1928 """
1731 Add a new rule to an existing security group. 1929 Add a new rule to an existing security group.
1732 You need to pass in either src_security_group_name and 1930 You need to pass in either src_security_group_name and
1733 src_security_group_owner_id OR ip_protocol, from_port, to_port, 1931 src_security_group_owner_id OR ip_protocol, from_port, to_port,
1734 and cidr_ip. In other words, either you are authorizing another 1932 and cidr_ip. In other words, either you are authorizing another
1735 group or you are authorizing some ip-based rule. 1933 group or you are authorizing some ip-based rule.
1736 1934
1737 :type group_name: string 1935 :type group_name: string
1738 :param group_name: The name of the security group you are adding 1936 :param group_name: The name of the security group you are adding
1739 the rule to. 1937 the rule to.
(...skipping 10 matching lines...) Expand all
1750 :param ip_protocol: Either tcp | udp | icmp 1948 :param ip_protocol: Either tcp | udp | icmp
1751 1949
1752 :type from_port: int 1950 :type from_port: int
1753 :param from_port: The beginning port number you are enabling 1951 :param from_port: The beginning port number you are enabling
1754 1952
1755 :type to_port: int 1953 :type to_port: int
1756 :param to_port: The ending port number you are enabling 1954 :param to_port: The ending port number you are enabling
1757 1955
1758 :type cidr_ip: string 1956 :type cidr_ip: string
1759 :param cidr_ip: The CIDR block you are providing access to. 1957 :param cidr_ip: The CIDR block you are providing access to.
1760 See http://en.wikipedia.org/wiki/Classless_Inter-Domain_ Routing 1958 See http://goo.gl/Yj5QC
1959
1960 :type group_id: string
1961 :param group_id: ID of the EC2 or VPC security group to modify.
1962 This is required for VPC security groups and
1963 can be used instead of group_name for EC2
1964 security groups.
1965
1966 :type group_id: string
1967 :param group_id: ID of the EC2 or VPC source security group.
1968 This is required for VPC security groups and
1969 can be used instead of group_name for EC2
1970 security groups.
1761 1971
1762 :rtype: bool 1972 :rtype: bool
1763 :return: True if successful. 1973 :return: True if successful.
1764 """ 1974 """
1765 if src_security_group_name: 1975 if src_security_group_name:
1766 if from_port is None and to_port is None and ip_protocol is None: 1976 if from_port is None and to_port is None and ip_protocol is None:
1767 return self._authorize_deprecated(group_name, 1977 return self.authorize_security_group_deprecated(
1768 src_security_group_name, 1978 group_name, src_security_group_name,
1769 src_security_group_owner_id) 1979 src_security_group_owner_id)
1770 params = {'GroupName':group_name} 1980
1981 params = {}
1982
1983 if group_name:
1984 params['GroupName'] = group_name
1985 if group_id:
1986 params['GroupId'] = group_id
1771 if src_security_group_name: 1987 if src_security_group_name:
1772 params['IpPermissions.1.Groups.1.GroupName'] = src_security_group_na me 1988 param_name = 'IpPermissions.1.Groups.1.GroupName'
1989 params[param_name] = src_security_group_name
1773 if src_security_group_owner_id: 1990 if src_security_group_owner_id:
1774 params['IpPermissions.1.Groups.1.UserId'] = src_security_group_owner _id 1991 param_name = 'IpPermissions.1.Groups.1.UserId'
1992 params[param_name] = src_security_group_owner_id
1993 if src_security_group_group_id:
1994 param_name = 'IpPermissions.1.Groups.1.GroupId'
1995 params[param_name] = src_security_group_group_id
1775 if ip_protocol: 1996 if ip_protocol:
1776 params['IpPermissions.1.IpProtocol'] = ip_protocol 1997 params['IpPermissions.1.IpProtocol'] = ip_protocol
1777 if from_port: 1998 if from_port is not None:
1778 params['IpPermissions.1.FromPort'] = from_port 1999 params['IpPermissions.1.FromPort'] = from_port
1779 if to_port: 2000 if to_port is not None:
1780 params['IpPermissions.1.ToPort'] = to_port 2001 params['IpPermissions.1.ToPort'] = to_port
1781 if cidr_ip: 2002 if cidr_ip:
1782 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip 2003 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
1783 return self.get_status('AuthorizeSecurityGroupIngress', params, verb='PO ST')
1784 2004
1785 def _revoke_deprecated(self, group_name, src_security_group_name=None, 2005 return self.get_status('AuthorizeSecurityGroupIngress',
1786 src_security_group_owner_id=None): 2006 params, verb='POST')
2007
2008 def authorize_security_group_egress(group_id,
2009 ip_protocol,
2010 from_port=None,
2011 to_port=None,
2012 src_group_id=None,
2013 cidr_ip=None):
1787 """ 2014 """
1788 This method is called only when someone tries to revoke a group 2015 The action adds one or more egress rules to a VPC security
1789 without specifying a from_port or to_port. Until recently, that was 2016 group. Specifically, this action permits instances in a
1790 the only way to do group revocation but the EC2 API has been 2017 security group to send traffic to one or more destination
1791 changed to now require a from_port and to_port when specifying a 2018 CIDR IP address ranges, or to one or more destination
1792 group. This is a much better approach but I don't want to break 2019 security groups in the same VPC.
1793 existing boto applications that depend on the old behavior, hence 2020 """
1794 this kludge. 2021 params = {
2022 'GroupId': group_id,
2023 'IpPermissions.1.IpProtocol': ip_protocol
2024 }
2025
2026 if from_port is not None:
2027 params['IpPermissions.1.FromPort'] = from_port
2028 if to_port is not None:
2029 params['IpPermissions.1.ToPort'] = to_port
2030 if src_group_id is not None:
2031 params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
2032 if cidr_ip is not None:
2033 params['IpPermissions.1.Groups.1.CidrIp'] = cidr_ip
2034
2035 return self.get_status('AuthorizeSecurityGroupEgress',
2036 params, verb='POST')
2037
2038 def revoke_security_group_deprecated(self, group_name,
2039 src_security_group_name=None,
2040 src_security_group_owner_id=None,
2041 ip_protocol=None,
2042 from_port=None, to_port=None,
2043 cidr_ip=None):
2044 """
2045 NOTE: This method uses the old-style request parameters
2046 that did not allow a port to be specified when
2047 authorizing a group.
2048
2049 Remove an existing rule from an existing security group.
2050 You need to pass in either src_security_group_name and
2051 src_security_group_owner_id OR ip_protocol, from_port, to_port,
2052 and cidr_ip. In other words, either you are revoking another
2053 group or you are revoking some ip-based rule.
1795 2054
1796 :type group_name: string 2055 :type group_name: string
1797 :param group_name: The name of the security group you are adding 2056 :param group_name: The name of the security group you are removing
1798 the rule to. 2057 the rule from.
1799 2058
1800 :type src_security_group_name: string 2059 :type src_security_group_name: string
1801 :param src_security_group_name: The name of the security group you are 2060 :param src_security_group_name: The name of the security group you are
1802 granting access to. 2061 revoking access to.
1803 2062
1804 :type src_security_group_owner_id: string 2063 :type src_security_group_owner_id: string
1805 :param src_security_group_owner_id: The ID of the owner of the security 2064 :param src_security_group_owner_id: The ID of the owner of the security
1806 group you are granting access to. 2065 group you are revoking access to.
2066
2067 :type ip_protocol: string
2068 :param ip_protocol: Either tcp | udp | icmp
2069
2070 :type from_port: int
2071 :param from_port: The beginning port number you are disabling
2072
2073 :type to_port: int
2074 :param to_port: The ending port number you are disabling
2075
2076 :type to_port: string
2077 :param to_port: The CIDR block you are revoking access to.
2078 http://goo.gl/Yj5QC
2079
2080 :type group_id: string
2081 :param group_id: ID of the EC2 or VPC security group to modify.
2082 This is required for VPC security groups and
2083 can be used instead of group_name for EC2
2084 security groups.
2085
2086 :type group_id: string
2087 :param group_id: ID of the EC2 or VPC source security group.
2088 This is required for VPC security groups and
2089 can be used instead of group_name for EC2
2090 security groups.
1807 2091
1808 :rtype: bool 2092 :rtype: bool
1809 :return: True if successful. 2093 :return: True if successful.
1810 """ 2094 """
1811 warnings.warn('FromPort and ToPort now required for group authorization' ,
1812 DeprecationWarning)
1813 params = {'GroupName':group_name} 2095 params = {'GroupName':group_name}
1814 if src_security_group_name: 2096 if src_security_group_name:
1815 params['SourceSecurityGroupName'] = src_security_group_name 2097 params['SourceSecurityGroupName'] = src_security_group_name
1816 if src_security_group_owner_id: 2098 if src_security_group_owner_id:
1817 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id 2099 params['SourceSecurityGroupOwnerId'] = src_security_group_owner_id
1818 return self.get_status('RevokeSecurityGroupIngress', params, verb='POST' ) 2100 if ip_protocol:
2101 params['IpProtocol'] = ip_protocol
2102 if from_port:
2103 params['FromPort'] = from_port
2104 if to_port:
2105 params['ToPort'] = to_port
2106 if cidr_ip:
2107 params['CidrIp'] = cidr_ip
2108 return self.get_status('RevokeSecurityGroupIngress', params)
1819 2109
1820 def revoke_security_group(self, group_name, src_security_group_name=None, 2110 def revoke_security_group(self, group_name, src_security_group_name=None,
1821 src_security_group_owner_id=None, 2111 src_security_group_owner_id=None,
1822 ip_protocol=None, from_port=None, to_port=None, 2112 ip_protocol=None, from_port=None, to_port=None,
1823 cidr_ip=None): 2113 cidr_ip=None, group_id=None,
2114 src_security_group_group_id=None):
1824 """ 2115 """
1825 Remove an existing rule from an existing security group. 2116 Remove an existing rule from an existing security group.
1826 You need to pass in either src_security_group_name and 2117 You need to pass in either src_security_group_name and
1827 src_security_group_owner_id OR ip_protocol, from_port, to_port, 2118 src_security_group_owner_id OR ip_protocol, from_port, to_port,
1828 and cidr_ip. In other words, either you are revoking another 2119 and cidr_ip. In other words, either you are revoking another
1829 group or you are revoking some ip-based rule. 2120 group or you are revoking some ip-based rule.
1830 2121
1831 :type group_name: string 2122 :type group_name: string
1832 :param group_name: The name of the security group you are removing 2123 :param group_name: The name of the security group you are removing
1833 the rule from. 2124 the rule from.
(...skipping 10 matching lines...) Expand all
1844 :param ip_protocol: Either tcp | udp | icmp 2135 :param ip_protocol: Either tcp | udp | icmp
1845 2136
1846 :type from_port: int 2137 :type from_port: int
1847 :param from_port: The beginning port number you are disabling 2138 :param from_port: The beginning port number you are disabling
1848 2139
1849 :type to_port: int 2140 :type to_port: int
1850 :param to_port: The ending port number you are disabling 2141 :param to_port: The ending port number you are disabling
1851 2142
1852 :type cidr_ip: string 2143 :type cidr_ip: string
1853 :param cidr_ip: The CIDR block you are revoking access to. 2144 :param cidr_ip: The CIDR block you are revoking access to.
1854 See http://en.wikipedia.org/wiki/Classless_Inter-Domain_ Routing 2145 See http://goo.gl/Yj5QC
1855 2146
1856 :rtype: bool 2147 :rtype: bool
1857 :return: True if successful. 2148 :return: True if successful.
1858 """ 2149 """
1859 if src_security_group_name: 2150 if src_security_group_name:
1860 if from_port is None and to_port is None and ip_protocol is None: 2151 if from_port is None and to_port is None and ip_protocol is None:
1861 return self._revoke_deprecated(group_name, 2152 return self.revoke_security_group_deprecated(
1862 src_security_group_name, 2153 group_name, src_security_group_name,
1863 src_security_group_owner_id) 2154 src_security_group_owner_id)
1864 params = {'GroupName':group_name} 2155 params = {}
2156 if group_name:
2157 params['GroupName'] = group_name
1865 if src_security_group_name: 2158 if src_security_group_name:
1866 params['IpPermissions.1.Groups.1.GroupName'] = src_security_group_na me 2159 param_name = 'IpPermissions.1.Groups.1.GroupName'
2160 params[param_name] = src_security_group_name
1867 if src_security_group_owner_id: 2161 if src_security_group_owner_id:
1868 params['IpPermissions.1.Groups.1.UserId'] = src_security_group_owner _id 2162 param_name = 'IpPermissions.1.Groups.1.UserId'
2163 params[param_name] = src_security_group_owner_id
1869 if ip_protocol: 2164 if ip_protocol:
1870 params['IpPermissions.1.IpProtocol'] = ip_protocol 2165 params['IpPermissions.1.IpProtocol'] = ip_protocol
1871 if from_port: 2166 if from_port is not None:
1872 params['IpPermissions.1.FromPort'] = from_port 2167 params['IpPermissions.1.FromPort'] = from_port
1873 if to_port: 2168 if to_port is not None:
1874 params['IpPermissions.1.ToPort'] = to_port 2169 params['IpPermissions.1.ToPort'] = to_port
1875 if cidr_ip: 2170 if cidr_ip:
1876 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip 2171 params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
1877 return self.get_status('RevokeSecurityGroupIngress', params, verb='POST' ) 2172 return self.get_status('RevokeSecurityGroupIngress',
2173 params, verb='POST')
1878 2174
1879 # 2175 #
1880 # Regions 2176 # Regions
1881 # 2177 #
1882 2178
1883 def get_all_regions(self, region_names=None, filters=None): 2179 def get_all_regions(self, region_names=None, filters=None):
1884 """ 2180 """
1885 Get all available regions for the EC2 service. 2181 Get all available regions for the EC2 service.
1886 2182
1887 :type region_names: list of str 2183 :type region_names: list of str
(...skipping 10 matching lines...) Expand all
1898 for details. 2194 for details.
1899 2195
1900 :rtype: list 2196 :rtype: list
1901 :return: A list of :class:`boto.ec2.regioninfo.RegionInfo` 2197 :return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
1902 """ 2198 """
1903 params = {} 2199 params = {}
1904 if region_names: 2200 if region_names:
1905 self.build_list_params(params, region_names, 'RegionName') 2201 self.build_list_params(params, region_names, 'RegionName')
1906 if filters: 2202 if filters:
1907 self.build_filter_params(params, filters) 2203 self.build_filter_params(params, filters)
1908 regions = self.get_list('DescribeRegions', params, [('item', RegionInfo )], verb='POST') 2204 regions = self.get_list('DescribeRegions', params,
2205 [('item', RegionInfo)], verb='POST')
1909 for region in regions: 2206 for region in regions:
1910 region.connection_cls = EC2Connection 2207 region.connection_cls = EC2Connection
1911 return regions 2208 return regions
1912 2209
1913 # 2210 #
1914 # Reservation methods 2211 # Reservation methods
1915 # 2212 #
1916 2213
1917 def get_all_reserved_instances_offerings(self, reserved_instances_id=None, 2214 def get_all_reserved_instances_offerings(self, reserved_instances_id=None,
1918 instance_type=None, 2215 instance_type=None,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 if instance_type: 2254 if instance_type:
1958 params['InstanceType'] = instance_type 2255 params['InstanceType'] = instance_type
1959 if availability_zone: 2256 if availability_zone:
1960 params['AvailabilityZone'] = availability_zone 2257 params['AvailabilityZone'] = availability_zone
1961 if product_description: 2258 if product_description:
1962 params['ProductDescription'] = product_description 2259 params['ProductDescription'] = product_description
1963 if filters: 2260 if filters:
1964 self.build_filter_params(params, filters) 2261 self.build_filter_params(params, filters)
1965 2262
1966 return self.get_list('DescribeReservedInstancesOfferings', 2263 return self.get_list('DescribeReservedInstancesOfferings',
1967 params, [('item', ReservedInstancesOffering)], verb ='POST') 2264 params, [('item', ReservedInstancesOffering)],
2265 verb='POST')
1968 2266
1969 def get_all_reserved_instances(self, reserved_instances_id=None, 2267 def get_all_reserved_instances(self, reserved_instances_id=None,
1970 filters=None): 2268 filters=None):
1971 """ 2269 """
1972 Describes Reserved Instance offerings that are available for purchase. 2270 Describes Reserved Instance offerings that are available for purchase.
1973 2271
1974 :type reserved_instance_ids: list 2272 :type reserved_instance_ids: list
1975 :param reserved_instance_ids: A list of the reserved instance ids that 2273 :param reserved_instance_ids: A list of the reserved instance ids that
1976 will be returned. If not provided, all 2274 will be returned. If not provided, all
1977 reserved instances will be returned. 2275 reserved instances will be returned.
(...skipping 13 matching lines...) Expand all
1991 """ 2289 """
1992 params = {} 2290 params = {}
1993 if reserved_instances_id: 2291 if reserved_instances_id:
1994 self.build_list_params(params, reserved_instances_id, 2292 self.build_list_params(params, reserved_instances_id,
1995 'ReservedInstancesId') 2293 'ReservedInstancesId')
1996 if filters: 2294 if filters:
1997 self.build_filter_params(params, filters) 2295 self.build_filter_params(params, filters)
1998 return self.get_list('DescribeReservedInstances', 2296 return self.get_list('DescribeReservedInstances',
1999 params, [('item', ReservedInstance)], verb='POST') 2297 params, [('item', ReservedInstance)], verb='POST')
2000 2298
2001 def purchase_reserved_instance_offering(self, reserved_instances_offering_id , 2299 def purchase_reserved_instance_offering(self,
2300 reserved_instances_offering_id,
2002 instance_count=1): 2301 instance_count=1):
2003 """ 2302 """
2004 Purchase a Reserved Instance for use with your account. 2303 Purchase a Reserved Instance for use with your account.
2005 ** CAUTION ** 2304 ** CAUTION **
2006 This request can result in large amounts of money being charged to your 2305 This request can result in large amounts of money being charged to your
2007 AWS account. Use with caution! 2306 AWS account. Use with caution!
2008 2307
2009 :type reserved_instances_offering_id: string 2308 :type reserved_instances_offering_id: string
2010 :param reserved_instances_offering_id: The offering ID of the Reserved 2309 :param reserved_instances_offering_id: The offering ID of the Reserved
2011 Instance to purchase 2310 Instance to purchase
2012 2311
2013 :type instance_count: int 2312 :type instance_count: int
2014 :param instance_count: The number of Reserved Instances to purchase. 2313 :param instance_count: The number of Reserved Instances to purchase.
2015 Default value is 1. 2314 Default value is 1.
2016 2315
2017 :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance` 2316 :rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
2018 :return: The newly created Reserved Instance 2317 :return: The newly created Reserved Instance
2019 """ 2318 """
2020 params = {'ReservedInstancesOfferingId' : reserved_instances_offering_id , 2319 params = {
2021 'InstanceCount' : instance_count} 2320 'ReservedInstancesOfferingId' : reserved_instances_offering_id,
2321 'InstanceCount' : instance_count}
2022 return self.get_object('PurchaseReservedInstancesOffering', params, 2322 return self.get_object('PurchaseReservedInstancesOffering', params,
2023 ReservedInstance, verb='POST') 2323 ReservedInstance, verb='POST')
2024 2324
2025 # 2325 #
2026 # Monitoring 2326 # Monitoring
2027 # 2327 #
2028 2328
2329 def monitor_instances(self, instance_ids):
2330 """
2331 Enable CloudWatch monitoring for the supplied instances.
2332
2333 :type instance_id: list of strings
2334 :param instance_id: The instance ids
2335
2336 :rtype: list
2337 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
2338 """
2339 params = {}
2340 self.build_list_params(params, instance_ids, 'InstanceId')
2341 return self.get_list('MonitorInstances', params,
2342 [('item', InstanceInfo)], verb='POST')
2343
2029 def monitor_instance(self, instance_id): 2344 def monitor_instance(self, instance_id):
2030 """ 2345 """
2346 Deprecated Version, maintained for backward compatibility.
2031 Enable CloudWatch monitoring for the supplied instance. 2347 Enable CloudWatch monitoring for the supplied instance.
2032 2348
2033 :type instance_id: string 2349 :type instance_id: string
2034 :param instance_id: The instance id 2350 :param instance_id: The instance id
2035 2351
2036 :rtype: list 2352 :rtype: list
2037 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` 2353 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
2038 """ 2354 """
2039 params = {'InstanceId' : instance_id} 2355 return self.monitor_instances([instance_id])
2040 return self.get_list('MonitorInstances', params, 2356
2357 def unmonitor_instances(self, instance_ids):
2358 """
2359 Disable CloudWatch monitoring for the supplied instance.
2360
2361 :type instance_id: list of string
2362 :param instance_id: The instance id
2363
2364 :rtype: list
2365 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
2366 """
2367 params = {}
2368 self.build_list_params(params, instance_ids, 'InstanceId')
2369 return self.get_list('UnmonitorInstances', params,
2041 [('item', InstanceInfo)], verb='POST') 2370 [('item', InstanceInfo)], verb='POST')
2042 2371
2043 def unmonitor_instance(self, instance_id): 2372 def unmonitor_instance(self, instance_id):
2044 """ 2373 """
2374 Deprecated Version, maintained for backward compatibility.
2045 Disable CloudWatch monitoring for the supplied instance. 2375 Disable CloudWatch monitoring for the supplied instance.
2046 2376
2047 :type instance_id: string 2377 :type instance_id: string
2048 :param instance_id: The instance id 2378 :param instance_id: The instance id
2049 2379
2050 :rtype: list 2380 :rtype: list
2051 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo` 2381 :return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
2052 """ 2382 """
2053 params = {'InstanceId' : instance_id} 2383 return self.unmonitor_instances([instance_id])
2054 return self.get_list('UnmonitorInstances', params,
2055 [('item', InstanceInfo)], verb='POST')
2056 2384
2057 # 2385 #
2058 # Bundle Windows Instances 2386 # Bundle Windows Instances
2059 # 2387 #
2060 2388
2061 def bundle_instance(self, instance_id, 2389 def bundle_instance(self, instance_id,
2062 s3_bucket, 2390 s3_bucket,
2063 s3_prefix, 2391 s3_prefix,
2064 s3_upload_policy): 2392 s3_upload_policy):
2065 """ 2393 """
2066 Bundle Windows instance. 2394 Bundle Windows instance.
2067 2395
2068 :type instance_id: string 2396 :type instance_id: string
2069 :param instance_id: The instance id 2397 :param instance_id: The instance id
2070 2398
2071 :type s3_bucket: string 2399 :type s3_bucket: string
2072 :param s3_bucket: The bucket in which the AMI should be stored. 2400 :param s3_bucket: The bucket in which the AMI should be stored.
2073 2401
2074 :type s3_prefix: string 2402 :type s3_prefix: string
2075 :param s3_prefix: The beginning of the file name for the AMI. 2403 :param s3_prefix: The beginning of the file name for the AMI.
2076 2404
2077 :type s3_upload_policy: string 2405 :type s3_upload_policy: string
2078 :param s3_upload_policy: Base64 encoded policy that specifies condition 2406 :param s3_upload_policy: Base64 encoded policy that specifies condition
2079 and permissions for Amazon EC2 to upload the 2407 and permissions for Amazon EC2 to upload the
2080 user's image into Amazon S3. 2408 user's image into Amazon S3.
2081 """ 2409 """
2082 2410
2083 params = {'InstanceId' : instance_id, 2411 params = {'InstanceId' : instance_id,
2084 'Storage.S3.Bucket' : s3_bucket, 2412 'Storage.S3.Bucket' : s3_bucket,
2085 'Storage.S3.Prefix' : s3_prefix, 2413 'Storage.S3.Prefix' : s3_prefix,
2086 'Storage.S3.UploadPolicy' : s3_upload_policy} 2414 'Storage.S3.UploadPolicy' : s3_upload_policy}
2087 s3auth = boto.auth.get_auth_handler(None, boto.config, self.provider, [' s3']) 2415 s3auth = boto.auth.get_auth_handler(None, boto.config,
2416 self.provider, ['s3'])
2088 params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id 2417 params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
2089 signature = s3auth.sign_string(s3_upload_policy) 2418 signature = s3auth.sign_string(s3_upload_policy)
2090 params['Storage.S3.UploadPolicySignature'] = signature 2419 params['Storage.S3.UploadPolicySignature'] = signature
2091 return self.get_object('BundleInstance', params, BundleInstanceTask, ver b='POST') 2420 return self.get_object('BundleInstance', params,
2421 BundleInstanceTask, verb='POST')
2092 2422
2093 def get_all_bundle_tasks(self, bundle_ids=None, filters=None): 2423 def get_all_bundle_tasks(self, bundle_ids=None, filters=None):
2094 """ 2424 """
2095 Retrieve current bundling tasks. If no bundle id is specified, all 2425 Retrieve current bundling tasks. If no bundle id is specified, all
2096 tasks are retrieved. 2426 tasks are retrieved.
2097 2427
2098 :type bundle_ids: list 2428 :type bundle_ids: list
2099 :param bundle_ids: A list of strings containing identifiers for 2429 :param bundle_ids: A list of strings containing identifiers for
2100 previously created bundling tasks. 2430 previously created bundling tasks.
2101 2431
2102 :type filters: dict 2432 :type filters: dict
2103 :param filters: Optional filters that can be used to limit 2433 :param filters: Optional filters that can be used to limit
2104 the results returned. Filters are provided 2434 the results returned. Filters are provided
2105 in the form of a dictionary consisting of 2435 in the form of a dictionary consisting of
2106 filter names as the key and filter values 2436 filter names as the key and filter values
2107 as the value. The set of allowable filter 2437 as the value. The set of allowable filter
2108 names/values is dependent on the request 2438 names/values is dependent on the request
2109 being performed. Check the EC2 API guide 2439 being performed. Check the EC2 API guide
2110 for details. 2440 for details.
2111 2441
2112 """ 2442 """
2113 2443
2114 params = {} 2444 params = {}
2115 if bundle_ids: 2445 if bundle_ids:
2116 self.build_list_params(params, bundle_ids, 'BundleId') 2446 self.build_list_params(params, bundle_ids, 'BundleId')
2117 if filters: 2447 if filters:
2118 self.build_filter_params(params, filters) 2448 self.build_filter_params(params, filters)
2119 return self.get_list('DescribeBundleTasks', params, 2449 return self.get_list('DescribeBundleTasks', params,
2120 [('item', BundleInstanceTask)], verb='POST') 2450 [('item', BundleInstanceTask)], verb='POST')
2121 2451
2122 def cancel_bundle_task(self, bundle_id): 2452 def cancel_bundle_task(self, bundle_id):
2123 """ 2453 """
2124 Cancel a previously submitted bundle task 2454 Cancel a previously submitted bundle task
2125 2455
2126 :type bundle_id: string 2456 :type bundle_id: string
2127 :param bundle_id: The identifier of the bundle task to cancel. 2457 :param bundle_id: The identifier of the bundle task to cancel.
2128 """ 2458 """
2129 2459
2130 params = {'BundleId' : bundle_id} 2460 params = {'BundleId' : bundle_id}
2131 return self.get_object('CancelBundleTask', params, BundleInstanceTask, v erb='POST') 2461 return self.get_object('CancelBundleTask', params,
2462 BundleInstanceTask, verb='POST')
2132 2463
2133 def get_password_data(self, instance_id): 2464 def get_password_data(self, instance_id):
2134 """ 2465 """
2135 Get encrypted administrator password for a Windows instance. 2466 Get encrypted administrator password for a Windows instance.
2136 2467
2137 :type instance_id: string 2468 :type instance_id: string
2138 :param instance_id: The identifier of the instance to retrieve the 2469 :param instance_id: The identifier of the instance to retrieve the
2139 password for. 2470 password for.
2140 """ 2471 """
2141 2472
2142 params = {'InstanceId' : instance_id} 2473 params = {'InstanceId' : instance_id}
2143 rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST') 2474 rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST')
2144 return rs.passwordData 2475 return rs.passwordData
2145 2476
2146 # 2477 #
2147 # Cluster Placement Groups 2478 # Cluster Placement Groups
2148 # 2479 #
2149 2480
2150 def get_all_placement_groups(self, groupnames=None, filters=None): 2481 def get_all_placement_groups(self, groupnames=None, filters=None):
2151 """ 2482 """
2152 Get all placement groups associated with your account in a region. 2483 Get all placement groups associated with your account in a region.
2153 2484
2154 :type groupnames: list 2485 :type groupnames: list
2155 :param groupnames: A list of the names of placement groups to retrieve. 2486 :param groupnames: A list of the names of placement groups to retrieve.
2156 If not provided, all placement groups will be 2487 If not provided, all placement groups will be
(...skipping 26 matching lines...) Expand all
2183 This will create the placement group within the region you 2514 This will create the placement group within the region you
2184 are currently connected to. 2515 are currently connected to.
2185 2516
2186 :type name: string 2517 :type name: string
2187 :param name: The name of the new placement group 2518 :param name: The name of the new placement group
2188 2519
2189 :type strategy: string 2520 :type strategy: string
2190 :param strategy: The placement strategy of the new placement group. 2521 :param strategy: The placement strategy of the new placement group.
2191 Currently, the only acceptable value is "cluster". 2522 Currently, the only acceptable value is "cluster".
2192 2523
2193 :rtype: :class:`boto.ec2.placementgroup.PlacementGroup` 2524 :rtype: bool
2194 :return: The newly created :class:`boto.ec2.keypair.KeyPair`. 2525 :return: True if successful
2195 """ 2526 """
2196 params = {'GroupName':name, 'Strategy':strategy} 2527 params = {'GroupName':name, 'Strategy':strategy}
2197 group = self.get_status('CreatePlacementGroup', params, verb='POST') 2528 group = self.get_status('CreatePlacementGroup', params, verb='POST')
2198 return group 2529 return group
2199 2530
2200 def delete_placement_group(self, name): 2531 def delete_placement_group(self, name):
2201 """ 2532 """
2202 Delete a placement group from your account. 2533 Delete a placement group from your account.
2203 2534
2204 :type key_name: string 2535 :type key_name: string
2205 :param key_name: The name of the keypair to delete 2536 :param key_name: The name of the keypair to delete
2206 """ 2537 """
2207 params = {'GroupName':name} 2538 params = {'GroupName':name}
2208 return self.get_status('DeletePlacementGroup', params, verb='POST') 2539 return self.get_status('DeletePlacementGroup', params, verb='POST')
2209 2540
2210 # Tag methods 2541 # Tag methods
2211 2542
2212 def build_tag_param_list(self, params, tags): 2543 def build_tag_param_list(self, params, tags):
2213 keys = tags.keys() 2544 keys = tags.keys()
2214 keys.sort() 2545 keys.sort()
2215 i = 1 2546 i = 1
2216 for key in keys: 2547 for key in keys:
2217 value = tags[key] 2548 value = tags[key]
2218 params['Tag.%d.Key'%i] = key 2549 params['Tag.%d.Key'%i] = key
2219 if value is not None: 2550 if value is not None:
2220 params['Tag.%d.Value'%i] = value 2551 params['Tag.%d.Value'%i] = value
2221 i += 1 2552 i += 1
2222 2553
2223 def get_all_tags(self, tags=None, filters=None): 2554 def get_all_tags(self, filters=None):
2224 """ 2555 """
2225 Retrieve all the metadata tags associated with your account. 2556 Retrieve all the metadata tags associated with your account.
2226 2557
2227 :type tags: list
2228 :param tags: A list of mumble
2229
2230 :type filters: dict 2558 :type filters: dict
2231 :param filters: Optional filters that can be used to limit 2559 :param filters: Optional filters that can be used to limit
2232 the results returned. Filters are provided 2560 the results returned. Filters are provided
2233 in the form of a dictionary consisting of 2561 in the form of a dictionary consisting of
2234 filter names as the key and filter values 2562 filter names as the key and filter values
2235 as the value. The set of allowable filter 2563 as the value. The set of allowable filter
2236 names/values is dependent on the request 2564 names/values is dependent on the request
2237 being performed. Check the EC2 API guide 2565 being performed. Check the EC2 API guide
2238 for details. 2566 for details.
2239 2567
2240 :rtype: dict 2568 :rtype: dict
2241 :return: A dictionary containing metadata tags 2569 :return: A dictionary containing metadata tags
2242 """ 2570 """
2243 params = {} 2571 params = {}
2244 if tags:
2245 self.build_list_params(params, instance_ids, 'InstanceId')
2246 if filters: 2572 if filters:
2247 self.build_filter_params(params, filters) 2573 self.build_filter_params(params, filters)
2248 return self.get_list('DescribeTags', params, [('item', Tag)], verb='POST ') 2574 return self.get_list('DescribeTags', params,
2575 [('item', Tag)], verb='POST')
2249 2576
2250 def create_tags(self, resource_ids, tags): 2577 def create_tags(self, resource_ids, tags):
2251 """ 2578 """
2252 Create new metadata tags for the specified resource ids. 2579 Create new metadata tags for the specified resource ids.
2253 2580
2254 :type resource_ids: list 2581 :type resource_ids: list
2255 :param resource_ids: List of strings 2582 :param resource_ids: List of strings
2256 2583
2257 :type tags: dict 2584 :type tags: dict
2258 :param tags: A dictionary containing the name/value pairs 2585 :param tags: A dictionary containing the name/value pairs.
2586 If you want to create only a tag name, the
2587 value for that tag should be the empty string
2588 (e.g. '').
2259 2589
2260 """ 2590 """
2261 params = {} 2591 params = {}
2262 self.build_list_params(params, resource_ids, 'ResourceId') 2592 self.build_list_params(params, resource_ids, 'ResourceId')
2263 self.build_tag_param_list(params, tags) 2593 self.build_tag_param_list(params, tags)
2264 return self.get_status('CreateTags', params, verb='POST') 2594 return self.get_status('CreateTags', params, verb='POST')
2265 2595
2266 def delete_tags(self, resource_ids, tags): 2596 def delete_tags(self, resource_ids, tags):
2267 """ 2597 """
2268 Delete metadata tags for the specified resource ids. 2598 Delete metadata tags for the specified resource ids.
2269 2599
2270 :type resource_ids: list 2600 :type resource_ids: list
2271 :param resource_ids: List of strings 2601 :param resource_ids: List of strings
2272 2602
2273 :type tags: dict or list 2603 :type tags: dict or list
2274 :param tags: Either a dictionary containing name/value pairs 2604 :param tags: Either a dictionary containing name/value pairs
2275 or a list containing just tag names. 2605 or a list containing just tag names.
2276 If you pass in a dictionary, the values must 2606 If you pass in a dictionary, the values must
2277 match the actual tag values or the tag will 2607 match the actual tag values or the tag will
2278 not be deleted. 2608 not be deleted. If you pass in a value of None
2609 for the tag value, all tags with that name will
2610 be deleted.
2279 2611
2280 """ 2612 """
2281 if isinstance(tags, list): 2613 if isinstance(tags, list):
2282 tags = {}.fromkeys(tags, None) 2614 tags = {}.fromkeys(tags, None)
2283 params = {} 2615 params = {}
2284 self.build_list_params(params, resource_ids, 'ResourceId') 2616 self.build_list_params(params, resource_ids, 'ResourceId')
2285 self.build_tag_param_list(params, tags) 2617 self.build_tag_param_list(params, tags)
2286 return self.get_status('DeleteTags', params, verb='POST') 2618 return self.get_status('DeleteTags', params, verb='POST')
2287 2619
OLDNEW
« no previous file with comments | « boto/ec2/cloudwatch/metric.py ('k') | boto/ec2/ec2object.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698