Add prompt check in action plugin for network platform (#32787)
* Add prompt check in action plugin for network platform In case of ignore_errors for a wrong configuration the prompt is left in configuration mode and moved to next task, if the next taks requires prompt to be in operational state it results in failure. Hence add a check to ensure right prompt at start of each task run. * Add prompt check in action plugin for network platform * In case of ignore_errors for a wrong configuration the prompt is left in configuration mode and moved to next task, if the next taks requires prompt to be in operational state it results in failure. * Hence add a check to ensure right prompt at start of each task run. * Fix CI issue * Fix CI issues Fix review comment Change iosxr exit command to abort as per review comment
This commit is contained in:
parent
414eaefcb5
commit
8472a53bea
14 changed files with 149 additions and 49 deletions
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.aireos import aireos_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -69,10 +71,11 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
if str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
if to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
conn.send_command('exit')
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.aruba import aruba_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -69,10 +71,11 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
if str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
if to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
conn.send_command('exit')
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.module_utils.f5_utils import F5_COMMON_ARGS
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
|
@ -64,12 +66,13 @@ class ActionModule(_ActionModule):
|
|||
'https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell'}
|
||||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config mode
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while '(config' in str(out):
|
||||
# enable mode and not config module
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while '(config' in to_text(out, errors='surrogate_then_replace').strip():
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.ce import ce_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -78,11 +80,12 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while str(out).strip().endswith(']'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(']'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('return')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.dellos10 import dellos10_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -73,11 +75,12 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.dellos6 import dellos6_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -69,11 +71,12 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.dellos9 import dellos9_provider_spec
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -73,11 +75,12 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.module_utils.eos import eos_provider_spec
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -38,6 +40,7 @@ class ActionModule(_ActionModule):
|
|||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
provider = load_provider(eos_provider_spec, self._task.args)
|
||||
transport = provider['transport'] or 'cli'
|
||||
|
@ -95,5 +98,18 @@ class ActionModule(_ActionModule):
|
|||
|
||||
self._task.args['provider'] = provider
|
||||
|
||||
if (self._play_context.connection == 'local' and transport == 'cli') or self._play_context.connection == 'network_cli':
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while '(config' in to_text(out, errors='surrogate_then_replace').strip():
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
return result
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
from ansible.module_utils.ios import ios_provider_spec
|
||||
|
@ -38,6 +40,7 @@ class ActionModule(_ActionModule):
|
|||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
provider = load_provider(ios_provider_spec, self._task.args)
|
||||
|
||||
|
@ -71,5 +74,18 @@ class ActionModule(_ActionModule):
|
|||
self._play_context.become = False
|
||||
self._play_context.become_method = None
|
||||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
|
||||
return result
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.module_utils.iosxr import iosxr_provider_spec
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -38,6 +40,7 @@ class ActionModule(_ActionModule):
|
|||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
provider = load_provider(iosxr_provider_spec, self._task.args)
|
||||
|
||||
|
@ -62,5 +65,18 @@ class ActionModule(_ActionModule):
|
|||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('abort')
|
||||
rc, out, err = conn.get_prompt()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
|
||||
return result
|
||||
|
|
|
@ -24,6 +24,8 @@ import copy
|
|||
import json
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
from ansible.module_utils.ironware import ironware_provider_spec
|
||||
|
@ -73,10 +75,11 @@ class ActionModule(_ActionModule):
|
|||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
if str(out).strip().endswith(')#'):
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
if to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
conn.send_command('exit')
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
|
|
|
@ -23,10 +23,13 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
from ansible.module_utils.junos import junos_provider_spec
|
||||
from ansible.plugins.loader import connection_loader, module_loader
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
||||
|
||||
try:
|
||||
from __main__ import display
|
||||
|
@ -53,7 +56,6 @@ class ActionModule(_ActionModule):
|
|||
if self._task.action == 'junos_netconf' or (provider['transport'] == 'cli' and self._task.action == 'junos_command'):
|
||||
pc.connection = 'network_cli'
|
||||
pc.port = int(provider['port'] or self._play_context.port or 22)
|
||||
|
||||
else:
|
||||
pc.connection = 'netconf'
|
||||
pc.port = int(provider['port'] or self._play_context.port or 830)
|
||||
|
@ -64,7 +66,7 @@ class ActionModule(_ActionModule):
|
|||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
||||
|
||||
display.vvv('using connection plugin %s' % pc.connection, pc.remote_addr)
|
||||
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||
|
||||
|
@ -75,16 +77,20 @@ class ActionModule(_ActionModule):
|
|||
'msg': 'unable to open shell. Please see: ' +
|
||||
'https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell'}
|
||||
|
||||
if pc.connection == 'network_cli':
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
while str(out).strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
if pc.connection == 'network_cli':
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
return result
|
||||
|
|
|
@ -21,6 +21,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
|
@ -67,10 +69,23 @@ class ActionModule(ActionBase):
|
|||
play_context.become = self.provider['authorize'] or False
|
||||
play_context.become_pass = self.provider['auth_pass']
|
||||
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
socket_path = self._start_connection(play_context)
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
if play_context.connection == 'network_cli':
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
if to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('exit')
|
||||
|
||||
if 'fail_on_missing_module' not in self._task.args:
|
||||
self._task.args['fail_on_missing_module'] = False
|
||||
|
||||
|
@ -119,13 +134,6 @@ class ActionModule(ActionBase):
|
|||
'msg': 'unable to open shell. Please see: ' +
|
||||
'https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell'}
|
||||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
rc, out, err = connection.exec_command('prompt()')
|
||||
if str(out).strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
connection.exec_command('exit')
|
||||
|
||||
if self._play_context.become_method == 'enable':
|
||||
self._play_context.become = False
|
||||
self._play_context.become_method = None
|
||||
|
|
|
@ -23,6 +23,8 @@ import sys
|
|||
import copy
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.plugins.action.normal import ActionModule as _ActionModule
|
||||
from ansible.module_utils.network_common import load_provider
|
||||
from ansible.module_utils.nxos import nxos_provider_spec
|
||||
|
@ -43,6 +45,7 @@ class ActionModule(_ActionModule):
|
|||
display.vvvv('connection transport is %s' % transport, self._play_context.remote_addr)
|
||||
|
||||
if transport == 'cli':
|
||||
socket_path = None
|
||||
if self._play_context.connection == 'local':
|
||||
pc = copy.deepcopy(self._play_context)
|
||||
pc.connection = 'network_cli'
|
||||
|
@ -66,6 +69,17 @@ class ActionModule(_ActionModule):
|
|||
|
||||
task_vars['ansible_socket'] = socket_path
|
||||
|
||||
# make sure we are in the right cli context which should be
|
||||
# enable mode and not config module
|
||||
if socket_path is None:
|
||||
socket_path = self._connection.socket_path
|
||||
|
||||
conn = Connection(socket_path)
|
||||
out = conn.get_prompt()
|
||||
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||
conn.send_command('exit')
|
||||
out = conn.get_prompt()
|
||||
else:
|
||||
provider['transport'] = 'nxapi'
|
||||
if provider.get('host') is None:
|
||||
|
|
Loading…
Reference in a new issue