comparison env/lib/python3.9/site-packages/boto/ec2/instance.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
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 interfaces: List of Elastic Network Interfaces associated with
205 this instance.
206 :ivar ebs_optimized: Whether instance is using optimized EBS volumes
207 or not.
208 :ivar instance_profile: A Python dict containing the instance
209 profile id and arn associated with this instance.
210 """
211
212 def __init__(self, connection=None):
213 super(Instance, self).__init__(connection)
214 self.id = None
215 self.dns_name = None
216 self.public_dns_name = None
217 self.private_dns_name = None
218 self.key_name = None
219 self.instance_type = None
220 self.launch_time = None
221 self.image_id = None
222 self.kernel = None
223 self.ramdisk = None
224 self.product_codes = ProductCodes()
225 self.ami_launch_index = None
226 self.monitored = False
227 self.monitoring_state = None
228 self.spot_instance_request_id = None
229 self.subnet_id = None
230 self.vpc_id = None
231 self.private_ip_address = None
232 self.ip_address = None
233 self.requester_id = None
234 self._in_monitoring_element = False
235 self.persistent = False
236 self.root_device_name = None
237 self.root_device_type = None
238 self.block_device_mapping = None
239 self.state_reason = None
240 self.group_name = None
241 self.client_token = None
242 self.eventsSet = None
243 self.groups = []
244 self.platform = None
245 self.interfaces = []
246 self.hypervisor = None
247 self.virtualization_type = None
248 self.architecture = None
249 self.instance_profile = None
250 self._previous_state = None
251 self._state = InstanceState()
252 self._placement = InstancePlacement()
253
254 def __repr__(self):
255 return 'Instance:%s' % self.id
256
257 @property
258 def state(self):
259 return self._state.name
260
261 @property
262 def state_code(self):
263 return self._state.code
264
265 @property
266 def previous_state(self):
267 if self._previous_state:
268 return self._previous_state.name
269 return None
270
271 @property
272 def previous_state_code(self):
273 if self._previous_state:
274 return self._previous_state.code
275 return 0
276
277 @property
278 def placement(self):
279 return self._placement.zone
280
281 @property
282 def placement_group(self):
283 return self._placement.group_name
284
285 @property
286 def placement_tenancy(self):
287 return self._placement.tenancy
288
289 def startElement(self, name, attrs, connection):
290 retval = super(Instance, self).startElement(name, attrs, connection)
291 if retval is not None:
292 return retval
293 if name == 'monitoring':
294 self._in_monitoring_element = True
295 elif name == 'blockDeviceMapping':
296 self.block_device_mapping = BlockDeviceMapping()
297 return self.block_device_mapping
298 elif name == 'productCodes':
299 return self.product_codes
300 elif name == 'stateReason':
301 self.state_reason = SubParse('stateReason')
302 return self.state_reason
303 elif name == 'groupSet':
304 self.groups = ResultSet([('item', Group)])
305 return self.groups
306 elif name == "eventsSet":
307 self.eventsSet = SubParse('eventsSet')
308 return self.eventsSet
309 elif name == 'networkInterfaceSet':
310 self.interfaces = ResultSet([('item', NetworkInterface)])
311 return self.interfaces
312 elif name == 'iamInstanceProfile':
313 self.instance_profile = SubParse('iamInstanceProfile')
314 return self.instance_profile
315 elif name == 'currentState':
316 return self._state
317 elif name == 'previousState':
318 self._previous_state = InstanceState()
319 return self._previous_state
320 elif name == 'instanceState':
321 return self._state
322 elif name == 'placement':
323 return self._placement
324 return None
325
326 def endElement(self, name, value, connection):
327 if name == 'instanceId':
328 self.id = value
329 elif name == 'imageId':
330 self.image_id = value
331 elif name == 'dnsName' or name == 'publicDnsName':
332 self.dns_name = value # backwards compatibility
333 self.public_dns_name = value
334 elif name == 'privateDnsName':
335 self.private_dns_name = value
336 elif name == 'keyName':
337 self.key_name = value
338 elif name == 'amiLaunchIndex':
339 self.ami_launch_index = value
340 elif name == 'previousState':
341 self.previous_state = value
342 elif name == 'instanceType':
343 self.instance_type = value
344 elif name == 'rootDeviceName':
345 self.root_device_name = value
346 elif name == 'rootDeviceType':
347 self.root_device_type = value
348 elif name == 'launchTime':
349 self.launch_time = value
350 elif name == 'platform':
351 self.platform = value
352 elif name == 'kernelId':
353 self.kernel = value
354 elif name == 'ramdiskId':
355 self.ramdisk = value
356 elif name == 'state':
357 if self._in_monitoring_element:
358 self.monitoring_state = value
359 if value == 'enabled':
360 self.monitored = True
361 self._in_monitoring_element = False
362 elif name == 'spotInstanceRequestId':
363 self.spot_instance_request_id = value
364 elif name == 'subnetId':
365 self.subnet_id = value
366 elif name == 'vpcId':
367 self.vpc_id = value
368 elif name == 'privateIpAddress':
369 self.private_ip_address = value
370 elif name == 'ipAddress':
371 self.ip_address = value
372 elif name == 'requesterId':
373 self.requester_id = value
374 elif name == 'persistent':
375 if value == 'true':
376 self.persistent = True
377 else:
378 self.persistent = False
379 elif name == 'groupName':
380 if self._in_monitoring_element:
381 self.group_name = value
382 elif name == 'clientToken':
383 self.client_token = value
384 elif name == "eventsSet":
385 self.events = value
386 elif name == 'hypervisor':
387 self.hypervisor = value
388 elif name == 'virtualizationType':
389 self.virtualization_type = value
390 elif name == 'architecture':
391 self.architecture = value
392 elif name == 'ebsOptimized':
393 self.ebs_optimized = (value == 'true')
394 else:
395 setattr(self, name, value)
396
397 def _update(self, updated):
398 self.__dict__.update(updated.__dict__)
399
400 def update(self, validate=False, dry_run=False):
401 """
402 Update the instance's state information by making a call to fetch
403 the current instance attributes from the service.
404
405 :type validate: bool
406 :param validate: By default, if EC2 returns no data about the
407 instance the update method returns quietly. If
408 the validate param is True, however, it will
409 raise a ValueError exception if no data is
410 returned from EC2.
411 """
412 rs = self.connection.get_all_reservations([self.id], dry_run=dry_run)
413 if len(rs) > 0:
414 r = rs[0]
415 for i in r.instances:
416 if i.id == self.id:
417 self._update(i)
418 elif validate:
419 raise ValueError('%s is not a valid Instance ID' % self.id)
420 return self.state
421
422 def terminate(self, dry_run=False):
423 """
424 Terminate the instance
425 """
426 rs = self.connection.terminate_instances([self.id], dry_run=dry_run)
427 if len(rs) > 0:
428 self._update(rs[0])
429
430 def stop(self, force=False, dry_run=False):
431 """
432 Stop the instance
433
434 :type force: bool
435 :param force: Forces the instance to stop
436
437 :rtype: list
438 :return: A list of the instances stopped
439 """
440 rs = self.connection.stop_instances([self.id], force, dry_run=dry_run)
441 if len(rs) > 0:
442 self._update(rs[0])
443
444 def start(self, dry_run=False):
445 """
446 Start the instance.
447 """
448 rs = self.connection.start_instances([self.id], dry_run=dry_run)
449 if len(rs) > 0:
450 self._update(rs[0])
451
452 def reboot(self, dry_run=False):
453 return self.connection.reboot_instances([self.id], dry_run=dry_run)
454
455 def get_console_output(self, dry_run=False):
456 """
457 Retrieves the console output for the instance.
458
459 :rtype: :class:`boto.ec2.instance.ConsoleOutput`
460 :return: The console output as a ConsoleOutput object
461 """
462 return self.connection.get_console_output(self.id, dry_run=dry_run)
463
464 def confirm_product(self, product_code, dry_run=False):
465 return self.connection.confirm_product_instance(
466 self.id,
467 product_code,
468 dry_run=dry_run
469 )
470
471 def use_ip(self, ip_address, dry_run=False):
472 """
473 Associates an Elastic IP to the instance.
474
475 :type ip_address: Either an instance of
476 :class:`boto.ec2.address.Address` or a string.
477 :param ip_address: The IP address to associate
478 with the instance.
479
480 :rtype: bool
481 :return: True if successful
482 """
483
484 if isinstance(ip_address, Address):
485 ip_address = ip_address.public_ip
486 return self.connection.associate_address(
487 self.id,
488 ip_address,
489 dry_run=dry_run
490 )
491
492 def monitor(self, dry_run=False):
493 return self.connection.monitor_instance(self.id, dry_run=dry_run)
494
495 def unmonitor(self, dry_run=False):
496 return self.connection.unmonitor_instance(self.id, dry_run=dry_run)
497
498 def get_attribute(self, attribute, dry_run=False):
499 """
500 Gets an attribute from this instance.
501
502 :type attribute: string
503 :param attribute: The attribute you need information about
504 Valid choices are:
505
506 * instanceType
507 * kernel
508 * ramdisk
509 * userData
510 * disableApiTermination
511 * instanceInitiatedShutdownBehavior
512 * rootDeviceName
513 * blockDeviceMapping
514 * productCodes
515 * sourceDestCheck
516 * groupSet
517 * ebsOptimized
518
519 :rtype: :class:`boto.ec2.image.InstanceAttribute`
520 :return: An InstanceAttribute object representing the value of the
521 attribute requested
522 """
523 return self.connection.get_instance_attribute(
524 self.id,
525 attribute,
526 dry_run=dry_run
527 )
528
529 def modify_attribute(self, attribute, value, dry_run=False):
530 """
531 Changes an attribute of this instance
532
533 :type attribute: string
534 :param attribute: The attribute you wish to change.
535
536 * instanceType - A valid instance type (m1.small)
537 * kernel - Kernel ID (None)
538 * ramdisk - Ramdisk ID (None)
539 * userData - Base64 encoded String (None)
540 * disableApiTermination - Boolean (true)
541 * instanceInitiatedShutdownBehavior - stop|terminate
542 * sourceDestCheck - Boolean (true)
543 * groupSet - Set of Security Groups or IDs
544 * ebsOptimized - Boolean (false)
545
546 :type value: string
547 :param value: The new value for the attribute
548
549 :rtype: bool
550 :return: Whether the operation succeeded or not
551 """
552 return self.connection.modify_instance_attribute(
553 self.id,
554 attribute,
555 value,
556 dry_run=dry_run
557 )
558
559 def reset_attribute(self, attribute, dry_run=False):
560 """
561 Resets an attribute of this instance to its default value.
562
563 :type attribute: string
564 :param attribute: The attribute to reset. Valid values are:
565 kernel|ramdisk
566
567 :rtype: bool
568 :return: Whether the operation succeeded or not
569 """
570 return self.connection.reset_instance_attribute(
571 self.id,
572 attribute,
573 dry_run=dry_run
574 )
575
576 def create_image(self, name, description=None, no_reboot=False,
577 dry_run=False):
578 """
579 Will create an AMI from the instance in the running or stopped
580 state.
581
582 :type name: string
583 :param name: The name of the new image
584
585 :type description: string
586 :param description: An optional human-readable string describing
587 the contents and purpose of the AMI.
588
589 :type no_reboot: bool
590 :param no_reboot: An optional flag indicating that the bundling process
591 should not attempt to shutdown the instance before
592 bundling. If this flag is True, the responsibility
593 of maintaining file system integrity is left to the
594 owner of the instance.
595
596 :rtype: string
597 :return: The new image id
598 """
599 return self.connection.create_image(
600 self.id,
601 name,
602 description,
603 no_reboot,
604 dry_run=dry_run
605 )
606
607
608 class ConsoleOutput(object):
609 def __init__(self, parent=None):
610 self.parent = parent
611 self.instance_id = None
612 self.timestamp = None
613 self.output = None
614
615 def startElement(self, name, attrs, connection):
616 return None
617
618 def endElement(self, name, value, connection):
619 if name == 'instanceId':
620 self.instance_id = value
621 elif name == 'timestamp':
622 self.timestamp = value
623 elif name == 'output':
624 self.output = base64.b64decode(value)
625 else:
626 setattr(self, name, value)
627
628
629 class InstanceAttribute(dict):
630 ValidValues = ['instanceType', 'kernel', 'ramdisk', 'userData',
631 'disableApiTermination',
632 'instanceInitiatedShutdownBehavior',
633 'rootDeviceName', 'blockDeviceMapping', 'sourceDestCheck',
634 'groupSet']
635
636 def __init__(self, parent=None):
637 dict.__init__(self)
638 self.instance_id = None
639 self.request_id = None
640 self._current_value = None
641
642 def startElement(self, name, attrs, connection):
643 if name == 'blockDeviceMapping':
644 self[name] = BlockDeviceMapping()
645 return self[name]
646 elif name == 'groupSet':
647 self[name] = ResultSet([('item', Group)])
648 return self[name]
649 else:
650 return None
651
652 def endElement(self, name, value, connection):
653 if name == 'instanceId':
654 self.instance_id = value
655 elif name == 'requestId':
656 self.request_id = value
657 elif name == 'value':
658 if value == 'true':
659 value = True
660 elif value == 'false':
661 value = False
662 self._current_value = value
663 elif name in self.ValidValues:
664 self[name] = self._current_value
665
666
667 class SubParse(dict):
668 def __init__(self, section, parent=None):
669 dict.__init__(self)
670 self.section = section
671
672 def startElement(self, name, attrs, connection):
673 return None
674
675 def endElement(self, name, value, connection):
676 if name != self.section:
677 self[name] = value