Transfer Files Using Junos PyEZ
Junos PyEZ provides utilities that enable you to perform file
management tasks on devices running Junos OS. You can use the Junos
PyEZ jnpr.junos.utils.scp.SCP
class to secure copy
(SCP) files between the local host and a device running Junos OS.
The SCP
open()
and close()
methods establish and terminate
the connection with the device. As a result, if the client application
only performs file copy operations, it can omit calls to the Device
open()
and close()
methods. Instances of the SCP
class can be used as context managers, which
automatically call the open()
and close()
methods. For example:
from jnpr.junos import Device from jnpr.junos.utils.scp import SCP dev = Device('router1.example.com') with SCP(dev) as scp: scp.put('local-file', remote_path='path') scp.get('remote-file', local_path='path')
Starting in Junos PyEZ Release 1.2.3, SCP
introduces new ways to enable you to track the progress of transfers
using the progress
parameter. By default, SCP
does not print progress messages. Set progress=True
to print default progress messages at
transfer completion intervals of 10 percent or greater.
with SCP(dev, progress=True) as scp:
Alternatively, you can define a custom function to print
progress messages, and then set the progress
parameter equal to the name of the function. The function definition
should include two parameters corresponding to the device instance
and the progress message. For example:
def log(dev, report): print (dev.hostname + ': ' + report) def main(): ... with SCP(dev, progress=log) as scp:
The following sample program transfers the scp-test1.txt and scp-test2.txt files from the local host to the /var/tmp directory on the target device, and then transfers the messages log file from the target device to a logs directory on the local host. The messages log is renamed to append the device hostname to the filename. The example uses SSH keys, which are already configured on the local host and the device, for authentication.
For comparison purposes, the program uses both the default progress
messages as well as custom messages, which are defined in the function
named log
, to track the progress of the
transfers.
from jnpr.junos import Device from jnpr.junos.utils.scp import SCP def log(dev, report): print (dev.hostname + ': ' + report) def main(): dev = Device('router1.example.com') msgfile = 'logs/'+dev.hostname+'-messages' try: #Default progress messages with SCP(dev, progress=True) as scp1: scp1.put('scp-test1.txt', remote_path='/var/tmp/') scp1.get('/var/log/messages', local_path=msgfile) #Custom progress messages with SCP(dev, progress=log) as scp2: scp2.put('scp-test2.txt', remote_path='/var/tmp/') scp2.get('/var/log/messages', local_path=msgfile) except Exception as err: print (err) return if __name__ == "__main__": main()
The progress of the transfers is sent to standard output.
The default output (progress=True
) includes
the device name, the file being transferred, and the progress of the
transfer in both bytes and as a percentage.
router1.example.com: scp-test1.txt: 8 / 8 (100%) router1.example.com: logs/router1.example.com-messages: 0 / 229513 (0%) router1.example.com: logs/router1.example.com-messages: 24576 / 229513 (10%) router1.example.com: logs/router1.example.com-messages: 139264 / 229513 (60%) router1.example.com: logs/router1.example.com-messages: 229513 / 229513 (100%)
The custom function produces similar output in this case.
router1.example.com : scp-test2.txt: 1 / 1 (100%) router1.example.com : logs/router1.example.com-messages: 0 / 526493 (0%) router1.example.com : logs/router1.example.com-messages: 57344 / 526493 (10%) router1.example.com : logs/router1.example.com-messages: 106496 / 526493 (20%) router1.example.com : logs/router1.example.com-messages: 212992 / 526493 (40%) router1.example.com : logs/router1.example.com-messages: 319488 / 526493 (60%) router1.example.com : logs/router1.example.com-messages: 368640 / 526493 (70%) router1.example.com : logs/router1.example.com-messages: 475136 / 526493 (90%) router1.example.com : logs/router1.example.com-messages: 526493 / 526493 (100%)
After executing the program, issue the file list
command on the target device to
verify that the scp-test1.txt and
scp-test2.txt files were copied to the correct
directory.
user1@router1> file list /var/tmp/scp-test* /var/tmp/scp-test1.txt /var/tmp/scp-test2.txt
On the local host, the messages log file, which is renamed to include the device hostname, should be present in the logs directory.
[user1@server ~]$ ls logs router1.example.com-messages
By default, Junos PyEZ queries the default SSH configuration
file at ~/.ssh/config, if one exists.
However, you can specify a different SSH configuration file when you
create the device instance by including the ssh_config
parameter in the Device
argument list.
For example:
ssh_config_file = '~/.ssh/config_dc' dev = Device('198.51.100.1', ssh_config=ssh_config_file)
Starting in Junos PyEZ Release 2.0.1, when you include
the ssh_private_key_file
parameter in the Device
argument list to define a specific SSH private
key file for authentication, the SCP
instance
uses the same key file for authentication when transferring files.
key_file='/home/user1/.ssh/id_rsa_dc' dev = Device('198.51.100.1', ssh_private_key_file=key_file) with SCP(dev) as scp: scp.put('scp-test.txt', remote_path='/var/tmp/')
The SCP
class also provides support
for ProxyCommand, which enables you to transfer files from the local
host to the target device through an intermediary host that supports
netcat. This is useful when you can only log in to the target device
through the intermediate host. To configure ProxyCommand, add the
appropriate information to the SSH configuration file. For example:
[user1@server ~]$ cat ~/.ssh/config Host 198.51.100.1 User user1 ProxyCommand ssh -l user1 198.51.100.2 nc %h 22 2>/dev/null