From a6cecef6bc175ec739cf079c76f02d0fabb80c99 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Fri, 17 Feb 2017 10:00:23 -0500 Subject: [PATCH] clean up of terminal plugins (#21549) * removes unneeded supports_multiplexing var * refactors terminal_prompts_re to terminal_stdout_re * refactors terminal_errors_re to terminal_stderr_re * updates network_cli unit test cases --- lib/ansible/plugins/connection/network_cli.py | 22 ++++--------------- lib/ansible/plugins/terminal/__init__.py | 10 ++------- lib/ansible/plugins/terminal/asa.py | 4 ++-- lib/ansible/plugins/terminal/eos.py | 4 ++-- lib/ansible/plugins/terminal/ios.py | 6 ++--- lib/ansible/plugins/terminal/iosxr.py | 9 +++----- lib/ansible/plugins/terminal/junos.py | 4 ++-- lib/ansible/plugins/terminal/nxos.py | 4 ++-- lib/ansible/plugins/terminal/sros.py | 6 ++--- lib/ansible/plugins/terminal/vyos.py | 10 ++------- .../plugins/connection/test_network_cli.py | 6 ++--- 11 files changed, 26 insertions(+), 59 deletions(-) diff --git a/lib/ansible/plugins/connection/network_cli.py b/lib/ansible/plugins/connection/network_cli.py index 3b068e901bc..a6bbaf608d5 100644 --- a/lib/ansible/plugins/connection/network_cli.py +++ b/lib/ansible/plugins/connection/network_cli.py @@ -41,7 +41,7 @@ class Connection(_Connection): ''' CLI (shell) SSH connections on Paramiko ''' transport = 'network_cli' - has_pipelining = False + has_pipelining = True def __init__(self, play_context, new_stdin, *args, **kwargs): super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) @@ -71,26 +71,12 @@ class Connection(_Connection): display.debug('starting network_cli._connect()') network_os = self._play_context.network_os - if not network_os: - for cls in terminal_loader.all(class_only=True): - try: - network_os = cls.guess_network_os(self.ssh) - if network_os: - break - except: - raise AnsibleConnectionFailure( - 'Unable to automatically determine host network os. ' - 'Please manually configure ansible_network_os value ' - 'for this host' - ) - if not network_os: raise AnsibleConnectionFailure( 'Unable to automatically determine host network os. Please ' 'manually configure ansible_network_os value for this host' ) - self._terminal = terminal_loader.get(network_os, self) if not self._terminal: raise AnsibleConnectionFailure('network os %s is not supported' % network_os) @@ -124,7 +110,7 @@ class Connection(_Connection): if self._shell: self._terminal.on_close_shell() - if self._terminal.supports_multiplexing and self._shell: + if self._shell: self._shell.close() self._shell = None @@ -194,12 +180,12 @@ class Connection(_Connection): def _find_prompt(self, response): """Searches the buffered response for a matching command prompt""" errored_response = None - for regex in self._terminal.terminal_errors_re: + for regex in self._terminal.terminal_stderr_re: if regex.search(response): errored_response = response break - for regex in self._terminal.terminal_prompts_re: + for regex in self._terminal.terminal_stdout_re: match = regex.search(response) if match: self._matched_pattern = regex.pattern diff --git a/lib/ansible/plugins/terminal/__init__.py b/lib/ansible/plugins/terminal/__init__.py index bdd424cbca7..b6798e3fa0a 100644 --- a/lib/ansible/plugins/terminal/__init__.py +++ b/lib/ansible/plugins/terminal/__init__.py @@ -32,17 +32,15 @@ class TerminalBase(with_metaclass(ABCMeta, object)): A base class for implementing cli connections ''' - terminalprompts_re = [] + terminal_stdout_re = [] - terminalerrors_re = [] + terminal_stderr_re = [] ansi_re = [ re.compile(r'(\x1b\[\?1h\x1b=)'), re.compile(r'\x08.') ] - supports_multiplexing = True - def __init__(self, connection): self._connection = connection @@ -68,7 +66,3 @@ class TerminalBase(with_metaclass(ABCMeta, object)): def on_deauthorize(self): pass - - @staticmethod - def guess_network_os(conn): - pass diff --git a/lib/ansible/plugins/terminal/asa.py b/lib/ansible/plugins/terminal/asa.py index 8737b72c482..da94e057e5a 100644 --- a/lib/ansible/plugins/terminal/asa.py +++ b/lib/ansible/plugins/terminal/asa.py @@ -28,12 +28,12 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"% ?Error"), re.compile(r"^% \w+", re.M), re.compile(r"% ?Bad secret"), diff --git a/lib/ansible/plugins/terminal/eos.py b/lib/ansible/plugins/terminal/eos.py index d84c6fb1d6e..ddbdfae1080 100644 --- a/lib/ansible/plugins/terminal/eos.py +++ b/lib/ansible/plugins/terminal/eos.py @@ -28,12 +28,12 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"% ?Error"), re.compile(r"^% \w+", re.M), re.compile(r"% User not present"), diff --git a/lib/ansible/plugins/terminal/ios.py b/lib/ansible/plugins/terminal/ios.py index 5a39acf06d6..ec31a25ecf5 100644 --- a/lib/ansible/plugins/terminal/ios.py +++ b/lib/ansible/plugins/terminal/ios.py @@ -28,12 +28,12 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"% ?Error"), re.compile(r"^% \w+", re.M), re.compile(r"% ?Bad secret"), @@ -44,8 +44,6 @@ class TerminalModule(TerminalBase): re.compile(r"'[^']' +returned error code: ?\d+"), ] - supports_multiplexing = False - def on_open_shell(self): try: self._exec_cli_command('terminal length 0') diff --git a/lib/ansible/plugins/terminal/iosxr.py b/lib/ansible/plugins/terminal/iosxr.py index 4040d83d4e4..7ccff77ef69 100644 --- a/lib/ansible/plugins/terminal/iosxr.py +++ b/lib/ansible/plugins/terminal/iosxr.py @@ -25,16 +25,15 @@ import json from ansible.plugins.terminal import TerminalBase from ansible.errors import AnsibleConnectionFailure - class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$"), re.compile(r']]>]]>[\r\n]?') ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"% ?Error"), re.compile(r"% ?Bad secret"), re.compile(r"invalid input", re.I), @@ -44,11 +43,9 @@ class TerminalModule(TerminalBase): re.compile(r"'[^']' +returned error code: ?\d+"), ] - supports_multiplexing = False - def on_open_shell(self): try: for cmd in ['terminal length 0', 'terminal exec prompt no-timestamp']: - self._connection.exec_command(cmd) + self._exec_cli_command(cmd) except AnsibleConnectionFailure: raise AnsibleConnectionFailure('unable to set terminal parameters') diff --git a/lib/ansible/plugins/terminal/junos.py b/lib/ansible/plugins/terminal/junos.py index 451f251c445..f41bb0e3231 100644 --- a/lib/ansible/plugins/terminal/junos.py +++ b/lib/ansible/plugins/terminal/junos.py @@ -34,12 +34,12 @@ except ImportError: class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|%) ?$"), ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"unknown command"), re.compile(r"syntax error,") ] diff --git a/lib/ansible/plugins/terminal/nxos.py b/lib/ansible/plugins/terminal/nxos.py index 21c1e2d6806..00cb3f588ce 100644 --- a/lib/ansible/plugins/terminal/nxos.py +++ b/lib/ansible/plugins/terminal/nxos.py @@ -27,12 +27,12 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r'[\r\n]?[a-zA-Z]{1}[a-zA-Z0-9-]*[>|#|%](?:\s*)$'), re.compile(r'[\r\n]?[a-zA-Z]{1}[a-zA-Z0-9-]*\(.+\)#(?:\s*)$') ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"% ?Error"), re.compile(r"^% \w+", re.M), re.compile(r"% ?Bad secret"), diff --git a/lib/ansible/plugins/terminal/sros.py b/lib/ansible/plugins/terminal/sros.py index d4ce99a2670..6eea535f4f1 100644 --- a/lib/ansible/plugins/terminal/sros.py +++ b/lib/ansible/plugins/terminal/sros.py @@ -28,17 +28,15 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"^\r\nError:"), ] - supports_multiplexing = False - def on_open_shell(self): try: self._exec_cli_command('environment no more') diff --git a/lib/ansible/plugins/terminal/vyos.py b/lib/ansible/plugins/terminal/vyos.py index da33c0c3adb..8b22019f49c 100644 --- a/lib/ansible/plugins/terminal/vyos.py +++ b/lib/ansible/plugins/terminal/vyos.py @@ -28,12 +28,12 @@ from ansible.errors import AnsibleConnectionFailure class TerminalModule(TerminalBase): - terminal_prompts_re = [ + terminal_stdout_re = [ re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), re.compile(r"\@[\w\-\.]+:\S+?[>#\$] ?$") ] - terminal_errors_re = [ + terminal_stderr_re = [ re.compile(r"\n\s*Invalid command:"), re.compile(r"\nCommit failed"), re.compile(r"\n\s+Set failed"), @@ -48,9 +48,3 @@ class TerminalModule(TerminalBase): except AnsibleConnectionFailure: raise AnsibleConnectionFailure('unable to set terminal parameters') - @staticmethod - def guess_network_os(conn): - stdin, stdout, stderr = conn.exec_command('cat /etc/issue') - if 'VyOS' in stdout.read(): - return 'vyos' - diff --git a/test/units/plugins/connection/test_network_cli.py b/test/units/plugins/connection/test_network_cli.py index fd3e0219051..f6535f9ae3f 100644 --- a/test/units/plugins/connection/test_network_cli.py +++ b/test/units/plugins/connection/test_network_cli.py @@ -45,7 +45,7 @@ class TestConnectionClass(unittest.TestCase): conn.ssh = None self.assertRaises(AnsibleConnectionFailure, conn._connect) - mocked_terminal_loader.all.assert_called_with(class_only=True) + #mocked_terminal_loader.all.assert_called_with(class_only=True) mocked_terminal_loader.reset_mock() mocked_terminal_loader.get.return_value = None @@ -151,8 +151,8 @@ class TestConnectionClass(unittest.TestCase): conn = network_cli.Connection(pc, new_stdin) mock__terminal = MagicMock() - mock__terminal.terminal_prompts_re = [re.compile('device#')] - mock__terminal.terminal_errors_re = [re.compile('^ERROR')] + mock__terminal.terminal_stdout_re = [re.compile('device#')] + mock__terminal.terminal_stderr_re = [re.compile('^ERROR')] conn._terminal = mock__terminal mock__shell = MagicMock()