Add AWS::AutoScaling::ScheduledAction action cloudformation support (#5289)
This commit is contained in:
parent
7658051594
commit
40eefb92d7
@ -280,6 +280,67 @@ class FakeLaunchConfiguration(CloudFormationModel):
|
|||||||
return block_device_map
|
return block_device_map
|
||||||
|
|
||||||
|
|
||||||
|
class FakeScheduledAction(CloudFormationModel):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
desired_capacity,
|
||||||
|
max_size,
|
||||||
|
min_size,
|
||||||
|
scheduled_action_name=None,
|
||||||
|
start_time=None,
|
||||||
|
end_time=None,
|
||||||
|
recurrence=None,
|
||||||
|
):
|
||||||
|
|
||||||
|
self.name = name
|
||||||
|
self.desired_capacity = desired_capacity
|
||||||
|
self.max_size = max_size
|
||||||
|
self.min_size = min_size
|
||||||
|
self.start_time = start_time
|
||||||
|
self.end_time = end_time
|
||||||
|
self.recurrence = recurrence
|
||||||
|
self.scheduled_action_name = scheduled_action_name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def cloudformation_name_type():
|
||||||
|
|
||||||
|
return "ScheduledActionName"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def cloudformation_type():
|
||||||
|
|
||||||
|
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-scheduledaction.html
|
||||||
|
return "AWS::AutoScaling::ScheduledAction"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_cloudformation_json(
|
||||||
|
cls, resource_name, cloudformation_json, region_name, **kwargs
|
||||||
|
):
|
||||||
|
|
||||||
|
properties = cloudformation_json["Properties"]
|
||||||
|
|
||||||
|
backend = autoscaling_backends[region_name]
|
||||||
|
|
||||||
|
scheduled_action_name = (
|
||||||
|
kwargs["LogicalId"]
|
||||||
|
if kwargs.get("LogicalId")
|
||||||
|
else "ScheduledScalingAction-{random.randint(0,100)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
scheduled_action = backend.put_scheduled_update_group_action(
|
||||||
|
name=properties.get("AutoScalingGroupName"),
|
||||||
|
desired_capacity=properties.get("DesiredCapacity"),
|
||||||
|
max_size=properties.get("MaxSize"),
|
||||||
|
min_size=properties.get("MinSize"),
|
||||||
|
scheduled_action_name=scheduled_action_name,
|
||||||
|
start_time=properties.get("StartTime"),
|
||||||
|
end_time=properties.get("EndTime"),
|
||||||
|
recurrence=properties.get("Recurrence"),
|
||||||
|
)
|
||||||
|
return scheduled_action
|
||||||
|
|
||||||
|
|
||||||
class FakeAutoScalingGroup(CloudFormationModel):
|
class FakeAutoScalingGroup(CloudFormationModel):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -676,6 +737,7 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
super().__init__(region_name, account_id)
|
super().__init__(region_name, account_id)
|
||||||
self.autoscaling_groups = OrderedDict()
|
self.autoscaling_groups = OrderedDict()
|
||||||
self.launch_configurations = OrderedDict()
|
self.launch_configurations = OrderedDict()
|
||||||
|
self.scheduled_actions = OrderedDict()
|
||||||
self.policies = {}
|
self.policies = {}
|
||||||
self.lifecycle_hooks = {}
|
self.lifecycle_hooks = {}
|
||||||
self.ec2_backend = ec2_backends[region_name]
|
self.ec2_backend = ec2_backends[region_name]
|
||||||
@ -760,6 +822,39 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
def delete_launch_configuration(self, launch_configuration_name):
|
def delete_launch_configuration(self, launch_configuration_name):
|
||||||
self.launch_configurations.pop(launch_configuration_name, None)
|
self.launch_configurations.pop(launch_configuration_name, None)
|
||||||
|
|
||||||
|
def make_int(self, value):
|
||||||
|
return int(value) if value is not None else value
|
||||||
|
|
||||||
|
def put_scheduled_update_group_action(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
desired_capacity,
|
||||||
|
max_size,
|
||||||
|
min_size,
|
||||||
|
scheduled_action_name=None,
|
||||||
|
start_time=None,
|
||||||
|
end_time=None,
|
||||||
|
recurrence=None,
|
||||||
|
):
|
||||||
|
# TODO: Add validations for parameters
|
||||||
|
max_size = self.make_int(max_size)
|
||||||
|
min_size = self.make_int(min_size)
|
||||||
|
desired_capacity = self.make_int(desired_capacity)
|
||||||
|
|
||||||
|
scheduled_action = FakeScheduledAction(
|
||||||
|
name=name,
|
||||||
|
desired_capacity=desired_capacity,
|
||||||
|
max_size=max_size,
|
||||||
|
min_size=min_size,
|
||||||
|
scheduled_action_name=scheduled_action_name,
|
||||||
|
start_time=start_time,
|
||||||
|
end_time=end_time,
|
||||||
|
recurrence=recurrence,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.scheduled_actions[scheduled_action_name] = scheduled_action
|
||||||
|
return scheduled_action
|
||||||
|
|
||||||
def create_auto_scaling_group(
|
def create_auto_scaling_group(
|
||||||
self,
|
self,
|
||||||
name,
|
name,
|
||||||
@ -781,17 +876,14 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
new_instances_protected_from_scale_in=False,
|
new_instances_protected_from_scale_in=False,
|
||||||
instance_id=None,
|
instance_id=None,
|
||||||
):
|
):
|
||||||
def make_int(value):
|
max_size = self.make_int(max_size)
|
||||||
return int(value) if value is not None else value
|
min_size = self.make_int(min_size)
|
||||||
|
desired_capacity = self.make_int(desired_capacity)
|
||||||
max_size = make_int(max_size)
|
default_cooldown = self.make_int(default_cooldown)
|
||||||
min_size = make_int(min_size)
|
|
||||||
desired_capacity = make_int(desired_capacity)
|
|
||||||
default_cooldown = make_int(default_cooldown)
|
|
||||||
if health_check_period is None:
|
if health_check_period is None:
|
||||||
health_check_period = 300
|
health_check_period = 300
|
||||||
else:
|
else:
|
||||||
health_check_period = make_int(health_check_period)
|
health_check_period = self.make_int(health_check_period)
|
||||||
|
|
||||||
# TODO: Add MixedInstancesPolicy once implemented.
|
# TODO: Add MixedInstancesPolicy once implemented.
|
||||||
# Verify only a single launch config-like parameter is provided.
|
# Verify only a single launch config-like parameter is provided.
|
||||||
|
@ -102,6 +102,20 @@ class AutoScalingResponse(BaseResponse):
|
|||||||
template = self.response_template(CREATE_AUTOSCALING_GROUP_TEMPLATE)
|
template = self.response_template(CREATE_AUTOSCALING_GROUP_TEMPLATE)
|
||||||
return template.render()
|
return template.render()
|
||||||
|
|
||||||
|
def put_scheduled_update_group_action(self):
|
||||||
|
self.autoscaling_backend.put_scheduled_update_group_action(
|
||||||
|
name=self._get_param("AutoScalingGroupName"),
|
||||||
|
desired_capacity=self._get_int_param("DesiredCapacity"),
|
||||||
|
max_size=self._get_int_param("MaxSize"),
|
||||||
|
min_size=self._get_int_param("MinSize"),
|
||||||
|
scheduled_action_name=None,
|
||||||
|
start_time=self._get_param("StartTime"),
|
||||||
|
end_time=self._get_param("EndTime"),
|
||||||
|
recurrence=self._get_param("Recurrence"),
|
||||||
|
)
|
||||||
|
template = self.response_template(PUT_SCHEDULED_UPDATE_GROUP_ACTION_TEMPLATE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
@amz_crc32
|
@amz_crc32
|
||||||
@amzn_request_id
|
@amzn_request_id
|
||||||
def attach_instances(self):
|
def attach_instances(self):
|
||||||
@ -580,6 +594,12 @@ CREATE_AUTOSCALING_GROUP_TEMPLATE = """<CreateAutoScalingGroupResponse xmlns="ht
|
|||||||
</ResponseMetadata>
|
</ResponseMetadata>
|
||||||
</CreateAutoScalingGroupResponse>"""
|
</CreateAutoScalingGroupResponse>"""
|
||||||
|
|
||||||
|
PUT_SCHEDULED_UPDATE_GROUP_ACTION_TEMPLATE = """<PutScheduledUpdateGroupActionResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId></RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</PutScheduledUpdateGroupActionResponse>"""
|
||||||
|
|
||||||
ATTACH_LOAD_BALANCER_TARGET_GROUPS_TEMPLATE = """<AttachLoadBalancerTargetGroupsResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
ATTACH_LOAD_BALANCER_TARGET_GROUPS_TEMPLATE = """<AttachLoadBalancerTargetGroupsResponse xmlns="http://autoscaling.amazonaws.com/doc/2011-01-01/">
|
||||||
<AttachLoadBalancerTargetGroupsResult>
|
<AttachLoadBalancerTargetGroupsResult>
|
||||||
</AttachLoadBalancerTargetGroupsResult>
|
</AttachLoadBalancerTargetGroupsResult>
|
||||||
|
@ -75,6 +75,17 @@ def test_create_autoscaling_group_within_elb():
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
as_client.put_scheduled_update_group_action(
|
||||||
|
AutoScalingGroupName="tester_group",
|
||||||
|
ScheduledActionName="my-scheduled-action",
|
||||||
|
StartTime="2022-07-01T00:00:00Z",
|
||||||
|
EndTime="2022-09-01T00:00:00Z",
|
||||||
|
Recurrence="* * * * *",
|
||||||
|
MinSize=10,
|
||||||
|
MaxSize=12,
|
||||||
|
DesiredCapacity=9,
|
||||||
|
)
|
||||||
|
|
||||||
group = as_client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
group = as_client.describe_auto_scaling_groups()["AutoScalingGroups"][0]
|
||||||
group["AutoScalingGroupName"].should.equal("tester_group")
|
group["AutoScalingGroupName"].should.equal("tester_group")
|
||||||
set(group["AvailabilityZones"]).should.equal(set(["us-east-1a", "us-east-1b"]))
|
set(group["AvailabilityZones"]).should.equal(set(["us-east-1a", "us-east-1b"]))
|
||||||
|
@ -1435,6 +1435,18 @@ def test_autoscaling_propagate_tags():
|
|||||||
"InstanceType": "t2.medium",
|
"InstanceType": "t2.medium",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"ScheduledAction": {
|
||||||
|
"Type": "AWS::AutoScaling::ScheduledAction",
|
||||||
|
"Properties": {
|
||||||
|
"AutoScalingGroupName": "test-scaling-group",
|
||||||
|
"DesiredCapacity": 10,
|
||||||
|
"EndTime": "2022-08-01T00:00:00Z",
|
||||||
|
"MaxSize": 15,
|
||||||
|
"MinSize": 5,
|
||||||
|
"Recurrence": "* * * * *",
|
||||||
|
"StartTime": "2022-07-01T00:00:00Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
boto3.client("cloudformation", "us-east-1").create_stack(
|
boto3.client("cloudformation", "us-east-1").create_stack(
|
||||||
|
Loading…
Reference in New Issue
Block a user