Ejemplo n.º 1
0
def delete_asg():
    """
    Method to delete AWS Auto-Scaling Groups via Asgard that are tagged for deletion.
    """
    error = False
    try:
        click.echo("Getting ASGs to delete")
        asgs = get_asgs_pending_delete()
        click.echo("Got ASGs to delete")
        for asg in asgs:
            click.echo("Attempting to delete ASG {0}".format(asg.name))
            try:
                asgard.delete_asg(asg.name, wait_for_deletion=False)
                click.secho("Successfully deleted ASG {0}".format(asg.name),
                            fg='green')
            except Exception as e:  # pylint: disable=broad-except
                click.secho("Unable to delete ASG: {0} - {1}".format(asg, e),
                            fg='red')
                error = True
    except Exception as e:  # pylint: disable=broad-except
        traceback.print_exc()
        click.secho("An error occured while cleaning up ASGs: {0}".format(e),
                    fg='red')
        error = True

    if error:
        sys.exit(1)
    else:
        sys.exit(0)
Ejemplo n.º 2
0
def rollback(current_clustered_asgs, rollback_to_clustered_asgs, ami_id=None):
    """
    Rollback to a particular list of ASGs for one or more clusters.
    If rollback does not succeed, create new ASGs based on the AMI ID and deploy those ASGs.

    Arguments:
        current_clustered_asgs(dict): ASGs currently enabled, grouped by cluster.
        rollback_to_clustered_asgs(dict): ASGs to rollback to, grouped by cluster.
        ami_id(str): AWS AMI ID to which to rollback to.

    Returns:
        dict(str, str, dict): Returns a dictionary with the keys:
            'ami_id' - AMI id used to deploy the AMI, None if unspecified
            'current_asgs' - Lists of current active ASGs, keyed by cluster.
            'disabled_asgs' - Lists of current inactive ASGs, keyed by cluster.

    Raises:
        TimeoutException: When the task to bring up the new instance times out.
        BackendError: When the task to bring up the new instance fails.
        ASGDoesNotExistException: If the ASG being queried does not exist.
    """
    # First, ensure that the ASGs to which we'll rollback are not tagged for deletion.
    # Also, ensure that those same ASGs are not in the process of deletion.
    rollback_ready = True
    asgs_tagged_for_deletion = [asg.name for asg in ec2.get_asgs_pending_delete()]
    for asgs in rollback_to_clustered_asgs.values():
        for asg in asgs:
            try:
                if asg in asgs_tagged_for_deletion:
                    # ASG is tagged for deletion. Remove the deletion tag.
                    ec2.remove_asg_deletion_tag(asg)
                if is_asg_pending_delete(asg):
                    # Too late for rollback - this ASG is already pending delete.
                    LOG.info("Rollback ASG '{}' is pending delete. Aborting rollback to ASGs.".format(asg))
                    rollback_ready = False
                    break
            except ASGDoesNotExistException:
                LOG.info("Rollback ASG '{}' has been removed. Aborting rollback to ASGs.".format(asg))
                rollback_ready = False
                break

    if rollback_ready:
        # Perform the rollback.
        success, enabled_asgs, disabled_asgs = _red_black_deploy(rollback_to_clustered_asgs, current_clustered_asgs)
        if not success:
            LOG.info("Rollback failed for cluster(s) {}.".format(current_clustered_asgs.keys()))
        else:
            LOG.info("Woot! Rollback Done!")
            return {'ami_id': ami_id, 'current_asgs': enabled_asgs, 'disabled_asgs': disabled_asgs}

    # Rollback failed -or- wasn't attempted. Attempt a deploy.
    if ami_id:
        LOG.info("Attempting rollback via deploy of AMI {}.".format(ami_id))
        return deploy(ami_id)
    else:
        LOG.info("No AMI id specified - so no deploy occurred during rollback.")
        return {'ami_id': None, 'current_asgs': current_clustered_asgs, 'disabled_asgs': rollback_to_clustered_asgs}
Ejemplo n.º 3
0
def rollback(current_clustered_asgs, rollback_to_clustered_asgs, ami_id=None):
    """
    Rollback to a particular list of ASGs for one or more clusters.
    If rollback does not succeed, create new ASGs based on the AMI ID and deploy those ASGs.

    Arguments:
        current_clustered_asgs(dict): ASGs currently enabled, grouped by cluster.
        rollback_to_clustered_asgs(dict): ASGs to rollback to, grouped by cluster.
        ami_id(str): AWS AMI ID to which to rollback to.

    Returns:
        dict(str, str, dict): Returns a dictionary with the keys:
            'ami_id' - AMI id used to deploy the AMI, None if unspecified
            'current_asgs' - Lists of current active ASGs, keyed by cluster.
            'disabled_asgs' - Lists of current inactive ASGs, keyed by cluster.

    Raises:
        TimeoutException: When the task to bring up the new instance times out.
        BackendError: When the task to bring up the new instance fails.
        ASGDoesNotExistException: If the ASG being queried does not exist.
    """
    # First, ensure that the ASGs to which we'll rollback are not tagged for deletion.
    # Also, ensure that those same ASGs are not in the process of deletion.
    rollback_ready = True
    asgs_tagged_for_deletion = [asg.name for asg in ec2.get_asgs_pending_delete()]
    for asgs in rollback_to_clustered_asgs.values():
        for asg in asgs:
            try:
                if asg in asgs_tagged_for_deletion:
                    # ASG is tagged for deletion. Remove the deletion tag.
                    ec2.remove_asg_deletion_tag(asg)
                if is_asg_pending_delete(asg):
                    # Too late for rollback - this ASG is already pending delete.
                    LOG.info("Rollback ASG '{}' is pending delete. Aborting rollback to ASGs.".format(asg))
                    rollback_ready = False
                    break
            except ASGDoesNotExistException:
                LOG.info("Rollback ASG '{}' has been removed. Aborting rollback to ASGs.".format(asg))
                rollback_ready = False
                break

    if rollback_ready:
        # Perform the rollback.
        success, enabled_asgs, disabled_asgs = _red_black_deploy(rollback_to_clustered_asgs, current_clustered_asgs)
        if not success:
            LOG.info("Rollback failed for cluster(s) {}.".format(current_clustered_asgs.keys()))
        else:
            LOG.info("Woot! Rollback Done!")
            return {'ami_id': ami_id, 'current_asgs': enabled_asgs, 'disabled_asgs': disabled_asgs}

    # Rollback failed -or- wasn't attempted. Attempt a deploy.
    if ami_id:
        LOG.info("Attempting rollback via deploy of AMI {}.".format(ami_id))
        return deploy(ami_id)
    else:
        LOG.info("No AMI id specified - so no deploy occurred during rollback.")
        return {'ami_id': None, 'current_asgs': current_clustered_asgs, 'disabled_asgs': rollback_to_clustered_asgs}
Ejemplo n.º 4
0
    def test_get_asgs_pending_delete(self):
        asg_name = "test-asg-deletion"
        deletion_dttm_str = datetime.datetime.utcnow().isoformat()
        create_asg_with_tags(asg_name, {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str})

        asgs = ec2.get_asgs_pending_delete()
        self.assertEqual(len(asgs), 1)
        asg = asgs.pop()
        self.assertEqual(asg.name, asg_name)
        self.assertEqual(asg.tags[0].key, ec2.ASG_DELETE_TAG_KEY)
        self.assertEqual(asg.tags[0].value, deletion_dttm_str)
Ejemplo n.º 5
0
    def test_get_asgs_pending_delete(self):
        asg_name = "test-asg-deletion"
        deletion_dttm_str = datetime.datetime.utcnow().isoformat()
        create_asg_with_tags(asg_name,
                             {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str})

        asgs = ec2.get_asgs_pending_delete()
        self.assertEqual(len(asgs), 1)
        asg = asgs.pop()
        self.assertEqual(asg.name, asg_name)
        self.assertEqual(asg.tags[0].key, ec2.ASG_DELETE_TAG_KEY)
        self.assertEqual(asg.tags[0].value, deletion_dttm_str)
Ejemplo n.º 6
0
    def test_get_asgs_pending_delete_incorrectly_formatted_timestamp(self):
        asg_name1 = "test-asg-deletion"
        asg_name2 = "test-asg-deletion-bad-timestamp"
        deletion_dttm_str1 = datetime.datetime.utcnow().isoformat()
        deletion_dttm_str2 = "2016-05-18 18:19:46.144884"
        create_asg_with_tags(asg_name1, {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str1})
        create_asg_with_tags(asg_name2, {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str2})

        asgs = ec2.get_asgs_pending_delete()
        self.assertEqual(len(asgs), 1)
        # boto.ec2.autoscale.group.AutoScalingGroup does not implement __eq__ so we need to iterate the list to see if
        # the ASGs we are interested in are members
        self.assertEqual(len([asg for asg in asgs if asg.name == asg_name1]), 1)
        self.assertEqual(len([asg for asg in asgs if asg.name == asg_name2]), 0)
Ejemplo n.º 7
0
    def test_get_asgs_pending_delete_incorrectly_formatted_timestamp(self):
        asg_name1 = "test-asg-deletion"
        asg_name2 = "test-asg-deletion-bad-timestamp"
        deletion_dttm_str1 = datetime.datetime.utcnow().isoformat()
        deletion_dttm_str2 = "2016-05-18 18:19:46.144884"
        create_asg_with_tags(asg_name1,
                             {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str1})
        create_asg_with_tags(asg_name2,
                             {ec2.ASG_DELETE_TAG_KEY: deletion_dttm_str2})

        asgs = ec2.get_asgs_pending_delete()
        self.assertEqual(len(asgs), 1)
        # boto.ec2.autoscale.group.AutoScalingGroup does not implement __eq__ so we need to iterate the list to see if
        # the ASGs we are interested in are members
        self.assertEqual(len([asg for asg in asgs if asg.name == asg_name1]),
                         1)
        self.assertEqual(len([asg for asg in asgs if asg.name == asg_name2]),
                         0)
Ejemplo n.º 8
0
def delete_asg():
    """
    Method to delete AWS Auto-Scaling Groups via Asgard that are tagged for deletion.
    """
    error = False
    try:
        asgs = get_asgs_pending_delete()
        for asg in asgs:
            try:
                asgard.delete_asg(asg.name)
            except Exception as e:  # pylint: disable=broad-except
                click.secho("Unable to delete ASG: {0} - {1}".format(asg, e.message), fg='red')
                error = True
    except Exception as e:  # pylint: disable=broad-except
        traceback.print_exc()
        click.secho("An error occured while cleaning up ASGs: {0}".format(e.message), fg='red')
        error = True

    if error:
        sys.exit(1)
    else:
        sys.exit(0)
Ejemplo n.º 9
0
def delete_asg():
    """
    Method to delete AWS Auto-Scaling Groups via Asgard that are tagged for deletion.
    """
    error = False
    try:
        asgs = get_asgs_pending_delete()
        for asg in asgs:
            try:
                asgard.delete_asg(asg.name)
            except Exception as e:  # pylint: disable=broad-except
                click.secho("Unable to delete ASG: {0} - {1}".format(asg, e),
                            fg='red')
                error = True
    except Exception as e:  # pylint: disable=broad-except
        traceback.print_exc()
        click.secho("An error occured while cleaning up ASGs: {0}".format(e),
                    fg='red')
        error = True

    if error:
        sys.exit(1)
    else:
        sys.exit(0)