183 lines
5.0 KiB
Python
183 lines
5.0 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# (c) 2018, 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
|
|
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
'status': ['preview'],
|
|
'supported_by': 'network'}
|
|
|
|
|
|
DOCUMENTATION = """
|
|
---
|
|
module: junos_scp
|
|
version_added: "2.5"
|
|
author: "Christian Giese (@GIC-de)"
|
|
short_description: Transfer files from or to remote devices running Junos
|
|
description:
|
|
- This module transfers files via SCP from or to remote devices
|
|
running Junos.
|
|
extends_documentation_fragment: junos
|
|
options:
|
|
src:
|
|
description:
|
|
- The C(src) argument takes a single path, or a list of paths to be
|
|
transfered. The argument C(recursive) must be C(true) to transfer
|
|
directories.
|
|
required: true
|
|
dest:
|
|
description:
|
|
- The C(dest) argument specifies the path in which to receive the files.
|
|
default: '.'
|
|
recursive:
|
|
description:
|
|
- The C(recursive) argument enables recursive transfer of files and
|
|
directories.
|
|
type: bool
|
|
default: 'no'
|
|
remote_src:
|
|
description:
|
|
- The C(remote_src) argument enables the download of files (I(scp get)) from
|
|
the remote device. The default behavior is to upload files (I(scp put))
|
|
to the remote device.
|
|
type: bool
|
|
default: 'no'
|
|
requirements:
|
|
- junos-eznc
|
|
- ncclient (>=v0.5.2)
|
|
notes:
|
|
- This module requires the netconf system service be enabled on
|
|
the remote device being managed.
|
|
- Tested against vMX JUNOS version 17.3R1.10.
|
|
- Works with C(local) connections only.
|
|
"""
|
|
|
|
EXAMPLES = """
|
|
# the required set of connection arguments have been purposely left off
|
|
# the examples for brevity
|
|
- name: upload local file to home directory on remote device
|
|
junos_scp:
|
|
src: test.tgz
|
|
|
|
- name: upload local file to tmp directory on remote device
|
|
junos_scp:
|
|
src: test.tgz
|
|
dest: /tmp/
|
|
|
|
- name: download file from remote device
|
|
junos_scp:
|
|
src: test.tgz
|
|
remote_src: true
|
|
"""
|
|
|
|
RETURN = """
|
|
changed:
|
|
description: always true
|
|
returned: always
|
|
type: bool
|
|
"""
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible.module_utils.network.junos.junos import junos_argument_spec, get_param
|
|
from ansible.module_utils._text import to_native
|
|
|
|
try:
|
|
from jnpr.junos import Device
|
|
from jnpr.junos.utils.scp import SCP
|
|
from jnpr.junos.exception import ConnectError
|
|
HAS_PYEZ = True
|
|
except ImportError:
|
|
HAS_PYEZ = False
|
|
|
|
|
|
def connect(module):
|
|
host = get_param(module, 'host')
|
|
|
|
kwargs = {
|
|
'port': get_param(module, 'port') or 830,
|
|
'user': get_param(module, 'username')
|
|
}
|
|
|
|
if get_param(module, 'password'):
|
|
kwargs['passwd'] = get_param(module, 'password')
|
|
|
|
if get_param(module, 'ssh_keyfile'):
|
|
kwargs['ssh_private_key_file'] = get_param(module, 'ssh_keyfile')
|
|
|
|
kwargs['gather_facts'] = False
|
|
|
|
try:
|
|
device = Device(host, **kwargs)
|
|
device.open()
|
|
device.timeout = get_param(module, 'timeout') or 10
|
|
except ConnectError as exc:
|
|
module.fail_json('unable to connect to %s: %s' % (host, to_native(exc)))
|
|
|
|
return device
|
|
|
|
|
|
def transfer_files(module, device):
|
|
dest = module.params['dest']
|
|
recursive = module.params['recursive']
|
|
|
|
with SCP(device) as scp:
|
|
for src in module.params['src']:
|
|
if module.params['remote_src']:
|
|
scp.get(src.strip(), local_path=dest, recursive=recursive)
|
|
else:
|
|
scp.put(src.strip(), remote_path=dest, recursive=recursive)
|
|
|
|
|
|
def main():
|
|
""" Main entry point for Ansible module execution
|
|
"""
|
|
argument_spec = dict(
|
|
src=dict(type='list', required=True),
|
|
dest=dict(type='path', required=False, default="."),
|
|
recursive=dict(type='bool', default=False),
|
|
remote_src=dict(type='bool', default=False),
|
|
transport=dict(default='netconf', choices=['netconf'])
|
|
)
|
|
|
|
argument_spec.update(junos_argument_spec)
|
|
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
supports_check_mode=True)
|
|
|
|
if module.params['provider'] is None:
|
|
module.params['provider'] = {}
|
|
|
|
if not HAS_PYEZ:
|
|
module.fail_json(
|
|
msg='junos-eznc is required but does not appear to be installed. '
|
|
'It can be installed using `pip install junos-eznc`'
|
|
)
|
|
|
|
result = dict(changed=True)
|
|
|
|
if not module.check_mode:
|
|
# open pyez connection and transfer files via SCP
|
|
try:
|
|
device = connect(module)
|
|
transfer_files(module, device)
|
|
except Exception as ex:
|
|
module.fail_json(
|
|
msg=to_native(ex)
|
|
)
|
|
finally:
|
|
try:
|
|
# close pyez connection and ignore exceptions
|
|
device.close()
|
|
except Exception:
|
|
pass
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|