def main(): """ main entry point for module execution """ argument_spec = dict( src=dict(type='path'), lines=dict(aliases=['commands'], type='list'), parents=dict(type='list'), before=dict(type='list'), after=dict(type='list'), match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), replace=dict(default='line', choices=['line', 'block', 'config']), defaults=dict(type='bool', default=False), backup=dict(type='bool', default=False), save=dict(default=False, type='bool'), # deprecated arguments (Ansible 2.3) config=dict(), # this argument is deprecated in favor of setting match: none # it will be removed in a future version force=dict(default=False, type='bool'), ) argument_spec.update(eos_argument_spec) mutually_exclusive = [('lines', 'src')] required_if = [('match', 'strict', ['lines']), ('match', 'exact', ['lines']), ('replace', 'block', ['lines']), ('replace', 'config', ['src'])] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_if=required_if, supports_check_mode=True) if module.params['force'] is True: module.params['match'] = 'none' warnings = list() check_args(module, warnings) result = {'changed': False} if warnings: result['warnings'] = warnings if module.params['backup']: result['__backup__'] = get_config(module) if any((module.params['src'], module.params['lines'])): run(module, result) if module.params['save']: if not module.check_mode: run_commands(module, ['copy running-config startup-config']) result['changed'] = True module.exit_json(**result)
def validate_vrf(value, module): out = run_commands(module, ['show vrf']) configured_vrfs = re.findall('^\s+(\w+)(?=\s)', out[0], re.M) configured_vrfs.append('default') if value not in configured_vrfs: module.fail_json(msg='vrf `%s` is not configured on the system' % value)
def map_config_to_obj(module): output = run_commands(module, ['show banner %s' % module.params['banner']]) obj = {'banner': module.params['banner'], 'state': 'absent'} if output: obj['text'] = output obj['state'] = 'present' return obj
def verify_state(updates, module): want, have = updates invalid_state = [('http', 'httpServer'), ('https', 'httpsServer'), ('local_http', 'localHttpServer'), ('socket', 'unixSocketServer')] timeout = module.params['timeout'] or 30 state = module.params['state'] while invalid_state: out = run_commands(module, ['show management api http-commands | json']) for index, item in enumerate(invalid_state): want_key, eapi_key = item if want[want_key] is not None: if want[want_key] == out[0][eapi_key]['running']: del invalid_state[index] elif state == 'stopped': if not out[0][eapi_key]['running']: del invalid_state[index] else: del invalid_state[index] time.sleep(1) timeout -= 1 if timeout == 0: module.fail_json( msg='timeout expired before eapi running state changed')
def map_config_to_obj(module): objs = [] output = run_commands(module, ['show vrf']) lines = output[0].strip().splitlines()[2:] for l in lines: if not l: continue splitted_line = re.split(r'\s{2,}', l.strip()) if len(splitted_line) == 1: continue else: obj = {} obj['name'] = splitted_line[0] obj['rd'] = splitted_line[1] obj['interfaces'] = None if len(splitted_line) > 4: obj['interfaces'] = [] for i in splitted_line[4].split(','): obj['interfaces'].append(i.strip()) objs.append(obj) return objs
def verify_state(updates, module): want, have = updates invalid_state = [('http', 'httpServer'), ('https', 'httpsServer'), ('local_http', 'localHttpServer'), ('socket', 'unixSocketServer')] timeout = module.params['timeout'] or 30 state = module.params['state'] while invalid_state: out = run_commands(module, ['show management api http-commands | json']) for index, item in enumerate(invalid_state): want_key, eapi_key = item if want[want_key] is not None: if want[want_key] == out[0][eapi_key]['running']: del invalid_state[index] elif state == 'stopped': if not out[0][eapi_key]['running']: del invalid_state[index] else: del invalid_state[index] time.sleep(1) timeout -= 1 if timeout == 0: module.fail_json(msg='timeout expired before eapi running state changed')
def map_config_to_obj(module): obj = {} output = run_commands(module, ['show vlan']) if isinstance(output[0], str): for l in output[0].strip().splitlines()[2:]: split_line = l.split() vlan_id = split_line[0] name = split_line[1] status = split_line[2] if vlan_id == str(module.params['vlan_id']): obj['vlan_id'] = vlan_id obj['name'] = name obj['state'] = status if obj['state'] == 'suspended': obj['state'] = 'suspend' break else: for k, v in iteritems(output[0]['vlans']): vlan_id = k name = v['name'] status = v['status'] if vlan_id == str(module.params['vlan_id']): obj['vlan_id'] = vlan_id obj['name'] = name obj['state'] = status if obj['state'] == 'suspended': obj['state'] = 'suspend' break return obj
def main(): argument_spec = dict( command=dict(type='list', required=True), isis_interface=dict(type='int', required=True) ) argument_spec.update(eos_argument_spec) module = AnsibleModule(argument_spec=argument_spec,supports_check_mode=True ) result = dict() warnings = list() check_args(module, warnings) command = module.params['command'] isis_interface = module.params['isis_interface'] # appending warning messages in result warnings as keyword if warnings: result['warnings'] = warnings # checking if command is not 'show isis summary' then failing tasks if(command[0] == 'show isis summary'): command_response = run_commands(module,command) else: module.fail_json(msg = 'please provide coorect command (hint: show isis summary)') # searching number of active isis interfaces regex = "(Number active interfaces:)\s(\d+)" m = re.search(regex,command_response[0]) active_int = int(m.group(2)) # if number of configured isis interface and active isis interface is not equal then run remediation script if(active_int!=isis_interface): obj = isis_remediate(module) responses = obj.action() result.update({ 'remediation': 'Done' }) else: result.update({ 'remediation': 'Not Needed' }) result.update({ 'changed': False, 'command': command, 'isis_interface': isis_interface, 'active_interface': active_int, 'stdout_lines': to_lines(command_response) }) module.exit_json(**result)
def collect_facts(module, result): out = run_commands(module, ['show management api http-commands | json']) facts = dict(eos_eapi_urls=dict()) for each in out[0]['urls']: intf, url = each.split(' : ') key = str(intf).strip() if key not in facts['eos_eapi_urls']: facts['eos_eapi_urls'][key] = list() facts['eos_eapi_urls'][key].append(str(url).strip()) result['ansible_facts'] = facts
def action(self): command = ["show ip int brief"] command_response = run_commands(self.module, command) command_responses = command_response[0].split('\n') regex = "(\w+)\s+([0-9/.]+)\s+(admin down)\s+(\w+)\s+(\w+)" for response in command_responses: m = re.match(regex, response) if m: interface = m.group(1) commands = [ 'config', 'int {}'.format(interface), 'no shut', 'wr', 'end' ] run_commands(self.module, commands) time.sleep(5) responses = run_commands(self.module, command) return responses
def map_config_to_obj(module): output = run_commands(module, ['show banner %s' % module.params['banner']]) obj = {'banner': module.params['banner'], 'state': 'absent'} if output: if module.params['transport'] == 'cli': obj['text'] = output[0] else: # On EAPI we need to extract the banner text from dict key # 'loginBanner' obj['text'] = output[0]['loginBanner'].strip('\n') obj['state'] = 'present' return obj
def map_config_to_obj(module): out = run_commands(module, ['show management api http-commands | json']) return { 'http': out[0]['httpServer']['configured'], 'http_port': out[0]['httpServer']['port'], 'https': out[0]['httpsServer']['configured'], 'https_port': out[0]['httpsServer']['port'], 'local_http': out[0]['localHttpServer']['configured'], 'local_http_port': out[0]['localHttpServer']['port'], 'socket': out[0]['unixSocketServer']['configured'], 'vrf': out[0]['vrf'], 'state': parse_state(out) }
def map_config_to_obj(module): output = run_commands(module, ['show banner %s' % module.params['banner']]) obj = {'banner': module.params['banner'], 'state': 'absent'} if output: if module.params['transport'] == 'cli': obj['text'] = output[0] else: # On EAPI we need to extract the banner text from dict key # 'loginBanner' if module.params['banner'] == 'login': banner_response_key = 'loginBanner' else: banner_response_key = 'motd' if isinstance(output[0], dict) and banner_response_key in output[0].keys(): obj['text'] = output[0][banner_response_key].strip('\n') obj['state'] = 'present' return obj
def map_config_to_obj(module): obj = {} output = run_commands(module, ['show vrf %s' % module.params['name']]) lines = output[0].strip().splitlines() if len(lines) > 2: splitted_line = re.split(r'\s{2,}', lines[2].strip()) obj['name'] = splitted_line[0] obj['rd'] = splitted_line[1] obj['interfaces'] = None if len(splitted_line) > 4: obj['interfaces'] = [] for i in splitted_line[4].split(','): obj['interfaces'].append(i.strip()) return obj
def map_config_to_obj(module): output = run_commands(module, ['show banner %s' % module.params['banner']]) obj = {'banner': module.params['banner'], 'state': 'absent'} if output: if module.params['transport'] == 'cli': obj['text'] = output[0] else: # On EAPI we need to extract the banner text from dict key # 'loginBanner' if module.params['banner'] == 'login': banner_response_key = 'loginBanner' else: banner_response_key = 'motd' if isinstance(output[0], dict) and banner_response_key in output[0].keys(): obj['text'] = output[0] obj['state'] = 'present' return obj
def map_config_to_obj(module): objs = [] try: out = run_commands(module, ['show ip route | json'])[0] except IndexError: out = {} if out: try: vrfs = out['vrfs']['default']['routes'] except (AttributeError, KeyError, TypeError): vrfs = {} if vrfs: for address in vrfs: obj = {} obj['address'] = address obj['admin_distance'] = vrfs[address].get('preference') obj['next_hop'] = vrfs[address].get('vias')[0].get('nexthopAddr') objs.append(obj) return objs
def map_config_to_obj(module): objs = [] output = run_commands(module, ['show vlan']) lines = output[0].strip().splitlines()[2:] for l in lines: splitted_line = re.split(r'\s{2,}', l.strip()) obj = {} obj['vlan_id'] = splitted_line[0] obj['name'] = splitted_line[1] obj['state'] = splitted_line[2] if obj['state'] == 'suspended': obj['state'] = 'suspend' obj['interfaces'] = [] if len(splitted_line) > 3: for i in splitted_line[3].split(','): obj['interfaces'].append(i.strip().replace('Et', 'Ethernet')) objs.append(obj) return objs
def 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')) argument_spec.update(eos_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) if warnings: result['warnings'] = warnings wait_for = module.params['wait_for'] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError: exc = get_exception() module.fail_json(msg=str(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 be satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ 'changed': False, 'stdout': responses, 'stdout_lines': to_lines(responses) }) module.exit_json(**result)
def 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') ) argument_spec.update(eos_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) if warnings: result['warnings'] = warnings wait_for = module.params['wait_for'] or list() try: conditionals = [Conditional(c) for c in wait_for] except AttributeError: exc = get_exception() module.fail_json(msg=str(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 be satisfied' module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update({ 'changed': False, 'stdout': responses, 'stdout_lines': to_lines(responses) }) module.exit_json(**result)
def populate(self): self.responses = run_commands(self.module, list(self.COMMANDS))
def main(): """ main entry point for module execution """ argument_spec = dict( src=dict(type='path'), lines=dict(aliases=['commands'], type='list'), parents=dict(type='list'), before=dict(type='list'), after=dict(type='list'), match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), replace=dict(default='line', choices=['line', 'block', 'config']), defaults=dict(type='bool', default=False), backup=dict(type='bool', default=False), save_when=dict(choices=['always', 'never', 'modified'], default='never'), diff_against=dict(choices=['startup', 'session', 'intended', 'running'], default='session'), diff_ignore_lines=dict(type='list'), running_config=dict(aliases=['config']), intended_config=dict(), # save is deprecated as of ans2.4, use save_when instead save=dict(default=False, type='bool', removed_in_version='2.4'), # force argument deprecated in ans2.2 force=dict(default=False, type='bool', removed_in_version='2.2') ) argument_spec.update(eos_argument_spec) mutually_exclusive = [('lines', 'src'), ('save', 'save_when')] required_if = [('match', 'strict', ['lines']), ('match', 'exact', ['lines']), ('replace', 'block', ['lines']), ('replace', 'config', ['src']), ('diff_against', 'intended', ['intended_config'])] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_if=required_if, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False} if warnings: result['warnings'] = warnings config = None if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'): contents = get_config(module) config = NetworkConfig(indent=2, contents=contents) if module.params['backup']: result['__backup__'] = contents if any((module.params['src'], module.params['lines'])): match = module.params['match'] replace = module.params['replace'] candidate = get_candidate(module) if match != 'none' and replace != 'config': config_text = get_running_config(module) config = NetworkConfig(indent=3, contents=config_text) path = module.params['parents'] configobjs = candidate.difference(config, match=match, replace=replace, path=path) else: configobjs = candidate.items if configobjs: commands = dumps(configobjs, 'commands').split('\n') if module.params['before']: commands[:0] = module.params['before'] if module.params['after']: commands.extend(module.params['after']) result['commands'] = commands result['updates'] = commands replace = module.params['replace'] == 'config' commit = not module.check_mode response = load_config(module, commands, replace=replace, commit=commit) if 'diff' in response and module.params['diff_against'] == 'session': result['diff'] = {'prepared': response['diff']} if 'session' in response: result['session'] = response['session'] result['changed'] = True running_config = None startup_config = None diff_ignore_lines = module.params['diff_ignore_lines'] if module.params['save_when'] != 'never': output = run_commands(module, [{'command': 'show running-config', 'output': 'text'}, {'command': 'show startup-config', 'output': 'text'}]) running_config = NetworkConfig(indent=1, contents=output[0], ignore_lines=diff_ignore_lines) startup_config = NetworkConfig(indent=1, contents=output[1], ignore_lines=diff_ignore_lines) if running_config.sha1 != startup_config.sha1 or module.params['save_when'] == 'always': result['changed'] = True if not module.check_mode: cmd = {'command': 'copy running-config startup-config', 'output': 'text'} run_commands(module, [cmd]) else: module.warn('Skipping command `copy running-config startup-config` ' 'due to check_mode. Configuration not copied to ' 'non-volatile storage') if module._diff: if not running_config: output = run_commands(module, {'command': 'show running-config', 'output': 'text'}) contents = output[0] else: contents = running_config.config_text # recreate the object in order to process diff_ignore_lines running_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if module.params['diff_against'] == 'running': if module.check_mode: module.warn("unable to perform diff against running-config due to check mode") contents = None else: contents = config.config_text elif module.params['diff_against'] == 'startup': if not startup_config: output = run_commands(module, {'command': 'show startup-config', 'output': 'text'}) contents = output[0] else: contents = startup_config.config_text elif module.params['diff_against'] == 'intended': contents = module.params['intended_config'] if contents is not None: base_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if running_config.sha1 != base_config.sha1: result.update({ 'changed': True, 'diff': {'before': str(base_config), 'after': str(running_config)} }) module.exit_json(**result)
def test_eos_run_commands(self): mock_module = MagicMock(name='AnsibleModule') mock_module.exec_command.return_value = (0, 'stdout', '') mock_module.from_json.side_effect = ValueError out = eos.run_commands(mock_module, 'command') self.assertEqual(out, ['stdout'])
def test_eos_run_commands_returns_json(self): mock_module = MagicMock(name='AnsibleModule') mock_module.exec_command.return_value = (0, '{"key": "value"}', '') mock_module.from_json.return_value = json.loads('{"key": "value"}') out = eos.run_commands(mock_module, 'command') self.assertEqual(out, [{'key': 'value'}])
def main(): """ main entry point for module execution """ argument_spec = dict( src=dict(type='path'), lines=dict(aliases=['commands'], type='list'), parents=dict(type='list'), before=dict(type='list'), after=dict(type='list'), match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), replace=dict(default='line', choices=['line', 'block', 'config']), defaults=dict(type='bool', default=False), backup=dict(type='bool', default=False), save_when=dict(choices=['always', 'never', 'modified'], default='never'), diff_against=dict( choices=['startup', 'session', 'intended', 'running'], default='session'), diff_ignore_lines=dict(type='list'), running_config=dict(aliases=['config']), intended_config=dict(), # save is deprecated as of ans2.4, use save_when instead save=dict(default=False, type='bool', removed_in_version='2.4'), # force argument deprecated in ans2.2 force=dict(default=False, type='bool', removed_in_version='2.2')) argument_spec.update(eos_argument_spec) mutually_exclusive = [('lines', 'src'), ('save', 'save_when')] required_if = [('match', 'strict', ['lines']), ('match', 'exact', ['lines']), ('replace', 'block', ['lines']), ('replace', 'config', ['src']), ('diff_against', 'intended', ['intended_config'])] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_if=required_if, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False} if warnings: result['warnings'] = warnings config = None if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'): contents = get_config(module) config = NetworkConfig(indent=2, contents=contents) if module.params['backup']: result['__backup__'] = contents if any((module.params['src'], module.params['lines'])): match = module.params['match'] replace = module.params['replace'] candidate = get_candidate(module) if match != 'none' and replace != 'config': config_text = get_running_config(module) config = NetworkConfig(indent=3, contents=config_text) path = module.params['parents'] configobjs = candidate.difference(config, match=match, replace=replace, path=path) else: configobjs = candidate.items if configobjs: commands = dumps(configobjs, 'commands').split('\n') if module.params['before']: commands[:0] = module.params['before'] if module.params['after']: commands.extend(module.params['after']) result['commands'] = commands result['updates'] = commands replace = module.params['replace'] == 'config' commit = not module.check_mode response = load_config(module, commands, replace=replace, commit=commit) if 'diff' in response and module.params[ 'diff_against'] == 'session': result['diff'] = {'prepared': response['diff']} if 'session' in response: result['session'] = response['session'] result['changed'] = True running_config = None startup_config = None diff_ignore_lines = module.params['diff_ignore_lines'] if module.params['save_when'] != 'never': output = run_commands(module, [{ 'command': 'show running-config', 'output': 'text' }, { 'command': 'show startup-config', 'output': 'text' }]) running_config = NetworkConfig(indent=1, contents=output[0], ignore_lines=diff_ignore_lines) startup_config = NetworkConfig(indent=1, contents=output[1], ignore_lines=diff_ignore_lines) if running_config.sha1 != startup_config.sha1 or module.params[ 'save_when'] == 'always': result['changed'] = True if not module.check_mode: cmd = { 'command': 'copy running-config startup-config', 'output': 'text' } run_commands(module, [cmd]) else: module.warn( 'Skipping command `copy running-config startup-config` ' 'due to check_mode. Configuration not copied to ' 'non-volatile storage') if module._diff: if not running_config: output = run_commands(module, { 'command': 'show running-config', 'output': 'text' }) contents = output[0] else: contents = running_config.config_text # recreate the object in order to process diff_ignore_lines running_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if module.params['diff_against'] == 'running': if module.check_mode: module.warn( "unable to perform diff against running-config due to check mode" ) contents = None else: contents = config.config_text elif module.params['diff_against'] == 'startup': if not startup_config: output = run_commands(module, { 'command': 'show startup-config', 'output': 'text' }) contents = output[0] else: contents = startup_config.config_text elif module.params['diff_against'] == 'intended': contents = module.params['intended_config'] if contents is not None: base_config = NetworkConfig(indent=1, contents=contents, ignore_lines=diff_ignore_lines) if running_config.sha1 != base_config.sha1: result.update({ 'changed': True, 'diff': { 'before': str(base_config), 'after': str(running_config) } }) module.exit_json(**result)
def test_eos_run_commands_check_rc_fails(self): mock_module = MagicMock(name='AnsibleModule') mock_module.exec_command.return_value = (1, '', 'stderr') out = eos.run_commands(mock_module, 'command') mock_module.fail_json.called_with_args({'msg': 'stderr'})