Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

header-navigation
keyboard_arrow_up
close
keyboard_arrow_left
Junos PyEZ Developer Guide
Table of Contents Expand all
list Table of Contents
file_download PDF
{ "lLangCode": "en", "lName": "English", "lCountryCode": "us", "transcode": "en_US" }
English
keyboard_arrow_right

Transfer Files Using Junos PyEZ

date_range 20-May-24

Use Junos PyEZ to secure copy (SCP) files between the local host and a Junos device.

Junos PyEZ provides utilities that enable you to perform file management tasks on Junos devices. You can use the Junos PyEZ jnpr.junos.utils.scp.SCP class to secure copy (SCP) files between the local host and a Junos device.

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:

content_copy zoom_out_map
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')

SCP enables 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.

content_copy zoom_out_map
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:

content_copy zoom_out_map
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.

content_copy zoom_out_map
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.

content_copy zoom_out_map
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.

content_copy zoom_out_map
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.

content_copy zoom_out_map
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.

content_copy zoom_out_map
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:

content_copy zoom_out_map
    ssh_config_file = '~/.ssh/config_dc'
    dev = Device('198.51.100.1', ssh_config=ssh_config_file)

Additionally, 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.

content_copy zoom_out_map
    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:

content_copy zoom_out_map
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
footer-navigation