mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Add nxos changes for Python3 (#24602)
* Add nxos changes for Python3 Make `execute_command` arguments and its return value complaint to PY3 changes made in PR #24431 * Fix CI issues * Fix review comment Replace surrogate_or_strict with surrogate_then_replace as per review comment os PR #24601
This commit is contained in:
parent
b65ebf3519
commit
7563d93901
3 changed files with 43 additions and 34 deletions
|
@ -30,6 +30,7 @@
|
||||||
import re
|
import re
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.module_utils.basic import env_fallback, return_values
|
from ansible.module_utils.basic import env_fallback, return_values
|
||||||
from ansible.module_utils.network_common import to_list, ComplexList
|
from ansible.module_utils.network_common import to_list, ComplexList
|
||||||
from ansible.module_utils.connection import exec_command
|
from ansible.module_utils.connection import exec_command
|
||||||
|
@ -60,12 +61,12 @@ ARGS_DEFAULT_VALUE = {
|
||||||
'timeout': 10
|
'timeout': 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def check_args(module, warnings):
|
def check_args(module, warnings):
|
||||||
provider = module.params['provider'] or {}
|
provider = module.params['provider'] or {}
|
||||||
for key in nxos_argument_spec:
|
for key in nxos_argument_spec:
|
||||||
if key not in ['provider', 'transport'] and module.params[key]:
|
if key not in ['provider', 'transport'] and module.params[key]:
|
||||||
warnings.append('argument %s has been deprecated and will be '
|
warnings.append('argument %s has been deprecated and will be removed in a future version' % key)
|
||||||
'removed in a future version' % key)
|
|
||||||
|
|
||||||
# set argument's default value if not provided in input
|
# set argument's default value if not provided in input
|
||||||
# This is done to avoid unwanted argument deprecation warning
|
# This is done to avoid unwanted argument deprecation warning
|
||||||
|
@ -79,6 +80,7 @@ def check_args(module, warnings):
|
||||||
if provider.get(param):
|
if provider.get(param):
|
||||||
module.no_log_values.update(return_values(provider[param]))
|
module.no_log_values.update(return_values(provider[param]))
|
||||||
|
|
||||||
|
|
||||||
def load_params(module):
|
def load_params(module):
|
||||||
provider = module.params.get('provider') or dict()
|
provider = module.params.get('provider') or dict()
|
||||||
for key, value in iteritems(provider):
|
for key, value in iteritems(provider):
|
||||||
|
@ -86,6 +88,7 @@ def load_params(module):
|
||||||
if module.params.get(key) is None and value is not None:
|
if module.params.get(key) is None and value is not None:
|
||||||
module.params[key] = value
|
module.params[key] = value
|
||||||
|
|
||||||
|
|
||||||
def get_connection(module):
|
def get_connection(module):
|
||||||
global _DEVICE_CONNECTION
|
global _DEVICE_CONNECTION
|
||||||
if not _DEVICE_CONNECTION:
|
if not _DEVICE_CONNECTION:
|
||||||
|
@ -97,6 +100,7 @@ def get_connection(module):
|
||||||
_DEVICE_CONNECTION = conn
|
_DEVICE_CONNECTION = conn
|
||||||
return _DEVICE_CONNECTION
|
return _DEVICE_CONNECTION
|
||||||
|
|
||||||
|
|
||||||
class Cli:
|
class Cli:
|
||||||
|
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
@ -120,8 +124,8 @@ class Cli:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
rc, out, err = self.exec_command(cmd)
|
rc, out, err = self.exec_command(cmd)
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
self._module.fail_json(msg=err)
|
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||||
cfg = str(out).strip()
|
cfg = to_text(out, errors='surrogate_then_replace').strip()
|
||||||
self._device_configs[cmd] = cfg
|
self._device_configs[cmd] = cfg
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
|
@ -139,9 +143,9 @@ class Cli:
|
||||||
cmd = item['command']
|
cmd = item['command']
|
||||||
|
|
||||||
rc, out, err = self.exec_command(cmd)
|
rc, out, err = self.exec_command(cmd)
|
||||||
|
out = to_text(out, errors='surrogate_then_replace')
|
||||||
if check_rc and rc != 0:
|
if check_rc and rc != 0:
|
||||||
self._module.fail_json(msg=err)
|
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
out = self._module.from_json(out)
|
out = self._module.from_json(out)
|
||||||
|
@ -156,15 +160,16 @@ class Cli:
|
||||||
"""
|
"""
|
||||||
rc, out, err = self.exec_command('configure')
|
rc, out, err = self.exec_command('configure')
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
self._module.fail_json(msg='unable to enter configuration mode', output=err)
|
self._module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_then_replace'))
|
||||||
|
|
||||||
for cmd in config:
|
for cmd in config:
|
||||||
rc, out, err = self.exec_command(cmd)
|
rc, out, err = self.exec_command(cmd)
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
self._module.fail_json(msg=err)
|
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||||
|
|
||||||
self.exec_command('end')
|
self.exec_command('end')
|
||||||
|
|
||||||
|
|
||||||
class Nxapi:
|
class Nxapi:
|
||||||
|
|
||||||
OUTPUT_TO_COMMAND_TYPE = {
|
OUTPUT_TO_COMMAND_TYPE = {
|
||||||
|
@ -277,14 +282,13 @@ class Nxapi:
|
||||||
self._error(output=output, **item)
|
self._error(output=output, **item)
|
||||||
elif 'body' in item:
|
elif 'body' in item:
|
||||||
result.append(item['body'])
|
result.append(item['body'])
|
||||||
#else:
|
# else:
|
||||||
# error in command but since check_status is disabled
|
# error in command but since check_status is disabled
|
||||||
# silently drop it.
|
# silently drop it.
|
||||||
#result.append(item['msg'])
|
# result.append(item['msg'])
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_config(self, flags=[]):
|
def get_config(self, flags=[]):
|
||||||
"""Retrieves the current config from the device or cache
|
"""Retrieves the current config from the device or cache
|
||||||
"""
|
"""
|
||||||
|
@ -300,7 +304,6 @@ class Nxapi:
|
||||||
self._device_configs[cmd] = cfg
|
self._device_configs[cmd] = cfg
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
|
|
||||||
def run_commands(self, commands, check_rc=True):
|
def run_commands(self, commands, check_rc=True):
|
||||||
"""Run list of commands on remote device and return results
|
"""Run list of commands on remote device and return results
|
||||||
"""
|
"""
|
||||||
|
@ -308,14 +311,15 @@ class Nxapi:
|
||||||
queue = list()
|
queue = list()
|
||||||
responses = list()
|
responses = list()
|
||||||
|
|
||||||
_send = lambda commands, output: self.send_request(commands, output, check_status=check_rc)
|
def _send(commands, output):
|
||||||
|
return self.send_request(commands, output, check_status=check_rc)
|
||||||
|
|
||||||
for item in to_list(commands):
|
for item in to_list(commands):
|
||||||
if is_json(item['command']):
|
if is_json(item['command']):
|
||||||
item['command'] = str(item['command']).split('|')[0]
|
item['command'] = str(item['command']).split('|')[0]
|
||||||
item['output'] = 'json'
|
item['output'] = 'json'
|
||||||
|
|
||||||
if all((output == 'json', item['output'] == 'text')) or all((output =='text', item['output'] == 'json')):
|
if all((output == 'json', item['output'] == 'text')) or all((output == 'text', item['output'] == 'json')):
|
||||||
responses.extend(_send(queue, output))
|
responses.extend(_send(queue, output))
|
||||||
queue = list()
|
queue = list()
|
||||||
|
|
||||||
|
@ -334,14 +338,20 @@ class Nxapi:
|
||||||
self.send_request(commands, output='config')
|
self.send_request(commands, output='config')
|
||||||
|
|
||||||
|
|
||||||
is_json = lambda x: str(x).endswith('| json')
|
def is_json(cmd):
|
||||||
is_text = lambda x: not is_json
|
return str(cmd).endswith('| json')
|
||||||
|
|
||||||
|
|
||||||
|
def is_text(cmd):
|
||||||
|
return not is_json(cmd)
|
||||||
|
|
||||||
|
|
||||||
def is_nxapi(module):
|
def is_nxapi(module):
|
||||||
transport = module.params['transport']
|
transport = module.params['transport']
|
||||||
provider_transport = (module.params['provider'] or {}).get('transport')
|
provider_transport = (module.params['provider'] or {}).get('transport')
|
||||||
return 'nxapi' in (transport, provider_transport)
|
return 'nxapi' in (transport, provider_transport)
|
||||||
|
|
||||||
|
|
||||||
def to_command(module, commands):
|
def to_command(module, commands):
|
||||||
if is_nxapi(module):
|
if is_nxapi(module):
|
||||||
default_output = 'json'
|
default_output = 'json'
|
||||||
|
@ -365,15 +375,17 @@ def to_command(module, commands):
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
def get_config(module, flags=[]):
|
def get_config(module, flags=[]):
|
||||||
conn = get_connection(module)
|
conn = get_connection(module)
|
||||||
return conn.get_config(flags)
|
return conn.get_config(flags)
|
||||||
|
|
||||||
|
|
||||||
def run_commands(module, commands, check_rc=True):
|
def run_commands(module, commands, check_rc=True):
|
||||||
conn = get_connection(module)
|
conn = get_connection(module)
|
||||||
return conn.run_commands(to_command(module, commands), check_rc)
|
return conn.run_commands(to_command(module, commands), check_rc)
|
||||||
|
|
||||||
|
|
||||||
def load_config(module, config):
|
def load_config(module, config):
|
||||||
conn = get_connection(module)
|
conn = get_connection(module)
|
||||||
return conn.load_config(config)
|
return conn.load_config(config)
|
||||||
|
|
||||||
|
|
|
@ -28,28 +28,27 @@ from ansible.errors import AnsibleConnectionFailure
|
||||||
class TerminalModule(TerminalBase):
|
class TerminalModule(TerminalBase):
|
||||||
|
|
||||||
terminal_stdout_re = [
|
terminal_stdout_re = [
|
||||||
re.compile(r'[\r\n]?[a-zA-Z]{1}[a-zA-Z0-9-]*[>|#|%](?:\s*)$'),
|
re.compile(br'[\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*)$')
|
re.compile(br'[\r\n]?[a-zA-Z]{1}[a-zA-Z0-9-]*\(.+\)#(?:\s*)$')
|
||||||
]
|
]
|
||||||
|
|
||||||
terminal_stderr_re = [
|
terminal_stderr_re = [
|
||||||
re.compile(r"% ?Error"),
|
re.compile(br"% ?Error"),
|
||||||
re.compile(r"^% \w+", re.M),
|
re.compile(br"^% \w+", re.M),
|
||||||
re.compile(r"% ?Bad secret"),
|
re.compile(br"% ?Bad secret"),
|
||||||
re.compile(r"invalid input", re.I),
|
re.compile(br"invalid input", re.I),
|
||||||
re.compile(r"(?:incomplete|ambiguous) command", re.I),
|
re.compile(br"(?:incomplete|ambiguous) command", re.I),
|
||||||
re.compile(r"connection timed out", re.I),
|
re.compile(br"connection timed out", re.I),
|
||||||
re.compile(r"[^\r\n]+ not found", re.I),
|
re.compile(br"[^\r\n]+ not found", re.I),
|
||||||
re.compile(r"'[^']' +returned error code: ?\d+"),
|
re.compile(br"'[^']' +returned error code: ?\d+"),
|
||||||
re.compile(r"syntax error"),
|
re.compile(br"syntax error"),
|
||||||
re.compile(r"unknown command"),
|
re.compile(br"unknown command"),
|
||||||
re.compile(r"user not present")
|
re.compile(br"user not present")
|
||||||
]
|
]
|
||||||
|
|
||||||
def on_open_shell(self):
|
def on_open_shell(self):
|
||||||
try:
|
try:
|
||||||
for cmd in ['terminal length 0', 'terminal width 511']:
|
for cmd in (b'terminal length 0', b'terminal width 511'):
|
||||||
self._exec_cli_command(cmd)
|
self._exec_cli_command(cmd)
|
||||||
except AnsibleConnectionFailure:
|
except AnsibleConnectionFailure:
|
||||||
raise AnsibleConnectionFailure('unable to set terminal parameters')
|
raise AnsibleConnectionFailure('unable to set terminal parameters')
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,6 @@ lib/ansible/module_utils/netcli.py
|
||||||
lib/ansible/module_utils/netconf.py
|
lib/ansible/module_utils/netconf.py
|
||||||
lib/ansible/module_utils/network.py
|
lib/ansible/module_utils/network.py
|
||||||
lib/ansible/module_utils/network_common.py
|
lib/ansible/module_utils/network_common.py
|
||||||
lib/ansible/module_utils/nxos.py
|
|
||||||
lib/ansible/module_utils/openstack.py
|
lib/ansible/module_utils/openstack.py
|
||||||
lib/ansible/module_utils/openswitch.py
|
lib/ansible/module_utils/openswitch.py
|
||||||
lib/ansible/module_utils/ordnance.py
|
lib/ansible/module_utils/ordnance.py
|
||||||
|
@ -814,7 +813,6 @@ lib/ansible/plugins/strategy/linear.py
|
||||||
lib/ansible/plugins/terminal/asa.py
|
lib/ansible/plugins/terminal/asa.py
|
||||||
lib/ansible/plugins/terminal/eos.py
|
lib/ansible/plugins/terminal/eos.py
|
||||||
lib/ansible/plugins/terminal/junos.py
|
lib/ansible/plugins/terminal/junos.py
|
||||||
lib/ansible/plugins/terminal/nxos.py
|
|
||||||
lib/ansible/plugins/test/core.py
|
lib/ansible/plugins/test/core.py
|
||||||
lib/ansible/plugins/test/files.py
|
lib/ansible/plugins/test/files.py
|
||||||
lib/ansible/plugins/test/mathstuff.py
|
lib/ansible/plugins/test/mathstuff.py
|
||||||
|
|
Loading…
Reference in a new issue