Example #1
0
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)
Example #2
0
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)
Example #4
0
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([])
Example #5
0
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)
Example #6
0
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")
Example #7
0
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)
Example #8
0
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")
Example #9
0
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)
Example #10
0
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
Example #12
0
 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'])
Example #13
0
 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'])
Example #14
0
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'])
Example #15
0
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)
Example #16
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)
Example #17
0
    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)
Example #18
0
 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'])
Example #19
0
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
Example #20
0
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
Example #21
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-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)
Example #22
0
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")
Example #23
0
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"])
Example #24
0
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
Example #25
0
 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)
Example #26
0
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)
Example #27
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)
Example #28
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)
Example #29
0
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([])
Example #30
0
  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)
Example #31
0
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)
Example #32
0
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])
Example #33
0
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)
Example #34
0
    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 ---')