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)
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")
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)
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)
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