1

I am working on a script that checks the storage space on a network device. It then checks to see if that space can accommodate a specific-sized file to be loaded onto it. What I would like to do is have a text file which lists the different files sizes which can be amended ad hoc. The script would then look at a specific line in this file for the data that is relevant for that task.

So at the moment in the script, I have the following information defined.

#Cisco IOS 2811 Data

new_ios_2811 = "c2800nm-ipvoice_ivs-mz.151-2.T1.bin"

new_ios_2811_size = "51707860"

new_ios_2811_md5 = "bf3e0811b5626534fd2e4b68cdd042df"

So in this example, I want to replace "51707860" in the text file on the second line. How would I call this into the script?

Troll
  • 1,978
  • 3
  • 13
  • 30
Steve
  • 19
  • 4
  • What are you using to connect to the network device, `netmiko`, `napalm`, ... ? You said you want to replace 51707860 in the text file, with what? Correct me if I am wrong, you want to add a new IOS image on a network device but you want to check if the flash has enough space and upload it if enough space is available? – Tes3awy Oct 31 '21 at 18:54
  • 1
    Hi, yes I am using netmiko. So basically I have new_ios_2811_size = "51707860" defined in the python script. I would like to instead have the 51707860 info held on a text file instead. So yes I am looking to check the device has enough space. But as and when that IOS file changes to a newer version I can amend the size in the text file rather than the script. Hope that makes sense. :) – Steve Nov 02 '21 at 16:17

1 Answers1

0

I guess the demo below illustrates what you need

import sys

import requests
from netmiko.ssh_dispatcher import ConnectHandler


def calc_size(url: str) -> int:
    r = requests.head(url, allow_redirects=True)
    return r.headers.get("Content-Length", -1)


device = {
    "device_type": "cisco_ios",
    "ip": "sandbox-iosxe-latest-1.cisco.com",
    "username": "developer",
    "password": "C1sco12345",
    "secret": "",
    "fast_cli": False,
}

new_ios_2811 = ""  # add IOS image url here
new_ios_2811_size = calc_size(url="https://python.org")  # gets IOS image size
# print(size, f"{'FILE SIZE':<40}: {int(size) / float(1 << 20):.2f} MB")
new_ios_2811_md5 = "bf3e0811b5626534fd2e4b68cdd042df"

with ConnectHandler(**device) as conn:
    print(f"Connected to {conn.host}")
    if not conn.check_enable_mode():
        conn.enable()
    content = conn.send_command(command_string="dir flash:", use_textfsm=True)

    print("Calculating available flash space...")
    for f in content:
        d = int(f["total_free"]) - int(new_ios_2811_size)
        if f["total_free"] <= new_ios_2811_size:
            raise SystemExit(
                f"Not enough free space available! Only {f['total_free']} (Need more {abs(d)})",
                file=sys.stderr,
            )

        print(
            f"You can upload the new IOS image safely. free size after upload {d}/{f['total_size']}"
        )

        break

    print("Uploading...")

    """
    Do the upload here (SCP/TFTP/FTP/SFTP)
    Example function
    status = upload_ios_image(image=new_ios_2811, md5=new_ios_2811_md5)
    where status checks if upload was successful and md5 hash was verified
    """

Used requests instead of urllib and requests.head in order to not download the file to the host and retransfer to the network device.

Tes3awy
  • 2,094
  • 4
  • 24
  • 47
  • Thanks for the reply. So I guess this is based on the ios file being in the same directory as the script? Ideally the ios file would be contained on a TFTP server. – Steve Nov 03 '21 at 13:04
  • @Steve Yes, that's right. The file should be within the same directory or on the localhost. However, if you want the file size from a TFTP server (before transfer), then you need to do the equivalent, please [check this answer](https://stackoverflow.com/questions/5909/get-size-of-a-file-before-downloading-in-python#answer-5985). Let me know if this is what you need to update my answer. – Tes3awy Nov 03 '21 at 21:36
  • Hi, yes I think this would work. This would be ideal so that whenever the IOS file is changed python can collect the file size from the remote server. – Steve Nov 04 '21 at 08:26
  • @Steve Please check the updated answer – Tes3awy Nov 06 '21 at 10:32
  • Perfect, I'll have a play with this. Thankyou! – Steve Nov 10 '21 at 09:12