Beispiel #1
0
def active_ami_for_edp(env, dep, play):
    """
    Given an environment, deployment, and play, find the base AMI id used for the active deployment.

    Arguments:
        env (str): Environment to check (stage, prod, loadtest, etc.)
        dep (str): Deployment to check (edx, edge, mckinsey, etc.)
        play (str): Play to check (edxapp, discovery, ecommerce, etc.)
    Returns:
        str: Base AMI id of current active deployment for the EDP.
    Raises:
        MultipleImagesFoundException: If multiple AMI IDs are found within the EDP's ELB.
        ImageNotFoundException: If no AMI IDs are found for the EDP.
    """
    LOG.info("Looking up AMI for {}-{}-{}...".format(env, dep, play))
    edp = EDP(env, dep, play)
    ec2_conn = boto.connect_ec2()
    asg_conn = boto.connect_autoscale()
    all_elbs = get_all_load_balancers()
    LOG.info("Found {} load balancers.".format(len(all_elbs)))

    edp_filter = {
        "tag:environment": env,
        "tag:deployment": dep,
        "tag:play": play,
    }
    reservations = ec2_conn.get_all_reservations(filters=edp_filter)
    LOG.info("{} reservations found for EDP {}-{}-{}".format(
        len(reservations), env, dep, play))
    amis = set()
    instances_by_id = {}
    for reservation in reservations:
        for instance in reservation.instances:
            # Need to build up instances_by_id for code below
            instances_by_id[instance.id] = instance

    asgs = asg_conn.get_all_groups(names=asgs_for_edp(edp))
    for asg in asgs:
        for asg_inst in asg.instances:
            instance = instances_by_id[asg_inst.instance_id]
            asg_enabled = len(asg.suspended_processes) == 0
            if instance.state == 'running' and asg_enabled:
                amis.add(instance.image_id)
                LOG.info("AMI found in ASG {} for {}-{}-{}: {}".format(
                    asg.name, env, dep, play, instance.image_id))
            else:
                LOG.info("Instance {} state: {} - asg {} enabled: {}".format(
                    instance.id, instance.state, asg.name, asg_enabled))

    if len(amis) > 1:
        msg = "Multiple AMIs found for {}-{}-{}, should have only one.".format(
            env, dep, play)
        raise MultipleImagesFoundException(msg)

    if not amis:
        msg = "No AMIs found for {}-{}-{}.".format(env, dep, play)
        raise ImageNotFoundException(msg)

    return amis.pop()
Beispiel #2
0
def asgs_for_edp(edp, filter_asgs_pending_delete=True):
    """
    All AutoScalingGroups that have the tags of this play.

    A play is made up of many auto_scaling groups.

    Arguments:
        EDP Named Tuple: The edp tags for the ASGs you want.
    Returns:
        list: list of ASG names that match the EDP.
    eg.

     [
         u'edxapp-v018',
         u'sandbox-edx-hacking-ASG',
         u'sandbox-edx-insights-ASG',
         u'test-edx-ecomapp',
         u'test-edx-edxapp-v007',
         u'test2-edx-certificates',
     ]

    """
    all_groups = get_all_autoscale_groups()
    matching_groups = []
    LOG.info("Found {} ASGs".format(len(all_groups)))

    for group in all_groups:
        LOG.debug("Checking group {}".format(group))
        tags = {tag.key: tag.value for tag in group.tags}
        LOG.debug("Tags for asg {}: {}".format(group.name, tags))
        if filter_asgs_pending_delete and ASG_DELETE_TAG_KEY in tags.keys():
            LOG.info(
                "filtering ASG: {0} because it is tagged for deletion on: {1}".
                format(group.name, tags[ASG_DELETE_TAG_KEY]))
            continue

        edp_keys = ['environment', 'deployment', 'play']
        if all([tag in tags for tag in edp_keys]):
            group_env = tags['environment']
            group_deployment = tags['deployment']
            group_play = tags['play']

            group_edp = EDP(group_env, group_deployment, group_play)

            if group_edp == edp:
                matching_groups.append(group.name)

    LOG.info("Returning %s ASGs for EDP %s-%s-%s.", len(matching_groups),
             edp.environment, edp.deployment, edp.play)
    return matching_groups
Beispiel #3
0
    def test_asgs_for_edp(self, params):
        asgs, expected_returned_count, expected_asg_names_list = params

        edp = EDP("foo", "bar", "baz")

        for name, tags in six.viewitems(asgs):
            create_asg_with_tags(name, tags)

        asgs = ec2.asgs_for_edp(edp)
        self.assertIsInstance(asgs, list)

        self.assertEqual(len(asgs), expected_returned_count)
        self.assertTrue(
            all(asg_name in asgs for asg_name in expected_asg_names_list))
Beispiel #4
0
def edp_for_ami(ami_id):
    """
    Look up the EDP tags for an AMI.

    Arguments:
        ami_id (str): An AMI Id.
    Returns:
        EDP Named Tuple: The EDP tags for this AMI.
    Raises:
        ImageNotFoundException: No image found with this ami ID.
        MissingTagException: AMI is missing one or more of the expected tags.
    """
    tags = tags_for_ami(ami_id)

    try:
        edp = EDP(tags['environment'], tags['deployment'], tags['play'])
    except KeyError as key_err:
        missing_key = key_err.args[0]
        msg = "{} is missing the {} tag.".format(ami_id, missing_key)
        raise MissingTagException(msg)

    LOG.debug("Got EDP for {}: {}".format(ami_id, edp))
    return edp
Beispiel #5
0
    def test_edp2_for_tagged_ami(self):
        actual_edp = ec2.edp_for_ami(self._make_fake_ami())
        expected_edp = EDP("foo", "bar", "baz")

        # Happy Path
        self.assertEqual(expected_edp, actual_edp)