Search code examples
pythonbackupparamikocisco-iosnetmiko

Python netmiko create folder Today date


Am I running below script to take backup of Cisco switches. It's actually working, but I am unable to create folder with today's date and placing the backup files into that folder.

I can create folder but can't see the backup file. How to place backup files into the todays' directory?

Expected OUTPUT

/tftpdata/Region1/20210804/southswitch-192.168.1.4_04-08-2021_14:22:22

Or creating subfolder for the switch IP by calling it from iplist.

/tftpdata/Region1/20210804/192.168.1.4/southswitch-192.168.1.4_04-08-2021_14:22:22

/tftpdata/Region1/20210804/192.168.1.5/southswitch-192.168.1.5_04-08-2021_14:22:22

iplist file contains below IPs:

192.168.1.4 192.168.1.5

import paramiko
import time
from getpass import getpass
import os, datetime

TNOW = datetime.datetime.now().replace(microsecond=0)
TFORMAT = '{:%d-%m-%Y_%H:%M:%S}'.format(TNOW)

target_dir = '/tftpdata/Region1/'
today = target_dir + time.strftime('%Y%m%d')
now = time.strftime('%H%M%S')
if not os.path.exists(today):
    os.mkdir(today)
    print ('\n Create folder successfully', today )
else:
    print ( today,'\n Folder already exists' )
os.chown (str(today), 1000,1001)

username = 'admin'
password = 'XXXXXXXXxx'

DEVICE_LIST = open ('iplist')
for RTR in DEVICE_LIST:
    RTR = RTR.strip()
    print ('\n #### Connecting to the device ' + RTR + '####\n' )
    SESSION = paramiko.SSHClient()
    SESSION.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    SESSION.connect(RTR,port=22,
                    username=username,
                    password=password,
                    look_for_keys=False,
                    allow_agent=False)
    DEVICE_ACCESS = SESSION.invoke_shell()
    DEVICE_ACCESS.send('copy running-config tftp://10.10.1.12/Region1/' +today+'/southswitch' + RTR + '_'+TFORMAT + '\n\n')
    time.sleep(5)
    time.sleep(1)
    print ('Backup completed for the device ' + RTR + '\n\n')
    SESSION.close()

Solution

  • You don't have to transfer the running-config through TFTP. All you need to do is to create a file on your PC/server and save it to the folder you created already.

    On some operating systems (Windows), the colon (:) is not allowed in folders or file names. Please avoid using it.

    Here is something similar to what you want to acheive:

    import os
    import time
    from datetime import datetime
    
    import paramiko
    
    TNOW = datetime.now().replace(microsecond=0)
    TFORMAT = TNOW.strftime("%d-%m-%Y_%H:%M:%S")
    
    target_dir = "tftpdata/Region1/"
    today = target_dir + time.strftime("%Y-%m-%d")
    now = TNOW.strftime("%H:%M:%S")
    
    if not os.path.isdir(today):  # Changed to os.path.isdir
        os.makedirs(today)
        print(f"\nCreated {today} folder successfully", today)
    else:
        print(f"\n{today} folder already exists!")
    
    username = "cisco"
    password = "cisco"
    
    DEVICE_LIST = open("iplist")
    for RTR in DEVICE_LIST:
        RTR = RTR.strip()
        print(f"\n#### Connecting to the device {RTR} ####\n")
        SESSION = paramiko.SSHClient()
        SESSION.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        SESSION.connect(
            RTR,
            port=22,
            username=username,
            password=password,
            look_for_keys=False,
            allow_agent=False,
        )
        
        # Used `exec_command` instead of `send`
        stdin, stdout, stderr = SESSION.exec_command("show running-config")
    
        with open(f"{today}/{RTR}-running-config.txt", "w") as outfile:
            outfile.write(str(stdout.read().decode("utf-8")))
        print(f"Backup completed for the {RTR}\n")
    
        SESSION.close()
    DEVICE_LIST.close()  # Don't forget to close the iplist file
    

    And even a better version of my code is:

    import os
    from datetime import date
    
    import paramiko
    
    today = date.today()
    target_dir = f"tftpdata/Region1/{today}"
    
    # Check if the target directory is created
    if not os.path.isdir(target_dir):
        os.makedirs(target_dir)
        print(f"\nCreated {target_dir} folder successfully")
    else:
        print(f"\n{target_dir} folder already exists!")
    
    # Username and password
    usr = "developer"
    pwd = "C1sco12345"
    
    # Read `iplist.txt` and create a list of IP Addresses
    with open("iplist.txt", "r") as iplist:
        DEVICE_LIST = [ip for ip in iplist.read().splitlines()]
    
    for DEVICE in DEVICE_LIST:
        print(f"\n#### Connecting to {DEVICE} ####\n")
        # Use `with` statement (Context Manager) to automatically close the connection
        with paramiko.SSHClient() as SESSION:
            SESSION.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            SESSION.connect(
                DEVICE,
                port=22,
                username=usr,
                password=pwd,
                look_for_keys=False,
                allow_agent=False,
            )
            
            # Sending command by `exec_command`
            stdin, stdout, stderr = SESSION.exec_command("show running-config")
    
            with open(f"{target_dir}/{DEVICE}-running-config-{today}.txt", "w") as outfile:
                outfile.write(stdout.read().decode("utf-8").lstrip().replace("\n", ""))
    
        print(f"Backup completed for {DEVICE}\n")
    
    

    UPDATE

    Since switches type is sg300, and it is implemented already in netmiko. To do the same thing using netmiko is like below:

    import csv
    import os
    from datetime import date
    
    from netmiko import ConnectHandler
    
    today = date.today()
    target_dir = f"tftpdata/Region1/{today}"
    
    # Check if the target directory is created
    if not os.path.isdir(target_dir):
        os.makedirs(target_dir)
        print(f"\nCreated {target_dir} folder successfully")
    else:
        print(f"\n{target_dir} folder already exists!")
    
    # Username and password
    usr = "developer"
    pwd = "C1sco12345"
    
    # Read `iplist.csv` and create a list of IP Addresses
    # Notice here iplist is a CSV file not text file
    with open(file="iplist.csv", mode="r") as iplist:
        reader = csv.reader(iplist)
        DEVICE_LIST = [
            {
                "device_type": "cisco_s300",
                "ip": ip.strip(),
                "username": usr,
                "password": pwd,
                "fast_cli": False,
            }
            for ip in iplist
        ]
    
    for DEVICE in DEVICE_LIST:
        print(f'\n#### Connecting to {DEVICE["ip"]} ####\n')
        with ConnectHandler(**DEVICE) as ssh_conn:
            # You don't need to send `terminal length 0`. netmiko handles this for you
            running_config = ssh_conn.send_command("show running-config")
    
        with open(
            f'{target_dir}/{DEVICE["ip"]}-running-config-{today}.txt', "w"
        ) as outfile:
            outfile.write(running_config.lstrip())
        print(f'Backup completed for {DEVICE["ip"]}\n')
    

    And the iplist.csv

    iplist