2017-02-16 15:53:03 +00:00
|
|
|
#!/usr/bin/python
|
2017-08-04 09:25:58 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# (c) 2017, Ansible by Red Hat, inc
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
|
2017-02-16 15:53:03 +00:00
|
|
|
|
2017-08-16 03:16:38 +00:00
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
2017-03-14 16:07:22 +00:00
|
|
|
'status': ['preview'],
|
2017-08-16 04:10:36 +00:00
|
|
|
'supported_by': 'network'}
|
2017-03-14 16:07:22 +00:00
|
|
|
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
DOCUMENTATION = """
|
|
|
|
---
|
|
|
|
module: junos_rpc
|
|
|
|
version_added: "2.3"
|
|
|
|
author: "Peter Sprygada (@privateip)"
|
2017-04-13 16:14:33 +00:00
|
|
|
short_description: Runs an arbitrary RPC over NetConf on an Juniper JUNOS device
|
2017-02-16 15:53:03 +00:00
|
|
|
description:
|
|
|
|
- Sends a request to the remote device running JUNOS to execute the
|
|
|
|
specified RPC using the NetConf transport. The reply is then
|
2017-08-29 15:59:41 +00:00
|
|
|
returned to the playbook in the C(xml) key. If an alternate output
|
2017-02-16 15:53:03 +00:00
|
|
|
format is requested, the reply is transformed to the requested output.
|
2017-03-05 08:37:01 +00:00
|
|
|
extends_documentation_fragment: junos
|
2017-02-16 15:53:03 +00:00
|
|
|
options:
|
|
|
|
rpc:
|
|
|
|
description:
|
|
|
|
- The C(rpc) argument specifies the RPC call to send to the
|
|
|
|
remote devices to be executed. The RPC Reply message is parsed
|
|
|
|
and the contents are returned to the playbook.
|
|
|
|
required: true
|
|
|
|
args:
|
|
|
|
description:
|
|
|
|
- The C(args) argument provides a set of arguments for the RPC
|
|
|
|
call and are encoded in the request message. This argument
|
|
|
|
accepts a set of key=value arguments.
|
|
|
|
required: false
|
|
|
|
default: null
|
2017-11-21 05:15:13 +00:00
|
|
|
attrs:
|
|
|
|
description:
|
|
|
|
- The C(attrs) arguments defines a list of attributes and their values
|
|
|
|
to set for the RPC call. This accepts a dictionary of key-values.
|
|
|
|
version_added: "2.5"
|
2017-02-16 15:53:03 +00:00
|
|
|
output:
|
|
|
|
description:
|
|
|
|
- The C(output) argument specifies the desired output of the
|
|
|
|
return data. This argument accepts one of C(xml), C(text),
|
|
|
|
or C(json). For C(json), the JUNOS device must be running a
|
|
|
|
version of software that supports native JSON output.
|
|
|
|
required: false
|
|
|
|
default: xml
|
2017-06-22 04:04:50 +00:00
|
|
|
requirements:
|
|
|
|
- ncclient (>=v0.5.2)
|
|
|
|
notes:
|
|
|
|
- This module requires the netconf system service be enabled on
|
2017-08-24 14:31:47 +00:00
|
|
|
the remote device being managed.
|
|
|
|
- Tested against vSRX JUNOS version 15.1X49-D15.4, vqfx-10000 JUNOS Version 15.1X53-D60.4.
|
2017-02-16 15:53:03 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
EXAMPLES = """
|
|
|
|
- name: collect interface information using rpc
|
|
|
|
junos_rpc:
|
|
|
|
rpc: get-interface-information
|
|
|
|
args:
|
2017-05-09 13:11:48 +00:00
|
|
|
interface-name: em0
|
2017-02-16 15:53:03 +00:00
|
|
|
media: True
|
|
|
|
|
|
|
|
- name: get system information
|
|
|
|
junos_rpc:
|
|
|
|
rpc: get-system-information
|
2017-11-21 05:15:13 +00:00
|
|
|
|
|
|
|
- name: load configuration
|
|
|
|
junos_rpc:
|
|
|
|
rpc: load-configuration
|
|
|
|
attrs:
|
|
|
|
action: override
|
|
|
|
url: /tmp/config.conf
|
2017-02-16 15:53:03 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
RETURN = """
|
|
|
|
xml:
|
2017-04-12 17:13:41 +00:00
|
|
|
description: The xml return string from the rpc request.
|
2017-02-16 15:53:03 +00:00
|
|
|
returned: always
|
2017-04-12 17:13:41 +00:00
|
|
|
type: string
|
2017-02-16 15:53:03 +00:00
|
|
|
output:
|
2017-04-12 17:13:41 +00:00
|
|
|
description: The rpc rely converted to the output format.
|
2017-02-16 15:53:03 +00:00
|
|
|
returned: always
|
2017-04-12 17:13:41 +00:00
|
|
|
type: string
|
2017-02-16 15:53:03 +00:00
|
|
|
output_lines:
|
2017-04-12 17:13:41 +00:00
|
|
|
description: The text output split into lines for readability.
|
2017-02-16 15:53:03 +00:00
|
|
|
returned: always
|
2017-04-12 17:13:41 +00:00
|
|
|
type: list
|
2017-02-16 15:53:03 +00:00
|
|
|
"""
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
2017-07-11 04:22:53 +00:00
|
|
|
from ansible.module_utils.junos import junos_argument_spec, check_args
|
2017-02-16 15:53:03 +00:00
|
|
|
from ansible.module_utils.netconf import send_request
|
|
|
|
from ansible.module_utils.six import iteritems
|
|
|
|
|
2017-05-03 13:30:07 +00:00
|
|
|
USE_PERSISTENT_CONNECTION = True
|
2017-02-16 15:53:03 +00:00
|
|
|
|
2017-06-22 04:04:50 +00:00
|
|
|
try:
|
|
|
|
from lxml.etree import Element, SubElement, tostring
|
|
|
|
except ImportError:
|
|
|
|
from xml.etree.ElementTree import Element, SubElement, tostring
|
|
|
|
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
def main():
|
|
|
|
"""main entry point for Ansible module
|
|
|
|
"""
|
|
|
|
argument_spec = dict(
|
|
|
|
rpc=dict(required=True),
|
|
|
|
args=dict(type='dict'),
|
2017-11-21 05:15:13 +00:00
|
|
|
attrs=dict(type='dict'),
|
2017-02-16 15:53:03 +00:00
|
|
|
output=dict(default='xml', choices=['xml', 'json', 'text']),
|
|
|
|
)
|
|
|
|
|
2017-05-03 13:30:07 +00:00
|
|
|
argument_spec.update(junos_argument_spec)
|
|
|
|
|
2017-02-16 15:53:03 +00:00
|
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
|
|
supports_check_mode=False)
|
|
|
|
|
2017-05-03 13:30:07 +00:00
|
|
|
warnings = list()
|
|
|
|
check_args(module, warnings)
|
|
|
|
|
|
|
|
result = {'changed': False, 'warnings': warnings}
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
rpc = str(module.params['rpc']).replace('_', '-')
|
|
|
|
|
|
|
|
if all((module.check_mode, not rpc.startswith('get'))):
|
|
|
|
module.fail_json(msg='invalid rpc for running in check_mode')
|
|
|
|
|
|
|
|
args = module.params['args'] or {}
|
2017-11-21 05:15:13 +00:00
|
|
|
attrs = module.params['attrs'] or {}
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
xattrs = {'format': module.params['output']}
|
|
|
|
|
2017-11-21 05:15:13 +00:00
|
|
|
for key, value in iteritems(attrs):
|
|
|
|
xattrs.update({key: value})
|
|
|
|
|
2017-05-03 13:30:07 +00:00
|
|
|
element = Element(module.params['rpc'], xattrs)
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
for key, value in iteritems(args):
|
|
|
|
key = str(key).replace('_', '-')
|
|
|
|
if isinstance(value, list):
|
|
|
|
for item in value:
|
2017-05-03 13:30:07 +00:00
|
|
|
child = SubElement(element, key)
|
2017-02-16 15:53:03 +00:00
|
|
|
if item is not True:
|
|
|
|
child.text = item
|
|
|
|
else:
|
2017-05-03 13:30:07 +00:00
|
|
|
child = SubElement(element, key)
|
2017-02-16 15:53:03 +00:00
|
|
|
if value is not True:
|
|
|
|
child.text = value
|
|
|
|
|
|
|
|
reply = send_request(module, element)
|
|
|
|
|
2017-05-03 13:30:07 +00:00
|
|
|
result['xml'] = str(tostring(reply))
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
if module.params['output'] == 'text':
|
2017-05-03 13:30:07 +00:00
|
|
|
data = reply.find('.//output')
|
|
|
|
result['output'] = data.text.strip()
|
2017-02-16 15:53:03 +00:00
|
|
|
result['output_lines'] = result['output'].split('\n')
|
|
|
|
|
|
|
|
elif module.params['output'] == 'json':
|
2017-05-03 13:30:07 +00:00
|
|
|
result['output'] = module.from_json(reply.text.strip())
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
else:
|
2017-05-03 13:30:07 +00:00
|
|
|
result['output'] = str(tostring(reply)).split('\n')
|
2017-02-16 15:53:03 +00:00
|
|
|
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|