diff options
Diffstat (limited to 'lib/ansible/plugins')
-rw-r--r-- | lib/ansible/plugins/action/iosxr.py | 106 | ||||
-rw-r--r-- | lib/ansible/plugins/cliconf/iosxr.py | 276 | ||||
-rw-r--r-- | lib/ansible/plugins/doc_fragments/iosxr.py | 65 | ||||
-rw-r--r-- | lib/ansible/plugins/netconf/iosxr.py | 214 | ||||
-rw-r--r-- | lib/ansible/plugins/terminal/iosxr.py | 52 |
5 files changed, 0 insertions, 713 deletions
diff --git a/lib/ansible/plugins/action/iosxr.py b/lib/ansible/plugins/action/iosxr.py deleted file mode 100644 index f5fa86aeda..0000000000 --- a/lib/ansible/plugins/action/iosxr.py +++ /dev/null @@ -1,106 +0,0 @@ -# -# (c) 2016 Red Hat Inc. -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import sys -import copy - -from ansible.module_utils.network.iosxr.iosxr import iosxr_provider_spec -from ansible.plugins.action.network import ActionModule as ActionNetworkModule -from ansible.module_utils.network.common.utils import load_provider -from ansible.utils.display import Display - -display = Display() - - -class ActionModule(ActionNetworkModule): - - def run(self, tmp=None, task_vars=None): - del tmp # tmp no longer has any effect - - module_name = self._task.action.split('.')[-1] - self._config_module = True if module_name == 'iosxr_config' else False - force_cli = module_name in ('iosxr_netconf', 'iosxr_config', 'iosxr_command', 'iosxr_facts') - persistent_connection = self._play_context.connection.split('.')[-1] - warnings = [] - - if self._play_context.connection == 'local': - provider = load_provider(iosxr_provider_spec, self._task.args) - pc = copy.deepcopy(self._play_context) - pc.network_os = 'cisco.iosxr.iosxr' - if force_cli or provider['transport'] == 'cli': - pc.connection = 'ansible.netcommon.network_cli' - pc.port = int(provider['port'] or self._play_context.port or 22) - elif provider['transport'] == 'netconf': - pc.connection = 'ansible.netcommon.netconf' - pc.port = int(provider['port'] or self._play_context.port or 830) - else: - return {'failed': True, 'msg': 'Transport type %s is not valid for this module' % provider['transport']} - - pc.remote_addr = provider['host'] or self._play_context.remote_addr - pc.port = int(provider['port'] or self._play_context.port or 22) - pc.remote_user = provider['username'] or self._play_context.connection_user - pc.password = provider['password'] or self._play_context.password - - connection = self._shared_loader_obj.connection_loader.get('ansible.netcommon.persistent', pc, sys.stdin, - task_uuid=self._task._uuid) - - # TODO: Remove below code after ansible minimal is cut out - if connection is None: - pc.network_os = 'iosxr' - if pc.connection.split('.')[-1] == 'netconf': - pc.connection = 'netconf' - else: - pc.connection = 'network_cli' - - connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin, task_uuid=self._task._uuid) - - display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr) - - command_timeout = int(provider['timeout']) if provider['timeout'] else connection.get_option('persistent_command_timeout') - connection.set_options(direct={'persistent_command_timeout': command_timeout}) - - socket_path = connection.run() - display.vvvv('socket_path: %s' % socket_path, pc.remote_addr) - if not socket_path: - return {'failed': True, - 'msg': 'unable to open shell. Please see: ' + - 'https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell'} - - task_vars['ansible_socket'] = socket_path - warnings.append(['connection local support for this module is deprecated and will be removed in version 2.14, use connection %s' % pc.connection]) - elif persistent_connection in ('netconf', 'network_cli'): - if force_cli and persistent_connection != 'network_cli': - return {'failed': True, 'msg': 'Connection type %s is not valid for module %s' % - (self._play_context.connection, module_name)} - provider = self._task.args.get('provider', {}) - if any(provider.values()): - display.warning('provider is unnecessary when using {0} and will be ignored'.format(self._play_context.connection)) - del self._task.args['provider'] - else: - return {'failed': True, 'msg': 'Connection type %s is not valid for this module' % self._play_context.connection} - - result = super(ActionModule, self).run(task_vars=task_vars) - if warnings: - if 'warnings' in result: - result['warnings'].extend(warnings) - else: - result['warnings'] = warnings - return result diff --git a/lib/ansible/plugins/cliconf/iosxr.py b/lib/ansible/plugins/cliconf/iosxr.py deleted file mode 100644 index d4524f88e4..0000000000 --- a/lib/ansible/plugins/cliconf/iosxr.py +++ /dev/null @@ -1,276 +0,0 @@ -# -# (c) 2017 Red Hat Inc. -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = """ ---- -author: Ansible Networking Team -cliconf: iosxr -short_description: Use iosxr cliconf to run command on Cisco IOS XR platform -description: - - This iosxr plugin provides low level abstraction apis for - sending and receiving CLI commands from Cisco IOS XR network devices. -version_added: "2.4" -""" - -import re -import json - -from ansible.errors import AnsibleConnectionFailure -from ansible.module_utils._text import to_text -from ansible.module_utils.common._collections_compat import Mapping -from ansible.module_utils.connection import ConnectionError -from ansible.module_utils.network.common.config import NetworkConfig, dumps -from ansible.module_utils.network.common.utils import to_list -from ansible.module_utils.network.iosxr.iosxr import sanitize_config, mask_config_blocks_from_diff -from ansible.plugins.cliconf import CliconfBase - - -class Cliconf(CliconfBase): - - def get_device_info(self): - device_info = {} - - device_info['network_os'] = 'iosxr' - reply = self.get('show version | utility head -n 20') - data = to_text(reply, errors='surrogate_or_strict').strip() - - match = re.search(r'Version (\S+)$', data, re.M) - if match: - device_info['network_os_version'] = match.group(1) - - match = re.search(r'image file is "(.+)"', data) - if match: - device_info['network_os_image'] = match.group(1) - - model_search_strs = [r'^[Cc]isco (.+) \(revision', r'^[Cc]isco (\S+ \S+).+bytes of .*memory'] - for item in model_search_strs: - match = re.search(item, data, re.M) - if match: - device_info['network_os_model'] = match.group(1) - break - - match = re.search(r'^(.+) uptime', data, re.M) - if match: - device_info['network_os_hostname'] = match.group(1) - - return device_info - - def configure(self, admin=False, exclusive=False): - prompt = to_text(self._connection.get_prompt(), errors='surrogate_or_strict').strip() - if not prompt.endswith(')#'): - if admin and 'admin-' not in prompt: - self.send_command('admin') - if exclusive: - self.send_command('configure exclusive') - return - self.send_command('configure terminal') - - def abort(self, admin=False): - prompt = to_text(self._connection.get_prompt(), errors='surrogate_or_strict').strip() - if prompt.endswith(')#'): - self.send_command('abort') - if admin and 'admin-' in prompt: - self.send_command('exit') - - def get_config(self, source='running', format='text', flags=None): - if source not in ['running']: - raise ValueError("fetching configuration from %s is not supported" % source) - - lookup = {'running': 'running-config'} - - cmd = 'show {0} '.format(lookup[source]) - cmd += ' '.join(to_list(flags)) - cmd = cmd.strip() - - return self.send_command(cmd) - - def edit_config(self, candidate=None, commit=True, admin=False, exclusive=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, exclusive=exclusive) - - 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) - - # Before any commit happend, we can get a real configuration - # diff from the device and make it available by the iosxr_config module. - # This information can be usefull either in check mode or normal mode. - resp['show_commit_config_diff'] = self.get('show commit changes diff') - - 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 get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'): - diff = {} - device_operations = self.get_device_operations() - option_values = self.get_option_values() - - if candidate is None and device_operations['supports_generate_diff']: - raise ValueError("candidate configuration is required to generate diff") - - if diff_match not in option_values['diff_match']: - raise ValueError("'match' value %s in invalid, valid values are %s" % (diff_match, ', '.join(option_values['diff_match']))) - - if diff_replace not in option_values['diff_replace']: - raise ValueError("'replace' value %s in invalid, valid values are %s" % (diff_replace, ', '.join(option_values['diff_replace']))) - - # prepare candidate configuration - sanitized_candidate = sanitize_config(candidate) - candidate_obj = NetworkConfig(indent=1) - candidate_obj.load(sanitized_candidate) - - if running and diff_match != 'none': - # running configuration - running = mask_config_blocks_from_diff(running, candidate, "ansible") - running = sanitize_config(running) - - running_obj = NetworkConfig(indent=1, contents=running, ignore_lines=diff_ignore_lines) - configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace) - - else: - configdiffobjs = candidate_obj.items - - diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else '' - return diff - - def get(self, command=None, prompt=None, answer=None, sendonly=False, newline=True, output=None, check_all=False): - if output: - raise ValueError("'output' value %s is not supported for get" % output) - return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline, check_all=check_all) - - def commit(self, comment=None, label=None, replace=None): - cmd_obj = {} - if replace: - cmd_obj['command'] = 'commit replace' - cmd_obj['prompt'] = 'This commit will replace or remove the entire running configuration' - cmd_obj['answer'] = 'yes' - else: - if comment and label: - cmd_obj['command'] = 'commit label {0} comment {1}'.format(label, comment) - elif comment: - cmd_obj['command'] = 'commit comment {0}'.format(comment) - elif label: - cmd_obj['command'] = 'commit label {0}'.format(label) - else: - cmd_obj['command'] = 'commit show-error' - # In some cases even a normal commit, i.e., !replace, - # throws a prompt and we need to handle it before - # proceeding further - cmd_obj['prompt'] = '(C|c)onfirm' - cmd_obj['answer'] = 'y' - - self.send_command(**cmd_obj) - - 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 discard_changes(self): - self.send_command('abort') - - def get_device_operations(self): - return { - 'supports_diff_replace': True, - 'supports_commit': True, - 'supports_rollback': False, - 'supports_defaults': False, - 'supports_onbox_diff': False, - 'supports_commit_comment': True, - 'supports_multiline_delimiter': False, - 'supports_diff_match': True, - 'supports_diff_ignore_lines': True, - 'supports_generate_diff': True, - 'supports_replace': True, - 'supports_admin': True, - 'supports_commit_label': True - } - - def get_option_values(self): - return { - 'format': ['text'], - 'diff_match': ['line', 'strict', 'exact', 'none'], - 'diff_replace': ['line', 'block', 'config'], - 'output': [] - } - - def get_capabilities(self): - result = super(Cliconf, self).get_capabilities() - result['rpc'] += ['commit', 'discard_changes', 'get_diff', 'configure', 'exit'] - result['device_operations'] = self.get_device_operations() - result.update(self.get_option_values()) - return json.dumps(result) - - def set_cli_prompt_context(self): - """ - Make sure we are in the operational cli mode - :return: None - """ - if self._connection.connected: - self._update_cli_prompt_context(config_context=')#', exit_command='abort') diff --git a/lib/ansible/plugins/doc_fragments/iosxr.py b/lib/ansible/plugins/doc_fragments/iosxr.py deleted file mode 100644 index 5c1b31aed0..0000000000 --- a/lib/ansible/plugins/doc_fragments/iosxr.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -class ModuleDocFragment(object): - - # Standard files documentation fragment - DOCUMENTATION = r''' -options: - provider: - description: - - B(Deprecated) - - "Starting with Ansible 2.5 we recommend using C(connection: network_cli)." - - For more information please see the L(Network Guide, ../network/getting_started/network_differences.html#multiple-communication-protocols). - - HORIZONTALLINE - - A dict object containing connection details. - type: dict - suboptions: - host: - description: - - Specifies the DNS host name or address for connecting to the remote - device over the specified transport. The value of host is used as - the destination address for the transport. - type: str - required: true - port: - description: - - Specifies the port to use when building the connection to the remote device. - type: int - default: 22 - username: - description: - - Configures the username to use to authenticate the connection to - the remote device. This value is used to authenticate - the SSH session. If the value is not specified in the task, the - value of environment variable C(ANSIBLE_NET_USERNAME) will be used instead. - type: str - password: - description: - - Specifies the password to use to authenticate the connection to - the remote device. This value is used to authenticate - the SSH session. If the value is not specified in the task, the - value of environment variable C(ANSIBLE_NET_PASSWORD) will be used instead. - type: str - timeout: - description: - - Specifies the timeout in seconds for communicating with the network device - for either connecting or sending commands. If the timeout is - exceeded before the operation is completed, the module will error. - type: int - default: 10 - ssh_keyfile: - description: - - Specifies the SSH key to use to authenticate the connection to - the remote device. This value is the path to the - key used to authenticate the SSH session. If the value is not specified - in the task, the value of environment variable C(ANSIBLE_NET_SSH_KEYFILE) - will be used instead. - type: path -notes: - - For more information on using Ansible to manage network devices see the :ref:`Ansible Network Guide <network_guide>` - - For more information on using Ansible to manage Cisco devices see the `Cisco integration page <https://www.ansible.com/integrations/networks/cisco>`_. -''' diff --git a/lib/ansible/plugins/netconf/iosxr.py b/lib/ansible/plugins/netconf/iosxr.py deleted file mode 100644 index 228c5828ab..0000000000 --- a/lib/ansible/plugins/netconf/iosxr.py +++ /dev/null @@ -1,214 +0,0 @@ -# -# (c) 2017 Red Hat Inc. -# (c) 2017 Kedar Kekan (kkekan@redhat.com) -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = """ ---- -author: Ansible Networking Team -netconf: iosxr -short_description: Use iosxr netconf plugin to run netconf commands on Cisco IOSXR platform -description: - - This iosxr plugin provides low level abstraction apis for - sending and receiving netconf commands from Cisco iosxr network devices. -version_added: "2.9" -options: - ncclient_device_handler: - type: str - default: iosxr - description: - - Specifies the ncclient device handler name for Cisco iosxr network os. To - identify the ncclient device handler name refer ncclient library documentation. -""" - -import json -import re -import collections - -from ansible.module_utils._text import to_native -from ansible.module_utils.network.common.netconf import remove_namespaces -from ansible.module_utils.network.iosxr.iosxr import build_xml, etree_find -from ansible.errors import AnsibleConnectionFailure -from ansible.plugins.netconf import NetconfBase, ensure_ncclient - -try: - from ncclient import manager - from ncclient.operations import RPCError - from ncclient.transport.errors import SSHUnknownHostError - from ncclient.xml_ import to_xml - HAS_NCCLIENT = True -except (ImportError, AttributeError): # paramiko and gssapi are incompatible and raise AttributeError not ImportError - HAS_NCCLIENT = False - - -class Netconf(NetconfBase): - def get_device_info(self): - device_info = {} - device_info['network_os'] = 'iosxr' - install_meta = collections.OrderedDict() - install_meta.update([ - ('boot-variables', {'xpath': 'install/boot-variables', 'tag': True}), - ('boot-variable', {'xpath': 'install/boot-variables/boot-variable', 'tag': True, 'lead': True}), - ('software', {'xpath': 'install/software', 'tag': True}), - ('alias-devices', {'xpath': 'install/software/alias-devices', 'tag': True}), - ('alias-device', {'xpath': 'install/software/alias-devices/alias-device', 'tag': True}), - ('m:device-name', {'xpath': 'install/software/alias-devices/alias-device/device-name', 'value': 'disk0:'}), - ]) - - install_filter = build_xml('install', install_meta, opcode='filter') - try: - reply = self.get(install_filter) - resp = remove_namespaces(re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', '', reply)) - ele_boot_variable = etree_find(resp, 'boot-variable/boot-variable') - if ele_boot_variable is not None: - device_info['network_os_image'] = re.split('[:|,]', ele_boot_variable.text)[1] - ele_package_name = etree_find(reply, 'package-name') - if ele_package_name is not None: - device_info['network_os_package'] = ele_package_name.text - device_info['network_os_version'] = re.split('-', ele_package_name.text)[-1] - - hostname_filter = build_xml('host-names', opcode='filter') - reply = self.get(hostname_filter) - resp = remove_namespaces(re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', '', reply)) - hostname_ele = etree_find(resp.strip(), 'host-name') - device_info['network_os_hostname'] = hostname_ele.text if hostname_ele is not None else None - except Exception as exc: - self._connection.queue_message('vvvv', 'Fail to retrieve device info %s' % exc) - return device_info - - def get_capabilities(self): - result = dict() - result['rpc'] = self.get_base_rpc() - result['network_api'] = 'netconf' - result['device_info'] = self.get_device_info() - result['server_capabilities'] = [c for c in self.m.server_capabilities] - result['client_capabilities'] = [c for c in self.m.client_capabilities] - result['session_id'] = self.m.session_id - result['device_operations'] = self.get_device_operations(result['server_capabilities']) - return json.dumps(result) - - @staticmethod - @ensure_ncclient - def guess_network_os(obj): - """ - Guess the remote network os name - :param obj: Netconf connection class object - :return: Network OS name - """ - try: - m = manager.connect( - host=obj._play_context.remote_addr, - port=obj._play_context.port or 830, - username=obj._play_context.remote_user, - password=obj._play_context.password, - key_filename=obj.key_filename, - hostkey_verify=obj.get_option('host_key_checking'), - look_for_keys=obj.get_option('look_for_keys'), - allow_agent=obj._play_context.allow_agent, - timeout=obj.get_option('persistent_connect_timeout'), - # We need to pass in the path to the ssh_config file when guessing - # the network_os so that a jumphost is correctly used if defined - ssh_config=obj._ssh_config - ) - except SSHUnknownHostError as exc: - raise AnsibleConnectionFailure(to_native(exc)) - - guessed_os = None - for c in m.server_capabilities: - if re.search('IOS-XR', c): - guessed_os = 'iosxr' - break - - m.close_session() - return guessed_os - - # TODO: change .xml to .data_xml, when ncclient supports data_xml on all platforms - def get(self, filter=None, remove_ns=False): - if isinstance(filter, list): - filter = tuple(filter) - try: - resp = self.m.get(filter=filter) - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) - - def get_config(self, source=None, filter=None, remove_ns=False): - if isinstance(filter, list): - filter = tuple(filter) - try: - resp = self.m.get_config(source=source, filter=filter) - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) - - def edit_config(self, config=None, format='xml', target='candidate', default_operation=None, test_option=None, error_option=None, remove_ns=False): - if config is None: - raise ValueError('config value must be provided') - try: - resp = self.m.edit_config(config, format=format, target=target, default_operation=default_operation, test_option=test_option, - error_option=error_option) - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) - - def commit(self, confirmed=False, timeout=None, persist=None, remove_ns=False): - try: - resp = self.m.commit(confirmed=confirmed, timeout=timeout, persist=persist) - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) - - def validate(self, source="candidate", remove_ns=False): - try: - resp = self.m.validate(source=source) - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) - - def discard_changes(self, remove_ns=False): - try: - resp = self.m.discard_changes() - if remove_ns: - response = remove_namespaces(resp) - else: - response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml - return response - except RPCError as exc: - raise Exception(to_xml(exc.xml)) diff --git a/lib/ansible/plugins/terminal/iosxr.py b/lib/ansible/plugins/terminal/iosxr.py deleted file mode 100644 index 20b001ab16..0000000000 --- a/lib/ansible/plugins/terminal/iosxr.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# (c) 2016 Red Hat Inc. -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see <http://www.gnu.org/licenses/>. -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import re - -from ansible.plugins.terminal import TerminalBase -from ansible.errors import AnsibleConnectionFailure - - -class TerminalModule(TerminalBase): - - terminal_stdout_re = [ - re.compile(br"[\r\n]*[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), - re.compile(br']]>]]>[\r\n]?') - ] - - terminal_stderr_re = [ - re.compile(br"% ?Error"), - re.compile(br"% ?Bad secret"), - re.compile(br"% ?This command is not authorized"), - re.compile(br"invalid input", re.I), - re.compile(br"(?:incomplete|ambiguous) command", re.I), - re.compile(br"(?<!\()connection timed out(?!\))", re.I), - re.compile(br"[^\r\n]+ not found", re.I), - re.compile(br"'[^']' +returned error code: ?\d+"), - re.compile(br"Failed to commit", re.I) - ] - - def on_open_shell(self): - try: - for cmd in (b'terminal length 0', b'terminal width 512', b'terminal exec prompt no-timestamp'): - self._exec_cli_command(cmd) - except AnsibleConnectionFailure: - raise AnsibleConnectionFailure('unable to set terminal parameters') |