-
Notifications
You must be signed in to change notification settings - Fork 0
/
connection.py
2844 lines (2366 loc) · 111 KB
/
connection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
# Copyright (c) 2010, Eucalyptus Systems, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
"""
Represents a connection to the EC2 service.
"""
import base64
import warnings
from datetime import datetime
from datetime import timedelta
import boto
from boto.connection import AWSQueryConnection
from boto.resultset import ResultSet
from boto.ec2.image import Image, ImageAttribute
from boto.ec2.instance import Reservation, Instance
from boto.ec2.instance import ConsoleOutput, InstanceAttribute
from boto.ec2.keypair import KeyPair
from boto.ec2.address import Address
from boto.ec2.volume import Volume
from boto.ec2.snapshot import Snapshot
from boto.ec2.snapshot import SnapshotAttribute
from boto.ec2.zone import Zone
from boto.ec2.securitygroup import SecurityGroup
from boto.ec2.regioninfo import RegionInfo
from boto.ec2.instanceinfo import InstanceInfo
from boto.ec2.reservedinstance import ReservedInstancesOffering
from boto.ec2.reservedinstance import ReservedInstance
from boto.ec2.spotinstancerequest import SpotInstanceRequest
from boto.ec2.spotpricehistory import SpotPriceHistory
from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
from boto.ec2.bundleinstance import BundleInstanceTask
from boto.ec2.placementgroup import PlacementGroup
from boto.ec2.tag import Tag
from boto.ec2.instancestatus import InstanceStatusSet
from boto.ec2.networkinterface import NetworkInterface
from boto.exception import EC2ResponseError
#boto.set_stream_logger('ec2')
class EC2Connection(AWSQueryConnection):
APIVersion = boto.config.get('Boto', 'ec2_version', '2011-12-15')
DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
'ec2.us-east-1.amazonaws.com')
ResponseError = EC2ResponseError
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=True, host=None, port=None,
proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
api_version=None, security_token=None):
"""
Init method to create a new connection to EC2.
"""
if not region:
region = RegionInfo(self, self.DefaultRegionName,
self.DefaultRegionEndpoint)
self.region = region
AWSQueryConnection.__init__(self, aws_access_key_id,
aws_secret_access_key,
is_secure, port, proxy, proxy_port,
proxy_user, proxy_pass,
self.region.endpoint, debug,
https_connection_factory, path,
security_token)
if api_version:
self.APIVersion = api_version
def _required_auth_capability(self):
return ['ec2']
def get_params(self):
"""
Returns a dictionary containing the value of of all of the keyword
arguments passed when constructing this connection.
"""
param_names = ['aws_access_key_id', 'aws_secret_access_key',
'is_secure', 'port', 'proxy', 'proxy_port',
'proxy_user', 'proxy_pass',
'debug', 'https_connection_factory']
params = {}
for name in param_names:
params[name] = getattr(self, name)
return params
def build_filter_params(self, params, filters):
i = 1
for name in filters:
aws_name = name
if not aws_name.startswith('tag:'):
aws_name = name.replace('_', '-')
params['Filter.%d.Name' % i] = aws_name
value = filters[name]
if not isinstance(value, list):
value = [value]
j = 1
for v in value:
params['Filter.%d.Value.%d' % (i,j)] = v
j += 1
i += 1
# Image methods
def get_all_images(self, image_ids=None, owners=None,
executable_by=None, filters=None):
"""
Retrieve all the EC2 images available on your account.
:type image_ids: list
:param image_ids: A list of strings with the image IDs wanted
:type owners: list
:param owners: A list of owner IDs
:type executable_by: list
:param executable_by: Returns AMIs for which the specified
user ID has explicit launch permissions
:type filters: dict
:param filters: Optional filters that can be used to limit
the results returned. Filters are provided
in the form of a dictionary consisting of
filter names as the key and filter values
as the value. The set of allowable filter
names/values is dependent on the request
being performed. Check the EC2 API guide
for details.
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
params = {}
if image_ids:
self.build_list_params(params, image_ids, 'ImageId')
if owners:
self.build_list_params(params, owners, 'Owner')
if executable_by:
self.build_list_params(params, executable_by, 'ExecutableBy')
if filters:
self.build_filter_params(params, filters)
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
def get_all_kernels(self, kernel_ids=None, owners=None):
"""
Retrieve all the EC2 kernels available on your account.
Constructs a filter to allow the processing to happen server side.
:type kernel_ids: list
:param kernel_ids: A list of strings with the image IDs wanted
:type owners: list
:param owners: A list of owner IDs
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
params = {}
if kernel_ids:
self.build_list_params(params, kernel_ids, 'ImageId')
if owners:
self.build_list_params(params, owners, 'Owner')
filter = {'image-type' : 'kernel'}
self.build_filter_params(params, filter)
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
def get_all_ramdisks(self, ramdisk_ids=None, owners=None):
"""
Retrieve all the EC2 ramdisks available on your account.
Constructs a filter to allow the processing to happen server side.
:type ramdisk_ids: list
:param ramdisk_ids: A list of strings with the image IDs wanted
:type owners: list
:param owners: A list of owner IDs
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
params = {}
if ramdisk_ids:
self.build_list_params(params, ramdisk_ids, 'ImageId')
if owners:
self.build_list_params(params, owners, 'Owner')
filter = {'image-type' : 'ramdisk'}
self.build_filter_params(params, filter)
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
def get_image(self, image_id):
"""
Shortcut method to retrieve a specific image (AMI).
:type image_id: string
:param image_id: the ID of the Image to retrieve
:rtype: :class:`boto.ec2.image.Image`
:return: The EC2 Image specified or None if the image is not found
"""
try:
return self.get_all_images(image_ids=[image_id])[0]
except IndexError: # None of those images available
return None
def register_image(self, name=None, description=None, image_location=None,
architecture=None, kernel_id=None, ramdisk_id=None,
root_device_name=None, block_device_map=None):
"""
Register an image.
:type name: string
:param name: The name of the AMI. Valid only for EBS-based images.
:type description: string
:param description: The description of the AMI.
:type image_location: string
:param image_location: Full path to your AMI manifest in
Amazon S3 storage.
Only used for S3-based AMI's.
:type architecture: string
:param architecture: The architecture of the AMI. Valid choices are:
i386 | x86_64
:type kernel_id: string
:param kernel_id: The ID of the kernel with which to launch
the instances
:type root_device_name: string
:param root_device_name: The root device name (e.g. /dev/sdh)
:type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
:param block_device_map: A BlockDeviceMapping data structure
describing the EBS volumes associated
with the Image.
:rtype: string
:return: The new image id
"""
params = {}
if name:
params['Name'] = name
if description:
params['Description'] = description
if architecture:
params['Architecture'] = architecture
if kernel_id:
params['KernelId'] = kernel_id
if ramdisk_id:
params['RamdiskId'] = ramdisk_id
if image_location:
params['ImageLocation'] = image_location
if root_device_name:
params['RootDeviceName'] = root_device_name
if block_device_map:
block_device_map.build_list_params(params)
rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
image_id = getattr(rs, 'imageId', None)
return image_id
def deregister_image(self, image_id, delete_snapshot=False):
"""
Unregister an AMI.
:type image_id: string
:param image_id: the ID of the Image to unregister
:type delete_snapshot: bool
:param delete_snapshot: Set to True if we should delete the
snapshot associated with an EBS volume
mounted at /dev/sda1
:rtype: bool
:return: True if successful
"""
snapshot_id = None
if delete_snapshot:
image = self.get_image(image_id)
for key in image.block_device_mapping:
if key == "/dev/sda1":
snapshot_id = image.block_device_mapping[key].snapshot_id
break
result = self.get_status('DeregisterImage',
{'ImageId':image_id}, verb='POST')
if result and snapshot_id:
return result and self.delete_snapshot(snapshot_id)
return result
def create_image(self, instance_id, name,
description=None, no_reboot=False):
"""
Will create an AMI from the instance in the running or stopped
state.
:type instance_id: string
:param instance_id: the ID of the instance to image.
:type name: string
:param name: The name of the new image
:type description: string
:param description: An optional human-readable string describing
the contents and purpose of the AMI.
:type no_reboot: bool
:param no_reboot: An optional flag indicating that the bundling process
should not attempt to shutdown the instance before
bundling. If this flag is True, the responsibility
of maintaining file system integrity is left to the
owner of the instance.
:rtype: string
:return: The new image id
"""
params = {'InstanceId' : instance_id,
'Name' : name}
if description:
params['Description'] = description
if no_reboot:
params['NoReboot'] = 'true'
img = self.get_object('CreateImage', params, Image, verb='POST')
return img.id
# ImageAttribute methods
def get_image_attribute(self, image_id, attribute='launchPermission'):
"""
Gets an attribute from an image.
:type image_id: string
:param image_id: The Amazon image id for which you want info about
:type attribute: string
:param attribute: The attribute you need information about.
Valid choices are:
* launchPermission
* productCodes
* blockDeviceMapping
:rtype: :class:`boto.ec2.image.ImageAttribute`
:return: An ImageAttribute object representing the value of the
attribute requested
"""
params = {'ImageId' : image_id,
'Attribute' : attribute}
return self.get_object('DescribeImageAttribute', params,
ImageAttribute, verb='POST')
def modify_image_attribute(self, image_id, attribute='launchPermission',
operation='add', user_ids=None, groups=None,
product_codes=None):
"""
Changes an attribute of an image.
:type image_id: string
:param image_id: The image id you wish to change
:type attribute: string
:param attribute: The attribute you wish to change
:type operation: string
:param operation: Either add or remove (this is required for changing
launchPermissions)
:type user_ids: list
:param user_ids: The Amazon IDs of users to add/remove attributes
:type groups: list
:param groups: The groups to add/remove attributes
:type product_codes: list
:param product_codes: Amazon DevPay product code. Currently only one
product code can be associated with an AMI. Once
set, the product code cannot be changed or reset.
"""
params = {'ImageId' : image_id,
'Attribute' : attribute,
'OperationType' : operation}
if user_ids:
self.build_list_params(params, user_ids, 'UserId')
if groups:
self.build_list_params(params, groups, 'UserGroup')
if product_codes:
self.build_list_params(params, product_codes, 'ProductCode')
return self.get_status('ModifyImageAttribute', params, verb='POST')
def reset_image_attribute(self, image_id, attribute='launchPermission'):
"""
Resets an attribute of an AMI to its default value.
:type image_id: string
:param image_id: ID of the AMI for which an attribute will be described
:type attribute: string
:param attribute: The attribute to reset
:rtype: bool
:return: Whether the operation succeeded or not
"""
params = {'ImageId' : image_id,
'Attribute' : attribute}
return self.get_status('ResetImageAttribute', params, verb='POST')
# Instance methods
def get_all_instances(self, instance_ids=None, filters=None):
"""
Retrieve all the instances associated with your account.
:type instance_ids: list
:param instance_ids: A list of strings of instance IDs
:type filters: dict
:param filters: Optional filters that can be used to limit
the results returned. Filters are provided
in the form of a dictionary consisting of
filter names as the key and filter values
as the value. The set of allowable filter
names/values is dependent on the request
being performed. Check the EC2 API guide
for details.
:rtype: list
:return: A list of :class:`boto.ec2.instance.Reservation`
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
if filters:
if 'group-id' in filters:
gid = filters.get('group-id')
if not gid.startswith('sg-') or len(gid) != 11:
warnings.warn(
"The group-id filter now requires a security group "
"identifier (sg-*) instead of a group name. To filter "
"by group name use the 'group-name' filter instead.",
UserWarning)
self.build_filter_params(params, filters)
return self.get_list('DescribeInstances', params,
[('item', Reservation)], verb='POST')
def get_all_instance_status(self, instance_ids=None,
max_results=None, next_token=None,
filters=None):
"""
Retrieve all the instances in your account scheduled for maintenance.
:type instance_ids: list
:param instance_ids: A list of strings of instance IDs
:type max_results: int
:param max_results: The maximum number of paginated instance
items per response.
:type next_token: str
:param next_token: A string specifying the next paginated set
of results to return.
:type filters: dict
:param filters: Optional filters that can be used to limit
the results returned. Filters are provided
in the form of a dictionary consisting of
filter names as the key and filter values
as the value. The set of allowable filter
names/values is dependent on the request
being performed. Check the EC2 API guide
for details.
:rtype: list
:return: A list of instances that have maintenance scheduled.
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
if max_results:
params['MaxResults'] = max_results
if next_token:
params['NextToken'] = next_token
if filters:
self.build_filter_params(params, filters)
return self.get_object('DescribeInstanceStatus', params,
InstanceStatusSet, verb='POST')
def run_instances(self, image_id, min_count=1, max_count=1,
key_name=None, security_groups=None,
user_data=None, addressing_type=None,
instance_type='m1.small', placement=None,
kernel_id=None, ramdisk_id=None,
monitoring_enabled=False, subnet_id=None,
block_device_map=None,
disable_api_termination=False,
instance_initiated_shutdown_behavior=None,
private_ip_address=None,
placement_group=None, client_token=None,
security_group_ids=None):
"""
Runs an image on EC2.
:type image_id: string
:param image_id: The ID of the image to run
:type min_count: int
:param min_count: The minimum number of instances to launch
:type max_count: int
:param max_count: The maximum number of instances to launch
:type key_name: string
:param key_name: The name of the key pair with which to launch instances
:type security_groups: list of strings
:param security_groups: The names of the security groups with which to
associate instances
:type user_data: string
:param user_data: The user data passed to the launched instances
:type instance_type: string
:param instance_type: The type of instance to run:
* m1.small
* m1.large
* m1.xlarge
* c1.medium
* c1.xlarge
* m2.xlarge
* m2.2xlarge
* m2.4xlarge
* cc1.4xlarge
* t1.micro
:type placement: string
:param placement: The availability zone in which to launch the instances
:type kernel_id: string
:param kernel_id: The ID of the kernel with which to launch the
instances
:type ramdisk_id: string
:param ramdisk_id: The ID of the RAM disk with which to launch the
instances
:type monitoring_enabled: bool
:param monitoring_enabled: Enable CloudWatch monitoring on the instance.
:type subnet_id: string
:param subnet_id: The subnet ID within which to launch the instances
for VPC.
:type private_ip_address: string
:param private_ip_address: If you're using VPC, you can optionally use
this parameter to assign the instance a
specific available IP address from the
subnet (e.g., 10.0.0.25).
:type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
:param block_device_map: A BlockDeviceMapping data structure
describing the EBS volumes associated
with the Image.
:type disable_api_termination: bool
:param disable_api_termination: If True, the instances will be locked
and will not be able to be terminated
via the API.
:type instance_initiated_shutdown_behavior: string
:param instance_initiated_shutdown_behavior: Specifies whether the
instance stops or
terminates on
instance-initiated
shutdown.
Valid values are:
* stop
* terminate
:type placement_group: string
:param placement_group: If specified, this is the name of the placement
group in which the instance(s) will be launched.
:type client_token: string
:param client_token: Unique, case-sensitive identifier you provide
to ensure idempotency of the request.
Maximum 64 ASCII characters
:rtype: Reservation
:return: The :class:`boto.ec2.instance.Reservation` associated with
the request for machines
:type security_group_ids: list of strings
:param security_group_ids: The ID of the VPC security groups with
which to associate instances
"""
params = {'ImageId':image_id,
'MinCount':min_count,
'MaxCount': max_count}
if key_name:
params['KeyName'] = key_name
if security_group_ids:
l = []
for group in security_group_ids:
if isinstance(group, SecurityGroup):
l.append(group.id)
else:
l.append(group)
self.build_list_params(params, l, 'SecurityGroupId')
if security_groups:
l = []
for group in security_groups:
if isinstance(group, SecurityGroup):
l.append(group.name)
else:
l.append(group)
self.build_list_params(params, l, 'SecurityGroup')
if user_data:
params['UserData'] = base64.b64encode(user_data)
if addressing_type:
params['AddressingType'] = addressing_type
if instance_type:
params['InstanceType'] = instance_type
if placement:
params['Placement.AvailabilityZone'] = placement
if placement_group:
params['Placement.GroupName'] = placement_group
if kernel_id:
params['KernelId'] = kernel_id
if ramdisk_id:
params['RamdiskId'] = ramdisk_id
if monitoring_enabled:
params['Monitoring.Enabled'] = 'true'
if subnet_id:
params['SubnetId'] = subnet_id
if private_ip_address:
params['PrivateIpAddress'] = private_ip_address
if block_device_map:
block_device_map.build_list_params(params)
if disable_api_termination:
params['DisableApiTermination'] = 'true'
if instance_initiated_shutdown_behavior:
val = instance_initiated_shutdown_behavior
params['InstanceInitiatedShutdownBehavior'] = val
if client_token:
params['ClientToken'] = client_token
return self.get_object('RunInstances', params, Reservation, verb='POST')
def terminate_instances(self, instance_ids=None):
"""
Terminate the instances specified
:type instance_ids: list
:param instance_ids: A list of strings of the Instance IDs to terminate
:rtype: list
:return: A list of the instances terminated
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
return self.get_list('TerminateInstances', params,
[('item', Instance)], verb='POST')
def stop_instances(self, instance_ids=None, force=False):
"""
Stop the instances specified
:type instance_ids: list
:param instance_ids: A list of strings of the Instance IDs to stop
:type force: bool
:param force: Forces the instance to stop
:rtype: list
:return: A list of the instances stopped
"""
params = {}
if force:
params['Force'] = 'true'
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
return self.get_list('StopInstances', params,
[('item', Instance)], verb='POST')
def start_instances(self, instance_ids=None):
"""
Start the instances specified
:type instance_ids: list
:param instance_ids: A list of strings of the Instance IDs to start
:rtype: list
:return: A list of the instances started
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
return self.get_list('StartInstances', params,
[('item', Instance)], verb='POST')
def get_console_output(self, instance_id):
"""
Retrieves the console output for the specified instance.
:type instance_id: string
:param instance_id: The instance ID of a running instance on the cloud.
:rtype: :class:`boto.ec2.instance.ConsoleOutput`
:return: The console output as a ConsoleOutput object
"""
params = {}
self.build_list_params(params, [instance_id], 'InstanceId')
return self.get_object('GetConsoleOutput', params,
ConsoleOutput, verb='POST')
def reboot_instances(self, instance_ids=None):
"""
Reboot the specified instances.
:type instance_ids: list
:param instance_ids: The instances to terminate and reboot
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
return self.get_status('RebootInstances', params)
def confirm_product_instance(self, product_code, instance_id):
params = {'ProductCode' : product_code,
'InstanceId' : instance_id}
rs = self.get_object('ConfirmProductInstance', params,
ResultSet, verb='POST')
return (rs.status, rs.ownerId)
# InstanceAttribute methods
def get_instance_attribute(self, instance_id, attribute):
"""
Gets an attribute from an instance.
:type instance_id: string
:param instance_id: The Amazon id of the instance
:type attribute: string
:param attribute: The attribute you need information about
Valid choices are:
* instanceType|kernel|ramdisk|userData|
* disableApiTermination|
* instanceInitiatedShutdownBehavior|
* rootDeviceName|blockDeviceMapping
:rtype: :class:`boto.ec2.image.InstanceAttribute`
:return: An InstanceAttribute object representing the value of the
attribute requested
"""
params = {'InstanceId' : instance_id}
if attribute:
params['Attribute'] = attribute
return self.get_object('DescribeInstanceAttribute', params,
InstanceAttribute, verb='POST')
def modify_instance_attribute(self, instance_id, attribute, value):
"""
Changes an attribute of an instance
:type instance_id: string
:param instance_id: The instance id you wish to change
:type attribute: string
:param attribute: The attribute you wish to change.
* AttributeName - Expected value (default)
* instanceType - A valid instance type (m1.small)
* kernel - Kernel ID (None)
* ramdisk - Ramdisk ID (None)
* userData - Base64 encoded String (None)
* disableApiTermination - Boolean (true)
* instanceInitiatedShutdownBehavior - stop|terminate
* rootDeviceName - device name (None)
:type value: string
:param value: The new value for the attribute
:rtype: bool
:return: Whether the operation succeeded or not
"""
# Allow a bool to be passed in for value of disableApiTermination
if attribute == 'disableApiTermination':
if isinstance(value, bool):
if value:
value = 'true'
else:
value = 'false'
params = {'InstanceId' : instance_id,
'Attribute' : attribute,
'Value' : value}
return self.get_status('ModifyInstanceAttribute', params, verb='POST')
def reset_instance_attribute(self, instance_id, attribute):
"""
Resets an attribute of an instance to its default value.
:type instance_id: string
:param instance_id: ID of the instance
:type attribute: string
:param attribute: The attribute to reset. Valid values are:
kernel|ramdisk
:rtype: bool
:return: Whether the operation succeeded or not
"""
params = {'InstanceId' : instance_id,
'Attribute' : attribute}
return self.get_status('ResetInstanceAttribute', params, verb='POST')
# Spot Instances
def get_all_spot_instance_requests(self, request_ids=None,
filters=None):
"""
Retrieve all the spot instances requests associated with your account.
:type request_ids: list
:param request_ids: A list of strings of spot instance request IDs
:type filters: dict
:param filters: Optional filters that can be used to limit
the results returned. Filters are provided
in the form of a dictionary consisting of
filter names as the key and filter values
as the value. The set of allowable filter
names/values is dependent on the request
being performed. Check the EC2 API guide
for details.
:rtype: list
:return: A list of
:class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
"""
params = {}
if request_ids:
self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
if filters:
if 'launch.group-id' in filters:
lgid = filters.get('launch.group-id')
if not lgid.startswith('sg-') or len(lgid) != 11:
warnings.warn(
"The 'launch.group-id' filter now requires a security "
"group id (sg-*) and no longer supports filtering by "
"group name. Please update your filters accordingly.",
UserWarning)
self.build_filter_params(params, filters)
return self.get_list('DescribeSpotInstanceRequests', params,
[('item', SpotInstanceRequest)], verb='POST')
def get_spot_price_history(self, start_time=None, end_time=None,
instance_type=None, product_description=None,
availability_zone=None):
"""
Retrieve the recent history of spot instances pricing.
:type start_time: str
:param start_time: An indication of how far back to provide price
changes for. An ISO8601 DateTime string.
:type end_time: str
:param end_time: An indication of how far forward to provide price
changes for. An ISO8601 DateTime string.
:type instance_type: str
:param instance_type: Filter responses to a particular instance type.
:type product_description: str
:param product_description: Filter responses to a particular platform.
Valid values are currently: "Linux/UNIX",
"SUSE Linux", and "Windows"
:type availability_zone: str
:param availability_zone: The availability zone for which prices
should be returned
:rtype: list
:return: A list tuples containing price and timestamp.
"""
params = {}
if start_time:
params['StartTime'] = start_time
if end_time:
params['EndTime'] = end_time
if instance_type:
params['InstanceType'] = instance_type
if product_description:
params['ProductDescription'] = product_description
if availability_zone:
params['AvailabilityZone'] = availability_zone
return self.get_list('DescribeSpotPriceHistory', params,
[('item', SpotPriceHistory)], verb='POST')
def request_spot_instances(self, price, image_id, count=1, type='one-time',
valid_from=None, valid_until=None,
launch_group=None, availability_zone_group=None,
key_name=None, security_groups=None,
user_data=None, addressing_type=None,
instance_type='m1.small', placement=None,
kernel_id=None, ramdisk_id=None,
monitoring_enabled=False, subnet_id=None,
block_device_map=None):
"""
Request instances on the spot market at a particular price.
:type price: str
:param price: The maximum price of your bid
:type image_id: string
:param image_id: The ID of the image to run
:type count: int
:param count: The of instances to requested
:type type: str
:param type: Type of request. Can be 'one-time' or 'persistent'.
Default is one-time.
:type valid_from: str
:param valid_from: Start date of the request. An ISO8601 time string.
:type valid_until: str
:param valid_until: End date of the request. An ISO8601 time string.
:type launch_group: str
:param launch_group: If supplied, all requests will be fulfilled
as a group.
:type availability_zone_group: str
:param availability_zone_group: If supplied, all requests will be
fulfilled within a single
availability zone.
:type key_name: string
:param key_name: The name of the key pair with which to launch instances
:type security_groups: list of strings
:param security_groups: The names of the security groups with which to
associate instances
:type user_data: string
:param user_data: The user data passed to the launched instances
:type instance_type: string
:param instance_type: The type of instance to run:
* m1.small
* m1.large
* m1.xlarge
* c1.medium
* c1.xlarge
* m2.xlarge
* m2.2xlarge
* m2.4xlarge
* cc1.4xlarge
* t1.micro
:type placement: string
:param placement: The availability zone in which to launch the instances
:type kernel_id: string
:param kernel_id: The ID of the kernel with which to launch the
instances
:type ramdisk_id: string
:param ramdisk_id: The ID of the RAM disk with which to launch the
instances
:type monitoring_enabled: bool