mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Fix fetch configuration in junos_command (#26392)
* Fix fetch configuration in junos_command Fixes #26358 Add support to fetch configuration from device in `xml`, `text`, `json`, `set` display format. * Add error message if set display is not supported * Throw error in case of warning for show commands
This commit is contained in:
parent
07b097af7c
commit
43bd993fac
2 changed files with 47 additions and 14 deletions
|
@ -37,7 +37,7 @@ except ImportError:
|
||||||
NS_MAP = {'nc': "urn:ietf:params:xml:ns:netconf:base:1.0"}
|
NS_MAP = {'nc': "urn:ietf:params:xml:ns:netconf:base:1.0"}
|
||||||
|
|
||||||
|
|
||||||
def send_request(module, obj, check_rc=True):
|
def send_request(module, obj, check_rc=True, ignore_warning=True):
|
||||||
request = tostring(obj)
|
request = tostring(obj)
|
||||||
rc, out, err = exec_command(module, request)
|
rc, out, err = exec_command(module, request)
|
||||||
if rc != 0 and check_rc:
|
if rc != 0 and check_rc:
|
||||||
|
@ -54,7 +54,7 @@ def send_request(module, obj, check_rc=True):
|
||||||
message = rpc_error.find('./nc:error-message', NS_MAP).text
|
message = rpc_error.find('./nc:error-message', NS_MAP).text
|
||||||
severity = rpc_error.find('./nc:error-severity', NS_MAP).text
|
severity = rpc_error.find('./nc:error-severity', NS_MAP).text
|
||||||
|
|
||||||
if severity == 'warning':
|
if severity == 'warning' and ignore_warning:
|
||||||
warnings.append(message)
|
warnings.append(message)
|
||||||
else:
|
else:
|
||||||
module.fail_json(msg=str(err))
|
module.fail_json(msg=str(err))
|
||||||
|
|
|
@ -96,11 +96,12 @@ options:
|
||||||
This handles how to properly understand the output and apply the
|
This handles how to properly understand the output and apply the
|
||||||
conditionals path to the result set. For I(rpcs) argument default
|
conditionals path to the result set. For I(rpcs) argument default
|
||||||
display is C(xml) and for I(commands) argument default display
|
display is C(xml) and for I(commands) argument default display
|
||||||
is C(text).
|
is C(text). Value C(set) is applicable only for fetching configuration
|
||||||
|
from device.
|
||||||
required: false
|
required: false
|
||||||
default: depends on input argument I(rpcs) or I(commands)
|
default: depends on input argument I(rpcs) or I(commands)
|
||||||
aliases: ['format', 'output']
|
aliases: ['format', 'output']
|
||||||
choices: ['text', 'json', 'xml']
|
choices: ['text', 'json', 'xml', 'set']
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
requirements:
|
requirements:
|
||||||
- jxmlease
|
- jxmlease
|
||||||
|
@ -142,8 +143,12 @@ EXAMPLES = """
|
||||||
|
|
||||||
- name: run rpc on the remote device
|
- name: run rpc on the remote device
|
||||||
junos_command:
|
junos_command:
|
||||||
rpcs: get-software-information
|
commands: show configuration
|
||||||
|
display: set
|
||||||
|
|
||||||
|
- name: run rpc on the remote device
|
||||||
|
junos_command:
|
||||||
|
rpcs: get-software-information
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
|
@ -173,7 +178,7 @@ import re
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.junos import junos_argument_spec, check_args
|
from ansible.module_utils.junos import junos_argument_spec, check_args, get_configuration
|
||||||
from ansible.module_utils.netcli import Conditional, FailedConditionalError
|
from ansible.module_utils.netcli import Conditional, FailedConditionalError
|
||||||
from ansible.module_utils.netconf import send_request
|
from ansible.module_utils.netconf import send_request
|
||||||
from ansible.module_utils.six import string_types, iteritems
|
from ansible.module_utils.six import string_types, iteritems
|
||||||
|
@ -208,6 +213,7 @@ def rpc(module, items):
|
||||||
for item in items:
|
for item in items:
|
||||||
name = item['name']
|
name = item['name']
|
||||||
xattrs = item['xattrs']
|
xattrs = item['xattrs']
|
||||||
|
fetch_config = False
|
||||||
|
|
||||||
args = item.get('args')
|
args = item.get('args')
|
||||||
text = item.get('text')
|
text = item.get('text')
|
||||||
|
@ -217,6 +223,9 @@ def rpc(module, items):
|
||||||
if all((module.check_mode, not name.startswith('get'))):
|
if all((module.check_mode, not name.startswith('get'))):
|
||||||
module.fail_json(msg='invalid rpc for running in check_mode')
|
module.fail_json(msg='invalid rpc for running in check_mode')
|
||||||
|
|
||||||
|
if name == 'command' and text.startswith('show configuration') or name == 'get-configuration':
|
||||||
|
fetch_config = True
|
||||||
|
|
||||||
element = Element(name, xattrs)
|
element = Element(name, xattrs)
|
||||||
|
|
||||||
if text:
|
if text:
|
||||||
|
@ -235,15 +244,31 @@ def rpc(module, items):
|
||||||
if value is not True:
|
if value is not True:
|
||||||
child.text = value
|
child.text = value
|
||||||
|
|
||||||
reply = send_request(module, element)
|
if fetch_config:
|
||||||
|
reply = get_configuration(module, format=xattrs['format'])
|
||||||
|
else:
|
||||||
|
reply = send_request(module, element, ignore_warning=False)
|
||||||
|
|
||||||
if xattrs['format'] == 'text':
|
if xattrs['format'] == 'text':
|
||||||
data = reply.find('.//output')
|
if fetch_config:
|
||||||
|
data = reply.find('.//configuration-text')
|
||||||
|
else:
|
||||||
|
data = reply.find('.//output')
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
module.fail_json(msg=tostring(reply))
|
||||||
|
|
||||||
responses.append(data.text.strip())
|
responses.append(data.text.strip())
|
||||||
|
|
||||||
elif xattrs['format'] == 'json':
|
elif xattrs['format'] == 'json':
|
||||||
responses.append(module.from_json(reply.text.strip()))
|
responses.append(module.from_json(reply.text.strip()))
|
||||||
|
|
||||||
|
elif xattrs['format'] == 'set':
|
||||||
|
data = reply.find('.//configuration-set')
|
||||||
|
if data is None:
|
||||||
|
module.fail_json(msg="Display format 'set' is not supported by remote device.")
|
||||||
|
responses.append(data.text.strip())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
responses.append(tostring(reply))
|
responses.append(tostring(reply))
|
||||||
|
|
||||||
|
@ -277,8 +302,11 @@ def parse_rpcs(module):
|
||||||
args[key] = str(value)
|
args[key] = str(value)
|
||||||
|
|
||||||
display = module.params['display'] or 'xml'
|
display = module.params['display'] or 'xml'
|
||||||
xattrs = {'format': display}
|
|
||||||
|
|
||||||
|
if display == 'set' and rpc != 'get-configuration':
|
||||||
|
module.fail_json(msg="Invalid display option '%s' given for rpc '%s'" % ('set', name))
|
||||||
|
|
||||||
|
xattrs = {'format': display}
|
||||||
items.append({'name': name, 'args': args, 'xattrs': xattrs})
|
items.append({'name': name, 'args': args, 'xattrs': xattrs})
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
@ -298,14 +326,20 @@ def parse_commands(module, warnings):
|
||||||
text = parts[0]
|
text = parts[0]
|
||||||
|
|
||||||
display = module.params['display'] or 'text'
|
display = module.params['display'] or 'text'
|
||||||
xattrs = {'format': display}
|
|
||||||
|
|
||||||
if '| display json' in command:
|
if '| display json' in command:
|
||||||
xattrs['format'] = 'json'
|
display = 'json'
|
||||||
|
|
||||||
elif '| display xml' in command:
|
elif '| display xml' in command:
|
||||||
xattrs['format'] = 'xml'
|
display = 'xml'
|
||||||
|
|
||||||
|
if display == 'set' or '| display set' in command:
|
||||||
|
if command.startswith('show configuration'):
|
||||||
|
display = 'set'
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="Invalid display option '%s' given for command '%s'" % ('set', command))
|
||||||
|
|
||||||
|
xattrs = {'format': display}
|
||||||
items.append({'name': 'command', 'xattrs': xattrs, 'text': text})
|
items.append({'name': 'command', 'xattrs': xattrs, 'text': text})
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
@ -318,7 +352,7 @@ def main():
|
||||||
commands=dict(type='list'),
|
commands=dict(type='list'),
|
||||||
rpcs=dict(type='list'),
|
rpcs=dict(type='list'),
|
||||||
|
|
||||||
display=dict(choices=['text', 'json', 'xml'], aliases=['format', 'output']),
|
display=dict(choices=['text', 'json', 'xml', 'set'], aliases=['format', 'output']),
|
||||||
|
|
||||||
wait_for=dict(type='list', aliases=['waitfor']),
|
wait_for=dict(type='list', aliases=['waitfor']),
|
||||||
match=dict(default='all', choices=['all', 'any']),
|
match=dict(default='all', choices=['all', 'any']),
|
||||||
|
@ -351,7 +385,6 @@ def main():
|
||||||
|
|
||||||
while retries > 0:
|
while retries > 0:
|
||||||
responses = rpc(module, items)
|
responses = rpc(module, items)
|
||||||
|
|
||||||
transformed = list()
|
transformed = list()
|
||||||
output = list()
|
output = list()
|
||||||
for item, resp in zip(items, responses):
|
for item, resp in zip(items, responses):
|
||||||
|
|
Loading…
Add table
Reference in a new issue