1# Copyright (c) 2009 Reza Lotun http://reza.lotun.name/ 2# Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved 3# 4# Permission is hereby granted, free of charge, to any person obtaining a 5# copy of this software and associated documentation files (the 6# "Software"), to deal in the Software without restriction, including 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 9# persons to whom the Software is furnished to do so, subject to the fol- 10# lowing conditions: 11# 12# The above copyright notice and this permission notice shall be included 13# in all copies or substantial portions of the Software. 14# 15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 17# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 18# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21# IN THE SOFTWARE. 22 23from boto.ec2.elb.listelement import ListElement 24# Namespacing issue with deprecated local class 25from boto.ec2.blockdevicemapping import BlockDeviceMapping as BDM 26from boto.resultset import ResultSet 27import boto.utils 28import base64 29 30 31# this should use the corresponding object from boto.ec2 32# Currently in use by deprecated local BlockDeviceMapping class 33class Ebs(object): 34 def __init__(self, connection=None, snapshot_id=None, volume_size=None): 35 self.connection = connection 36 self.snapshot_id = snapshot_id 37 self.volume_size = volume_size 38 39 def __repr__(self): 40 return 'Ebs(%s, %s)' % (self.snapshot_id, self.volume_size) 41 42 def startElement(self, name, attrs, connection): 43 pass 44 45 def endElement(self, name, value, connection): 46 if name == 'SnapshotId': 47 self.snapshot_id = value 48 elif name == 'VolumeSize': 49 self.volume_size = value 50 51 52class InstanceMonitoring(object): 53 def __init__(self, connection=None, enabled='false'): 54 self.connection = connection 55 self.enabled = enabled 56 57 def __repr__(self): 58 return 'InstanceMonitoring(%s)' % self.enabled 59 60 def startElement(self, name, attrs, connection): 61 pass 62 63 def endElement(self, name, value, connection): 64 if name == 'Enabled': 65 self.enabled = value 66 67 68# this should use the BlockDeviceMapping from boto.ec2.blockdevicemapping 69# Currently in use by deprecated code for backwards compatability 70# Removing this class can also remove the Ebs class in this same file 71class BlockDeviceMapping(object): 72 def __init__(self, connection=None, device_name=None, virtual_name=None, 73 ebs=None, no_device=None): 74 self.connection = connection 75 self.device_name = device_name 76 self.virtual_name = virtual_name 77 self.ebs = ebs 78 self.no_device = no_device 79 80 def __repr__(self): 81 return 'BlockDeviceMapping(%s, %s)' % (self.device_name, 82 self.virtual_name) 83 84 def startElement(self, name, attrs, connection): 85 if name == 'Ebs': 86 self.ebs = Ebs(self) 87 return self.ebs 88 89 def endElement(self, name, value, connection): 90 if name == 'DeviceName': 91 self.device_name = value 92 elif name == 'VirtualName': 93 self.virtual_name = value 94 elif name == 'NoDevice': 95 self.no_device = bool(value) 96 97 98class LaunchConfiguration(object): 99 def __init__(self, connection=None, name=None, image_id=None, 100 key_name=None, security_groups=None, user_data=None, 101 instance_type='m1.small', kernel_id=None, 102 ramdisk_id=None, block_device_mappings=None, 103 instance_monitoring=False, spot_price=None, 104 instance_profile_name=None, ebs_optimized=False, 105 associate_public_ip_address=None, volume_type=None, 106 delete_on_termination=True, iops=None, 107 use_block_device_types=False, classic_link_vpc_id=None, 108 classic_link_vpc_security_groups=None): 109 """ 110 A launch configuration. 111 112 :type name: str 113 :param name: Name of the launch configuration to create. 114 115 :type image_id: str 116 :param image_id: Unique ID of the Amazon Machine Image (AMI) which was 117 assigned during registration. 118 119 :type key_name: str 120 :param key_name: The name of the EC2 key pair. 121 122 :type security_groups: list 123 :param security_groups: Names or security group id's of the security 124 groups with which to associate the EC2 instances or VPC instances, 125 respectively. 126 127 :type user_data: str 128 :param user_data: The user data available to launched EC2 instances. 129 130 :type instance_type: str 131 :param instance_type: The instance type 132 133 :type kernel_id: str 134 :param kernel_id: Kernel id for instance 135 136 :type ramdisk_id: str 137 :param ramdisk_id: RAM disk id for instance 138 139 :type block_device_mappings: list 140 :param block_device_mappings: Specifies how block devices are exposed 141 for instances 142 143 :type instance_monitoring: bool 144 :param instance_monitoring: Whether instances in group are launched 145 with detailed monitoring. 146 147 :type spot_price: float 148 :param spot_price: The spot price you are bidding. Only applies 149 if you are building an autoscaling group with spot instances. 150 151 :type instance_profile_name: string 152 :param instance_profile_name: The name or the Amazon Resource 153 Name (ARN) of the instance profile associated with the IAM 154 role for the instance. 155 156 :type ebs_optimized: bool 157 :param ebs_optimized: Specifies whether the instance is optimized 158 for EBS I/O (true) or not (false). 159 160 161 :type associate_public_ip_address: bool 162 :param associate_public_ip_address: Used for Auto Scaling groups that launch instances into an Amazon Virtual Private Cloud. 163 Specifies whether to assign a public IP address to each instance launched in a Amazon VPC. 164 165 :type classic_link_vpc_id: str 166 :param classic_link_vpc_id: ID of ClassicLink enabled VPC. 167 168 :type classic_link_vpc_security_groups: list 169 :param classic_link_vpc_security_groups: Security group 170 id's of the security groups with which to associate the 171 ClassicLink VPC instances. 172 """ 173 self.connection = connection 174 self.name = name 175 self.instance_type = instance_type 176 self.block_device_mappings = block_device_mappings 177 self.key_name = key_name 178 sec_groups = security_groups or [] 179 self.security_groups = ListElement(sec_groups) 180 self.image_id = image_id 181 self.ramdisk_id = ramdisk_id 182 self.created_time = None 183 self.kernel_id = kernel_id 184 self.user_data = user_data 185 self.created_time = None 186 self.instance_monitoring = instance_monitoring 187 self.spot_price = spot_price 188 self.instance_profile_name = instance_profile_name 189 self.launch_configuration_arn = None 190 self.ebs_optimized = ebs_optimized 191 self.associate_public_ip_address = associate_public_ip_address 192 self.volume_type = volume_type 193 self.delete_on_termination = delete_on_termination 194 self.iops = iops 195 self.use_block_device_types = use_block_device_types 196 self.classic_link_vpc_id = classic_link_vpc_id 197 classic_link_vpc_sec_groups = classic_link_vpc_security_groups or [] 198 self.classic_link_vpc_security_groups = \ 199 ListElement(classic_link_vpc_sec_groups) 200 201 if connection is not None: 202 self.use_block_device_types = connection.use_block_device_types 203 204 def __repr__(self): 205 return 'LaunchConfiguration:%s' % self.name 206 207 def startElement(self, name, attrs, connection): 208 if name == 'SecurityGroups': 209 return self.security_groups 210 elif name == 'ClassicLinkVPCSecurityGroups': 211 return self.classic_link_vpc_security_groups 212 elif name == 'BlockDeviceMappings': 213 if self.use_block_device_types: 214 self.block_device_mappings = BDM() 215 else: 216 self.block_device_mappings = ResultSet([('member', BlockDeviceMapping)]) 217 return self.block_device_mappings 218 elif name == 'InstanceMonitoring': 219 self.instance_monitoring = InstanceMonitoring(self) 220 return self.instance_monitoring 221 222 def endElement(self, name, value, connection): 223 if name == 'InstanceType': 224 self.instance_type = value 225 elif name == 'LaunchConfigurationName': 226 self.name = value 227 elif name == 'KeyName': 228 self.key_name = value 229 elif name == 'ImageId': 230 self.image_id = value 231 elif name == 'CreatedTime': 232 self.created_time = boto.utils.parse_ts(value) 233 elif name == 'KernelId': 234 self.kernel_id = value 235 elif name == 'RamdiskId': 236 self.ramdisk_id = value 237 elif name == 'UserData': 238 try: 239 self.user_data = base64.b64decode(value) 240 except TypeError: 241 self.user_data = value 242 elif name == 'LaunchConfigurationARN': 243 self.launch_configuration_arn = value 244 elif name == 'InstanceMonitoring': 245 self.instance_monitoring = value 246 elif name == 'SpotPrice': 247 self.spot_price = float(value) 248 elif name == 'IamInstanceProfile': 249 self.instance_profile_name = value 250 elif name == 'EbsOptimized': 251 self.ebs_optimized = True if value.lower() == 'true' else False 252 elif name == 'AssociatePublicIpAddress': 253 self.associate_public_ip_address = True if value.lower() == 'true' else False 254 elif name == 'VolumeType': 255 self.volume_type = value 256 elif name == 'DeleteOnTermination': 257 if value.lower() == 'true': 258 self.delete_on_termination = True 259 else: 260 self.delete_on_termination = False 261 elif name == 'Iops': 262 self.iops = int(value) 263 elif name == 'ClassicLinkVPCId': 264 self.classic_link_vpc_id = value 265 else: 266 setattr(self, name, value) 267 268 def delete(self): 269 """ Delete this launch configuration. """ 270 return self.connection.delete_launch_configuration(self.name) 271