Implemented creating autoscaling group from instance.

This commit is contained in:
acsbendi 2019-07-17 20:58:23 +02:00
parent 4ca0bd807f
commit c8abd43c88
4 changed files with 52 additions and 13 deletions

View File

@ -13,3 +13,12 @@ class ResourceContentionError(RESTError):
super(ResourceContentionError, self).__init__( super(ResourceContentionError, self).__init__(
"ResourceContentionError", "ResourceContentionError",
"You already have a pending update to an Auto Scaling resource (for example, a group, instance, or load balancer).") "You already have a pending update to an Auto Scaling resource (for example, a group, instance, or load balancer).")
class InvalidInstanceError(AutoscalingClientError):
def __init__(self, instance_id):
super(InvalidInstanceError, self).__init__(
"ValidationError",
"Instance [{0}] is invalid."
.format(instance_id))

View File

@ -3,6 +3,8 @@ from __future__ import unicode_literals
import random import random
from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
from moto.ec2.exceptions import InvalidInstanceIdError
from moto.compat import OrderedDict from moto.compat import OrderedDict
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
@ -10,7 +12,7 @@ from moto.elb import elb_backends
from moto.elbv2 import elbv2_backends from moto.elbv2 import elbv2_backends
from moto.elb.exceptions import LoadBalancerNotFoundError from moto.elb.exceptions import LoadBalancerNotFoundError
from .exceptions import ( from .exceptions import (
AutoscalingClientError, ResourceContentionError, AutoscalingClientError, ResourceContentionError, InvalidInstanceError
) )
# http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AS_Concepts.html#Cooldown # http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AS_Concepts.html#Cooldown
@ -73,6 +75,26 @@ class FakeLaunchConfiguration(BaseModel):
self.associate_public_ip_address = associate_public_ip_address self.associate_public_ip_address = associate_public_ip_address
self.block_device_mapping_dict = block_device_mapping_dict self.block_device_mapping_dict = block_device_mapping_dict
@classmethod
def create_from_instance(cls, name, instance, backend):
config = backend.create_launch_configuration(
name=name,
image_id=instance.image_id,
kernel_id='',
ramdisk_id='',
key_name=instance.key_name,
security_groups=instance.security_groups,
user_data=instance.user_data,
instance_type=instance.instance_type,
instance_monitoring=False,
instance_profile_name=None,
spot_price=None,
ebs_optimized=instance.ebs_optimized,
associate_public_ip_address=instance.associate_public_ip,
block_device_mappings=instance.block_device_mapping
)
return config
@classmethod @classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties'] properties = cloudformation_json['Properties']
@ -408,13 +430,13 @@ class AutoScalingBackend(BaseBackend):
self.launch_configurations.pop(launch_configuration_name, None) self.launch_configurations.pop(launch_configuration_name, None)
def create_auto_scaling_group(self, name, availability_zones, def create_auto_scaling_group(self, name, availability_zones,
desired_capacity, max_size, min_size, desired_capacity, max_size, min_size,
launch_config_name, vpc_zone_identifier, instance_id, launch_config_name,
default_cooldown, health_check_period, vpc_zone_identifier, default_cooldown,
health_check_type, load_balancers, health_check_period, health_check_type,
target_group_arns, placement_group, load_balancers, target_group_arns,
termination_policies, tags, placement_group,termination_policies, tags,
new_instances_protected_from_scale_in=False): new_instances_protected_from_scale_in=False):
def make_int(value): def make_int(value):
return int(value) if value is not None else value return int(value) if value is not None else value
@ -427,6 +449,13 @@ class AutoScalingBackend(BaseBackend):
health_check_period = 300 health_check_period = 300
else: else:
health_check_period = make_int(health_check_period) health_check_period = make_int(health_check_period)
if launch_config_name is None and instance_id is not None:
try:
instance = self.ec2_backend.get_instance(instance_id)
launch_config_name = name
FakeLaunchConfiguration.create_from_instance(launch_config_name, instance, self)
except InvalidInstanceIdError:
raise InvalidInstanceError(instance_id)
group = FakeAutoScalingGroup( group = FakeAutoScalingGroup(
name=name, name=name,

View File

@ -74,6 +74,7 @@ class AutoScalingResponse(BaseResponse):
desired_capacity=self._get_int_param('DesiredCapacity'), desired_capacity=self._get_int_param('DesiredCapacity'),
max_size=self._get_int_param('MaxSize'), max_size=self._get_int_param('MaxSize'),
min_size=self._get_int_param('MinSize'), min_size=self._get_int_param('MinSize'),
instance_id=self._get_param('InstanceId'),
launch_config_name=self._get_param('LaunchConfigurationName'), launch_config_name=self._get_param('LaunchConfigurationName'),
vpc_zone_identifier=self._get_param('VPCZoneIdentifier'), vpc_zone_identifier=self._get_param('VPCZoneIdentifier'),
default_cooldown=self._get_int_param('DefaultCooldown'), default_cooldown=self._get_int_param('DefaultCooldown'),

View File

@ -406,10 +406,10 @@ class Instance(TaggedEC2Resource, BotoInstance):
self.ami_launch_index = kwargs.get("ami_launch_index", 0) self.ami_launch_index = kwargs.get("ami_launch_index", 0)
self.disable_api_termination = kwargs.get("disable_api_termination", False) self.disable_api_termination = kwargs.get("disable_api_termination", False)
self._spot_fleet_id = kwargs.get("spot_fleet_id", None) self._spot_fleet_id = kwargs.get("spot_fleet_id", None)
associate_public_ip = kwargs.get("associate_public_ip", False) self.associate_public_ip = kwargs.get("associate_public_ip", False)
if in_ec2_classic: if in_ec2_classic:
# If we are in EC2-Classic, autoassign a public IP # If we are in EC2-Classic, autoassign a public IP
associate_public_ip = True self.associate_public_ip = True
amis = self.ec2_backend.describe_images(filters={'image-id': image_id}) amis = self.ec2_backend.describe_images(filters={'image-id': image_id})
ami = amis[0] if amis else None ami = amis[0] if amis else None
@ -440,9 +440,9 @@ class Instance(TaggedEC2Resource, BotoInstance):
self.vpc_id = subnet.vpc_id self.vpc_id = subnet.vpc_id
self._placement.zone = subnet.availability_zone self._placement.zone = subnet.availability_zone
if associate_public_ip is None: if self.associate_public_ip is None:
# Mapping public ip hasnt been explicitly enabled or disabled # Mapping public ip hasnt been explicitly enabled or disabled
associate_public_ip = subnet.map_public_ip_on_launch == 'true' self.associate_public_ip = subnet.map_public_ip_on_launch == 'true'
elif placement: elif placement:
self._placement.zone = placement self._placement.zone = placement
else: else:
@ -454,7 +454,7 @@ class Instance(TaggedEC2Resource, BotoInstance):
self.prep_nics( self.prep_nics(
kwargs.get("nics", {}), kwargs.get("nics", {}),
private_ip=kwargs.get("private_ip"), private_ip=kwargs.get("private_ip"),
associate_public_ip=associate_public_ip associate_public_ip=self.associate_public_ip
) )
def __del__(self): def __del__(self):