def test_autoscaling_group_describe_filter(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) group.name = 'tester_group2' conn.create_auto_scaling_group(group) group.name = 'tester_group3' conn.create_auto_scaling_group(group) conn.get_all_groups( names=['tester_group', 'tester_group2']).should.have.length_of(2) conn.get_all_groups().should.have.length_of(3)
def test_autoscaling_update(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1c', 'us-east-1b'], desired_capacity=2, max_size=2, min_size=2, launch_config=config, vpc_zone_identifier='subnet-1234abcd', ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.vpc_zone_identifier.should.equal('subnet-1234abcd') group.vpc_zone_identifier = 'subnet-5678efgh' group.update() group = conn.get_all_groups()[0] group.vpc_zone_identifier.should.equal('subnet-5678efgh')
def setUpAutoScaleGroup(self, configurations, env="stg"): conn = boto.connect_autoscale() for configuration in configurations: config = LaunchConfiguration( name=configuration[self.launch_configuration_name], image_id='ami-abcd1234', instance_type='m1.medium', ) load_balancer_name = 'servergmsextenderELB{0}'.format(env) group = AutoScalingGroup( name=configuration[self.autoscaling_group_name], availability_zones=['us-east-1a'], default_cooldown=300, desired_capacity=2, health_check_period='0', health_check_type="EC2", max_size=10, min_size=2, launch_config=config, load_balancers=[load_balancer_name], vpc_zone_identifier='subnet-1234abcd', termination_policies=["Default"], ) conn.create_launch_configuration(config) conn.create_auto_scaling_group(group)
def test_create_autoscaling_groups_defaults(): """ Test with the minimum inputs and check that all of the proper defaults are assigned for the other attributes """ conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='m1.small', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.name.should.equal('tester_group') group.max_size.should.equal(2) group.min_size.should.equal(2) group.launch_config_name.should.equal('tester') # Defaults list(group.availability_zones).should.equal([]) group.desired_capacity.should.equal(2) group.vpc_zone_identifier.should.equal('') group.default_cooldown.should.equal(300) group.health_check_period.should.equal(None) group.health_check_type.should.equal("EC2") list(group.load_balancers).should.equal([]) group.placement_group.should.equal(None) list(group.termination_policies).should.equal([])
def test_create_autoscaling_group(): elb_conn = boto.ec2.elb.connect_to_region('us-east-1') elb_conn.create_load_balancer('test_lb', zones=[], listeners=[(80, 8080, 'http')]) conn = boto.ec2.autoscale.connect_to_region('us-east-1') config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1c', 'us-east-1b'], default_cooldown=60, desired_capacity=2, health_check_period=100, health_check_type="EC2", max_size=2, min_size=2, launch_config=config, load_balancers=["test_lb"], placement_group="test_placement", vpc_zone_identifier='subnet-1234abcd', termination_policies=["OldestInstance", "NewestInstance"], tags=[ Tag(resource_id='tester_group', key='test_key', value='test_value', propagate_at_launch=True) ], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.name.should.equal('tester_group') set(group.availability_zones).should.equal( set(['us-east-1c', 'us-east-1b'])) group.desired_capacity.should.equal(2) group.max_size.should.equal(2) group.min_size.should.equal(2) group.instances.should.have.length_of(2) group.vpc_zone_identifier.should.equal('subnet-1234abcd') group.launch_config_name.should.equal('tester') group.default_cooldown.should.equal(60) group.health_check_period.should.equal(100) group.health_check_type.should.equal("EC2") list(group.load_balancers).should.equal(["test_lb"]) group.placement_group.should.equal("test_placement") list(group.termination_policies).should.equal( ["OldestInstance", "NewestInstance"]) len(list(group.tags)).should.equal(1) tag = list(group.tags)[0] tag.resource_id.should.equal('tester_group') tag.key.should.equal('test_key') tag.value.should.equal('test_value') tag.propagate_at_launch.should.equal(True)
def test_autoscaling_group_describe_instances(): mocked_networking = setup_networking_deprecated() conn = boto.ec2.autoscale.connect_to_region('us-east-1') config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(2) instances[0].launch_config_name.should.equal('tester') instances[0].health_status.should.equal('Healthy') autoscale_instance_ids = [instance.instance_id for instance in instances] ec2_conn = boto.ec2.connect_to_region('us-east-1') reservations = ec2_conn.get_all_instances() instances = reservations[0].instances instances.should.have.length_of(2) instance_ids = [instance.id for instance in instances] set(autoscale_instance_ids).should.equal(set(instance_ids)) instances[0].instance_type.should.equal("t2.medium")
def test_set_desired_capacity_down(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1a'], desired_capacity=2, max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.desired_capacity.should.equal(2) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(2) conn.set_desired_capacity("tester_group", 1) group = conn.get_all_groups()[0] group.desired_capacity.should.equal(1) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(1)
def test_autoscaling_group_describe_instances(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, ) conn.create_auto_scaling_group(group) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(2) instances[0].launch_config_name.should.equal('tester') autoscale_instance_ids = [instance.instance_id for instance in instances] ec2_conn = boto.connect_ec2() reservations = ec2_conn.get_all_instances() instances = reservations[0].instances instances.should.have.length_of(2) instance_ids = [instance.id for instance in instances] set(autoscale_instance_ids).should.equal(set(instance_ids)) instances[0].instance_type.should.equal("t2.medium")
def test_set_desired_capacity_the_same(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1c', 'us-east-1b'], desired_capacity=2, max_size=2, min_size=2, launch_config=config, vpc_zone_identifier='subnet-1234abcd', ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.desired_capacity.should.equal(2) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(2) conn.set_desired_capacity("tester_group", 2) group = conn.get_all_groups()[0] group.desired_capacity.should.equal(2) instances = list(conn.get_all_autoscaling_instances()) instances.should.have.length_of(2)
def get_all_groups(names=None, max_records=None, next_token=None): groups = [] for i in xrange(1, 3): tags = [ boto.ec2.autoscale.tag.Tag( None, key='aws:cloudformation:stack-name', value='test{0}'.format(i)) ] asg = AutoScalingGroup() asg.name = 'test{0}'.format(i) asg.tags = tags groups.append(asg) return groups
def get_all_groups(names=None, max_records=None, next_token=None): groups = ResultSet() for i in xrange(1, 3): tags = [ boto.ec2.autoscale.tag.Tag( None, key='aws:cloudformation:stack-name', value='test{0}'.format(i)) ] asg = AutoScalingGroup() asg.name = 'test{0}'.format(i) asg.tags = tags groups.append(asg) groups.next_token = None return groups
def test_autoscaling_group_vpc_zone_identifier_multi(self): self.set_http_response(status_code=200) autoscale = AutoScalingGroup( name='foo', vpc_zone_identifier='vpc_zone_1,vpc_zone_2') self.service_connection.create_auto_scaling_group(autoscale) self.assert_request_parameters({ 'Action': 'CreateAutoScalingGroup', 'AutoScalingGroupName': 'foo', 'VPCZoneIdentifier': 'vpc_zone_1,vpc_zone_2', }, ignore_params_values=['MaxSize', 'MinSize', 'LaunchConfigurationName', 'Version'])
def test_autoscaling_group_put_notification_configuration(self): self.set_http_response(status_code=200) autoscale = AutoScalingGroup( name='ana', launch_config='lauch_config', min_size=1, max_size=2, termination_policies=['OldestInstance', 'OldestLaunchConfiguration']) self.service_connection.delete_notification_configuration(autoscale, 'arn:aws:sns:us-east-1:19890506:AutoScaling-Up') self.assert_request_parameters({ 'Action': 'DeleteNotificationConfiguration', 'AutoScalingGroupName': 'ana', 'TopicARN': 'arn:aws:sns:us-east-1:19890506:AutoScaling-Up', }, ignore_params_values=['Version'])
def test_autoscaling_update(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', desired_capacity=2, max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.availability_zones.should.equal(['us-east-1a']) group.vpc_zone_identifier.should.equal(mocked_networking['subnet1']) group.availability_zones = ['us-east-1b'] group.vpc_zone_identifier = mocked_networking['subnet2'] group.update() group = conn.get_all_groups()[0] group.availability_zones.should.equal(['us-east-1b']) group.vpc_zone_identifier.should.equal(mocked_networking['subnet2'])
def test_autoscaling_group_with_elb(): mocked_networking = setup_networking_deprecated() elb_conn = boto.connect_elb() zones = ['us-east-1a', 'us-east-1b'] ports = [(80, 8080, 'http'), (443, 8443, 'tcp')] lb = elb_conn.create_load_balancer('my-lb', zones, ports) instances_health = elb_conn.describe_instance_health('my-lb') instances_health.should.be.empty conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, load_balancers=["my-lb"], vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] elb = elb_conn.get_all_load_balancers()[0] group.desired_capacity.should.equal(2) elb.instances.should.have.length_of(2) autoscale_instance_ids = set( instance.instance_id for instance in group.instances) elb_instace_ids = set(instance.id for instance in elb.instances) autoscale_instance_ids.should.equal(elb_instace_ids) conn.set_desired_capacity("tester_group", 3) group = conn.get_all_groups()[0] elb = elb_conn.get_all_load_balancers()[0] group.desired_capacity.should.equal(3) elb.instances.should.have.length_of(3) autoscale_instance_ids = set( instance.instance_id for instance in group.instances) elb_instace_ids = set(instance.id for instance in elb.instances) autoscale_instance_ids.should.equal(elb_instace_ids) conn.delete_auto_scaling_group('tester_group') conn.get_all_groups().should.have.length_of(0) elb = elb_conn.get_all_load_balancers()[0] elb.instances.should.have.length_of(0)
def test_autoscaling_group_describe_filter(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, ) conn.create_auto_scaling_group(group) group.name = 'tester_group2' conn.create_auto_scaling_group(group) group.name = 'tester_group3' conn.create_auto_scaling_group(group) conn.get_all_groups(names=['tester_group', 'tester_group2']).should.have.length_of(2) conn.get_all_groups().should.have.length_of(3)
def create_domain(self): # Set our policy name policy_name_key = 'PHANTOM_DEFINITION' policy_name = 'error_overflow_n_preserving' # Set the order of clouds in which VMs are started ordered_clouds_key = 'clouds' ordered_clouds = "" cloud_size_pairs = ["%s:%s" % (cloud, self.max_vms) for cloud in self.clouds] ordered_clouds = ",".join(cloud_size_pairs) # Get a Cloud and Launch Config to feed to the domain constructor a_cloud = self.clouds[0] a_lc_name = "%s@%s" % (self.launch_config_name, a_cloud) a_lc_list = self.connection.get_all_launch_configurations(names=[a_lc_name, ]) if len(a_lc_list) != 1: raise SystemExit("Couldn't get launch config %s" % self.launch_config_name) a_lc = a_lc_list[0] # Set how many domains we would like to start our domain with n_preserve_key = 'minimum_vms' n_preserve = 0 # Marshall Phantom Parameters policy_tag = Tag(connection=self.connection, key=policy_name_key, value=policy_name, resource_id=self.domain_name) clouds_tag = Tag(connection=self.connection, key=ordered_clouds_key, value=ordered_clouds, resource_id=self.domain_name) npreserve_tag = Tag(connection=self.connection, key=n_preserve_key, value=n_preserve, resource_id=self.domain_name) tags = [policy_tag, clouds_tag, npreserve_tag] # Remove any existing domain name with the same name existing_domains = self.connection.get_all_groups(names=[self.domain_name, ]) for domain in existing_domains: print "Removing existing instance of domain '%s'" % domain.name domain.delete() # Create our domain print "Creating domain %s" % self.domain_name domain = AutoScalingGroup( availability_zones=["us-east-1"], connection=self.connection, group_name=self.domain_name, min_size=n_preserve, max_size=n_preserve, launch_config=a_lc, tags=tags) self.connection.create_auto_scaling_group(domain)
def test_autoscaling_group_with_termination_policies(self): self.set_http_response(status_code=200) autoscale = AutoScalingGroup( name='foo', launch_config='lauch_config', min_size=1, max_size=2, termination_policies=['OldestInstance', 'OldestLaunchConfiguration']) self.service_connection.create_auto_scaling_group(autoscale) self.assert_request_parameters({ 'Action': 'CreateAutoScalingGroup', 'AutoScalingGroupName': 'foo', 'LaunchConfigurationName': 'lauch_config', 'MaxSize': 2, 'MinSize': 1, 'TerminationPolicies.member.1': 'OldestInstance', 'TerminationPolicies.member.2': 'OldestLaunchConfiguration', }, ignore_params_values=['Version'])
def setup_autoscale_group(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='m1.small', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, ) conn.create_auto_scaling_group(group) return group
def setup_autoscale_group(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration(name="tester", image_id=EXAMPLE_AMI_ID, instance_type="m1.small") conn.create_launch_configuration(config) group = AutoScalingGroup( name="tester_group", max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking["subnet1"], ) conn.create_auto_scaling_group(group) return group
def test_autoscaling_tags_update(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name="tester", image_id="ami-abcd1234", instance_type="t2.medium" ) conn.create_launch_configuration(config) group = AutoScalingGroup( name="tester_group", availability_zones=["us-east-1a"], desired_capacity=2, max_size=2, min_size=2, launch_config=config, tags=[ Tag( resource_id="tester_group", key="test_key", value="test_value", propagate_at_launch=True, ) ], vpc_zone_identifier=mocked_networking["subnet1"], ) conn.create_auto_scaling_group(group) conn.create_or_update_tags( tags=[ Tag( resource_id="tester_group", key="test_key", value="new_test_value", propagate_at_launch=True, ), Tag( resource_id="tester_group", key="test_key2", value="test_value2", propagate_at_launch=True, ), ] ) group = conn.get_all_groups()[0] group.tags.should.have.length_of(2)
def test_editing_launch_configuration_update_AS_groups(): conn = boto.connect_autoscale(use_block_device_types=True) config = add_launch_config("web", user_data="echo 'web_machine' > /etc/config") group = AutoScalingGroup( name='web', launch_config=config, max_size=2, min_size=2, ) conn.create_auto_scaling_group(group) # Now edit the user data edit_launch_config("web", user_data="echo 'other_machine' > /etc/config") group = conn.get_all_groups()[0] config_name = group.launch_config_name config_name.should.equal("web") config = conn.get_all_launch_configurations(names=[config_name])[0] config.user_data.should.equal("echo 'other_machine' > /etc/config")
def test_create_autoscaling_group(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1c', 'us-east-1b'], default_cooldown=60, desired_capacity=2, health_check_period=100, health_check_type="EC2", max_size=2, min_size=2, launch_config=config, load_balancers=["test_lb"], placement_group="test_placement", vpc_zone_identifier='subnet-1234abcd', termination_policies=["OldestInstance", "NewestInstance"], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.name.should.equal('tester_group') set(group.availability_zones).should.equal( set(['us-east-1c', 'us-east-1b'])) group.desired_capacity.should.equal(2) group.max_size.should.equal(2) group.min_size.should.equal(2) group.instances.should.have.length_of(2) group.vpc_zone_identifier.should.equal('subnet-1234abcd') group.launch_config_name.should.equal('tester') group.default_cooldown.should.equal(60) group.health_check_period.should.equal(100) group.health_check_type.should.equal("EC2") list(group.load_balancers).should.equal(["test_lb"]) group.placement_group.should.equal("test_placement") list(group.termination_policies).should.equal( ["OldestInstance", "NewestInstance"])
def setup_autoscale_group(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='m1.small', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) return group
def _create_or_set_autoscale_group(self): name = self.config.asg_name if not self._asg: LOG.debug("Attempting to load autoscale group: %s" % name) asg = self._as_conn.get_all_groups(names=[name]) LOG.debug("Autoscale group: %s" % asg) if len(asg) == 1: LOG.debug("Autoscale group %s found." % name) self._asg = asg[0] if not self._asg: # TODO(pdmars): more hard coded grossness, for now try: cloud_guess = self.config.lc_name.split("@")[1].strip() except Exception as e: LOG.warn("Unable to guess cloud for auto scale tags") LOG.warn("Setting cloud to hotel") cloud_guess = "hotel" policy_name_key = "PHANTOM_DEFINITION" policy_name = "error_overflow_n_preserving" ordered_clouds_key = "clouds" n_preserve_key = "minimum_vms" ordered_clouds = cloud_guess + ":-1" n_preserve = 0 policy_tag = Tag(connection=self._as_conn, key=policy_name_key, value=policy_name, resource_id=name) clouds_tag = Tag(connection=self._as_conn, key=ordered_clouds_key, value=ordered_clouds, resource_id=name) npreserve_tag = Tag(connection=self._as_conn, key=n_preserve_key, value=n_preserve, resource_id=name) tags = [policy_tag, clouds_tag, npreserve_tag] zones = [self.config.az] LOG.debug("Creating autoscale group %s" % name) LOG.debug("\tname: %s" % name) LOG.debug("\tavailability_zones: %s" % zones) LOG.debug("\tlaunch_config: %s" % self._lc) self._asg = AutoScalingGroup(group_name=name, availability_zones=zones, min_size=0, max_size=0, launch_config=self._lc, tags=tags) self._as_conn.create_auto_scaling_group(self._asg)
def test_autoscaling_group_delete(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration(name="tester", image_id="ami-abcd1234", instance_type="t2.medium") conn.create_launch_configuration(config) group = AutoScalingGroup( name="tester_group", max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking["subnet1"], ) conn.create_auto_scaling_group(group) conn.get_all_groups().should.have.length_of(1) conn.delete_auto_scaling_group("tester_group") conn.get_all_groups().should.have.length_of(0)
def test_autoscaling_group_delete(): conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='m1.small', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', max_size=2, min_size=2, launch_config=config, ) conn.create_auto_scaling_group(group) conn.get_all_groups().should.have.length_of(1) conn.delete_auto_scaling_group('tester_group') conn.get_all_groups().should.have.length_of(0)
def test_autoscaling_tags_update(): mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration( name='tester', image_id='ami-abcd1234', instance_type='t2.medium', ) conn.create_launch_configuration(config) group = AutoScalingGroup( name='tester_group', availability_zones=['us-east-1c', 'us-east-1b'], desired_capacity=2, max_size=2, min_size=2, launch_config=config, tags=[Tag( resource_id='tester_group', key='test_key', value='test_value', propagate_at_launch=True )], vpc_zone_identifier=mocked_networking['subnet1'], ) conn.create_auto_scaling_group(group) conn.create_or_update_tags(tags=[Tag( resource_id='tester_group', key='test_key', value='new_test_value', propagate_at_launch=True ), Tag( resource_id='tester_group', key='test_key2', value='test_value2', propagate_at_launch=True )]) group = conn.get_all_groups()[0] group.tags.should.have.length_of(2)
def test_create_autoscaling_groups_defaults(): """ Test with the minimum inputs and check that all of the proper defaults are assigned for the other attributes """ mocked_networking = setup_networking_deprecated() conn = boto.connect_autoscale() config = LaunchConfiguration(name="tester", image_id="ami-abcd1234", instance_type="t2.medium") conn.create_launch_configuration(config) group = AutoScalingGroup( name="tester_group", max_size=2, min_size=2, launch_config=config, vpc_zone_identifier=mocked_networking["subnet1"], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.name.should.equal("tester_group") group.max_size.should.equal(2) group.min_size.should.equal(2) group.launch_config_name.should.equal("tester") # Defaults list(group.availability_zones).should.equal(["us-east-1a"]) # subnet1 group.desired_capacity.should.equal(2) group.vpc_zone_identifier.should.equal(mocked_networking["subnet1"]) group.default_cooldown.should.equal(300) group.health_check_period.should.equal(300) group.health_check_type.should.equal("EC2") list(group.load_balancers).should.equal([]) group.placement_group.should.equal(None) list(group.termination_policies).should.equal([]) list(group.tags).should.equal([])
def setUpAutoScaleGroup(self): conn = boto.connect_autoscale() config = LaunchConfiguration( name='server-backend-stg-servergmsextenderLCstg-46TIE5ZFQTLB', image_id='ami-abcd1234', instance_type='m1.medium', ) group = AutoScalingGroup( name='server-backend-stg-servergmsextenderASGstg-3ELOD1FOTESTING', availability_zones=['us-east-1a'], default_cooldown=300, desired_capacity=2, health_check_period=0, health_check_type="EC2", max_size=10, min_size=2, launch_config=config, load_balancers=['servergmsextenderELBstg'], vpc_zone_identifier='subnet-1234abcd', termination_policies=["Default"], ) conn.create_launch_configuration(config) conn.create_auto_scaling_group(group)
class Cloud(object): def __init__(self, cloud_config): self.config = cloud_config self.all_instances = [] self.failed_launch = False self.failed_count = 0 self.failed_last_valid_count = 0 self._conn = None self._as_conn = None self._lc = None self._asg = None self._last_asg_launch_attempt = None self.maxed = False self._last_launch_attempt = datetime.datetime.utcnow() self._initialize() def _create_connection(self): LOG.debug("Creating connection for %s" % self.config.name) self._conn = boto.connect_ec2(self.config.access_id, self.config.secret_key, validate_certs=False) self._conn.host = self.config.cloud_uri self._conn.port = self.config.cloud_port def _create_autoscale_connection(self): LOG.debug("Creating autoscale connection for %s" % self.config.name) region = RegionInfo(name=self.config.cloud_type, endpoint=self.config.as_uri) self._as_conn = AutoScaleConnection( aws_access_key_id=self.config.access_id, aws_secret_access_key=self.config.secret_key, is_secure=True, port=self.config.as_port, region=region, validate_certs=False) def _create_or_set_launch_configuration(self): name = self.config.lc_name if not self._lc: LOG.debug("Attempting to load launch configuration: %s" % (name)) lc = self._as_conn.get_all_launch_configurations(names=[name]) if len(lc) == 1: LOG.debug("Launch configuration %s found." % (name)) self._lc = lc[0] if not self._lc: #TODO(pdmars): key and security groups are hardcoded for now, gross if self.config.user_data_file is not None: user_data_file = self.config.user_data_file with open(user_data_file) as f: user_data = f.read() else: user_data = None LOG.debug("Creating launch configuration %s" % name) LOG.debug("\tname: %s" % name) LOG.debug("\timage_id: %s" % self.config.image_id) LOG.debug("\tinstance_type: %s" % self.config.instance_type) LOG.debug("\tuser_data: %s" % user_data) self._lc = LaunchConfiguration( name=name, image_id=self.config.image_id, key_name="phantomkey", security_groups=['default'], instance_type=self.config.instance_type, user_data=user_data) self._as_conn.create_launch_configuration(self._lc) def _create_or_set_autoscale_group(self): name = self.config.asg_name if not self._asg: LOG.debug("Attempting to load autoscale group: %s" % name) asg = self._as_conn.get_all_groups(names=[name]) LOG.debug("Autoscale group: %s" % asg) if len(asg) == 1: LOG.debug("Autoscale group %s found." % name) self._asg = asg[0] if not self._asg: # TODO(pdmars): more hard coded grossness, for now try: cloud_guess = self.config.lc_name.split("@")[1].strip() except Exception as e: LOG.warn("Unable to guess cloud for auto scale tags") LOG.warn("Setting cloud to hotel") cloud_guess = "hotel" policy_name_key = "PHANTOM_DEFINITION" policy_name = "error_overflow_n_preserving" ordered_clouds_key = "clouds" n_preserve_key = "minimum_vms" ordered_clouds = cloud_guess + ":-1" n_preserve = 0 policy_tag = Tag(connection=self._as_conn, key=policy_name_key, value=policy_name, resource_id=name) clouds_tag = Tag(connection=self._as_conn, key=ordered_clouds_key, value=ordered_clouds, resource_id=name) npreserve_tag = Tag(connection=self._as_conn, key=n_preserve_key, value=n_preserve, resource_id=name) tags = [policy_tag, clouds_tag, npreserve_tag] zones = [self.config.az] LOG.debug("Creating autoscale group %s" % name) LOG.debug("\tname: %s" % name) LOG.debug("\tavailability_zones: %s" % zones) LOG.debug("\tlaunch_config: %s" % self._lc) self._asg = AutoScalingGroup(group_name=name, availability_zones=zones, min_size=0, max_size=0, launch_config=self._lc, tags=tags) self._as_conn.create_auto_scaling_group(self._asg) def _initialize(self): LOG.debug("Initializing %s" % self.config.name) self._create_connection() self._create_autoscale_connection() self._create_or_set_launch_configuration() self._create_or_set_autoscale_group() LOG.debug("Initialization complete for %s" % self.config.name) def get_valid_instances(self): return self.all_instances def _refresh_instances(self): LOG.debug("%s: getting instance information" % self.config.name) self.all_instances = [] instances = [] as_instances = self._asg.instances as_instance_ids = [i.instance_id for i in as_instances] reservations = self._conn.get_all_instances() for reservation in reservations: for instance in reservation.instances: if instance.id in as_instance_ids: if instance.state in VALID_RUN_STATES: instances.append(instance) for instance in instances: self.all_instances.append(instance) num_instances = len(self.all_instances) LOG.debug("%s: updated %d instances" % (self.config.name, num_instances)) if num_instances >= self.config.max_instances: LOG.warn("%s reached the max (%s) instances: %s" % ( self.config.name, self.config.max_instances, num_instances)) self.maxed = True else: self.maxed = False def _refresh_asg(self): LOG.debug("%s: refreshing autoscale group" % self.config.name) asg_name = self.config.asg_name asgs = self._as_conn.get_all_groups(names=[asg_name]) if len(asgs) == 1: self._asg = asgs[0] LOG.debug("\trefreshed autoscale group: %s" % asg_name) else: LOG.warn("\tunable to refresh autoscale group: %s" % asg_name) def refresh(self, cluster): self._refresh_asg() self._refresh_instances() def get_total_num_valid_cores(self): LOG.debug("%s: getting number of valid cores" % self.config.name) total_num_valid_cores = 0 num_valid_instances = len(self.get_valid_instances()) total_valid_cores = num_valid_instances * self.config.instance_cores num_desired_instances = self._asg.desired_capacity num_desired_cores = num_desired_instances * self.config.instance_cores if num_desired_cores != total_num_valid_cores: LOG.debug("\tmismatching core counts") LOG.debug("\tnum_desired_cores: %d" % (num_desired_cores)) LOG.debug("\ttotal_valid_cores: %d" % (total_valid_cores)) return total_valid_cores def get_instance_by_id(self, id): LOG.debug("Searching for instance %s" % id) for instances in self.all_instances: if instance.id == id: LOG.debug("Found instance %s" % id) return instance return None def get_instance_ids_for_public_dns_names(self, public_dns_names): instance_ids = [] for instance in self.all_instances: if instance.public_dns_name in public_dns_names: instance_ids.append(instance.id) return instance_ids def get_public_dns_names_close_to_charge(self): instances_close_to_charge = [] sleep_secs = self.config.get_loop_sleep_secs() cur_utc_time = datetime.datetime.utcnow() valid_instances = self.get_valid_instances() time_fmt = "%Y-%m-%dT%H:%M:%S.%fZ" for instance in valid_instances: launch_time = datetime.datetime.strptime(instance.launch_time, time_fmt) time_diff = cur_utc_time - launch_time # Ignores microseconds time_diff_secs = time_diff.seconds + time_diff.days * 24 * 3600 cur_charge_secs = time_diff_secs % self.config.charge_time_secs secs_to_charge = self.config.charge_time_secs - cur_charge_secs LOG.debug("%s:%s: charge: %d; current: %d; to charge: %d" % ( instance.id, instance.public_dns_name, self.config.charge_time_secs, cur_charge_secs, secs_to_charge)) if secs_to_charge < (3 * sleep_secs): instances_close_to_charge.append(instance.public_dns_name) return instances_close_to_charge def delete_instances(self, instance_ids=[]): if not instance_ids: return LOG.debug("Deleting instances: %s" % instance_ids) # TODO(pdmars): this has the potential to kill instances running jobs # maybe I should err on the side of having extra instances if the # capacity is higher than the cloud can currently support num_instances = len(self.all_instances) if ((self._asg.desired_capacity > num_instances) and (num_instances > 0)): LOG.warn("Desired capacity is greater than num_instances running") LOG.warn("Adjusting desired capacity to match") self.set_capacity(num_instances) for instance_id in instance_ids: self._as_conn.terminate_instance(instance_id) # TODO(pdmars): due to a bug in phantom, maybe this will help # 2013/04/05: this might not be relevant anymore time.sleep(.1) def launch_autoscale_instances(self, num_instances=1): new_capacity = self._asg.desired_capacity + int(num_instances) if new_capacity > self.config.max_instances: new_capacity = self.config.max_instances LOG.warn("%s can launch %s total instances" % (self.config.name, new_capacity)) self._last_launch_attempt = datetime.datetime.utcnow() LOG.debug("Setting cloud capacity for %s to %s" % (self.config.name, new_capacity)) self.set_capacity(new_capacity) def set_capacity(self, new_capacity): self._asg.set_capacity(new_capacity)
def main(): # pseudocode (repeats in code comments below) # check for autoscale group # if autoscale group not present, create it # else read launchconfig name from asg # define new launchconfig # assign launchconfig # delete old launchconfig - we can only have so many # read config print "reading configuration ..." config = ConfigParser.SafeConfigParser(allow_no_value=True) # This assumes that the file is either in the local directory being ran, or in the home/aws/ folder # We have to use the second option because XLD does not run the script in the same location that it's located config.read(['ec2-deploy.conf', os.path.expanduser('/var/lib/jenkins/workspace/AWS-Demo/cm/ec2-deploy.conf')]) # check for autoscale group # FIXME: Should connect to region there # FIXME: proxy information? print "connecting to ec2..." #asconn = boto.ec2.autoscale.AutoScaleConnection(aws_access_key_id=config.get('auth', 'AWS_ACCESS_KEY_ID'), #aws_secret_access_key=config.get('auth', 'AWS_SECRET_ACCESS_KEY'), security_token=config.get('auth', 'AWS_SECURITY_TOKEN')) #boto.set_stream_logger('boto') asconn = boto.ec2.autoscale.AutoScaleConnection() print "validating autoscaling group ..." asg = get_autoscale_group(config.get('autoscalegroup','name'), asconn) oldlc = None # read userdata userdata = "" with open(config.get('launchconfig', 'userdata_filename'), 'r') as udf: userdata=udf.read() # define new launchconfig timenow = str(datetime.now()).split(".")[0] timenow = timenow.replace(" ", "").replace("-", "").replace(":", "") lcname = config.get('autoscalegroup', 'name') + "-lc-" + timenow print "Creating new launch config '{}'".format(lcname) newlc = LaunchConfiguration( name = lcname, image_id = config.get('launchconfig', 'ami'), key_name = config.get('launchconfig', 'keypair'), instance_type = config.get('launchconfig', 'instancetype'), # security_groups = sgnames_to_list( config.get('launchconfig', 'sgnames') , config.get('ec2', 'region')), security_groups = str(config.get('launchconfig', 'security_groups')).split(','), # classic_link_vpc_security_groups = str(config.get('launchconfig', 'security_groups')).split(','), user_data = userdata, associate_public_ip_address = True, delete_on_termination = True, instance_monitoring = False, instance_profile_name = config.get('launchconfig', 'instance_profile_name') ) print "new lc created" asconn.create_launch_configuration(newlc) print "lc associated, now checking if asg exists" # if autoscale group not present, create it if asg is None: print "Autoscaling Group '{}' not found, creating...".format(config.get('autoscalegroup', 'name')) azlist = str(config.get('autoscalegroup', 'azs')).split(',') elblist = str(config.get('autoscalegroup', 'elbs')).split(',') vpclist = str(config.get('launchconfig', 'subnet')).split(',') asg = AutoScalingGroup( connection = asconn, name = config.get('autoscalegroup', 'name'), load_balancers = elblist, availability_zones = azlist, desired_capacity = config.getint('autoscalegroup','desired_capacity'), launch_config = newlc, max_size = config.getint('autoscalegroup','max_size'), min_size = config.getint('autoscalegroup','min_size'), vpc_zone_identifier = vpclist ) asconn.create_auto_scaling_group(asg) else: # else read launchconfig name from asg # Note that the oldlc is just the name of the lc we're about to delete oldlc = asg.launch_config_name print "Replacing launch configuration '{}' with new lc '{}'.".format(oldlc, lcname) asg.endElement("LaunchConfigurationName", lcname, asconn) asg.update() # this part now terminates each instance individually autoscale = boto.connect_autoscale() ec2 = boto.connect_ec2() group = autoscale.get_all_groups([config.get('autoscalegroup', 'name')])[0] instance_ids = [i.instance_id for i in group.instances] # reservations = ec2.get_all_instances(instance_ids) # instances = [i for r in reservations for i in r.instances] for i in instance_ids: asconn.terminate_instance(i,decrement_capacity=False) # delete old launchconfig - we can only have so many if oldlc is not None: print "Deleting old launch configuration ... " asconn.delete_launch_configuration(oldlc) print "done." # end main print "Now injecting the Name Tag" # can't figure out a better way to inject the boto Tag tag class - will need to fix later to make it look better taglist = Tag(key='Name', value=config.get('tags', 'name'), propagate_at_launch=True, resource_id=config.get('autoscalegroup', 'name')) asconn.create_or_update_tags([taglist])
def test_create_autoscaling_group(): mocked_networking = setup_networking_deprecated() elb_conn = boto.ec2.elb.connect_to_region("us-east-1") elb_conn.create_load_balancer("test_lb", zones=[], listeners=[(80, 8080, "http")]) conn = boto.ec2.autoscale.connect_to_region("us-east-1") config = LaunchConfiguration(name="tester", image_id="ami-abcd1234", instance_type="t2.medium") conn.create_launch_configuration(config) group = AutoScalingGroup( name="tester_group", availability_zones=["us-east-1a", "us-east-1b"], default_cooldown=60, desired_capacity=2, health_check_period=100, health_check_type="EC2", max_size=2, min_size=2, launch_config=config, load_balancers=["test_lb"], placement_group="test_placement", vpc_zone_identifier="{subnet1},{subnet2}".format( subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]), termination_policies=["OldestInstance", "NewestInstance"], tags=[ Tag( resource_id="tester_group", key="test_key", value="test_value", propagate_at_launch=True, ) ], ) conn.create_auto_scaling_group(group) group = conn.get_all_groups()[0] group.name.should.equal("tester_group") set(group.availability_zones).should.equal( set(["us-east-1a", "us-east-1b"])) group.desired_capacity.should.equal(2) group.max_size.should.equal(2) group.min_size.should.equal(2) group.instances.should.have.length_of(2) group.vpc_zone_identifier.should.equal("{subnet1},{subnet2}".format( subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"])) group.launch_config_name.should.equal("tester") group.default_cooldown.should.equal(60) group.health_check_period.should.equal(100) group.health_check_type.should.equal("EC2") list(group.load_balancers).should.equal(["test_lb"]) group.placement_group.should.equal("test_placement") list(group.termination_policies).should.equal( ["OldestInstance", "NewestInstance"]) len(list(group.tags)).should.equal(1) tag = list(group.tags)[0] tag.resource_id.should.equal("tester_group") tag.key.should.equal("test_key") tag.value.should.equal("test_value") tag.propagate_at_launch.should.equal(True)
def test_basic(self): # NB: as it says on the tin these are really basic tests that only # (lightly) exercise read-only behaviour - and that's only if you # have any autoscale groups to introspect. It's useful, however, to # catch simple errors print('--- running %s tests ---' % self.__class__.__name__) c = AutoScaleConnection() self.assertTrue(repr(c).startswith('AutoScaleConnection')) groups = c.get_all_groups() for group in groups: self.assertIsInstance(group, AutoScalingGroup) # get activities activities = group.get_activities() for activity in activities: self.assertIsInstance(activity, Activity) # get launch configs configs = c.get_all_launch_configurations() for config in configs: self.assertIsInstance(config, LaunchConfiguration) # get policies policies = c.get_all_policies() for policy in policies: self.assertIsInstance(policy, ScalingPolicy) # get scheduled actions actions = c.get_all_scheduled_actions() for action in actions: self.assertIsInstance(action, ScheduledUpdateGroupAction) # get instances instances = c.get_all_autoscaling_instances() for instance in instances: self.assertIsInstance(instance, Instance) # get all scaling process types ptypes = c.get_all_scaling_process_types() for ptype in ptypes: self.assertTrue(ptype, ProcessType) # get adjustment types adjustments = c.get_all_adjustment_types() for adjustment in adjustments: self.assertIsInstance(adjustment, AdjustmentType) # get metrics collection types types = c.get_all_metric_collection_types() self.assertIsInstance(types, MetricCollectionTypes) # create the simplest possible AutoScale group # first create the launch configuration time_string = '%d' % int(time.time()) lc_name = 'lc-%s' % time_string lc = LaunchConfiguration(name=lc_name, image_id='ami-2272864b', instance_type='t1.micro') c.create_launch_configuration(lc) found = False lcs = c.get_all_launch_configurations() for lc in lcs: if lc.name == lc_name: found = True break assert found # now create autoscaling group group_name = 'group-%s' % time_string group = AutoScalingGroup(name=group_name, launch_config=lc, availability_zones=['us-east-1a'], min_size=1, max_size=1) c.create_auto_scaling_group(group) found = False groups = c.get_all_groups() for group in groups: if group.name == group_name: found = True break assert found # now create a tag tag = Tag(key='foo', value='bar', resource_id=group_name, propagate_at_launch=True) c.create_or_update_tags([tag]) found = False tags = c.get_all_tags() for tag in tags: if tag.resource_id == group_name and tag.key == 'foo': found = True break assert found c.delete_tags([tag]) # shutdown instances and wait for them to disappear group.shutdown_instances() instances = True while instances: time.sleep(5) groups = c.get_all_groups() for group in groups: if group.name == group_name: if not group.instances: instances = False group.delete() lc.delete() found = True while found: found = False time.sleep(5) tags = c.get_all_tags() for tag in tags: if tag.resource_id == group_name and tag.key == 'foo': found = True assert not found print('--- tests completed ---')