Example #1
0
def main(assets_glob):
    diff = False

    for file_name in sorted(glob.glob(assets_glob, recursive=True)):
        asset = load_asset(file_name)

        try:
            jt_data = tower_receive(asset['asset_type'], asset['name'])[0]
        except TowerCLIError:
            log('INFO', (f"Asset '{asset['name']}' doesn't exist in Tower, no "
                         "need to check for diffs"))
            continue

        # Need to parse extra vars to dict becuse in assets file it is YAML and
        # in reponse from tower it is JSON.
        asset['extra_vars'] = yaml.safe_load(asset['extra_vars'])
        jt_data['extra_vars'] = yaml.safe_load(jt_data['extra_vars'])

        log('INFO', f"Differentiating '{file_name}' and '{asset['name']}'")
        differences = list(dictdiffer.diff(jt_data, asset))
        if differences != []:
            diff = True
            log('WARNING', (f"  Mismatch, '{file_name}' is not the same as "
                            f"the '{asset['name']}' in tower!"))
            log('INFO', "  Difference:")
            for d in differences:
                log('INFO', "    " + json.dumps(d, indent=2))

    if diff:
        log('ERROR', "Difference(s) found!", fatal=True)
Example #2
0
def main(destination, assets_glob):
    try:
        os.makedirs(destination, exist_ok=True)
    except OSError:
        log('ERROR', f"Directory path: {destination}")
        log('ERROR', "Failed to create directory!", fatal=True)

    for file_name in sorted(glob.glob(assets_glob, recursive=True)):
        asset = load_asset(file_name)

        try:
            log('INFO', f"Downloading '{asset['name']}' ...")
            asset_data = tower_receive(asset['asset_type'], asset['name'])[0]
        except TowerCLIError:
            log('INFO',
                (f"... asset '{asset['name']}' does not exist in Tower"))
            continue

        file_path = os.path.join(
            destination,
            asset_data['name'].replace('/', '-').replace(' ', '_') + '.yml')

        file_content = yaml.dump(asset_data,
                                 Dumper=Dumper,
                                 default_flow_style=False)

        try:
            log('INFO', f"    File path: {file_path}")
            with open(file_path, 'w') as file:
                file.write("---\n")
                file.write(file_content)
        except EnvironmentError:
            log('ERROR', "Failed to write to the file!", fatal=True)

        log('INFO', "... downloaded")
Example #3
0
def test_load_asset_valid_path():
    file_data = textwrap.dedent(
        """\
        ---
        key_a:
          key_i: foo
          key_j: 111
        key_b:
          key_x: bar
          key_y: 222
        """
    )

    with tempfile.NamedTemporaryFile() as tmpfile:
        tmpfile.write(bytes(file_data, encoding="utf-8"))
        tmpfile.seek(0)

        result = _utils.load_asset(tmpfile.name)

        assert result == yaml.safe_load(file_data)
Example #4
0
def main(label_id, assets_glob):
    # asset names in repository
    local_assets = []
    for file_name in sorted(glob.glob(assets_glob, recursive=True)):
        asset = load_asset(file_name)
        # Can synchronize only assets of type job_template because we are
        # getting assets from tower by label. Label is not available on projects
        # or inventories.
        if asset['asset_type'] != 'job_template':
            continue
        local_assets.append(asset['name'])

    # asset names in tower
    tower_assets = [
        item['name']
        for item in tower_list('job_template', [('labels', label_id)])
    ]

    common_assets = set(tower_assets).intersection(set(local_assets))

    for asset in common_assets:
        log('INFO', f"'{asset}' located both in the repository and in the tower")

    # symmetric difference == disjunctive union == union without the intersection
    diff = set(tower_assets).symmetric_difference(set(local_assets))

    error = False
    for asset in diff:
        if asset not in tower_assets:
            log('WARNING', f"'{asset}' not found in tower ... will be recreated")
        elif asset not in local_assets:
            error = True
            log('ERROR', (f"'{asset}' not found in repository ... will be reported "
                          "(not allowed)"))

    if error:
        log('INFO', (
            "Investigate if the asset should be deleted from tower, "
            "added to the repository, or it's label removed."
        ))
        log('ERROR', "Reported error(s) are not permitted!", fatal=True)
Example #5
0
def test_load_asset_invalid_path():
    try:
        _utils.load_asset("./a/b/c/d/e/f/g/h/i/file")
    except _utils.Error as e:
        assert re.match(r"^Failed to read content of '\./a/b/c/d/e/f/g/h/i/file'$", str(e))
        assert e.error_code == 1