Merge pull request #2891 from DenverJ/enhancement/autoscaling-standby-terminate
Implement enter_standby, exit_standby and terminate_instance_in_auto_scaling_group
This commit is contained in:
commit
d0c60ecaac
@ -267,6 +267,9 @@ class FakeAutoScalingGroup(BaseModel):
|
|||||||
self.tags = tags if tags else []
|
self.tags = tags if tags else []
|
||||||
self.set_desired_capacity(desired_capacity)
|
self.set_desired_capacity(desired_capacity)
|
||||||
|
|
||||||
|
def active_instances(self):
|
||||||
|
return [x for x in self.instance_states if x.lifecycle_state == "InService"]
|
||||||
|
|
||||||
def _set_azs_and_vpcs(self, availability_zones, vpc_zone_identifier, update=False):
|
def _set_azs_and_vpcs(self, availability_zones, vpc_zone_identifier, update=False):
|
||||||
# for updates, if only AZs are provided, they must not clash with
|
# for updates, if only AZs are provided, they must not clash with
|
||||||
# the AZs of existing VPCs
|
# the AZs of existing VPCs
|
||||||
@ -413,9 +416,11 @@ class FakeAutoScalingGroup(BaseModel):
|
|||||||
else:
|
else:
|
||||||
self.desired_capacity = new_capacity
|
self.desired_capacity = new_capacity
|
||||||
|
|
||||||
curr_instance_count = len(self.instance_states)
|
curr_instance_count = len(self.active_instances())
|
||||||
|
|
||||||
if self.desired_capacity == curr_instance_count:
|
if self.desired_capacity == curr_instance_count:
|
||||||
|
self.autoscaling_backend.update_attached_elbs(self.name)
|
||||||
|
self.autoscaling_backend.update_attached_target_groups(self.name)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.desired_capacity > curr_instance_count:
|
if self.desired_capacity > curr_instance_count:
|
||||||
@ -442,6 +447,8 @@ class FakeAutoScalingGroup(BaseModel):
|
|||||||
self.instance_states = list(
|
self.instance_states = list(
|
||||||
set(self.instance_states) - set(instances_to_remove)
|
set(self.instance_states) - set(instances_to_remove)
|
||||||
)
|
)
|
||||||
|
self.autoscaling_backend.update_attached_elbs(self.name)
|
||||||
|
self.autoscaling_backend.update_attached_target_groups(self.name)
|
||||||
|
|
||||||
def get_propagated_tags(self):
|
def get_propagated_tags(self):
|
||||||
propagated_tags = {}
|
propagated_tags = {}
|
||||||
@ -703,7 +710,7 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
|
|
||||||
def detach_instances(self, group_name, instance_ids, should_decrement):
|
def detach_instances(self, group_name, instance_ids, should_decrement):
|
||||||
group = self.autoscaling_groups[group_name]
|
group = self.autoscaling_groups[group_name]
|
||||||
original_size = len(group.instance_states)
|
original_size = group.desired_capacity
|
||||||
|
|
||||||
detached_instances = [
|
detached_instances = [
|
||||||
x for x in group.instance_states if x.instance.id in instance_ids
|
x for x in group.instance_states if x.instance.id in instance_ids
|
||||||
@ -720,13 +727,8 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
|
|
||||||
if should_decrement:
|
if should_decrement:
|
||||||
group.desired_capacity = original_size - len(instance_ids)
|
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)
|
group.set_desired_capacity(group.desired_capacity)
|
||||||
return detached_instances
|
return detached_instances
|
||||||
|
|
||||||
def set_desired_capacity(self, group_name, desired_capacity):
|
def set_desired_capacity(self, group_name, desired_capacity):
|
||||||
@ -791,7 +793,9 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
|
|
||||||
def update_attached_elbs(self, group_name):
|
def update_attached_elbs(self, group_name):
|
||||||
group = self.autoscaling_groups[group_name]
|
group = self.autoscaling_groups[group_name]
|
||||||
group_instance_ids = set(state.instance.id for state in group.instance_states)
|
group_instance_ids = set(
|
||||||
|
state.instance.id for state in group.active_instances()
|
||||||
|
)
|
||||||
|
|
||||||
# skip this if group.load_balancers is empty
|
# skip this if group.load_balancers is empty
|
||||||
# otherwise elb_backend.describe_load_balancers returns all available load balancers
|
# otherwise elb_backend.describe_load_balancers returns all available load balancers
|
||||||
@ -908,15 +912,15 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
autoscaling_group_name,
|
autoscaling_group_name,
|
||||||
autoscaling_group,
|
autoscaling_group,
|
||||||
) in self.autoscaling_groups.items():
|
) in self.autoscaling_groups.items():
|
||||||
original_instance_count = len(autoscaling_group.instance_states)
|
original_active_instance_count = len(autoscaling_group.active_instances())
|
||||||
autoscaling_group.instance_states = list(
|
autoscaling_group.instance_states = list(
|
||||||
filter(
|
filter(
|
||||||
lambda i_state: i_state.instance.id not in instance_ids,
|
lambda i_state: i_state.instance.id not in instance_ids,
|
||||||
autoscaling_group.instance_states,
|
autoscaling_group.instance_states,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
difference = original_instance_count - len(
|
difference = original_active_instance_count - len(
|
||||||
autoscaling_group.instance_states
|
autoscaling_group.active_instances()
|
||||||
)
|
)
|
||||||
if difference > 0:
|
if difference > 0:
|
||||||
autoscaling_group.replace_autoscaling_group_instances(
|
autoscaling_group.replace_autoscaling_group_instances(
|
||||||
@ -924,6 +928,45 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
)
|
)
|
||||||
self.update_attached_elbs(autoscaling_group_name)
|
self.update_attached_elbs(autoscaling_group_name)
|
||||||
|
|
||||||
|
def enter_standby_instances(self, group_name, instance_ids, should_decrement):
|
||||||
|
group = self.autoscaling_groups[group_name]
|
||||||
|
original_size = group.desired_capacity
|
||||||
|
standby_instances = []
|
||||||
|
for instance_state in group.instance_states:
|
||||||
|
if instance_state.instance.id in instance_ids:
|
||||||
|
instance_state.lifecycle_state = "Standby"
|
||||||
|
standby_instances.append(instance_state)
|
||||||
|
if should_decrement:
|
||||||
|
group.desired_capacity = group.desired_capacity - len(instance_ids)
|
||||||
|
else:
|
||||||
|
group.set_desired_capacity(group.desired_capacity)
|
||||||
|
return standby_instances, original_size, group.desired_capacity
|
||||||
|
|
||||||
|
def exit_standby_instances(self, group_name, instance_ids):
|
||||||
|
group = self.autoscaling_groups[group_name]
|
||||||
|
original_size = group.desired_capacity
|
||||||
|
standby_instances = []
|
||||||
|
for instance_state in group.instance_states:
|
||||||
|
if instance_state.instance.id in instance_ids:
|
||||||
|
instance_state.lifecycle_state = "InService"
|
||||||
|
standby_instances.append(instance_state)
|
||||||
|
group.desired_capacity = group.desired_capacity + len(instance_ids)
|
||||||
|
return standby_instances, original_size, group.desired_capacity
|
||||||
|
|
||||||
|
def terminate_instance(self, instance_id, should_decrement):
|
||||||
|
instance = self.ec2_backend.get_instance(instance_id)
|
||||||
|
instance_state = next(
|
||||||
|
instance_state
|
||||||
|
for group in self.autoscaling_groups.values()
|
||||||
|
for instance_state in group.instance_states
|
||||||
|
if instance_state.instance.id == instance.id
|
||||||
|
)
|
||||||
|
group = instance.autoscaling_group
|
||||||
|
original_size = group.desired_capacity
|
||||||
|
self.detach_instances(group.name, [instance.id], should_decrement)
|
||||||
|
self.ec2_backend.terminate_instances([instance.id])
|
||||||
|
return instance_state, original_size, group.desired_capacity
|
||||||
|
|
||||||
|
|
||||||
autoscaling_backends = {}
|
autoscaling_backends = {}
|
||||||
for region, ec2_backend in ec2_backends.items():
|
for region, ec2_backend in ec2_backends.items():
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import datetime
|
||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from moto.core.utils import amz_crc32, amzn_request_id
|
from moto.core.utils import (
|
||||||
|
amz_crc32,
|
||||||
|
amzn_request_id,
|
||||||
|
iso_8601_datetime_with_milliseconds,
|
||||||
|
)
|
||||||
from .models import autoscaling_backends
|
from .models import autoscaling_backends
|
||||||
|
|
||||||
|
|
||||||
@ -291,6 +296,50 @@ class AutoScalingResponse(BaseResponse):
|
|||||||
template = self.response_template(DETACH_LOAD_BALANCERS_TEMPLATE)
|
template = self.response_template(DETACH_LOAD_BALANCERS_TEMPLATE)
|
||||||
return template.render()
|
return template.render()
|
||||||
|
|
||||||
|
@amz_crc32
|
||||||
|
@amzn_request_id
|
||||||
|
def enter_standby(self):
|
||||||
|
group_name = self._get_param("AutoScalingGroupName")
|
||||||
|
instance_ids = self._get_multi_param("InstanceIds.member")
|
||||||
|
should_decrement_string = self._get_param("ShouldDecrementDesiredCapacity")
|
||||||
|
if should_decrement_string == "true":
|
||||||
|
should_decrement = True
|
||||||
|
else:
|
||||||
|
should_decrement = False
|
||||||
|
(
|
||||||
|
standby_instances,
|
||||||
|
original_size,
|
||||||
|
desired_capacity,
|
||||||
|
) = self.autoscaling_backend.enter_standby_instances(
|
||||||
|
group_name, instance_ids, should_decrement
|
||||||
|
)
|
||||||
|
template = self.response_template(ENTER_STANDBY_TEMPLATE)
|
||||||
|
return template.render(
|
||||||
|
standby_instances=standby_instances,
|
||||||
|
should_decrement=should_decrement,
|
||||||
|
original_size=original_size,
|
||||||
|
desired_capacity=desired_capacity,
|
||||||
|
timestamp=iso_8601_datetime_with_milliseconds(datetime.datetime.utcnow()),
|
||||||
|
)
|
||||||
|
|
||||||
|
@amz_crc32
|
||||||
|
@amzn_request_id
|
||||||
|
def exit_standby(self):
|
||||||
|
group_name = self._get_param("AutoScalingGroupName")
|
||||||
|
instance_ids = self._get_multi_param("InstanceIds.member")
|
||||||
|
(
|
||||||
|
standby_instances,
|
||||||
|
original_size,
|
||||||
|
desired_capacity,
|
||||||
|
) = self.autoscaling_backend.exit_standby_instances(group_name, instance_ids)
|
||||||
|
template = self.response_template(EXIT_STANDBY_TEMPLATE)
|
||||||
|
return template.render(
|
||||||
|
standby_instances=standby_instances,
|
||||||
|
original_size=original_size,
|
||||||
|
desired_capacity=desired_capacity,
|
||||||
|
timestamp=iso_8601_datetime_with_milliseconds(datetime.datetime.utcnow()),
|
||||||
|
)
|
||||||
|
|
||||||
def suspend_processes(self):
|
def suspend_processes(self):
|
||||||
autoscaling_group_name = self._get_param("AutoScalingGroupName")
|
autoscaling_group_name = self._get_param("AutoScalingGroupName")
|
||||||
scaling_processes = self._get_multi_param("ScalingProcesses.member")
|
scaling_processes = self._get_multi_param("ScalingProcesses.member")
|
||||||
@ -310,6 +359,29 @@ class AutoScalingResponse(BaseResponse):
|
|||||||
template = self.response_template(SET_INSTANCE_PROTECTION_TEMPLATE)
|
template = self.response_template(SET_INSTANCE_PROTECTION_TEMPLATE)
|
||||||
return template.render()
|
return template.render()
|
||||||
|
|
||||||
|
@amz_crc32
|
||||||
|
@amzn_request_id
|
||||||
|
def terminate_instance_in_auto_scaling_group(self):
|
||||||
|
instance_id = self._get_param("InstanceId")
|
||||||
|
should_decrement_string = self._get_param("ShouldDecrementDesiredCapacity")
|
||||||
|
if should_decrement_string == "true":
|
||||||
|
should_decrement = True
|
||||||
|
else:
|
||||||
|
should_decrement = False
|
||||||
|
(
|
||||||
|
instance,
|
||||||
|
original_size,
|
||||||
|
desired_capacity,
|
||||||
|
) = self.autoscaling_backend.terminate_instance(instance_id, should_decrement)
|
||||||
|
template = self.response_template(TERMINATE_INSTANCES_TEMPLATE)
|
||||||
|
return template.render(
|
||||||
|
instance=instance,
|
||||||
|
should_decrement=should_decrement,
|
||||||
|
original_size=original_size,
|
||||||
|
desired_capacity=desired_capacity,
|
||||||
|
timestamp=iso_8601_datetime_with_milliseconds(datetime.datetime.utcnow()),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
CREATE_LAUNCH_CONFIGURATION_TEMPLATE = """<CreateLaunchConfigurationResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
CREATE_LAUNCH_CONFIGURATION_TEMPLATE = """<CreateLaunchConfigurationResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
<ResponseMetadata>
|
<ResponseMetadata>
|
||||||
@ -707,3 +779,73 @@ SET_INSTANCE_PROTECTION_TEMPLATE = """<SetInstanceProtectionResponse xmlns="http
|
|||||||
<RequestId></RequestId>
|
<RequestId></RequestId>
|
||||||
</ResponseMetadata>
|
</ResponseMetadata>
|
||||||
</SetInstanceProtectionResponse>"""
|
</SetInstanceProtectionResponse>"""
|
||||||
|
|
||||||
|
ENTER_STANDBY_TEMPLATE = """<EnterStandbyResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
|
<EnterStandbyResult>
|
||||||
|
<Activities>
|
||||||
|
{% for instance in standby_instances %}
|
||||||
|
<member>
|
||||||
|
<ActivityId>12345678-1234-1234-1234-123456789012</ActivityId>
|
||||||
|
<AutoScalingGroupName>{{ group_name }}</AutoScalingGroupName>
|
||||||
|
{% if should_decrement %}
|
||||||
|
<Cause>At {{ timestamp }} instance {{ instance.instance.id }} was moved to standby in response to a user request, shrinking the capacity from {{ original_size }} to {{ desired_capacity }}.</Cause>
|
||||||
|
{% else %}
|
||||||
|
<Cause>At {{ timestamp }} instance {{ instance.instance.id }} was moved to standby in response to a user request.</Cause>
|
||||||
|
{% endif %}
|
||||||
|
<Description>Moving EC2 instance to Standby: {{ instance.instance.id }}</Description>
|
||||||
|
<Progress>50</Progress>
|
||||||
|
<StartTime>{{ timestamp }}</StartTime>
|
||||||
|
<Details>{"Subnet ID":"??","Availability Zone":"{{ instance.instance.placement }}"}</Details>
|
||||||
|
<StatusCode>InProgress</StatusCode>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Activities>
|
||||||
|
</EnterStandbyResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>7c6e177f-f082-11e1-ac58-3714bEXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</EnterStandbyResponse>"""
|
||||||
|
|
||||||
|
EXIT_STANDBY_TEMPLATE = """<ExitStandbyResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
|
<ExitStandbyResult>
|
||||||
|
<Activities>
|
||||||
|
{% for instance in standby_instances %}
|
||||||
|
<member>
|
||||||
|
<ActivityId>12345678-1234-1234-1234-123456789012</ActivityId>
|
||||||
|
<AutoScalingGroupName>{{ group_name }}</AutoScalingGroupName>
|
||||||
|
<Description>Moving EC2 instance out of Standby: {{ instance.instance.id }}</Description>
|
||||||
|
<Progress>30</Progress>
|
||||||
|
<Cause>At {{ timestamp }} instance {{ instance.instance.id }} was moved out of standby in response to a user request, increasing the capacity from {{ original_size }} to {{ desired_capacity }}.</Cause>
|
||||||
|
<StartTime>{{ timestamp }}</StartTime>
|
||||||
|
<Details>{"Subnet ID":"??","Availability Zone":"{{ instance.instance.placement }}"}</Details>
|
||||||
|
<StatusCode>PreInService</StatusCode>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Activities>
|
||||||
|
</ExitStandbyResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>7c6e177f-f082-11e1-ac58-3714bEXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</ExitStandbyResponse>"""
|
||||||
|
|
||||||
|
TERMINATE_INSTANCES_TEMPLATE = """<TerminateInstanceInAutoScalingGroupResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
|
<TerminateInstanceInAutoScalingGroupResult>
|
||||||
|
<Activity>
|
||||||
|
<ActivityId>35b5c464-0b63-2fc7-1611-467d4a7f2497EXAMPLE</ActivityId>
|
||||||
|
<AutoScalingGroupName>{{ group_name }}</AutoScalingGroupName>
|
||||||
|
{% if should_decrement %}
|
||||||
|
<Cause>At {{ timestamp }} instance {{ instance.instance.id }} was taken out of service in response to a user request, shrinking the capacity from {{ original_size }} to {{ desired_capacity }}.</Cause>
|
||||||
|
{% else %}
|
||||||
|
<Cause>At {{ timestamp }} instance {{ instance.instance.id }} was taken out of service in response to a user request.</Cause>
|
||||||
|
{% endif %}
|
||||||
|
<Description>Terminating EC2 instance: {{ instance.instance.id }}</Description>
|
||||||
|
<Progress>0</Progress>
|
||||||
|
<StartTime>{{ timestamp }}</StartTime>
|
||||||
|
<Details>{"Subnet ID":"??","Availability Zone":"{{ instance.instance.placement }}"}</Details>
|
||||||
|
<StatusCode>InProgress</StatusCode>
|
||||||
|
</Activity>
|
||||||
|
</TerminateInstanceInAutoScalingGroupResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>a1ba8fb9-31d6-4d9a-ace1-a7f76749df11EXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</TerminateInstanceInAutoScalingGroupResponse>"""
|
||||||
|
@ -1102,8 +1102,6 @@ def test_detach_one_instance_decrement():
|
|||||||
|
|
||||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
response = ec2_client.describe_instances(InstanceIds=[instance_to_detach])
|
|
||||||
|
|
||||||
response = client.detach_instances(
|
response = client.detach_instances(
|
||||||
AutoScalingGroupName="test_asg",
|
AutoScalingGroupName="test_asg",
|
||||||
InstanceIds=[instance_to_detach],
|
InstanceIds=[instance_to_detach],
|
||||||
@ -1156,8 +1154,6 @@ def test_detach_one_instance():
|
|||||||
|
|
||||||
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
response = ec2_client.describe_instances(InstanceIds=[instance_to_detach])
|
|
||||||
|
|
||||||
response = client.detach_instances(
|
response = client.detach_instances(
|
||||||
AutoScalingGroupName="test_asg",
|
AutoScalingGroupName="test_asg",
|
||||||
InstanceIds=[instance_to_detach],
|
InstanceIds=[instance_to_detach],
|
||||||
@ -1178,6 +1174,516 @@ def test_detach_one_instance():
|
|||||||
tags.should.have.length_of(2)
|
tags.should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_one_instance_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=2,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"]
|
||||||
|
instance_to_keep = response["AutoScalingGroups"][0]["Instances"][1]["InstanceId"]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby],
|
||||||
|
ShouldDecrementDesiredCapacity=True,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(2)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(1)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(InstanceIds=[instance_to_standby])
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
# test to ensure tag has been retained (standby instance is still part of the ASG)
|
||||||
|
response = ec2_client.describe_instances()
|
||||||
|
for reservation in response["Reservations"]:
|
||||||
|
for instance in reservation["Instances"]:
|
||||||
|
tags = instance["Tags"]
|
||||||
|
tags.should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_one_instance():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=2,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"]
|
||||||
|
instance_to_keep = response["AutoScalingGroups"][0]["Instances"][1]["InstanceId"]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(InstanceIds=[instance_to_standby])
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
# test to ensure tag has been retained (standby instance is still part of the ASG)
|
||||||
|
response = ec2_client.describe_instances()
|
||||||
|
for reservation in response["Reservations"]:
|
||||||
|
for instance in reservation["Instances"]:
|
||||||
|
tags = instance["Tags"]
|
||||||
|
tags.should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_elb
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_elb_update():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=2,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
elb_client = boto3.client("elb", region_name="us-east-1")
|
||||||
|
elb_client.create_load_balancer(
|
||||||
|
LoadBalancerName="my-lb",
|
||||||
|
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
|
||||||
|
AvailabilityZones=["us-east-1a", "us-east-1b"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.attach_load_balancers(
|
||||||
|
AutoScalingGroupName="test_asg", LoadBalancerNames=["my-lb"]
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby = response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"]
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(InstanceIds=[instance_to_standby])
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = elb_client.describe_load_balancers(LoadBalancerNames=["my-lb"])
|
||||||
|
list(response["LoadBalancerDescriptions"][0]["Instances"]).should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_terminate_instance_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=3,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby_terminate = response["AutoScalingGroups"][0]["Instances"][0][
|
||||||
|
"InstanceId"
|
||||||
|
]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_terminate],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(
|
||||||
|
InstanceIds=[instance_to_standby_terminate]
|
||||||
|
)
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = client.terminate_instance_in_auto_scaling_group(
|
||||||
|
InstanceId=instance_to_standby_terminate, ShouldDecrementDesiredCapacity=True
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
# AWS still decrements desired capacity ASG if requested, even if the terminated instance is in standby
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(1)
|
||||||
|
response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"].should_not.equal(
|
||||||
|
instance_to_standby_terminate
|
||||||
|
)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(1)
|
||||||
|
|
||||||
|
response = ec2_client.describe_instances(
|
||||||
|
InstanceIds=[instance_to_standby_terminate]
|
||||||
|
)
|
||||||
|
response["Reservations"][0]["Instances"][0]["State"]["Name"].should.equal(
|
||||||
|
"terminated"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_terminate_instance_no_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=3,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby_terminate = response["AutoScalingGroups"][0]["Instances"][0][
|
||||||
|
"InstanceId"
|
||||||
|
]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_terminate],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(
|
||||||
|
InstanceIds=[instance_to_standby_terminate]
|
||||||
|
)
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = client.terminate_instance_in_auto_scaling_group(
|
||||||
|
InstanceId=instance_to_standby_terminate, ShouldDecrementDesiredCapacity=False
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
group = response["AutoScalingGroups"][0]
|
||||||
|
group["Instances"].should.have.length_of(2)
|
||||||
|
instance_to_standby_terminate.shouldnt.be.within(
|
||||||
|
[x["InstanceId"] for x in group["Instances"]]
|
||||||
|
)
|
||||||
|
group["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = ec2_client.describe_instances(
|
||||||
|
InstanceIds=[instance_to_standby_terminate]
|
||||||
|
)
|
||||||
|
response["Reservations"][0]["Instances"][0]["State"]["Name"].should.equal(
|
||||||
|
"terminated"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_detach_instance_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=3,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby_detach = response["AutoScalingGroups"][0]["Instances"][0][
|
||||||
|
"InstanceId"
|
||||||
|
]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_detach],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(
|
||||||
|
InstanceIds=[instance_to_standby_detach]
|
||||||
|
)
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = client.detach_instances(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_detach],
|
||||||
|
ShouldDecrementDesiredCapacity=True,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
# AWS still decrements desired capacity ASG if requested, even if the detached instance was in standby
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(1)
|
||||||
|
response["AutoScalingGroups"][0]["Instances"][0]["InstanceId"].should_not.equal(
|
||||||
|
instance_to_standby_detach
|
||||||
|
)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(1)
|
||||||
|
|
||||||
|
response = ec2_client.describe_instances(InstanceIds=[instance_to_standby_detach])
|
||||||
|
response["Reservations"][0]["Instances"][0]["State"]["Name"].should.equal("running")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_detach_instance_no_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=3,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby_detach = response["AutoScalingGroups"][0]["Instances"][0][
|
||||||
|
"InstanceId"
|
||||||
|
]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_detach],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(
|
||||||
|
InstanceIds=[instance_to_standby_detach]
|
||||||
|
)
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = client.detach_instances(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_detach],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
group = response["AutoScalingGroups"][0]
|
||||||
|
group["Instances"].should.have.length_of(2)
|
||||||
|
instance_to_standby_detach.shouldnt.be.within(
|
||||||
|
[x["InstanceId"] for x in group["Instances"]]
|
||||||
|
)
|
||||||
|
group["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = ec2_client.describe_instances(InstanceIds=[instance_to_standby_detach])
|
||||||
|
response["Reservations"][0]["Instances"][0]["State"]["Name"].should.equal("running")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_standby_exit_standby():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
MaxSize=3,
|
||||||
|
DesiredCapacity=2,
|
||||||
|
Tags=[
|
||||||
|
{
|
||||||
|
"ResourceId": "test_asg",
|
||||||
|
"ResourceType": "auto-scaling-group",
|
||||||
|
"Key": "propogated-tag-key",
|
||||||
|
"Value": "propagate-tag-value",
|
||||||
|
"PropagateAtLaunch": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
instance_to_standby_exit_standby = response["AutoScalingGroups"][0]["Instances"][0][
|
||||||
|
"InstanceId"
|
||||||
|
]
|
||||||
|
|
||||||
|
ec2_client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = client.enter_standby(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
InstanceIds=[instance_to_standby_exit_standby],
|
||||||
|
ShouldDecrementDesiredCapacity=False,
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.have.length_of(3)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(2)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_instances(
|
||||||
|
InstanceIds=[instance_to_standby_exit_standby]
|
||||||
|
)
|
||||||
|
response["AutoScalingInstances"][0]["LifecycleState"].should.equal("Standby")
|
||||||
|
|
||||||
|
response = client.exit_standby(
|
||||||
|
AutoScalingGroupName="test_asg", InstanceIds=[instance_to_standby_exit_standby],
|
||||||
|
)
|
||||||
|
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
group = response["AutoScalingGroups"][0]
|
||||||
|
group["Instances"].should.have.length_of(3)
|
||||||
|
instance_to_standby_exit_standby.should.be.within(
|
||||||
|
[x["InstanceId"] for x in group["Instances"]]
|
||||||
|
)
|
||||||
|
group["DesiredCapacity"].should.equal(3)
|
||||||
|
|
||||||
|
response = ec2_client.describe_instances(
|
||||||
|
InstanceIds=[instance_to_standby_exit_standby]
|
||||||
|
)
|
||||||
|
response["Reservations"][0]["Instances"][0]["State"]["Name"].should.equal("running")
|
||||||
|
|
||||||
|
|
||||||
@mock_autoscaling
|
@mock_autoscaling
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_attach_one_instance():
|
def test_attach_one_instance():
|
||||||
@ -1411,7 +1917,7 @@ def test_set_desired_capacity_down_boto3():
|
|||||||
|
|
||||||
@mock_autoscaling
|
@mock_autoscaling
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_terminate_instance_in_autoscaling_group():
|
def test_terminate_instance_via_ec2_in_autoscaling_group():
|
||||||
mocked_networking = setup_networking()
|
mocked_networking = setup_networking()
|
||||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
_ = client.create_launch_configuration(
|
_ = client.create_launch_configuration(
|
||||||
@ -1440,3 +1946,71 @@ def test_terminate_instance_in_autoscaling_group():
|
|||||||
for instance in response["AutoScalingGroups"][0]["Instances"]
|
for instance in response["AutoScalingGroups"][0]["Instances"]
|
||||||
)
|
)
|
||||||
replaced_instance_id.should_not.equal(original_instance_id)
|
replaced_instance_id.should_not.equal(original_instance_id)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_terminate_instance_in_auto_scaling_group_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
_ = client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
DesiredCapacity=1,
|
||||||
|
MaxSize=2,
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
NewInstancesProtectedFromScaleIn=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
original_instance_id = next(
|
||||||
|
instance["InstanceId"]
|
||||||
|
for instance in response["AutoScalingGroups"][0]["Instances"]
|
||||||
|
)
|
||||||
|
client.terminate_instance_in_auto_scaling_group(
|
||||||
|
InstanceId=original_instance_id, ShouldDecrementDesiredCapacity=True
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
response["AutoScalingGroups"][0]["Instances"].should.equal([])
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_autoscaling
|
||||||
|
@mock_ec2
|
||||||
|
def test_terminate_instance_in_auto_scaling_group_no_decrement():
|
||||||
|
mocked_networking = setup_networking()
|
||||||
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
|
_ = client.create_launch_configuration(
|
||||||
|
LaunchConfigurationName="test_launch_configuration"
|
||||||
|
)
|
||||||
|
_ = client.create_auto_scaling_group(
|
||||||
|
AutoScalingGroupName="test_asg",
|
||||||
|
LaunchConfigurationName="test_launch_configuration",
|
||||||
|
MinSize=0,
|
||||||
|
DesiredCapacity=1,
|
||||||
|
MaxSize=2,
|
||||||
|
VPCZoneIdentifier=mocked_networking["subnet1"],
|
||||||
|
NewInstancesProtectedFromScaleIn=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
original_instance_id = next(
|
||||||
|
instance["InstanceId"]
|
||||||
|
for instance in response["AutoScalingGroups"][0]["Instances"]
|
||||||
|
)
|
||||||
|
client.terminate_instance_in_auto_scaling_group(
|
||||||
|
InstanceId=original_instance_id, ShouldDecrementDesiredCapacity=False
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=["test_asg"])
|
||||||
|
replaced_instance_id = next(
|
||||||
|
instance["InstanceId"]
|
||||||
|
for instance in response["AutoScalingGroups"][0]["Instances"]
|
||||||
|
)
|
||||||
|
replaced_instance_id.should_not.equal(original_instance_id)
|
||||||
|
response["AutoScalingGroups"][0]["DesiredCapacity"].should.equal(1)
|
||||||
|
Loading…
Reference in New Issue
Block a user