def test_to_list(): for scalar in ('string', 1, True, False, None): assert isinstance(to_list(scalar), list) for container in ([1, 2, 3], {'one': 1}): assert isinstance(to_list(container), list) test_list = [1, 2, 3] assert id(test_list) != id(to_list(test_list))
def send_request(self, commands, output='text'): commands = to_list(commands) if self._enable: commands.insert(0, self._enable) body = self._request_builder(commands, output) data = self._module.jsonify(body) headers = {'Content-Type': 'application/json-rpc'} timeout = self._module.params['timeout'] use_proxy = self._module.params['provider']['use_proxy'] response, headers = fetch_url( self._module, self._url, data=data, headers=headers, method='POST', timeout=timeout, use_proxy=use_proxy ) 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 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']).rsplit('|', 1)[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 run_command(module, commands): conn = get_connection(module) responses = list() for cmd in to_list(commands): try: if isinstance(cmd, str): cmd = json.loads(cmd) command = cmd.get('command', None) prompt = cmd.get('prompt', None) answer = cmd.get('answer', None) sendonly = cmd.get('sendonly', False) newline = cmd.get('newline', True) except: command = cmd prompt = None answer = None sendonly = False newline = True out = conn.get(command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline) try: responses.append(to_text(out, errors='surrogate_or_strict')) except UnicodeError: module.fail_json(msg=u'failed to decode output from {0}:{1}'.format(cmd, to_text(out))) return responses
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ responses = list() connection = self._get_connection() for cmd in to_list(commands): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] else: command = cmd prompt = None answer = None out = connection.get(command, prompt, answer) out = to_text(out, errors='surrogate_or_strict') try: out = self._module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def run_commands(module, commands, check_rc=True): responses = list() connection = get_connection(module) for cmd in to_list(commands): try: cmd = json.loads(cmd) command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] except: command = cmd prompt = None answer = None out = connection.get(command, prompt, answer) try: out = to_text(out, errors='surrogate_or_strict') except UnicodeError: module.fail_json(msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) responses.append(out) return responses
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 parse_roles(data): configured_roles = None if 'TABLE_role' in 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 load_config(self, commands, return_error=False, opts=None): """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, opts=opts) if return_error: return msg else: return []
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: raise F5ModuleError(to_text(err, errors='surrogate_then_replace')) result = to_text(out, errors='surrogate_then_replace') responses.append(result) return responses
def get_config(module, flags=None): flag_str = ' '.join(to_list(flags)) try: return _DEVICE_CONFIGS[flag_str] except KeyError: connection = get_connection(module) out = connection.get_config(flags=flags) cfg = to_text(out, errors='surrogate_then_replace').strip() _DEVICE_CONFIGS[flag_str] = cfg return cfg
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 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, 'end')
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 load_config(module, command_filter, commit=False, replace=False, comment=None, admin=False, running=None, nc_get_filter=None): conn = get_connection(module) diff = None if is_netconf(module): # FIXME: check for platform behaviour and restore this # conn.lock(target = 'candidate') # conn.discard_changes() try: for filter in to_list(command_filter): conn.edit_config(filter) candidate = get_config(module, source='candidate', config_filter=nc_get_filter) diff = get_config_diff(module, running, candidate) if commit and diff: commit_config(module) else: discard_config(module) finally: # conn.unlock(target = 'candidate') pass elif is_cliconf(module): # to keep the pre-cliconf behaviour, make a copy, avoid adding commands to input list cmd_filter = deepcopy(command_filter) cmd_filter.insert(0, 'configure terminal') if admin: cmd_filter.insert(0, 'admin') conn.edit_config(cmd_filter) if module._diff: diff = get_config_diff(module) if replace: cmd = list() cmd.append({'command': 'commit replace', 'prompt': 'This commit will replace or remove the entire running configuration', 'answer': 'yes'}) cmd.append('end') conn.edit_config(cmd) elif commit: commit_config(module, comment=comment) conn.edit_config('end') if admin: conn.edit_config('exit') else: conn.discard_changes() return diff
def get_config(self, source='running', format='text', flags=None): lookup = {'running': 'running-config', 'startup': 'startup-config'} if source not in lookup: return self.invalid_params("fetching configuration from %s is not supported" % source) cmd = 'show %s ' % lookup[source] if format and format is not 'text': cmd += '| %s ' % format cmd += ' '.join(to_list(flags)) cmd = cmd.strip() return self.send_command(cmd)
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, 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 execute_on_device(self, commands): responses = [] for item in to_list(commands): try: command = '-c "{0}"'.format(item['command']) output = self.client.api.tm.util.bash.exec_cmd( 'run', utilCmdArgs=command ) if hasattr(output, 'commandResult'): responses.append(str(output.commandResult).strip()) except Exception as ex: pass return responses
def edit_config(self, command): for cmd in chain(['configure terminal'], to_list(command), ['end']): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] newline = cmd.get('newline', True) else: command = cmd prompt = None answer = None newline = True self.send_command(command, prompt, answer, False, newline)
def edit_config(self, command): for cmd in chain(to_list(command)): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] newline = cmd.get('newline', True) else: command = cmd prompt = None answer = None newline = True self.send_command(to_bytes(command), to_bytes(prompt), to_bytes(answer), False, newline)
def send_config(self, commands): conn = self._get_connection() multiline = False rc = 0 for command in to_list(commands): if command == 'end': continue if command.startswith('banner') or multiline: multiline = True elif command == 'EOF' and multiline: multiline = False conn.get(command, None, None, multiline)
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 get_config(self, source='running', format='text', flags=None): if source not in ('running', 'startup'): return self.invalid_params("fetching configuration from %s is not supported" % source) if not flags: flags = [] if source == 'running': cmd = 'show running-config ' else: cmd = 'show startup-config ' cmd += ' '.join(to_list(flags)) cmd = cmd.strip() return self.send_command(cmd)
def run_commands(self, commands, check_rc=True): """Run list of commands on remote device and return results """ responses = list() connection = self._get_connection() 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'].rsplit('|', 1)[0] else: cmd = item['command'] out = '' try: out = connection.get(cmd) code = 0 except ConnectionError as e: code = getattr(e, 'code', 1) message = getattr(e, 'err', e) err = to_text(message, errors='surrogate_then_replace') try: out = to_text(out, errors='surrogate_or_strict') except UnicodeError: self._module.fail_json(msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) if check_rc and code != 0: self._module.fail_json(msg=err) if not check_rc and code != 0: try: out = self._module.from_json(err) except ValueError: out = to_text(message).strip() else: try: out = self._module.from_json(out) except ValueError: out = to_text(out).strip() responses.append(out) return responses
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 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): cmd = item['command'] rc, out, err = self.exec_command(cmd) if check_rc and rc != 0: self._module.fail_json(msg=cli_err_msg(cmd.strip(), err)) try: out = self._module.from_json(out) except ValueError: out = str(out).strip() responses.append(out) return responses
def run_commands(self, commands, check_rc=True): """Runs list of commands on remote device and returns results """ output = None queue = list() responses = list() def run_queue(queue, output): response = to_list(self.send_request(queue, output=output)) if output == 'json': response = [json.loads(item) for item in response] return response for item in to_list(commands): cmd_output = 'text' if isinstance(item, dict): command = item['command'] if 'output' in item: cmd_output = item['output'] else: command = item # Emulate '| json' from CLI if command.endswith('| json'): command = command.rsplit('|', 1)[0] cmd_output = 'json' if output and output != cmd_output: responses.extend(run_queue(queue, output)) queue = list() output = cmd_output queue.append(command) if queue: responses.extend(run_queue(queue, output)) return responses
def edit_config(self, candidate=None, commit=True, replace=None, comment=None): resp = {} operations = self.get_device_operations() self.check_edit_config_capabiltiy(operations, candidate, commit, replace, comment) results = [] requests = [] if replace: device_info = self.get_device_info() if '9K' not in device_info.get('network_os_platform', ''): raise ConnectionError( msg=u'replace is supported only on Nexus 9K devices') candidate = 'config replace {0}'.format(replace) if commit: self.send_command('configure terminal') for line in to_list(candidate): if not isinstance(line, collections.Mapping): line = {'command': line} cmd = line['command'] if cmd != 'end': results.append(self.send_command(**line)) requests.append(cmd) self.send_command('end') else: raise ValueError('check mode is not supported') resp['request'] = requests resp['response'] = results return resp
def run_commands(module, commands): """Run command list against connection. Get new or previously used connection and send commands to it one at a time, collecting response. Args: module: A valid AnsibleModule instance. commands: Iterable of command strings. Returns: A list of output strings. """ responses = list() connection = get_connection(module) for cmd in to_list(commands): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] else: command = cmd prompt = None answer = None try: out = connection.get(command, prompt, answer) out = to_text(out, errors='surrogate_or_strict') except ConnectionError as exc: module.fail_json(msg=to_text(exc)) except UnicodeError: module.fail_json(msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) responses.append(out) return responses
def render(self, config=None): commands = list() safe_list = list() router_context = 'router bgp %s' % self.get_value('config.bgp_as') context_config = None for item in self.get_value('config.address_family'): context = 'address-family %s' % item['afi'] if item['safi'] != 'unicast': context += ' %s' % item['safi'] context_commands = list() if config: context_path = [router_context, context] context_config = self.get_config_context(config, context_path, indent=1) for key, value in iteritems(item): if value is not None: meth = getattr(self, '_render_%s' % key, None) if meth: resp = meth(item, context_config) if resp: context_commands.extend(to_list(resp)) if context_commands: commands.append(context) commands.extend(context_commands) commands.append('exit-address-family') safe_list.append(context) if self.params['operation'] == 'replace': if config: resp = self._negate_config(config, safe_list) commands.extend(resp) return commands
def send_request(self, data, **message_kwargs): data = to_list(data) if self._become: display.vvvv('firing event: on_become') data.insert(0, {"cmd": "enable", "input": self._become_pass}) output = message_kwargs.get('output', 'text') request = request_builder(data, output) headers = {'Content-Type': 'application/json-rpc'} response = self.connection.send('/command-api', request, headers=headers, method='POST') response = json.loads(to_text(response.read())) results = handle_response(response) if self._become: results = results[1:] if len(results) == 1: results = results[0] return results
def compare(self, parsers, want=None, have=None): """ compare """ if want is None: want = self.want if have is None: have = self.have for parser in to_list(parsers): compval = self.get_parser(parser).get('compval') if not compval: compval = parser inw = get_from_dict(want, compval) inh = get_from_dict(have, compval) if inw is not None and inw != inh: if isinstance(inw, bool): self.addcmd(want, parser, not inw) else: self.addcmd(want, parser, False) elif inw is None and inh is not None: if isinstance(inh, bool): self.addcmd(have, parser, inh) else: self.addcmd(have, parser, True)
def edit_config(self, candidate=None, commit=True, replace=None, comment=None): resp = {} results = [] requests = [] if commit: self.send_command('configure terminal') for line in to_list(candidate): if not isinstance(line, Mapping): line = {'command': line} cmd = line['command'] if cmd != 'end' and cmd[0] != '!': results.append(self.send_command(**line)) requests.append(cmd) self.send_command('end') else: raise ValueError('check mode is not supported') resp['request'] = requests resp['response'] = results return resp
def show_cmd(module, cmd, json_fmt=True, fail_on_error=True): if json_fmt: cmd += " | json-print" conn = get_connection(module) command_obj = to_commands(module, to_list(cmd))[0] try: out = conn.get(**command_obj) except ConnectionError: if fail_on_error: raise return None if json_fmt: out = _parse_json_output(out) try: cfg = json.loads(out) except ValueError: module.fail_json( msg="got invalid json", stderr=to_text(out, errors='surrogate_then_replace')) else: cfg = to_text(out, errors='surrogate_then_replace').strip() return cfg
def show_cmd(module, cmd, json_fmt=True, fail_on_error=True): if json_fmt: cmd += " | json-print" conn = get_connection(module) command_obj = to_commands(module, to_list(cmd))[0] try: out = conn.get(**command_obj) except ConnectionError: if fail_on_error: raise return None if json_fmt: out = _parse_json_output(out) try: cfg = json.loads(out) except ValueError: module.fail_json( msg="got invalid json", stderr=to_text(out, errors='surrogate_then_replace')) else: cfg = to_text(out, errors='surrogate_then_replace').strip() return cfg
def set_config(self, existing_acl_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ want = self._module.params['config'] if want: for item in want: item['name'] = normalize_interface(item['name']) if 'members' in want and want['members']: for item in want['members']: item.update({ 'member': normalize_interface(item['member']), 'mode': item['mode'] }) have = existing_acl_interfaces_facts resp = self.set_state(want, have) return to_list(resp)
def run_commands(module, commands, check_rc=True): responses = list() connection = get_connection(module) for cmd in to_list(commands): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] else: command = cmd prompt = None answer = None out = connection.get(command, prompt, answer) try: out = to_text(out, errors='surrogate_or_strict') except UnicodeError: module.fail_json(msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) responses.append(out) return responses
def run_commands(module): commands = module.params['commands'] commands = to_list(commands) pause = module.params['pause'] responses = list() for i, cmd in enumerate(commands): if isinstance(cmd, dict): command = cmd.get('command', '') prompt = cmd.get('prompt', None) answer = cmd.get('answer', None) else: command = cmd prompt = None answer = None out = send_and_wait(module, command, prompt=prompt, answer=answer) responses.append(out) if i != len(commands) - 1: sleep(pause) return responses
def render(self, config=None): commands = list() context = 'router bgp %s' % self.bgp_as if self.state in ('absent', 'replace'): bgp_as = get_bgp_as(config) if bgp_as: commands.append('no router bgp %s' % bgp_as) if self.state == 'replace': commands.append(context) if self.state in ('present', 'replace'): for attr in self.argument_spec: if attr in self.values: meth = getattr(self, '_set_%s' % attr, None) if meth: resp = meth(config) if resp: if not commands: commands.append(context) commands.extend(to_list(resp)) return commands
def to_command(module, commands): if is_local_nxapi(module): default_output = 'json' else: default_output = 'text' transform = ComplexList( dict( command=dict(key=True), output=dict(default=default_output), prompt=dict(type='list'), answer=dict(type='list'), sendonly=dict(type='bool', default=False), check_all=dict(type='bool', default=False), ), module) commands = transform(to_list(commands)) for item in commands: if is_json(item['command']): item['output'] = 'json' return commands
def run_command(module, commands): conn = get_connection(module) responses = list() for cmd in to_list(commands): try: cmd = json.loads(cmd) command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] except: command = cmd prompt = None answer = None out = conn.get(command, prompt, answer) try: responses.append(to_text(out, errors='surrogate_or_strict')) except UnicodeError: module.fail_json( msg=u'failed to decode output from {0}:{1}'.format( cmd, to_text(out))) return responses
def run_commands(self, commands, check_rc=True, return_timestamps=False): """Runs list of commands on remote device and returns results """ try: out = self._connection.send_request(commands) except ConnectionError as exc: if check_rc is True: raise out = to_text(exc) out = to_list(out) if not out[0]: return out for index, response in enumerate(out): if response[0] == '{': out[index] = json.loads(response) if return_timestamps: # workaround until timestamps are implemented return out, list() else: return out
def run_commands(self, commands=None, check_rc=True): if commands is None: raise ValueError("'commands' value is required") responses = list() for cmd in to_list(commands): if not isinstance(cmd, collections.Mapping): cmd = {'command': cmd} output = cmd.pop('output', None) if output: raise ValueError("'output' value %s is not supported for run_commands" % output) try: out = self.send_command(**cmd) except AnsibleConnectionFailure as e: if check_rc: raise out = getattr(e, 'err', e) responses.append(out) return responses
def set_config(self, existing_lag_interfaces_facts): """ Collect the configuration from the args passed to the module, collect the current configuration (as a dict from facts) :rtype: A list :returns: the commands necessary to migrate the current configuration to the desired configuration """ want = self._module.params["config"] if want: for item in want: item["name"] = normalize_interface(item["name"]) if "members" in want and want["members"]: for item in want["members"]: item.update({ "member": normalize_interface(item["member"]), "mode": item["mode"], }) have = existing_lag_interfaces_facts resp = self.set_state(want, have) return to_list(resp)
def render(self, config=None): commands = list() safe_list = list() router_context = "router bgp %s" % self.get_value("config.bgp_as") context_config = None for item in self.get_value("config.address_family"): context = "address-family %s %s" % (item["afi"], item["safi"]) context_commands = list() if config: context_path = [router_context, context] context_config = self.get_config_context(config, context_path, indent=1) for key, value in iteritems(item): if value is not None: meth = getattr(self, "_render_%s" % key, None) if meth: resp = meth(item, context_config) if resp: context_commands.extend(to_list(resp)) if context_commands: commands.append(context) commands.extend(context_commands) commands.append("exit") safe_list.append(context) if config: resp = self._negate_config(config, safe_list) commands.extend(resp) return commands
def execute_module(self): """ Execute the module :rtype: A dictionary :returns: The result from module execution """ result = {'changed': False} warnings = list() existing_vlans_facts = self.get_vlans_facts() config_xmls = self.set_config(existing_vlans_facts) with locked_config(self._module): for config_xml in to_list(config_xmls): diff = load_config(self._module, config_xml, warnings) commit = not self._module.check_mode if diff: if commit: commit_configuration(self._module) else: discard_changes(self._module) result['changed'] = True if self._module._diff: result['diff'] = {'prepared': diff} result['commands'] = config_xmls changed_vlans_facts = self.get_vlans_facts() result['before'] = existing_vlans_facts if result['changed']: result['after'] = changed_vlans_facts result['warnings'] = warnings return result
def edit_config(self, candidate=None, commit=True, replace=None, comment=None): resp = {} operations = self.get_device_operations() self.check_edit_config_capability(operations, candidate, commit, replace, comment) results = [] requests = [] if commit: prompt = self._connection.get_prompt() if (b'(config-if' in prompt) or (b'(config' in prompt) or (b'(config-lag-if' in prompt): self.send_command('end') self.send_command('configure terminal') for line in to_list(candidate): if not isinstance(line, collections.Mapping): line = {'command': line} cmd = line['command'] if cmd != 'end' and cmd[0] != '!': results.append(self.send_command(**line)) requests.append(cmd) self.send_command('end') else: raise ValueError('check mode is not supported') resp['request'] = requests resp['response'] = results return resp
def edit_config(self, candidate=None, commit=True, admin=False, replace=None, comment=None, label=None): operations = self.get_device_operations() self.check_edit_config_capability(operations, candidate, commit, replace, comment) resp = {} results = [] requests = [] self.configure(admin=admin) if replace: candidate = 'load {0}'.format(replace) for line in to_list(candidate): if not isinstance(line, Mapping): line = {'command': line} cmd = line['command'] results.append(self.send_command(**line)) requests.append(cmd) if commit: self.commit(comment=comment, label=label, replace=replace) else: self.discard_changes() self.abort(admin=admin) resp['request'] = requests resp['response'] = results return resp
def execute_module(self): """ Execute the module :rtype: A dictionary :returns: The result from module execution """ result = {"changed": False} warnings = list() existing_interfaces_facts = self.get_l3_interfaces_facts() config_xmls = self.set_config(existing_interfaces_facts) with locked_config(self._module): for config_xml in to_list(config_xmls): diff = load_config(self._module, config_xml, warnings) commit = not self._module.check_mode if diff: if commit: commit_configuration(self._module) else: discard_changes(self._module) result["changed"] = True if self._module._diff: result["diff"] = {"prepared": diff} result["xml"] = config_xmls changed_interfaces_facts = self.get_l3_interfaces_facts() result["before"] = existing_interfaces_facts if result["changed"]: result["after"] = changed_interfaces_facts result["warnings"] = warnings return result
def edit_config(self, candidate=None, commit=True, replace=None, comment=None): resp = {} operations = self.get_device_operations() self.check_edit_config_capabiltiy(operations, candidate, commit, replace, comment) results = [] requests = [] self.send_command('configure') for cmd in to_list(candidate): if not isinstance(cmd, collections.Mapping): cmd = {'command': cmd} results.append(self.send_command(**cmd)) requests.append(cmd['command']) out = self.get('compare') out = to_text(out, errors='surrogate_or_strict') diff_config = out if not out.startswith('No changes') else None if diff_config: if commit: try: self.commit(comment) except AnsibleConnectionFailure as e: msg = 'commit failed: %s' % e.message self.discard_changes() raise AnsibleConnectionFailure(msg) else: self.send_command('exit') else: self.discard_changes() else: self.send_command('exit') resp['diff'] = diff_config resp['response'] = results resp['request'] = requests return resp
def send_request(self, commands, output='text'): commands = to_list(commands) if self._enable: commands.insert(0, self._enable) body = self._request_builder(commands, output) data = self._module.jsonify(body) headers = {'Content-Type': 'application/json-rpc'} timeout = self._module.params['timeout'] use_proxy = self._module.params['provider']['use_proxy'] response, headers = fetch_url(self._module, self._url, data=data, headers=headers, method='POST', timeout=timeout, use_proxy=use_proxy) 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 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 do_lines_template(self, template, join=False, when=None, required=False): templated_lines = list() _processed = list() if when is not None: if not self._check_conditional(when, self.ds): display.vvv("skipping due to conditional failure") return templated_lines for line in to_list(template): res = self.template(line, self.ds) if res: _processed.append(res) elif not res and join: break if required and not _processed: raise AnsibleError('unabled to templated required line') elif _processed and join: templated_lines.append(' '.join(_processed)) elif _processed: templated_lines.extend(_processed) return templated_lines
def load_config(self, commands, return_error=False, opts=None, replace=None): """Sends the ordered set of commands to the device """ if replace: device_info = self.get_device_info() if '9K' not in device_info.get('network_os_platform', ''): self._module.fail_json( msg='replace is supported only on Nexus 9K devices') commands = 'config replace {0}'.format(replace) commands = to_list(commands) msg = self.send_request(commands, output='config', check_status=True, return_error=return_error, opts=opts) if return_error: return msg else: return []
def run_commands(self, commands, check_rc=True): """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 run_commands(self, commands=None, check_rc=True): if commands is None: raise ValueError("'commands' value is required") responses = list() for cmd in to_list(commands): if not isinstance(cmd, Mapping): cmd = {'command': cmd} output = cmd.pop('output', None) if output: raise ValueError( "'output' value %s is not supported for run_commands" % output) try: out = self.send_command(**cmd) except AnsibleConnectionFailure as e: if check_rc: raise out = getattr(e, 'err', e) if out is not None: try: out = to_text(out, errors='surrogate_or_strict').strip() except UnicodeError: raise ConnectionError( message=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) try: out = json.loads(out) except ValueError: pass responses.append(out) return responses
def get_config(module, flags=None): flags = to_list(flags) section_filter = False if flags and 'section' in flags[-1]: section_filter = True flag_str = ' '.join(flags) try: return _DEVICE_CONFIGS[flag_str] except KeyError: connection = get_connection(module) try: out = connection.get_config(flags=flags) except ConnectionError as exc: if section_filter: # Some ios devices don't understand `| section foo` out = get_config(module, flags=flags[:-1]) else: module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) cfg = to_text(out, errors='surrogate_then_replace').strip() _DEVICE_CONFIGS[flag_str] = cfg return cfg
def execute_on_device(self, commands): responses = [] uri = "https://{0}:{1}/mgmt/tm/util/bash".format( self.client.provider['server'], self.client.provider['server_port'], ) for item in to_list(commands): try: args = dict(command='run', utilCmdArgs='-c "{0}"'.format(item['command'])) resp = self.client.api.post(uri, json=args) response = resp.json() if 'commandResult' in response: output = u'{0}'.format(response['commandResult']) responses.append(output.strip()) except ValueError as ex: raise F5ModuleError(str(ex)) if 'code' in response and response['code'] == 400: if 'message' in response: raise F5ModuleError(response['message']) else: raise F5ModuleError(resp.content) return responses
def run_commands(module, commands): """Run command list against connection. Get new or previously used connection and send commands to it one at a time, collecting response. Args: module: A valid AnsibleModule instance. commands: Iterable of command strings. Returns: A list of output strings. """ responses = list() connection = get_connection(module) for cmd in to_list(commands): if isinstance(cmd, dict): command = cmd['command'] prompt = cmd['prompt'] answer = cmd['answer'] else: command = cmd prompt = None answer = None out = connection.get(command, prompt, answer) try: out = to_text(out, errors='surrogate_or_strict') except UnicodeError: module.fail_json(msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) responses.append(out) return responses