comparison venv/lib/python2.7/site-packages/boto/ec2/instance.py @ 0:d67268158946 draft

planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author bcclaywell
date Mon, 12 Oct 2015 17:43:33 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d67268158946
1 # Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
3 # Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish, dis-
9 # tribute, sublicense, and/or sell copies of the Software, and to permit
10 # persons to whom the Software is furnished to do so, subject to the fol-
11 # lowing conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 # IN THE SOFTWARE.
23
24 """
25 Represents an EC2 Instance
26 """
27 import boto
28 from boto.ec2.ec2object import EC2Object, TaggedEC2Object
29 from boto.resultset import ResultSet
30 from boto.ec2.address import Address
31 from boto.ec2.blockdevicemapping import BlockDeviceMapping
32 from boto.ec2.image import ProductCodes
33 from boto.ec2.networkinterface import NetworkInterface
34 from boto.ec2.group import Group
35 import base64
36
37
38 class InstanceState(object):
39 """
40 The state of the instance.
41
42 :ivar code: The low byte represents the state. The high byte is an
43 opaque internal value and should be ignored. Valid values:
44
45 * 0 (pending)
46 * 16 (running)
47 * 32 (shutting-down)
48 * 48 (terminated)
49 * 64 (stopping)
50 * 80 (stopped)
51
52 :ivar name: The name of the state of the instance. Valid values:
53
54 * "pending"
55 * "running"
56 * "shutting-down"
57 * "terminated"
58 * "stopping"
59 * "stopped"
60 """
61 def __init__(self, code=0, name=None):
62 self.code = code
63 self.name = name
64
65 def __repr__(self):
66 return '%s(%d)' % (self.name, self.code)
67
68 def startElement(self, name, attrs, connection):
69 pass
70
71 def endElement(self, name, value, connection):
72 if name == 'code':
73 self.code = int(value)
74 elif name == 'name':
75 self.name = value
76 else:
77 setattr(self, name, value)
78
79
80 class InstancePlacement(object):
81 """
82 The location where the instance launched.
83
84 :ivar zone: The Availability Zone of the instance.
85 :ivar group_name: The name of the placement group the instance is
86 in (for cluster compute instances).
87 :ivar tenancy: The tenancy of the instance (if the instance is
88 running within a VPC). An instance with a tenancy of dedicated
89 runs on single-tenant hardware.
90 """
91 def __init__(self, zone=None, group_name=None, tenancy=None):
92 self.zone = zone
93 self.group_name = group_name
94 self.tenancy = tenancy
95
96 def __repr__(self):
97 return self.zone
98
99 def startElement(self, name, attrs, connection):
100 pass
101
102 def endElement(self, name, value, connection):
103 if name == 'availabilityZone':
104 self.zone = value
105 elif name == 'groupName':
106 self.group_name = value
107 elif name == 'tenancy':
108 self.tenancy = value
109 else:
110 setattr(self, name, value)
111
112
113 class Reservation(EC2Object):
114 """
115 Represents a Reservation response object.
116
117 :ivar id: The unique ID of the Reservation.
118 :ivar owner_id: The unique ID of the owner of the Reservation.
119 :ivar groups: A list of Group objects representing the security
120 groups associated with launched instances.
121 :ivar instances: A list of Instance objects launched in this
122 Reservation.
123 """
124 def __init__(self, connection=None):
125 super(Reservation, self).__init__(connection)
126 self.id = None
127 self.owner_id = None
128 self.groups = []
129 self.instances = []
130
131 def __repr__(self):
132 return 'Reservation:%s' % self.id
133
134 def startElement(self, name, attrs, connection):
135 if name == 'instancesSet':
136 self.instances = ResultSet([('item', Instance)])
137 return self.instances
138 elif name == 'groupSet':
139 self.groups = ResultSet([('item', Group)])
140 return self.groups
141 else:
142 return None
143
144 def endElement(self, name, value, connection):
145 if name == 'reservationId':
146 self.id = value
147 elif name == 'ownerId':
148 self.owner_id = value
149 else:
150 setattr(self, name, value)
151
152 def stop_all(self, dry_run=False):
153 for instance in self.instances:
154 instance.stop(dry_run=dry_run)
155
156
157 class Instance(TaggedEC2Object):
158 """
159 Represents an instance.
160
161 :ivar id: The unique ID of the Instance.
162 :ivar groups: A list of Group objects representing the security
163 groups associated with the instance.
164 :ivar public_dns_name: The public dns name of the instance.
165 :ivar private_dns_name: The private dns name of the instance.
166 :ivar state: The string representation of the instance's current state.
167 :ivar state_code: An integer representation of the instance's
168 current state.
169 :ivar previous_state: The string representation of the instance's
170 previous state.
171 :ivar previous_state_code: An integer representation of the
172 instance's current state.
173 :ivar key_name: The name of the SSH key associated with the instance.
174 :ivar instance_type: The type of instance (e.g. m1.small).
175 :ivar launch_time: The time the instance was launched.
176 :ivar image_id: The ID of the AMI used to launch this instance.
177 :ivar placement: The availability zone in which the instance is running.
178 :ivar placement_group: The name of the placement group the instance
179 is in (for cluster compute instances).
180 :ivar placement_tenancy: The tenancy of the instance, if the instance
181 is running within a VPC. An instance with a tenancy of dedicated
182 runs on a single-tenant hardware.
183 :ivar kernel: The kernel associated with the instance.
184 :ivar ramdisk: The ramdisk associated with the instance.
185 :ivar architecture: The architecture of the image (i386|x86_64).
186 :ivar hypervisor: The hypervisor used.
187 :ivar virtualization_type: The type of virtualization used.
188 :ivar product_codes: A list of product codes associated with this instance.
189 :ivar ami_launch_index: This instances position within it's launch group.
190 :ivar monitored: A boolean indicating whether monitoring is enabled or not.
191 :ivar monitoring_state: A string value that contains the actual value
192 of the monitoring element returned by EC2.
193 :ivar spot_instance_request_id: The ID of the spot instance request
194 if this is a spot instance.
195 :ivar subnet_id: The VPC Subnet ID, if running in VPC.
196 :ivar vpc_id: The VPC ID, if running in VPC.
197 :ivar private_ip_address: The private IP address of the instance.
198 :ivar ip_address: The public IP address of the instance.
199 :ivar platform: Platform of the instance (e.g. Windows)
200 :ivar root_device_name: The name of the root device.
201 :ivar root_device_type: The root device type (ebs|instance-store).
202 :ivar block_device_mapping: The Block Device Mapping for the instance.
203 :ivar state_reason: The reason for the most recent state transition.
204 :ivar groups: List of security Groups associated with the instance.
205 :ivar interfaces: List of Elastic Network Interfaces associated with
206 this instance.
207 :ivar ebs_optimized: Whether instance is using optimized EBS volumes
208 or not.
209 :ivar instance_profile: A Python dict containing the instance
210 profile id and arn associated with this instance.
211 """
212
213 def __init__(self, connection=None):
214 super(Instance, self).__init__(connection)
215 self.id = None
216 self.dns_name = None
217 self.public_dns_name = None
218 self.private_dns_name = None
219 self.key_name = None
220 self.instance_type = None
221 self.launch_time = None
222 self.image_id = None
223 self.kernel = None
224 self.ramdisk = None
225 self.product_codes = ProductCodes()
226 self.ami_launch_index = None
227 self.monitored = False
228 self.monitoring_state = None
229 self.spot_instance_request_id = None
230 self.subnet_id = None
231 self.vpc_id = None
232 self.private_ip_address = None
233 self.ip_address = None
234 self.requester_id = None
235 self._in_monitoring_element = False
236 self.persistent = False
237 self.root_device_name = None
238 self.root_device_type = None
239 self.block_device_mapping = None
240 self.state_reason = None
241 self.group_name = None
242 self.client_token = None
243 self.eventsSet = None
244 self.groups = []
245 self.platform = None
246 self.interfaces = []
247 self.hypervisor = None
248 self.virtualization_type = None
249 self.architecture = None
250 self.instance_profile = None
251 self._previous_state = None
252 self._state = InstanceState()
253 self._placement = InstancePlacement()
254
255 def __repr__(self):
256 return 'Instance:%s' % self.id
257
258 @property
259 def state(self):
260 return self._state.name
261
262 @property
263 def state_code(self):
264 return self._state.code
265
266 @property
267 def previous_state(self):
268 if self._previous_state:
269 return self._previous_state.name
270 return None
271
272 @property
273 def previous_state_code(self):
274 if self._previous_state:
275 return self._previous_state.code
276 return 0
277
278 @property
279 def placement(self):
280 return self._placement.zone
281
282 @property
283 def placement_group(self):
284 return self._placement.group_name
285
286 @property
287 def placement_tenancy(self):
288 return self._placement.tenancy
289
290 def startElement(self, name, attrs, connection):
291 retval = super(Instance, self).startElement(name, attrs, connection)
292 if retval is not None:
293 return retval
294 if name == 'monitoring':
295 self._in_monitoring_element = True
296 elif name == 'blockDeviceMapping':
297 self.block_device_mapping = BlockDeviceMapping()
298 return self.block_device_mapping
299 elif name == 'productCodes':
300 return self.product_codes
301 elif name == 'stateReason':
302 self.state_reason = SubParse('stateReason')
303 return self.state_reason
304 elif name == 'groupSet':
305 self.groups = ResultSet([('item', Group)])
306 return self.groups
307 elif name == "eventsSet":
308 self.eventsSet = SubParse('eventsSet')
309 return self.eventsSet
310 elif name == 'networkInterfaceSet':
311 self.interfaces = ResultSet([('item', NetworkInterface)])
312 return self.interfaces
313 elif name == 'iamInstanceProfile':
314 self.instance_profile = SubParse('iamInstanceProfile')
315 return self.instance_profile
316 elif name == 'currentState':
317 return self._state
318 elif name == 'previousState':
319 self._previous_state = InstanceState()
320 return self._previous_state
321 elif name == 'instanceState':
322 return self._state
323 elif name == 'placement':
324 return self._placement
325 return None
326
327 def endElement(self, name, value, connection):
328 if name == 'instanceId':
329 self.id = value
330 elif name == 'imageId':
331 self.image_id = value
332 elif name == 'dnsName' or name == 'publicDnsName':
333 self.dns_name = value # backwards compatibility
334 self.public_dns_name = value
335 elif name == 'privateDnsName':
336 self.private_dns_name = value
337 elif name == 'keyName':
338 self.key_name = value
339 elif name == 'amiLaunchIndex':
340 self.ami_launch_index = value
341 elif name == 'previousState':
342 self.previous_state = value
343 elif name == 'instanceType':
344 self.instance_type = value
345 elif name == 'rootDeviceName':
346 self.root_device_name = value
347 elif name == 'rootDeviceType':
348 self.root_device_type = value
349 elif name == 'launchTime':
350 self.launch_time = value
351 elif name == 'platform':
352 self.platform = value
353 elif name == 'kernelId':
354 self.kernel = value
355 elif name == 'ramdiskId':
356 self.ramdisk = value
357 elif name == 'state':
358 if self._in_monitoring_element:
359 self.monitoring_state = value
360 if value == 'enabled':
361 self.monitored = True
362 self._in_monitoring_element = False
363 elif name == 'spotInstanceRequestId':
364 self.spot_instance_request_id = value
365 elif name == 'subnetId':
366 self.subnet_id = value
367 elif name == 'vpcId':
368 self.vpc_id = value
369 elif name == 'privateIpAddress':
370 self.private_ip_address = value
371 elif name == 'ipAddress':
372 self.ip_address = value
373 elif name == 'requesterId':
374 self.requester_id = value
375 elif name == 'persistent':
376 if value == 'true':
377 self.persistent = True
378 else:
379 self.persistent = False
380 elif name == 'groupName':
381 if self._in_monitoring_element:
382 self.group_name = value
383 elif name == 'clientToken':
384 self.client_token = value
385 elif name == "eventsSet":
386 self.events = value
387 elif name == 'hypervisor':
388 self.hypervisor = value
389 elif name == 'virtualizationType':
390 self.virtualization_type = value
391 elif name == 'architecture':
392 self.architecture = value
393 elif name == 'ebsOptimized':
394 self.ebs_optimized = (value == 'true')
395 else:
396 setattr(self, name, value)
397
398 def _update(self, updated):
399 self.__dict__.update(updated.__dict__)
400
401 def update(self, validate=False, dry_run=False):
402 """
403 Update the instance's state information by making a call to fetch
404 the current instance attributes from the service.
405
406 :type validate: bool
407 :param validate: By default, if EC2 returns no data about the
408 instance the update method returns quietly. If
409 the validate param is True, however, it will
410 raise a ValueError exception if no data is
411 returned from EC2.
412 """
413 rs = self.connection.get_all_reservations([self.id], dry_run=dry_run)
414 if len(rs) > 0:
415 r = rs[0]
416 for i in r.instances:
417 if i.id == self.id:
418 self._update(i)
419 elif validate:
420 raise ValueError('%s is not a valid Instance ID' % self.id)
421 return self.state
422
423 def terminate(self, dry_run=False):
424 """
425 Terminate the instance
426 """
427 rs = self.connection.terminate_instances([self.id], dry_run=dry_run)
428 if len(rs) > 0:
429 self._update(rs[0])
430
431 def stop(self, force=False, dry_run=False):
432 """
433 Stop the instance
434
435 :type force: bool
436 :param force: Forces the instance to stop
437
438 :rtype: list
439 :return: A list of the instances stopped
440 """
441 rs = self.connection.stop_instances([self.id], force, dry_run=dry_run)
442 if len(rs) > 0:
443 self._update(rs[0])
444
445 def start(self, dry_run=False):
446 """
447 Start the instance.
448 """
449 rs = self.connection.start_instances([self.id], dry_run=dry_run)
450 if len(rs) > 0:
451 self._update(rs[0])
452
453 def reboot(self, dry_run=False):
454 return self.connection.reboot_instances([self.id], dry_run=dry_run)
455
456 def get_console_output(self, dry_run=False):
457 """
458 Retrieves the console output for the instance.
459
460 :rtype: :class:`boto.ec2.instance.ConsoleOutput`
461 :return: The console output as a ConsoleOutput object
462 """
463 return self.connection.get_console_output(self.id, dry_run=dry_run)
464
465 def confirm_product(self, product_code, dry_run=False):
466 return self.connection.confirm_product_instance(
467 self.id,
468 product_code,
469 dry_run=dry_run
470 )
471
472 def use_ip(self, ip_address, dry_run=False):
473 """
474 Associates an Elastic IP to the instance.
475
476 :type ip_address: Either an instance of
477 :class:`boto.ec2.address.Address` or a string.
478 :param ip_address: The IP address to associate
479 with the instance.
480
481 :rtype: bool
482 :return: True if successful
483 """
484
485 if isinstance(ip_address, Address):
486 ip_address = ip_address.public_ip
487 return self.connection.associate_address(
488 self.id,
489 ip_address,
490 dry_run=dry_run
491 )
492
493 def monitor(self, dry_run=False):
494 return self.connection.monitor_instance(self.id, dry_run=dry_run)
495
496 def unmonitor(self, dry_run=False):
497 return self.connection.unmonitor_instance(self.id, dry_run=dry_run)
498
499 def get_attribute(self, attribute, dry_run=False):
500 """
501 Gets an attribute from this instance.
502
503 :type attribute: string
504 :param attribute: The attribute you need information about
505 Valid choices are:
506
507 * instanceType
508 * kernel
509 * ramdisk
510 * userData
511 * disableApiTermination
512 * instanceInitiatedShutdownBehavior
513 * rootDeviceName
514 * blockDeviceMapping
515 * productCodes
516 * sourceDestCheck
517 * groupSet
518 * ebsOptimized
519
520 :rtype: :class:`boto.ec2.image.InstanceAttribute`
521 :return: An InstanceAttribute object representing the value of the
522 attribute requested
523 """
524 return self.connection.get_instance_attribute(
525 self.id,
526 attribute,
527 dry_run=dry_run
528 )
529
530 def modify_attribute(self, attribute, value, dry_run=False):
531 """
532 Changes an attribute of this instance
533
534 :type attribute: string
535 :param attribute: The attribute you wish to change.
536
537 * instanceType - A valid instance type (m1.small)
538 * kernel - Kernel ID (None)
539 * ramdisk - Ramdisk ID (None)
540 * userData - Base64 encoded String (None)
541 * disableApiTermination - Boolean (true)
542 * instanceInitiatedShutdownBehavior - stop|terminate
543 * sourceDestCheck - Boolean (true)
544 * groupSet - Set of Security Groups or IDs
545 * ebsOptimized - Boolean (false)
546
547 :type value: string
548 :param value: The new value for the attribute
549
550 :rtype: bool
551 :return: Whether the operation succeeded or not
552 """
553 return self.connection.modify_instance_attribute(
554 self.id,
555 attribute,
556 value,
557 dry_run=dry_run
558 )
559
560 def reset_attribute(self, attribute, dry_run=False):
561 """
562 Resets an attribute of this instance to its default value.
563
564 :type attribute: string
565 :param attribute: The attribute to reset. Valid values are:
566 kernel|ramdisk
567
568 :rtype: bool
569 :return: Whether the operation succeeded or not
570 """
571 return self.connection.reset_instance_attribute(
572 self.id,
573 attribute,
574 dry_run=dry_run
575 )
576
577 def create_image(self, name, description=None, no_reboot=False,
578 dry_run=False):
579 """
580 Will create an AMI from the instance in the running or stopped
581 state.
582
583 :type name: string
584 :param name: The name of the new image
585
586 :type description: string
587 :param description: An optional human-readable string describing
588 the contents and purpose of the AMI.
589
590 :type no_reboot: bool
591 :param no_reboot: An optional flag indicating that the bundling process
592 should not attempt to shutdown the instance before
593 bundling. If this flag is True, the responsibility
594 of maintaining file system integrity is left to the
595 owner of the instance.
596
597 :rtype: string
598 :return: The new image id
599 """
600 return self.connection.create_image(
601 self.id,
602 name,
603 description,
604 no_reboot,
605 dry_run=dry_run
606 )
607
608
609 class ConsoleOutput(object):
610 def __init__(self, parent=None):
611 self.parent = parent
612 self.instance_id = None
613 self.timestamp = None
614 self.output = None
615
616 def startElement(self, name, attrs, connection):
617 return None
618
619 def endElement(self, name, value, connection):
620 if name == 'instanceId':
621 self.instance_id = value
622 elif name == 'timestamp':
623 self.timestamp = value
624 elif name == 'output':
625 self.output = base64.b64decode(value)
626 else:
627 setattr(self, name, value)
628
629
630 class InstanceAttribute(dict):
631 ValidValues = ['instanceType', 'kernel', 'ramdisk', 'userData',
632 'disableApiTermination',
633 'instanceInitiatedShutdownBehavior',
634 'rootDeviceName', 'blockDeviceMapping', 'sourceDestCheck',
635 'groupSet']
636
637 def __init__(self, parent=None):
638 dict.__init__(self)
639 self.instance_id = None
640 self.request_id = None
641 self._current_value = None
642
643 def startElement(self, name, attrs, connection):
644 if name == 'blockDeviceMapping':
645 self[name] = BlockDeviceMapping()
646 return self[name]
647 elif name == 'groupSet':
648 self[name] = ResultSet([('item', Group)])
649 return self[name]
650 else:
651 return None
652
653 def endElement(self, name, value, connection):
654 if name == 'instanceId':
655 self.instance_id = value
656 elif name == 'requestId':
657 self.request_id = value
658 elif name == 'value':
659 if value == 'true':
660 value = True
661 elif value == 'false':
662 value = False
663 self._current_value = value
664 elif name in self.ValidValues:
665 self[name] = self._current_value
666
667
668 class SubParse(dict):
669 def __init__(self, section, parent=None):
670 dict.__init__(self)
671 self.section = section
672
673 def startElement(self, name, attrs, connection):
674 return None
675
676 def endElement(self, name, value, connection):
677 if name != self.section:
678 self[name] = value