adds feature to try to auto determine network_os (#18674)

This updates the network_cli connection plugin to attempt to automatically
determine the remote device os.  The device network os discovery can
be overridden by setting the ansible_network_os value.
This commit is contained in:
Peter Sprygada 2016-11-30 16:28:47 -05:00 committed by GitHub
parent 6fe9a5e40c
commit 8137c7207d
8 changed files with 56 additions and 7 deletions

View file

@ -39,14 +39,8 @@ class Connection(_Connection):
def __init__(self, play_context, new_stdin, *args, **kwargs): def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
assert self._play_context.network_os, 'ansible_network_os must be set' self._terminal = None
self._terminal = terminal_loader.get(self._play_context.network_os, self)
if not self._terminal:
raise AnsibleConnectionFailure('network os %s is not supported' % self._play_context.network_os)
self._shell = None self._shell = None
self._matched_prompt = None self._matched_prompt = None
self._matched_pattern = None self._matched_pattern = None
self._last_response = None self._last_response = None
@ -64,6 +58,24 @@ class Connection(_Connection):
def _connect(self): def _connect(self):
super(Connection, self)._connect() super(Connection, self)._connect()
network_os = self._play_context.network_os
if not network_os:
for cls in terminal_loader.all(class_only=True):
network_os = cls.guess_network_os(self.ssh)
if network_os:
break
if not network_os:
raise AnsibleConnectionFailure(
'unable to determine device network os. Please configure '
'ansible_network_os value'
)
self._terminal = terminal_loader.get(network_os, self)
if not self._terminal:
raise AnsibleConnectionFailure('network os %s is not supported' % network_os)
return (0, 'connected', '') return (0, 'connected', '')
def open_shell(self, timeout=10): def open_shell(self, timeout=10):

View file

@ -69,3 +69,6 @@ class TerminalBase(with_metaclass(ABCMeta, object)):
def on_deauthorize(self): def on_deauthorize(self):
pass pass
@staticmethod
def guess_network_os(conn):
pass

View file

@ -79,4 +79,9 @@ class TerminalModule(TerminalBase):
elif prompt.endswith('#'): elif prompt.endswith('#'):
self._exec_cli_command('disable') self._exec_cli_command('disable')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('show version')
if 'Arista' in stdout.read():
return 'eos'

View file

@ -80,3 +80,9 @@ class TerminalModule(TerminalBase):
self._exec_cli_command('disable') self._exec_cli_command('disable')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('show version')
if 'Cisco IOS Software' in stdout.read():
return 'ios'

View file

@ -52,4 +52,10 @@ class TerminalModule(TerminalBase):
except AnsibleConnectionFailure: except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to set terminal parameters') raise AnsibleConnectionFailure('unable to set terminal parameters')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('show version')
if 'Cisco IOS XR' in stdout.read():
return 'iosxr'

View file

@ -45,3 +45,9 @@ class TerminalModule(TerminalBase):
except AnsibleConnectionFailure: except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to set terminal parameters') raise AnsibleConnectionFailure('unable to set terminal parameters')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('show version')
if 'Junos' in stdout.read():
return 'junos'

View file

@ -52,5 +52,11 @@ class TerminalModule(TerminalBase):
except AnsibleConnectionFailure: except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to set terminal parameters') raise AnsibleConnectionFailure('unable to set terminal parameters')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('show version')
if 'NX-OS' in stdout.read():
return 'nxos'

View file

@ -44,4 +44,9 @@ class TerminalModule(TerminalBase):
except AnsibleConnectionFailure: except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to set terminal parameters') raise AnsibleConnectionFailure('unable to set terminal parameters')
@staticmethod
def guess_network_os(conn):
stdin, stdout, stderr = conn.exec_command('cat /proc/version')
if 'vyos' in stdout.read():
return 'vyos'