OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2009-2011 Reza Lotun http://reza.lotun.name/ |
| 2 # |
| 3 # Permission is hereby granted, free of charge, to any person obtaining a |
| 4 # copy of this software and associated documentation files (the |
| 5 # "Software"), to deal in the Software without restriction, including |
| 6 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 7 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 8 # persons to whom the Software is furnished to do so, subject to the fol- |
| 9 # lowing conditions: |
| 10 # |
| 11 # The above copyright notice and this permission notice shall be included |
| 12 # in all copies or substantial portions of the Software. |
| 13 # |
| 14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 20 # IN THE SOFTWARE. |
| 21 |
| 22 from boto.ec2.elb.listelement import ListElement |
| 23 from boto.resultset import ResultSet |
| 24 from boto.ec2.autoscale.launchconfig import LaunchConfiguration |
| 25 from boto.ec2.autoscale.request import Request |
| 26 from boto.ec2.autoscale.instance import Instance |
| 27 from boto.ec2.autoscale.tag import Tag |
| 28 |
| 29 |
| 30 class ProcessType(object): |
| 31 def __init__(self, connection=None): |
| 32 self.connection = connection |
| 33 self.process_name = None |
| 34 |
| 35 def __repr__(self): |
| 36 return 'ProcessType(%s)' % self.process_name |
| 37 |
| 38 def startElement(self, name, attrs, connection): |
| 39 pass |
| 40 |
| 41 def endElement(self, name, value, connection): |
| 42 if name == 'ProcessName': |
| 43 self.process_name = value |
| 44 |
| 45 |
| 46 class SuspendedProcess(object): |
| 47 def __init__(self, connection=None): |
| 48 self.connection = connection |
| 49 self.process_name = None |
| 50 self.reason = None |
| 51 |
| 52 def __repr__(self): |
| 53 return 'SuspendedProcess(%s, %s)' % (self.process_name, self.reason) |
| 54 |
| 55 def startElement(self, name, attrs, connection): |
| 56 pass |
| 57 |
| 58 def endElement(self, name, value, connection): |
| 59 if name == 'ProcessName': |
| 60 self.process_name = value |
| 61 elif name == 'SuspensionReason': |
| 62 self.reason = value |
| 63 |
| 64 |
| 65 class EnabledMetric(object): |
| 66 def __init__(self, connection=None, metric=None, granularity=None): |
| 67 self.connection = connection |
| 68 self.metric = metric |
| 69 self.granularity = granularity |
| 70 |
| 71 def __repr__(self): |
| 72 return 'EnabledMetric(%s, %s)' % (self.metric, self.granularity) |
| 73 |
| 74 def startElement(self, name, attrs, connection): |
| 75 pass |
| 76 |
| 77 def endElement(self, name, value, connection): |
| 78 if name == 'Granularity': |
| 79 self.granularity = value |
| 80 elif name == 'Metric': |
| 81 self.metric = value |
| 82 |
| 83 |
| 84 class TerminationPolicies(list): |
| 85 |
| 86 def startElement(self, name, attrs, connection): |
| 87 pass |
| 88 |
| 89 def endElement(self, name, value, connection): |
| 90 if name == 'member': |
| 91 self.append(value) |
| 92 |
| 93 |
| 94 class AutoScalingGroup(object): |
| 95 def __init__(self, connection=None, name=None, |
| 96 launch_config=None, availability_zones=None, |
| 97 load_balancers=None, default_cooldown=None, |
| 98 health_check_type=None, health_check_period=None, |
| 99 placement_group=None, vpc_zone_identifier=None, |
| 100 desired_capacity=None, min_size=None, max_size=None, |
| 101 tags=None, termination_policies=None, **kwargs): |
| 102 """ |
| 103 Creates a new AutoScalingGroup with the specified name. |
| 104 |
| 105 You must not have already used up your entire quota of |
| 106 AutoScalingGroups in order for this call to be successful. Once the |
| 107 creation request is completed, the AutoScalingGroup is ready to be |
| 108 used in other calls. |
| 109 |
| 110 :type name: str |
| 111 :param name: Name of autoscaling group (required). |
| 112 |
| 113 :type availability_zones: list |
| 114 :param availability_zones: List of availability zones (required). |
| 115 |
| 116 :type default_cooldown: int |
| 117 :param default_cooldown: Number of seconds after a Scaling Activity |
| 118 completes before any further scaling activities can start. |
| 119 |
| 120 :type desired_capacity: int |
| 121 :param desired_capacity: The desired capacity for the group. |
| 122 |
| 123 :type health_check_period: str |
| 124 :param health_check_period: Length of time in seconds after a new |
| 125 EC2 instance comes into service that Auto Scaling starts |
| 126 checking its health. |
| 127 |
| 128 :type health_check_type: str |
| 129 :param health_check_type: The service you want the health status from, |
| 130 Amazon EC2 or Elastic Load Balancer. |
| 131 |
| 132 :type launch_config_name: str or LaunchConfiguration |
| 133 :param launch_config_name: Name of launch configuration (required). |
| 134 |
| 135 :type load_balancers: list |
| 136 :param load_balancers: List of load balancers. |
| 137 |
| 138 :type max_size: int |
| 139 :param max_size: Maximum size of group (required). |
| 140 |
| 141 :type min_size: int |
| 142 :param min_size: Minimum size of group (required). |
| 143 |
| 144 :type placement_group: str |
| 145 :param placement_group: Physical location of your cluster placement |
| 146 group created in Amazon EC2. |
| 147 |
| 148 :type vpc_zone_identifier: str |
| 149 :param vpc_zone_identifier: The subnet identifier of the Virtual |
| 150 Private Cloud. |
| 151 |
| 152 :type termination_policies: list |
| 153 :param termination_policies: A list of termination policies. Valid value
s |
| 154 are: "OldestInstance", "NewestInstance", "OldestLaunchConfiguration"
, |
| 155 "ClosestToNextInstanceHour", "Default". If no value is specified, |
| 156 the "Default" value is used. |
| 157 |
| 158 :rtype: :class:`boto.ec2.autoscale.group.AutoScalingGroup` |
| 159 :return: An autoscale group. |
| 160 """ |
| 161 self.name = name or kwargs.get('group_name') # backwards compat |
| 162 self.connection = connection |
| 163 self.min_size = int(min_size) if min_size is not None else None |
| 164 self.max_size = int(max_size) if max_size is not None else None |
| 165 self.created_time = None |
| 166 # backwards compatibility |
| 167 default_cooldown = default_cooldown or kwargs.get('cooldown') |
| 168 if default_cooldown is not None: |
| 169 default_cooldown = int(default_cooldown) |
| 170 self.default_cooldown = default_cooldown |
| 171 self.launch_config_name = launch_config |
| 172 if launch_config and isinstance(launch_config, LaunchConfiguration): |
| 173 self.launch_config_name = launch_config.name |
| 174 self.desired_capacity = desired_capacity |
| 175 lbs = load_balancers or [] |
| 176 self.load_balancers = ListElement(lbs) |
| 177 zones = availability_zones or [] |
| 178 self.availability_zones = ListElement(zones) |
| 179 self.health_check_period = health_check_period |
| 180 self.health_check_type = health_check_type |
| 181 self.placement_group = placement_group |
| 182 self.autoscaling_group_arn = None |
| 183 self.vpc_zone_identifier = vpc_zone_identifier |
| 184 self.instances = None |
| 185 self.tags = tags or None |
| 186 termination_policies = termination_policies or [] |
| 187 self.termination_policies = ListElement(termination_policies) |
| 188 |
| 189 # backwards compatible access to 'cooldown' param |
| 190 def _get_cooldown(self): |
| 191 return self.default_cooldown |
| 192 |
| 193 def _set_cooldown(self, val): |
| 194 self.default_cooldown = val |
| 195 |
| 196 cooldown = property(_get_cooldown, _set_cooldown) |
| 197 |
| 198 def __repr__(self): |
| 199 return 'AutoScaleGroup<%s>' % self.name |
| 200 |
| 201 def startElement(self, name, attrs, connection): |
| 202 if name == 'Instances': |
| 203 self.instances = ResultSet([('member', Instance)]) |
| 204 return self.instances |
| 205 elif name == 'LoadBalancerNames': |
| 206 return self.load_balancers |
| 207 elif name == 'AvailabilityZones': |
| 208 return self.availability_zones |
| 209 elif name == 'EnabledMetrics': |
| 210 self.enabled_metrics = ResultSet([('member', EnabledMetric)]) |
| 211 return self.enabled_metrics |
| 212 elif name == 'SuspendedProcesses': |
| 213 self.suspended_processes = ResultSet([('member', SuspendedProcess)]) |
| 214 return self.suspended_processes |
| 215 elif name == 'Tags': |
| 216 self.tags = ResultSet([('member', Tag)]) |
| 217 return self.tags |
| 218 elif name == 'TerminationPolicies': |
| 219 return self.termination_policies |
| 220 else: |
| 221 return |
| 222 |
| 223 def endElement(self, name, value, connection): |
| 224 if name == 'MinSize': |
| 225 self.min_size = int(value) |
| 226 elif name == 'AutoScalingGroupARN': |
| 227 self.autoscaling_group_arn = value |
| 228 elif name == 'CreatedTime': |
| 229 self.created_time = value |
| 230 elif name == 'DefaultCooldown': |
| 231 self.default_cooldown = int(value) |
| 232 elif name == 'LaunchConfigurationName': |
| 233 self.launch_config_name = value |
| 234 elif name == 'DesiredCapacity': |
| 235 self.desired_capacity = int(value) |
| 236 elif name == 'MaxSize': |
| 237 self.max_size = int(value) |
| 238 elif name == 'AutoScalingGroupName': |
| 239 self.name = value |
| 240 elif name == 'PlacementGroup': |
| 241 self.placement_group = value |
| 242 elif name == 'HealthCheckGracePeriod': |
| 243 try: |
| 244 self.health_check_period = int(value) |
| 245 except ValueError: |
| 246 self.health_check_period = None |
| 247 elif name == 'HealthCheckType': |
| 248 self.health_check_type = value |
| 249 elif name == 'VPCZoneIdentifier': |
| 250 self.vpc_zone_identifier = value |
| 251 else: |
| 252 setattr(self, name, value) |
| 253 |
| 254 def set_capacity(self, capacity): |
| 255 """ |
| 256 Set the desired capacity for the group. |
| 257 """ |
| 258 params = {'AutoScalingGroupName': self.name, |
| 259 'DesiredCapacity': capacity} |
| 260 req = self.connection.get_object('SetDesiredCapacity', params, |
| 261 Request) |
| 262 self.connection.last_request = req |
| 263 return req |
| 264 |
| 265 def update(self): |
| 266 """ |
| 267 Sync local changes with AutoScaling group. |
| 268 """ |
| 269 return self.connection._update_group('UpdateAutoScalingGroup', self) |
| 270 |
| 271 def shutdown_instances(self): |
| 272 """ |
| 273 Convenience method which shuts down all instances associated with |
| 274 this group. |
| 275 """ |
| 276 self.min_size = 0 |
| 277 self.max_size = 0 |
| 278 self.desired_capacity = 0 |
| 279 self.update() |
| 280 |
| 281 def delete(self, force_delete=False): |
| 282 """ |
| 283 Delete this auto-scaling group if no instances attached or no |
| 284 scaling activities in progress. |
| 285 """ |
| 286 return self.connection.delete_auto_scaling_group(self.name, |
| 287 force_delete) |
| 288 |
| 289 def get_activities(self, activity_ids=None, max_records=50): |
| 290 """ |
| 291 Get all activies for this group. |
| 292 """ |
| 293 return self.connection.get_all_activities(self, activity_ids, |
| 294 max_records) |
| 295 |
| 296 def put_notification_configuration(self, topic, notification_types): |
| 297 """ |
| 298 Configures an Auto Scaling group to send notifications when |
| 299 specified events take place. |
| 300 """ |
| 301 return self.connection.put_notification_configuration(self, |
| 302 topic, |
| 303 notification_types
) |
| 304 |
| 305 def suspend_processes(self, scaling_processes=None): |
| 306 """ |
| 307 Suspends Auto Scaling processes for an Auto Scaling group. |
| 308 """ |
| 309 return self.connection.suspend_processes(self.name, scaling_processes) |
| 310 |
| 311 def resume_processes(self, scaling_processes=None): |
| 312 """ |
| 313 Resumes Auto Scaling processes for an Auto Scaling group. |
| 314 """ |
| 315 return self.connection.resume_processes(self.name, scaling_processes) |
| 316 |
| 317 |
| 318 class AutoScalingGroupMetric(object): |
| 319 def __init__(self, connection=None): |
| 320 |
| 321 self.connection = connection |
| 322 self.metric = None |
| 323 self.granularity = None |
| 324 |
| 325 def __repr__(self): |
| 326 return 'AutoScalingGroupMetric:%s' % self.metric |
| 327 |
| 328 def startElement(self, name, attrs, connection): |
| 329 return |
| 330 |
| 331 def endElement(self, name, value, connection): |
| 332 if name == 'Metric': |
| 333 self.metric = value |
| 334 elif name == 'Granularity': |
| 335 self.granularity = value |
| 336 else: |
| 337 setattr(self, name, value) |
OLD | NEW |