net_put module: add default mode to copy binary files (#41476)

* add default mode to copy binary files

* sanity fix

* add version for new options
pull/36442/merge
Deepak Agrawal 7 years ago committed by GitHub
parent 2e68811c34
commit e91cee1a31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -42,6 +42,15 @@ options:
- Filename from src and at default directory of user shell on - Filename from src and at default directory of user shell on
network_os. network_os.
required: no required: no
mode:
description:
- Set the file transfer mode. If mode is set to 'template' then src
file will go through jinja2 template engine to replace any vars if
present in src file. If mode is set to 'binary' then file will be
copied as it is to destination device.
default: binary
choices: ['binary', 'template']
version_added: "2.7"
requirements: requirements:
- "scp" - "scp"

@ -50,18 +50,13 @@ class ActionModule(ActionBase):
result['msg'] = ('please use network_cli connection type for net_put module') result['msg'] = ('please use network_cli connection type for net_put module')
return result return result
src_file_path_name = self._task.args.get('src')
try:
self._handle_template()
except ValueError as exc:
return dict(failed=True, msg=to_text(exc))
try: try:
src = self._task.args.get('src') src = self._task.args.get('src')
except KeyError as exc: except KeyError as exc:
return {'failed': True, 'msg': 'missing required argument: %s' % exc} return {'failed': True, 'msg': 'missing required argument: %s' % exc}
src_file_path_name = src
# Get destination file if specified # Get destination file if specified
dest = self._task.args.get('dest') dest = self._task.args.get('dest')
@ -70,22 +65,38 @@ class ActionModule(ActionBase):
if proto is None: if proto is None:
proto = 'scp' proto = 'scp'
sock_timeout = play_context.timeout # Get mode if set
mode = self._task.args.get('mode')
if mode is None:
mode = 'binary'
# Now src has resolved file write to disk in current diectory for scp if mode == 'template':
filename = str(uuid.uuid4()) try:
cwd = self._loader.get_basedir() self._handle_template()
output_file = cwd + '/' + filename except ValueError as exc:
with open(output_file, 'w') as f: return dict(failed=True, msg=to_text(exc))
f.write(src)
# Now src has resolved file write to disk in current diectory for scp
src = self._task.args.get('src')
filename = str(uuid.uuid4())
cwd = self._loader.get_basedir()
output_file = cwd + '/' + filename
with open(output_file, 'w') as f:
f.write(src)
else:
try:
output_file = self._get_binary_src_file(src)
except ValueError as exc:
return dict(failed=True, msg=to_text(exc))
if socket_path is None: if socket_path is None:
socket_path = self._connection.socket_path socket_path = self._connection.socket_path
conn = Connection(socket_path) conn = Connection(socket_path)
sock_timeout = conn.get_option('persistent_command_timeout')
if dest is None: if dest is None:
dest = src_file_path_name dest = src_file_path_name
try: try:
out = conn.copy_file( out = conn.copy_file(
source=output_file, destination=dest, source=output_file, destination=dest,
@ -101,8 +112,10 @@ class ActionModule(ActionBase):
result['failed'] = True result['failed'] = True
result['msg'] = ('Exception received : %s' % exc) result['msg'] = ('Exception received : %s' % exc)
# Cleanup tmp file expanded wih ansible vars if mode == 'template':
os.remove(output_file) # Cleanup tmp file expanded wih ansible vars
os.remove(output_file)
result['changed'] = True result['changed'] = True
return result return result
@ -165,3 +178,18 @@ class ActionModule(ActionBase):
raise AnsibleError('ansible_network_os must be specified on this host to use platform agnostic modules') raise AnsibleError('ansible_network_os must be specified on this host to use platform agnostic modules')
return network_os return network_os
def _get_binary_src_file(self, src):
working_path = self._get_working_path()
if os.path.isabs(src) or urlsplit('src').scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
raise ValueError('path specified in src not found')
return source

@ -31,4 +31,20 @@
that: that:
- result.changed == true - result.changed == true
- name: copy file with non-ascii characters to ios in template mode(Fail case)
net_put:
src: nonascii.bin
mode: 'template'
register: result
ignore_errors: true
- name: copy file with non-ascii characters to ios in default mode(binary)
net_put:
src: nonascii.bin
register: result
- assert:
that:
- result.changed == true
- debug: msg="END ios cli/net_put.yaml on connection={{ ansible_connection }}" - debug: msg="END ios cli/net_put.yaml on connection={{ ansible_connection }}"

Loading…
Cancel
Save