def _parse_directory(module, result, dir_pathj): command = {'command': f'dir {dir_pathj}'} responses = run_commands(module, command) files = [] for idx, response in enumerate(to_lines(responses)): for line in response: if NOT_EXIST in line: module.fail_json( msg=f'Directory {dir_pathj} does not exists on device.') if not line or any(word in line for word in SKIP_LINES): continue if EMPTY_DIR in line: result['warnings'].append( f"Directory {dir_pathj} is currently empty") break item_info = line.split() if len(item_info) != 9: result['warnings'].append( f"Could not parse content of {dir_pathj}, please report this. Output was: {responses[idx]}. Offending line seems to be: {line}" ) break if 'd' in item_info[1]: # This is a directory continue filename = item_info[-1] files.append(filename) return files
def main(): """main entry point for module execution """ argument_spec = dict( # { command: <str>, prompt: <str>, response: <str> } commands=dict(type='list', required=True), wait_for=dict(type='list'), match=dict(default='all', choices=['all', 'any']), retries=dict(default=10, type='int'), interval=dict(default=1, type='int')) argument_spec.update(dellos10_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) result = {'changed': False} warnings = list() check_args(module, warnings) commands = parse_commands(module, warnings) result['warnings'] = warnings wait_for = module.params['wait_for'] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError as exc: module.fail_json(msg=to_text(exc)) retries = module.params['retries'] interval = module.params['interval'] match = module.params['match'] while retries > 0: responses = run_commands(module, commands) for item in list(conditionals): if item(responses): if match == 'any': conditionals = list() break conditionals.remove(item) if not conditionals: break time.sleep(interval) retries -= 1 if conditionals: failed_conditions = [item.raw for item in conditionals] msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ 'stdout': responses, 'stdout_lines': list(to_lines(responses)) }) module.exit_json(**result)
def main(): """entry point for module execution""" argument_spec = dict( # { command: <str>, output: <str>, prompt: <str>, response: <str> } commands=dict(type="list", required=True, elements="raw"), wait_for=dict(type="list", aliases=["waitfor"], elements="str"), match=dict(default="all", choices=["any", "all"]), retries=dict(default=10, type="int"), interval=dict(default=1, type="int"), ) argument_spec.update(nxos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() result = {"changed": False, "warnings": warnings} commands = parse_commands(module, warnings) wait_for = module.params["wait_for"] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError as exc: module.fail_json(msg=to_text(exc)) retries = module.params["retries"] interval = module.params["interval"] match = module.params["match"] while retries > 0: responses = run_commands(module, commands) for item in list(conditionals): try: if item(responses): if match == "any": conditionals = list() break conditionals.remove(item) except FailedConditionalError as exc: module.fail_json(msg=to_text(exc)) if not conditionals: break time.sleep(interval) retries -= 1 if conditionals: failed_conditions = [item.raw for item in conditionals] msg = "One or more conditional statements have not been satisfied" module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ "stdout": responses, "stdout_lines": list(to_lines(responses)) }) module.exit_json(**result)
def main(): """main entry point for module execution """ argument_spec = dict( commands=dict(type='list', required=True), match=dict(type='str', choices=['exact']), lines=dict(type='list'), ) argument_spec.update(dmos_argument_spec) required_if = [('match', 'exact', ['lines'])] module = AnsibleModule(argument_spec=argument_spec, required_if=required_if, supports_check_mode=True) warnings = list() commands = parse_commands(module, warnings) responses = run_commands(module, commands) if module.params['match']: for line in module.params['lines']: if line not in responses: module.fail_json(msg="didn't match the lines") return result = {'changed': False, 'warnings': warnings} result.update({ 'stdout': responses, 'stdout_lines': list(to_lines(responses)), }) module.exit_json(**result)
def test_to_lines(): expected_output = [[ "! Command: show running-config", "! device: veos23 (vEOS, EOS-4.23.3M)", "!", "! boot system flash:/vEOS-lab-4.23.3M.swi", "!", "transceiver qsfp default-mode 4x10G", "!", "interface Management1", " ip address dhcp", "!", "end", ]] assert expected_output == list(utils.to_lines(expected_output)) stdout = ["\n".join(expected_output[0])] assert expected_output == list(utils.to_lines(stdout))
def _get_file_md5(module, result, file_path): command = {'command': f'verify /md5 {file_path}'} responses = run_commands(module, command) for idx, response in enumerate(to_lines(responses)): for line in response: if line.startswith('verify /md5'): remote_md5 = line.split()[-1] return remote_md5 result['warnings'].append( f"Could not parse device output to get MD5 hash of {file_path}, please report this. File will be skipped. Output was: {responses[idx]}. Offending line seems to be: {line}" ) return None
def main(): spec = dict(commands=dict(type='list', required=True), wait_for=dict(type='list', aliases=['waitfor']), match=dict(default='all', choices=['all', 'any']), retries=dict(default=10, type='int'), interval=dict(default=1, type='int')) spec.update(vyos_argument_spec) module = AnsibleModule(argument_spec=spec, supports_check_mode=True) warnings = list() result = {'changed': False, 'warnings': warnings} commands = parse_commands(module, warnings) wait_for = module.params['wait_for'] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError as exc: module.fail_json(msg=to_text(exc)) retries = module.params['retries'] interval = module.params['interval'] match = module.params['match'] for _ in range(retries): responses = run_commands(module, commands) for item in list(conditionals): if item(responses): if match == 'any': conditionals = list() break conditionals.remove(item) if not conditionals: break time.sleep(interval) if conditionals: failed_conditions = [item.raw for item in conditionals] msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ 'stdout': responses, 'stdout_lines': list(to_lines(responses)), }) module.exit_json(**result)
def _parse_file(module, result, file_path): command = {'command': f'dir {file_path}'} responses = run_commands(module, command) filename = None for idx, response in enumerate(to_lines(responses)): for line in response: if NOT_EXIST in line: break if not line or any(word in line for word in SKIP_LINES): continue item_info = line.split() if len(item_info) != 9: result['warnings'].append( f"Could not check for {file_path} presence, please report this. Output was: {responses[idx]}. Offending line seems to be: {line}" ) break if 'd' in item_info[1] or filename: module.fail_json( msg=f'{file_path} does not seem to be a file path.') else: filename = item_info[-1] return filename
def main(): """entry point for module execution """ argument_spec = dict( commands=dict(type="list", elements="str"), rpcs=dict(type="list", elements="str"), display=dict( choices=["text", "json", "xml", "set"], aliases=["format", "output"], ), wait_for=dict(type="list", aliases=["waitfor"], elements="str"), match=dict(default="all", choices=["all", "any"]), retries=dict(default=10, type="int"), interval=dict(default=1, type="int"), ) argument_spec.update(junos_argument_spec) required_one_of = [("commands", "rpcs")] module = AnsibleModule( argument_spec=argument_spec, required_one_of=required_one_of, supports_check_mode=True, ) warnings = list() conn = get_connection(module) capabilities = get_capabilities(module) if capabilities.get("network_api") == "cliconf": if any(( module.params["wait_for"], module.params["match"], module.params["rpcs"], )): module.warn( "arguments wait_for, match, rpcs are not supported when using transport=cli" ) commands = module.params["commands"] output = list() display = module.params["display"] for cmd in commands: # if display format is not mentioned in command, add the display format # from the modules params if ("display json" not in cmd) and ("display xml" not in cmd): if display and display != "text": cmd += " | display {0}".format(display) try: output.append(conn.get(command=cmd)) except ConnectionError as exc: module.fail_json( msg=to_text(exc, errors="surrogate_then_replace")) lines = [out.split("\n") for out in output] result = {"changed": False, "stdout": output, "stdout_lines": lines} module.exit_json(**result) items = list() items.extend(parse_commands(module, warnings)) items.extend(parse_rpcs(module)) wait_for = module.params["wait_for"] or list() conditionals = [Conditional(c) for c in wait_for] retries = module.params["retries"] interval = module.params["interval"] match = module.params["match"] while retries > 0: responses = rpc(module, items) transformed = list() output = list() for item, resp in zip(items, responses): if item["xattrs"]["format"] == "xml": if not HAS_JXMLEASE: module.fail_json( msg= "jxmlease is required but does not appear to be installed. " "It can be installed using `pip install jxmlease`") try: json_resp = jxmlease.parse(resp) transformed.append(json_resp) output.append(json_resp) except Exception: raise ValueError(resp) else: transformed.append(resp) for item in list(conditionals): try: if item(transformed): if match == "any": conditionals = list() break conditionals.remove(item) except FailedConditionalError: pass if not conditionals: break time.sleep(interval) retries -= 1 if conditionals: failed_conditions = [item.raw for item in conditionals] msg = "One or more conditional statements have not been satisfied" module.fail_json(msg=msg, failed_conditions=failed_conditions) result = { "changed": False, "warnings": warnings, "stdout": responses, "stdout_lines": list(to_lines(responses)), } if output: result["output"] = output module.exit_json(**result)
def main(): """entry point for module execution """ argument_spec = dict(commands=dict(type='list'), rpcs=dict(type='list'), display=dict(choices=['text', 'json', 'xml', 'set'], aliases=['format', 'output']), wait_for=dict(type='list', aliases=['waitfor']), match=dict(default='all', choices=['all', 'any']), retries=dict(default=10, type='int'), interval=dict(default=1, type='int')) argument_spec.update(junos_argument_spec) required_one_of = [('commands', 'rpcs')] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, supports_check_mode=True) warnings = list() conn = get_connection(module) capabilities = get_capabilities(module) if capabilities.get('network_api') == 'cliconf': if any((module.params['wait_for'], module.params['match'], module.params['rpcs'])): module.warn( 'arguments wait_for, match, rpcs are not supported when using transport=cli' ) commands = module.params['commands'] output = list() display = module.params['display'] for cmd in commands: # if display format is not mentioned in command, add the display format # from the modules params if ('display json' not in cmd) and ('display xml' not in cmd): if display and display != 'text': cmd += ' | display {0}'.format(display) try: output.append(conn.get(command=cmd)) except ConnectionError as exc: module.fail_json( msg=to_text(exc, errors='surrogate_then_replace')) lines = [out.split('\n') for out in output] result = {'changed': False, 'stdout': output, 'stdout_lines': lines} module.exit_json(**result) items = list() items.extend(parse_commands(module, warnings)) items.extend(parse_rpcs(module)) wait_for = module.params['wait_for'] or list() conditionals = [Conditional(c) for c in wait_for] retries = module.params['retries'] interval = module.params['interval'] match = module.params['match'] while retries > 0: responses = rpc(module, items) transformed = list() output = list() for item, resp in zip(items, responses): if item['xattrs']['format'] == 'xml': if not HAS_JXMLEASE: module.fail_json( msg= 'jxmlease is required but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`') try: json_resp = jxmlease.parse(resp) transformed.append(json_resp) output.append(json_resp) except Exception: raise ValueError(resp) else: transformed.append(resp) for item in list(conditionals): try: if item(transformed): if match == 'any': conditionals = list() break conditionals.remove(item) except FailedConditionalError: pass if not conditionals: break time.sleep(interval) retries -= 1 if conditionals: failed_conditions = [item.raw for item in conditionals] msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result = { 'changed': False, 'warnings': warnings, 'stdout': responses, 'stdout_lines': list(to_lines(responses)), } if output: result['output'] = output module.exit_json(**result)
def main(): spec = dict(commands=dict(type='list', required=True), wait_for=dict(type='list'), match=dict(default='all', choices=['all', 'any']), retries=dict(default=10, type='int'), interval=dict(default=1, type='int')) module = AnsibleModule(argument_spec=spec, supports_check_mode=False) warnings = list() result = {'changed': False, 'warnings': warnings} wait_for = module.params['wait_for'] or list() conditionals = [Conditional(c) for c in wait_for] commands = parse_commands(module, warnings) commands = module.params['commands'] retries = module.params['retries'] interval = module.params['interval'] match = module.params['match'] while retries > 0: responses = run_commands(module, commands) for item in list(conditionals): if item(responses): if match == 'any': conditionals = list() break conditionals.remove(item) if not conditionals: break time.sleep(interval) retries -= 1 if conditionals: failed_conditions = [item.raw for item in conditionals] msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) for item in responses: if len(item) == 0: if module.check_mode: result.update({ 'changed': False, 'stdout': responses, 'stdout_lines': list(to_lines(responses)) }) else: result.update({ 'changed': True, 'stdout': responses, 'stdout_lines': list(to_lines(responses)) }) elif 'ERROR' in item: result.update({ 'failed': True, 'stdout': responses, 'stdout_lines': list(to_lines(responses)) }) else: result.update({ 'stdout': item, 'stdout_lines': list(to_lines(responses)) }) module.exit_json(**result)
def main(): """main entry point for module execution """ argument_spec = dict( commands=dict(type='list', required=True), wait_for=dict(type='list', aliases=['waitfor']), match=dict(default='all', choices=['all', 'any']), retries=dict(default=10, type='int'), interval=dict(default=1, type='int'), partition=dict(default='shared') ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() result = {'changed': False, 'warnings': warnings} commands = parse_commands(module, warnings) wait_for = module.params['wait_for'] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError as exc: module.fail_json(msg=to_text(exc)) retries = module.params['retries'] interval = module.params['interval'] match = module.params['match'] if module.params['partition'].lower() != 'shared': partition_name = module.params['partition'] out = run_commands(module, 'active-partition %s' % (partition_name)) if "does not exist" in str(out[0]): module.fail_json(msg="Provided partition does not exist") before_config_list = configuration_to_list(run_commands(module, 'show running-config')) while retries > 0: responses = run_commands(module, commands) for item in list(conditionals): if item(responses): if match == 'any': conditionals = list() break conditionals.remove(item) if not conditionals: break time.sleep(interval) retries -= 1 after_config_list = configuration_to_list(run_commands(module, 'show running-config')) diff = list(set(after_config_list) - set(before_config_list)) if len(diff) != 0: result['changed'] = True else: result['changed'] = False if conditionals: failed_conditions = [item.raw for item in conditionals] msg = 'One or more conditional statements have not been satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ 'stdout': responses, 'stdout_lines': list(to_lines(responses)), }) module.exit_json(**result)