def test_to_list(self): for scalar in ('string', 1, True, False, None): self.assertTrue(isinstance(to_list(scalar), list)) for container in ([1, 2, 3], {'one': 1}): self.assertTrue(isinstance(to_list(container), list)) test_list = [1, 2, 3] self.assertNotEqual(id(test_list), id(to_list(test_list)))
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ responses = list() for item in to_list(commands): if item['output'] == 'json' and not is_json(item['command']): cmd = '%s | json' % item['command'] elif item['output'] == 'text' and is_json(item['command']): cmd = item['command'].split('|')[0] else: cmd = item['command'] rc, out, err = self.exec_command(cmd) if check_rc and rc != 0: self._module.fail_json(msg=err) try: out = self._module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def send_request(self, commands, output='text'): commands = to_list(commands) if self._enable: commands.insert(0, 'enable') body = self._request_builder(commands, output) data = self._module.jsonify(body) headers = {'Content-Type': 'application/json-rpc'} timeout = self._module.params['timeout'] response, headers = fetch_url( self._module, self._url, data=data, headers=headers, method='POST', timeout=timeout ) if headers['status'] != 200: self._module.fail_json(**headers) try: data = response.read() response = self._module.from_json(to_text(data, errors='surrogate_then_replace')) except ValueError: self._module.fail_json(msg='unable to load response from device', data=data) if self._enable and 'result' in response: response['result'].pop(0) return response
def load_config(module, commands, commit=False, comment=None, save=False): commands.insert(0, 'configure') for cmd in to_list(commands): conn = connection(module) rc, out, err = conn.exec_command(cmd, check_rc=False) if rc != 0: # discard any changes in case of failure conn.exec_command('exit discard') module.fail_json(msg='configuration failed') diff = None if module._diff: rc, out, err = conn.exec_command('compare') if not out.startswith('No changes'): rc, out, err = conn.exec_command('show') diff = str(out).strip() if commit: cmd = 'commit' if comment: cmd += ' comment "%s"' % comment conn.exec_command(cmd) if save: conn.exec_command(cmd) if not commit: conn.exec_command('exit discard') else: conn.exec_command('exit') if diff: return diff
def load_config(module, commands, commit=False, replace=False, comment=None): rc, out, err = conn.exec_command('configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=err) failed = False for command in to_list(commands): if command == 'end': pass conn = connection(module) rc, out, err = conn.exec_command(command) if rc != 0: failed = True break if failed: conn.exec_command('abort') module.fail_json(msg=err, commands=commands, rc=rc) rc, diff, err = conn.exec_command('show commit changes diff') if commit: cmd = 'commit' if comment: cmd += ' comment {0}'.format(comment) else: cmd = 'abort' diff = None conn.exec_command(cmd) return diff
def load_config(module, commands, commit=False, comment=None): rc, out, err = exec_command(module, 'configure') if rc != 0: module.fail_json(msg='unable to enter configuration mode', output=err) for cmd in to_list(commands): rc, out, err = exec_command(module, cmd) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='configuration failed') diff = None if module._diff: rc, out, err = exec_command(module, 'compare') if not out.startswith('No changes'): rc, out, err = exec_command(module, 'show') diff = str(out).strip() if commit: cmd = 'commit' if comment: cmd += ' comment "%s"' % comment exec_command(module, cmd) if not commit: exec_command(module, 'exit discard') else: exec_command(module, 'exit') if diff: return diff
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ output = None queue = list() responses = list() _send = lambda commands, output: self.send_request( commands, output, check_status=check_rc) for item in to_list(commands): if is_json(item['command']): item['command'] = str(item['command']).split('|')[0] item['output'] = 'json' if all((output == 'json', item['output'] == 'text')) or all( (output == 'text', item['output'] == 'json')): responses.extend(_send(queue, output)) queue = list() output = item['output'] or 'json' queue.append(item['command']) if queue: responses.extend(_send(queue, output)) return responses
def parse_roles(data): configured_roles = data.get('TABLE_role')['ROW_role'] roles = list() if configured_roles: for item in to_list(configured_roles): roles.append(item['role']) return roles
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ responses = list() for item in to_list(commands): if item['output'] == 'json' and not is_json(item['command']): cmd = '%s | json' % item['command'] elif item['output'] == 'text' and is_json(item['command']): cmd = item['command'].split('|')[0] else: cmd = item['command'] rc, out, err = self.exec_command(cmd) out = to_text(out, errors='surrogate_then_replace') if check_rc and rc != 0: self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace')) try: out = self._module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def handle_prompt(self, resp, cmd): for prompt in to_list(cmd['prompt']): match = re.search(prompt, resp) if match: answer = '%s\r' % cmd['response'] self.shell.sendall(answer) return True
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ output = None queue = list() responses = list() def _send(commands, output): return self.send_request(commands, output, check_status=check_rc) for item in to_list(commands): if is_json(item['command']): item['command'] = str(item['command']).split('|')[0] item['output'] = 'json' if all((output == 'json', item['output'] == 'text')) or all((output == 'text', item['output'] == 'json')): responses.extend(_send(queue, output)) queue = list() output = item['output'] or 'json' queue.append(item['command']) if queue: responses.extend(_send(queue, output)) return responses
def load_config(module, config, commit=False, comment=None, confirm=False, confirm_timeout=None): exec_command(module, 'configure') for item in to_list(config): rc, out, err = exec_command(module, item) if rc != 0: module.fail_json(msg=str(err)) exec_command(module, 'top') rc, diff, err = exec_command(module, 'show | compare') if commit: cmd = 'commit' if commit: cmd = 'commit confirmed' if confirm_timeout: cmd + ' %s' % confirm_timeout if comment: cmd += ' comment "%s"' % comment cmd += ' and-quit' exec_command(module, cmd) else: for cmd in ['rollback 0', 'exit']: exec_command(module, cmd) return str(diff).strip()
def add(self, lines, parents=None): """Adds one or lines of configuration """ ancestors = list() offset = 0 obj = None ## global config command if not parents: for line in to_list(lines): item = ConfigLine(line) item.raw = line if item not in self.items: self.items.append(item) else: for index, p in enumerate(parents): try: i = index + 1 obj = self.get_section_objects(parents[:i])[0] ancestors.append(obj) except ValueError: # add parent to config offset = index * self.indent obj = ConfigLine(p) obj.raw = p.rjust(len(p) + offset) if ancestors: obj.parents = list(ancestors) ancestors[-1].children.append(obj) self.items.append(obj) ancestors.append(obj) # add child objects for line in to_list(lines): # check if child already exists for child in ancestors[-1].children: if child.text == line: break else: offset = len(parents) * self.indent item = ConfigLine(line) item.raw = line.rjust(len(line) + offset) item.parents = ancestors ancestors[-1].children.append(item) self.items.append(item)
def run_commands(module, commands, check_rc=True): responses = list() for cmd in to_list(commands): rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc) responses.append(to_text(out, errors='surrogate_or_strict')) return responses
def to_command(self, obj): if isinstance(command, Command): cmdobj = dict() cmdobj['command'] = obj.command cmdobj['response'] = obj.response cmdobj['prompt'] = [p.pattern for p in to_list(obj.prompt)] return cmdobj return obj
def load_config(module, commands): for command in to_list(commands): rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), command=command, rc=rc) exec_command(module, 'exit all')
def execute_on_device(self, commands): responses = [] for item in to_list(commands): output = self.client.api.tm.util.bash.exec_cmd( 'run', utilCmdArgs='-c "{0}"'.format(item['command'])) if hasattr(output, 'commandResult'): responses.append(str(output.commandResult)) return responses
def send(self, commands): responses = list() for command in to_list(commands): rc, out, err = self.send_command(command) if rc != 0: raise ShellError(err) responses.append(out) return responses
def run_commands(module, commands, check_rc=True): responses = list() for cmd in to_list(commands): rc, out, err = module.exec_command(cmd) if check_rc and rc != 0: module.fail_json(msg=err, rc=rc) responses.append(out) return responses
def load_config(self, commands, return_error=False): """Sends the ordered set of commands to the device """ commands = to_list(commands) msg = self.send_request(commands, output='config', check_status=True, return_error=return_error) if return_error: return msg else: return []
def send_request(self, commands, output='text'): # only 10 show commands can be encoded in each request # messages sent to the remote device if output != 'config': commands = collections.deque(commands) stack = list() requests = list() while commands: stack.append(commands.popleft()) if len(stack) == 10: body = self._request_builder(stack, output) data = self._module.jsonify(body) requests.append(data) stack = list() if stack: body = self._request_builder(stack, output) data = self._module.jsonify(body) requests.append(data) else: requests = commands headers = {'Content-Type': 'application/json'} result = list() timeout = self._module.params['timeout'] or 10 for req in requests: if self._nxapi_auth: headers['Cookie'] = self._nxapi_auth response, headers = fetch_url(self._module, self._url, data=data, headers=headers, timeout=timeout, method='POST') self._nxapi_auth = headers.get('set-cookie') if headers['status'] != 200: self._error(**headers) try: response = self._module.from_json(response.read()) except ValueError: self._module.fail_json(msg='unable to parse response') output = response['ins_api']['outputs']['output'] for item in to_list(output): if item['code'] != '200': self._error(output=output, **item) else: result.append(item['body']) return result
def run_commands(module, commands, check_rc=True): responses = list() commands = to_commands(module, to_list(commands)) for cmd in commands: cmd = module.jsonify(cmd) rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), rc=rc) responses.append(to_text(out, errors='surrogate_then_replace')) return responses
def execute_on_device(self, commands): responses = [] for item in to_list(commands): output = self.client.api.tm.util.bash.exec_cmd( 'run', utilCmdArgs='-c "{0}"'.format(item['command']) ) if hasattr(output, 'commandResult'): responses.append(str(output.commandResult)) return responses
def execute_on_device(self, commands): responses = [] escape_patterns = r'([$' + "'])" for item in to_list(commands): command = re.sub(escape_patterns, r'\\\1', item['command']) output = self.client.api.tm.util.bash.exec_cmd( 'run', utilCmdArgs='-c "{0}"'.format(command)) if hasattr(output, 'commandResult'): responses.append(str(output.commandResult)) return responses
def execute_show_commands(module, commands, output='text'): cmds = [] for command in to_list(commands): cmd = { 'command': command, 'output': output, } cmds.append(cmd) body = run_commands(module, cmds) return body
def run_commands(module, commands, check_rc=True): responses = list() commands = to_commands(module, to_list(commands)) for cmd in commands: cmd = module.jsonify(cmd) rc, out, err = exec_command(module, cmd) if check_rc and rc != 0: module.fail_json(msg=err, rc=rc) responses.append(out) return responses
def to_command(module, commands): default_output = 'text' transform = ComplexList( dict(command=dict(key=True), output=dict(default=default_output), prompt=dict(), response=dict()), module) commands = transform(to_list(commands)) return commands
def run_commands(module, commands, check_rc=True): commands = to_commands(module, to_list(commands)) connection = get_connection(module) responses = list() for cmd in commands: out = connection.get(**cmd) responses.append(to_text(out, errors='surrogate_then_replace')) return responses
def run_commands(module, commands, check_rc=True): connection = get_connection(module) commands = to_commands(module, to_list(commands)) responses = list() for cmd in commands: out = connection.get(**cmd) responses.append(to_text(out, errors='surrogate_then_replace')) return responses
def load_config(module, commands, warnings, commit=False, replace=False, comment=None, admin=False): cmd = 'configure terminal' if admin: cmd = 'admin ' + cmd rc, out, err = exec_command(module, cmd) if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(err, errors='surrogate_or_strict')) failed = False for command in to_list(commands): if command == 'end': continue rc, out, err = exec_command(module, command) if rc != 0: failed = True break if failed: exec_command(module, 'abort') module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), commands=commands, rc=rc) rc, diff, err = exec_command(module, 'show commit changes diff') if rc != 0: # If we failed, maybe we are in an old version so # we run show configuration instead rc, diff, err = exec_command(module, 'show configuration') if module._diff: warnings.append('device platform does not support config diff') if commit: cmd = 'commit' if comment: cmd += ' comment {0}'.format(comment) else: cmd = 'abort' rc, out, err = exec_command(module, cmd) if rc != 0: exec_command(module, 'abort') module.fail_json(msg=err, commands=commands, rc=rc) return to_text(diff, errors='surrogate_or_strict')
def execute(self, commands): try: responses = list() for item in to_list(commands): item = self.to_command(item) rc, out, err = self.shell.send(item) if rc != 0: raise ShellError(err) responses.append(out) return responses except ShellError as exc: raise NetworkError(to_native(exc))
def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(err, errors='surrogate_or_strict')) for command in to_list(commands): if command == 'end': continue cmd = {'command': command, 'prompt': WARNING_PROMPTS_RE, 'answer': 'yes'} rc, out, err = exec_command(module, module.jsonify(cmd)) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), command=command, rc=rc) exec_command(module, 'end')
def load_config(module, config, commit=False): conn = get_connection(module) conn.edit_config(to_list(config) + ['top']) diff = conn.compare_configuration() if diff: if commit: commit_configuration(module) else: discard_changes(module) return str(diff).strip()
def to_command(module, commands): if is_eapi(module): default_output = 'json' else: default_output = 'text' transform = ComplexList( dict(command=dict(key=True), output=dict(default=default_output), prompt=dict(), answer=dict()), module) return transform(to_list(commands))
def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=err) for command in to_list(commands): if command == 'end': continue cmd = {'command': command, 'prompt': WARNING_PROMPTS_RE, 'answer': 'yes'} rc, out, err = exec_command(module, module.jsonify(cmd)) if rc != 0: module.fail_json(msg=err, command=command, rc=rc) exec_command(module, 'end')
def load_config(module, commands): conn = connection(module) rc, out, err = conn.exec_command('configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=err) for command in to_list(commands): if command == 'end': continue rc, out, err = conn.exec_command(command) if rc != 0: module.fail_json(msg=err, command=command, rc=rc) conn.exec_command('end')
def to_command(module, commands): if is_eapi(module): default_output = 'json' else: default_output = 'text' transform = ComplexList(dict( command=dict(key=True), output=dict(default=default_output), prompt=dict(), answer=dict() ), module) return transform(to_list(commands))
def load_config(module, commands): rc, out, err = exec_command(module, 'configure terminal') if rc != 0: module.fail_json(msg='unable to enter configuration mode', err=to_text(out, errors='surrogate_then_replace')) for command in to_list(commands): if command == 'end': continue rc, out, err = exec_command(module, command) if rc != 0: module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) exec_command(module, 'end')
def map_config_to_obj(module): out = run_commands(module, ['show user-account | json']) data = out[0] objects = list() for item in to_list(data['TABLE_template']['ROW_template']): objects.append({ 'name': item['usr_name'], 'configured_password': parse_password(item), 'sshkey': item.get('sshkey_info'), 'roles': parse_roles(item), 'state': 'present' }) return objects
def send_config(self, commands): multiline = False rc = 0 for command in to_list(commands): if command == 'end': pass if command.startswith('banner') or multiline: multiline = True command = self._module.jsonify({'command': command, 'sendonly': True}) elif command == 'EOF' and multiline: multiline = False rc, out, err = self.exec_command(command) if rc != 0: return (rc, out, to_text(err, errors='surrogate_then_replace')) return (rc, 'ok', '')
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ responses = list() for cmd in to_list(commands): rc, out, err = self.exec_command(cmd) out = to_text(out, errors='surrogate_then_replace') if check_rc and rc != 0: self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace')) try: out = self._module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def load_config(module, config, commit=False): exec_command(module, 'configure') for item in to_list(config): rc, out, err = exec_command(module, item) if rc != 0: module.fail_json(msg=str(err)) exec_command(module, 'top') rc, diff, err = exec_command(module, 'show | compare') if diff: if commit: exec_command(module, 'commit and-quit') else: for cmd in ['rollback 0', 'exit']: exec_command(module, cmd) return str(diff).strip()
def to_command(module, commands): if is_nxapi(module): default_output = 'json' else: default_output = 'text' transform = ComplexList(dict( command=dict(key=True), output=dict(default=default_output), prompt=dict(), answer=dict() ), module) commands = transform(to_list(commands)) for item in commands: if is_json(item['command']): item['output'] = 'json' return commands
def load_config(module, commands, commit=False, comment=None): rc, out, err = exec_command(module, 'configure') if rc != 0: module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_or_strict')) for cmd in to_list(commands): rc, out, err = exec_command(module, cmd) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='configuration failed') diff = None if module._diff: rc, out, err = exec_command(module, 'compare') out = to_text(out, errors='surrogate_or_strict') if not out.startswith('No changes'): rc, out, err = exec_command(module, 'show') diff = to_text(out, errors='surrogate_or_strict').strip() if commit: cmd = 'commit' if comment: cmd += ' comment "%s"' % comment rc, out, err = exec_command(module, cmd) if rc != 0: # discard any changes in case of failure exec_command(module, 'exit discard') module.fail_json(msg='commit failed: %s' % err) if not commit: exec_command(module, 'exit discard') else: exec_command(module, 'exit') if diff: return diff
def run_commands(self, commands): """Runs list of commands on remote device and returns results """ output = None queue = list() responses = list() def _send(commands, output): response = self.send_request(commands, output=output) if 'error' in response: err = response['error'] self._module.fail_json(msg=err['message'], code=err['code']) return response['result'] for item in to_list(commands): if is_json(item['command']): item['command'] = str(item['command']).replace('| json', '') item['output'] = 'json' if output and output != item['output']: responses.extend(_send(queue, output)) queue = list() output = item['output'] or 'json' queue.append(item['command']) if queue: responses.extend(_send(queue, output)) for index, item in enumerate(commands): try: responses[index] = responses[index]['output'].strip() except KeyError: pass return responses
def edit_config(self, command): for cmd in chain([b'configure'], to_list(command)): self.send_command(cmd)
def edit_config(self, command): for cmd in chain([b'configure terminal'], to_list(command), [b'end']): self.send_command(cmd)
def send_request(self, commands, output='text', check_status=True, return_error=False): # only 10 show commands can be encoded in each request # messages sent to the remote device if output != 'config': commands = collections.deque(to_list(commands)) stack = list() requests = list() while commands: stack.append(commands.popleft()) if len(stack) == 10: body = self._request_builder(stack, output) data = self._module.jsonify(body) requests.append(data) stack = list() if stack: body = self._request_builder(stack, output) data = self._module.jsonify(body) requests.append(data) else: body = self._request_builder(commands, 'config') requests = [self._module.jsonify(body)] headers = {'Content-Type': 'application/json'} result = list() timeout = self._module.params['timeout'] for req in requests: if self._nxapi_auth: headers['Cookie'] = self._nxapi_auth response, headers = fetch_url( self._module, self._url, data=req, headers=headers, timeout=timeout, method='POST' ) self._nxapi_auth = headers.get('set-cookie') if headers['status'] != 200: self._error(**headers) try: response = self._module.from_json(response.read()) except ValueError: self._module.fail_json(msg='unable to parse response') if response['ins_api'].get('outputs'): output = response['ins_api']['outputs']['output'] for item in to_list(output): if check_status and item['code'] != '200': if return_error: result.append(item) else: self._error(output=output, **item) elif 'body' in item: result.append(item['body']) # else: # error in command but since check_status is disabled # silently drop it. # result.append(item['msg']) return result