Exemplo n.º 1
0
def get_zone_id(zone_name):
    """
    Returns the Zone ID for the specified zone name.

    Args:
        zone_name: string representing the zone name.

    Returns:
        None

    Raises:
        MissingConfigurationParameterException if zone_name is not defined.
    """
    if not zone_name:
        msg = "DNS Zone Name not defined."
        raise MissingConfigurationParameterException(msg)

    r53 = boto3.client('route53')
    zones = r53.list_hosted_zones_by_name()
    for zone in zones['HostedZones']:
        if zone['Name'].rstrip('.') == zone_name:
            if not zone['Config']['PrivateZone']:
                return zone['Id'].split('/')[2]

    return None
Exemplo n.º 2
0
def teardown(config):
    """
    Teardown the build directory structure created to deploy the environment.
    Modifies the dictionary passed in, then returns it.

    Args:
        config: dictionary containing all variable settings required
                to run terraform with
    Returns:
        config

    Raises:
        MissingConfigurationParameterException if 'tmpdir' is unset.
    """
    logger.debug("Removing tmpdir: {}".format(config['tmpdir']))
    workdir.options.path = config.get('tmpdir')
    if not workdir.options.path:
        msg = "tmpdir variable is not set. Can not destroy tmpdir location"
        raise MissingConfigurationParameterException(msg)

    workdir.remove()

    if not utils.git_url(config['terraform']):
        workdir.options.path = config.get('tf_root')
        workdir.remove()

    return config
Exemplo n.º 3
0
def upload_staged_artifacts(config):
    """
    Upload artifacts specified in config file to S3 bucket location.

    Args:
        config: dictionary containing all variable settings required
                to run terraform with

    Returns:
        True on success

    Raises:
         ValueError exception on failure.
    """
    schema = {
        "type": "object",
        "project_config":   { "type": "string"},
        "staged_artifacts": { "type": "object"},
        "required": ["project_config", "staged_artifacts"]
    }
    try:
        validate(config, schema)
    except ValidationError as e:
        msg = "{}: Configuration missing key fields. {}".format(__name__,
                                                                e.message)
        logger.error(msg)
        raise MissingConfigurationParameterException(msg)

    logmsg = "{}: Uploading staged artifacts to {}"
    logger.debug(logmsg.format(__name__, config['project_config']))

    s3resource = boto3.resource('s3')
    bucket_name = config['project_config']

    for bucket_key in config['staged_artifacts'].keys():
        source_file = os.path.abspath(config['staged_artifacts'][bucket_key])
        bucket_file = s3resource.Object(bucket_name, bucket_key)

        if not os.path.isfile(source_file):
            msg = "File {} does not exist".format(source_file)
            logger.critical(msg)
            raise SystemExit(msg)

        try:
            bucket_file.upload_file(source_file)
            log_msg = "Uploaded {} to {}/{}"
            logger.debug(log_msg.format(source_file,
                                        bucket_name,
                                        bucket_key))
        except ValueError as v:
            log_msg = "Error uploading {} to {}/{}: {}".format(source_file,
                                                               bucket_name,
                                                               bucket_key,
                                                               v.message)
            logger.critical(log_msg)
            raise ValueError(log_msg)

    return True
Exemplo n.º 4
0
def setup(config, sync=True):
    """
    Get ready to run 'terraform apply' for this environment.
    Modifies the dictionary passed in, then returns it.

    Args:
        config: dictionary containing all variable settings required
                to run terraform with

        sync: boolean. Toggles setting the branch on/off. Defaults to on.

    Returns:
        config with updated values.

    Raises:
        MissingConfigurationParameterException for missing config file entries.
    """
    # Create the per-environment S3 folder in pre-flight
    logmsg = "{}: Creating per-environment folder : {}:{}"
    logger.debug(
        logmsg.format(__name__, config['project_config'],
                      config['env_folder']))
    s3.create_folder(config['project_config'], config['env_folder'])

    if not config.get('route53_tld', None):
        msg = "route53_tld variable is not set in config file."
        raise MissingConfigurationParameterException(msg)

    zone_id = r53.get_zone_id(config['route53_tld'])
    if not zone_id:
        msg = "zone_id not set."
        raise MissingConfigurationParameterException(msg)

    config['public_zone_id'] = config.get('public_zone_id', zone_id)

    return config
Exemplo n.º 5
0
def download_staged_artifacts(config):
    """
    Downloads staged artifacts from S3 so terraform can use them access
    them for placing in environment-specific staging location.

    Args:
        config: dictionary containing all variable settings required
                to run terraform with
    Returns:
        nothing

    Raises:
        MissingConfigurationParameterException if 'project_config' is undefined.
    """
    s3 = boto3.resource('s3')
    bucket_name = config.get('project_config', None)
    if not bucket_name:
        msg = "project_config bucket is not defined. Can not proceed."
        raise MissingConfigurationParameterException(msg)

    if not config.get('staged_artifacts', None):
        logger.warn(
            "'staged_artifacts' not defined. Nothing to download from S3. ")
        return

    logmsg = "Downloading project files from s3 bucket {}"
    logger.debug(logmsg.format(bucket_name))
    for bucket_key in config['staged_artifacts'].keys():
        s3_file = os.path.basename(bucket_key)
        bucket_file = s3.Object(bucket_name, bucket_key)
        try:
            local_file = os.path.join(config['tmpdir'], s3_file)
            workdir.options.path = os.path.dirname(local_file)
            workdir.create()

            bucket_file.download_file(local_file)
            log_msg = "Downloading {}/{} to {}"
            logger.debug(
                log_msg.format(config['project_config'], bucket_key,
                               local_file))
        except:
            log_msg = "Error downloading {}/{} to {}"
            logger.debug(
                log_msg.format(config['project_config'], bucket_key,
                               local_file))

    return
Exemplo n.º 6
0
def test_MissingConfigurationParameterException():
    with pytest.raises(Exception):
        raise MissingConfigurationParameterException("Bam!")
Exemplo n.º 7
0
def setup(config, sync=True):
    """
    Get ready to run 'terraform apply' for this environment.
    Modifies the dictionary passed in, then returns it.

    Args:
        config: dictionary containing all variable settings required
                to run terraform with

        sync: boolean. Toggles setting the branch on/off. Defaults to on.

    Returns:
        config with updated values.

    Raises:
        MissingConfigurationParameterException for missing config file entries.
    """
    #create tmp dir to stage a deployment from
    config['tmpdir'] = config.get('tmpdir',
                                  os.path.join('/tmp', str(uuid.uuid4())))

    logger.debug("{}: Creating tmpdir: {}".format(__name__, config['tmpdir']))
    workdir.options.path = config['tmpdir']
    workdir.create()

    config['tfvars'] = os.path.join(workdir.options.path,
                                    config.get('tfvars_file', 'vars.tf'))

    # Create the per-environment S3 folder in pre-flight
    logmsg = "{}: Creating per-environment folder : {}:{}"
    logger.debug(
        logmsg.format(__name__, config['project_config'],
                      config['env_folder']))
    s3.create_folder(config['project_config'], config['env_folder'])

    if not config.get('route53_tld', None):
        msg = "route53_tld variable is not set in config file."
        raise MissingConfigurationParameterException(msg)

    zone_id = r53.get_zone_id(config['route53_tld'])
    if not zone_id:
        msg = "zone_id not set."
        raise MissingConfigurationParameterException(msg)

    config['public_zone_id'] = config.get('public_zone_id', zone_id)
    config['tf_root'] = config.get('tf_root', utils.get_tf_location(config))

    # If the tf location is set to a local directory, we need to deal
    # with things like the possibility of the actual tf location being
    # in a subdir and a specified branch.
    if not utils.git_url(config['terraform']):
        (repo, branch, subdir) = utils.parse_git_url(config['terraform'])
        config['tf_root'] = repo
        if branch:
            msg = "Setting branch to: {}".format(branch)
            logger.debug(msg)
            if sync:
                git_pull_cmd = utils.git_pull(repo)
                utils.run_command(git_pull_cmd, repo)
                git_set_branch_cmd = utils.git_set_branch(branch)
                utils.run_command(git_set_branch_cmd, repo)

        if subdir:
            tf_root = os.path.join(config.get('tf_root', repo), subdir)
            msg = "Setting tf_root to: {}".format(tf_root)
            logger.debug(msg)
            config['tf_root'] = tf_root

    return config