Add attach_ and detach_instances methods to autoscaling service (#1264)
* add detach_instances functionality to autoscaling service * use ASG_NAME_TAG constant * cleanup models method a bit, add mocked DetachInstancesResult to response template * add attach_instances method
This commit is contained in:
parent
49ddb500a8
commit
5ef236e966
4 changed files with 277 additions and 21 deletions
|
|
@ -5,6 +5,9 @@ from moto.core import BaseBackend, BaseModel
|
|||
from moto.ec2 import ec2_backends
|
||||
from moto.elb import elb_backends
|
||||
from moto.elb.exceptions import LoadBalancerNotFoundError
|
||||
from .exceptions import (
|
||||
ResourceContentionError,
|
||||
)
|
||||
|
||||
# http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AS_Concepts.html#Cooldown
|
||||
DEFAULT_COOLDOWN = 300
|
||||
|
|
@ -259,27 +262,8 @@ class FakeAutoScalingGroup(BaseModel):
|
|||
# Need more instances
|
||||
count_needed = int(self.desired_capacity) - int(curr_instance_count)
|
||||
|
||||
propagated_tags = {}
|
||||
for tag in self.tags:
|
||||
# boto uses 'propagate_at_launch
|
||||
# boto3 and cloudformation use PropagateAtLaunch
|
||||
if 'propagate_at_launch' in tag and tag['propagate_at_launch'] == 'true':
|
||||
propagated_tags[tag['key']] = tag['value']
|
||||
if 'PropagateAtLaunch' in tag and tag['PropagateAtLaunch']:
|
||||
propagated_tags[tag['Key']] = tag['Value']
|
||||
|
||||
propagated_tags[ASG_NAME_TAG] = self.name
|
||||
reservation = self.autoscaling_backend.ec2_backend.add_instances(
|
||||
self.launch_config.image_id,
|
||||
count_needed,
|
||||
self.launch_config.user_data,
|
||||
self.launch_config.security_groups,
|
||||
instance_type=self.launch_config.instance_type,
|
||||
tags={'instance': propagated_tags}
|
||||
)
|
||||
for instance in reservation.instances:
|
||||
instance.autoscaling_group = self
|
||||
self.instance_states.append(InstanceState(instance))
|
||||
propagated_tags = self.get_propagated_tags()
|
||||
self.replace_autoscaling_group_instances(count_needed, propagated_tags)
|
||||
else:
|
||||
# Need to remove some instances
|
||||
count_to_remove = curr_instance_count - self.desired_capacity
|
||||
|
|
@ -290,6 +274,31 @@ class FakeAutoScalingGroup(BaseModel):
|
|||
instance_ids_to_remove)
|
||||
self.instance_states = self.instance_states[count_to_remove:]
|
||||
|
||||
def get_propagated_tags(self):
|
||||
propagated_tags = {}
|
||||
for tag in self.tags:
|
||||
# boto uses 'propagate_at_launch
|
||||
# boto3 and cloudformation use PropagateAtLaunch
|
||||
if 'propagate_at_launch' in tag and tag['propagate_at_launch'] == 'true':
|
||||
propagated_tags[tag['key']] = tag['value']
|
||||
if 'PropagateAtLaunch' in tag and tag['PropagateAtLaunch']:
|
||||
propagated_tags[tag['Key']] = tag['Value']
|
||||
return propagated_tags
|
||||
|
||||
def replace_autoscaling_group_instances(self, count_needed, propagated_tags):
|
||||
propagated_tags[ASG_NAME_TAG] = self.name
|
||||
reservation = self.autoscaling_backend.ec2_backend.add_instances(
|
||||
self.launch_config.image_id,
|
||||
count_needed,
|
||||
self.launch_config.user_data,
|
||||
self.launch_config.security_groups,
|
||||
instance_type=self.launch_config.instance_type,
|
||||
tags={'instance': propagated_tags}
|
||||
)
|
||||
for instance in reservation.instances:
|
||||
instance.autoscaling_group = self
|
||||
self.instance_states.append(InstanceState(instance))
|
||||
|
||||
|
||||
class AutoScalingBackend(BaseBackend):
|
||||
def __init__(self, ec2_backend, elb_backend):
|
||||
|
|
@ -409,6 +418,40 @@ class AutoScalingBackend(BaseBackend):
|
|||
instance_states.extend(group.instance_states)
|
||||
return instance_states
|
||||
|
||||
def attach_instances(self, group_name, instance_ids):
|
||||
group = self.autoscaling_groups[group_name]
|
||||
original_size = len(group.instance_states)
|
||||
|
||||
if (original_size + len(instance_ids)) > group.max_size:
|
||||
raise ResourceContentionError
|
||||
else:
|
||||
group.desired_capacity = original_size + len(instance_ids)
|
||||
new_instances = [InstanceState(self.ec2_backend.get_instance(x)) for x in instance_ids]
|
||||
for instance in new_instances:
|
||||
self.ec2_backend.create_tags([instance.instance.id], {ASG_NAME_TAG: group.name})
|
||||
group.instance_states.extend(new_instances)
|
||||
self.update_attached_elbs(group.name)
|
||||
|
||||
def detach_instances(self, group_name, instance_ids, should_decrement):
|
||||
group = self.autoscaling_groups[group_name]
|
||||
original_size = len(group.instance_states)
|
||||
|
||||
detached_instances = [x for x in group.instance_states if x.instance.id in instance_ids]
|
||||
for instance in detached_instances:
|
||||
self.ec2_backend.delete_tags([instance.instance.id], {ASG_NAME_TAG: group.name})
|
||||
|
||||
new_instance_state = [x for x in group.instance_states if x.instance.id not in instance_ids]
|
||||
group.instance_states = new_instance_state
|
||||
|
||||
if should_decrement:
|
||||
group.desired_capacity = original_size - len(instance_ids)
|
||||
else:
|
||||
count_needed = len(instance_ids)
|
||||
group.replace_autoscaling_group_instances(count_needed, group.get_propagated_tags())
|
||||
|
||||
self.update_attached_elbs(group_name)
|
||||
return detached_instances
|
||||
|
||||
def set_desired_capacity(self, group_name, desired_capacity):
|
||||
group = self.autoscaling_groups[group_name]
|
||||
group.set_desired_capacity(desired_capacity)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue