├── .gitignore ├── LICENSE ├── README.md ├── backup_hosts.csv ├── gui.py ├── multivendor_run.py ├── requirements.txt └── vendor_backups ├── cisco_asa.py ├── cisco_ios.py ├── fortinet.py ├── huawei.py ├── juniper.py ├── microtik.py └── vyos.py /.gitignore: -------------------------------------------------------------------------------- 1 | backup-config 2 | .idea/ 3 | dev_hosts.csv 4 | vendor_backups/__pycache__ 5 | __pycache__ 6 | .vscode 7 | dist 8 | build 9 | gui.spec -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alexander Muñoz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python3 Multivendor Backup 2 | [![published](https://static.production.devnetcloud.com/codeexchange/assets/images/devnet-published.svg)](https://developer.cisco.com/codeexchange/github/repo/AlexMunoz905/Python-Cisco-Backup) 3 | 4 | Backup your network configuration of a supported vendor, with easy options for automation. 5 | #### Supported Vendors 6 | * Cisco IOS & ASA 7 | * Juniper 8 | * VyOS 9 | * Huawei 10 | * Fortinet 11 | * MicroTik 12 | 13 | This is running on Python3 with Netmiko, and ping3. 14 | Version 2.1 15 | 16 | ## Example: 17 | CLI 18 | 19 | ![Screenshot of manual option](https://i.imgur.com/46JnIdM.png) 20 | GUI 21 | 22 | ![Screenshot of GUI option](https://i.imgur.com/bmbiNce.png) 23 | 24 | ## Installation 25 | 26 | 1. You must have Python3 and PIP installed on the device you are running the program on. 27 | 2. You need to run `pip3 install netmiko` or `pip install netmiko` in a command prompt / terminal on your computer. 28 | 3. You need to run `pip3 install ping3` or `pip install ping3` in a command prompt / terminal on your computer. 29 | 4. You need to download this repository or copy all of the contents of the run.py file into a python file. 30 | 31 | ## Usage of this program 32 | #### CLI 33 | 1. To run this, you need to run `python3 multivendor_run.py` in your terminal or command prompt. 34 | 2. Host list will be taken from `backup_hosts.csv`. Please populate the file with the host, username, password, with **optional** secret for cisco devices. 35 | 3. It will copy the saved configuration into a folder named `backup-config` in the same directory of the python file. The configuration file name will be the Cisco device hostname, date, and time. Unreachable hosts will be listed in a separated file named `downDevices_` + date and time. 36 | 37 | #### GUI 38 | 1. Download & run executable from GitHub releases tab. 39 | 2. Select the vendor you want to copy the config of. 40 | 3. Select the CSV file from the popup window. 41 | 4. It'll give you a popup for each successfull configuration copied, as well as for each down host, if any. 42 | 43 | ## Getting help 44 | 45 | If you are having trouble or need help, create an issue [here](https://github.com/alexmunoz905/Python-Cisco-Backup/issues) 46 | 47 | ## Contributors 48 | [ste-giraldo](https://github.com/ste-giraldo) for adding a memory and cpu saving feature to grabbing the hostname, and suggesting the ping feature. 49 | 50 | ## Credits and references 51 | 52 | I'd like to credit Kirk Byers for making [Netmiko](https://github.com/ktbyers/netmiko), and Kyan for making [Ping3](https://github.com/kyan001/ping3) 53 | 54 | ---- 55 | 56 | ## Licensing info 57 | 58 | This code is with the MIT license. 59 | -------------------------------------------------------------------------------- /backup_hosts.csv: -------------------------------------------------------------------------------- 1 | IP,Username,Password,Enable_Secret 2 | 10.0.0.1,username,password,secret 3 | 10.0.0.2,username,password,secret 4 | 10.0.0.3,username,password 5 | 10.0.0.4,username,password -------------------------------------------------------------------------------- /gui.py: -------------------------------------------------------------------------------- 1 | from csv import reader 2 | from datetime import datetime 3 | from netmiko import ConnectHandler 4 | from ping3 import ping, verbose_ping 5 | from vendor_backups import cisco_ios,cisco_asa,fortinet,huawei,juniper,microtik,vyos 6 | import os 7 | from tkinter import * 8 | from tkinter.ttk import * 9 | from tkinter.filedialog import * 10 | from tkinter import messagebox 11 | 12 | # Initializes Tkinter 13 | root = Tk() 14 | root.title("Backup Configurator") 15 | tk_frame = Frame(root) 16 | tk_frame.pack(expand=True) 17 | 18 | # Checks if the folder exists, if not, it creates it. 19 | if not os.path.exists('backup-config'): 20 | os.makedirs('backup-config') 21 | 22 | # Current time and formats it to the North American time of Month, Day, and Year. 23 | now = datetime.now() 24 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 25 | 26 | # Popup window that tells that the backup worked 27 | def backup_completion_popup(backup_file_name): 28 | messagebox.showinfo("Configuration Backup","Saved To: " + backup_file_name) 29 | 30 | # Popup window that tells user each down host 31 | def down_host_popup(down_host_ip): 32 | messagebox.showinfo("Down Host","Down Host: " + down_host_ip) 33 | 34 | # Main function. 35 | def run_script(user_selection): 36 | file_path = askopenfilename(title="Open CSV File", filetypes=[("CSV files", "*.csv")]) 37 | if file_path: 38 | with open(file_path, 'r') as read_obj: 39 | csv_reader = reader(read_obj) 40 | list_of_rows = list(csv_reader) 41 | rows = len(list_of_rows) 42 | while rows >= 2: 43 | rows = rows - 1 44 | ip = list_of_rows[rows][0] 45 | # Pings the hosts in the CSV file, successful pings move onto the else statement. 46 | # Unsuccessful pings go into a down_devices file. 47 | ip_ping = ping(ip) 48 | if ip_ping == None: 49 | fileName = "down_devices_" + dt_string + ".txt" 50 | downDeviceOutput = open("backup-config/" + fileName, "a") 51 | downDeviceOutput.write(str(ip) + "\n") 52 | down_host_popup(str(ip)) 53 | else: 54 | # Based on user selection, run the script in the vendor_backups folder. The passed variables are hosts, username, password, and optional secret. 55 | if user_selection == "1": 56 | cisco_ios.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2], list_of_rows[rows][3]) 57 | backup_completion_popup(cisco_ios.gui_filename_output) 58 | elif user_selection == "2": 59 | cisco_asa.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2], list_of_rows[rows][3]) 60 | backup_completion_popup(cisco_asa.gui_filename_output) 61 | elif user_selection == "3": 62 | juniper.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 63 | backup_completion_popup(juniper.gui_filename_output) 64 | elif user_selection == "4": 65 | vyos.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 66 | backup_completion_popup(vyos.gui_filename_output) 67 | elif user_selection == "5": 68 | huawei.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 69 | backup_completion_popup(huawei.gui_filename_output) 70 | elif user_selection == "6": 71 | fortinet.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 72 | backup_completion_popup(fortinet.gui_filename_output) 73 | elif user_selection == "7": 74 | microtik.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 75 | backup_completion_popup(microtik.gui_filename_output) 76 | 77 | # Build the button and assign values 78 | tk_cisco_ios = Button(tk_frame, text="Cisco IOS", command=lambda : run_script("1")) 79 | tk_cisco_asa = Button(tk_frame, text="Cisco ASA", command=lambda : run_script("2")) 80 | tk_juniper = Button(tk_frame, text="Juniper", command=lambda : run_script("3")) 81 | tk_vyos = Button(tk_frame, text="VyOS", command=lambda : run_script("4")) 82 | tk_huawei = Button(tk_frame, text="Huawei", command=lambda : run_script("5")) 83 | tk_fortinet = Button(tk_frame, text="Fortinet", command=lambda : run_script("6")) 84 | tk_microtik = Button(tk_frame, text="Microtik", command=lambda : run_script("7")) 85 | 86 | # Place the button on the GUI 87 | tk_cisco_ios.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 88 | tk_cisco_asa.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 89 | tk_juniper.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 90 | tk_vyos.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 91 | tk_huawei.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 92 | tk_fortinet.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 93 | tk_microtik.pack(side=LEFT, padx=5, fill=BOTH, expand=True) 94 | 95 | # Runs the gui 96 | mainloop() -------------------------------------------------------------------------------- /multivendor_run.py: -------------------------------------------------------------------------------- 1 | # All pre-installed besides Netmiko and ping3. 2 | from csv import reader 3 | from datetime import datetime 4 | from netmiko import ConnectHandler 5 | from ping3 import ping, verbose_ping 6 | from vendor_backups import cisco_ios,cisco_asa,fortinet,huawei,juniper,microtik,vyos 7 | import os 8 | 9 | # Specified CSV file for the script to grab the hosts from. 10 | csv_name = "backup_hosts.csv" 11 | 12 | # Checks if the folder exists, if not, it creates it. 13 | if not os.path.exists('backup-config'): 14 | os.makedirs('backup-config') 15 | 16 | # Current time and formats it to the North American time of Month, Day, and Year. 17 | now = datetime.now() 18 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 19 | 20 | # Main function. 21 | def run_script(user_selection): 22 | # Imports the CSV file specified in the csv_name variable. 23 | with open(csv_name, 'r') as read_obj: 24 | csv_reader = reader(read_obj) 25 | list_of_rows = list(csv_reader) 26 | rows = len(list_of_rows) 27 | while rows >= 2: 28 | rows = rows - 1 29 | ip = list_of_rows[rows][0] 30 | # Pings the hosts in the CSV file, successful pings move onto the else statement. 31 | # Unsuccessful pings go into a down_devices file. 32 | ip_ping = ping(ip) 33 | if ip_ping == None: 34 | fileName = "down_devices_" + dt_string + ".txt" 35 | downDeviceOutput = open("backup-config/" + fileName, "a") 36 | downDeviceOutput.write(str(ip) + "\n") 37 | print(str(ip) + " is down!") 38 | else: 39 | # Based on user selection, run the script in the vendor_backups folder. The passed variables are hosts, username, password, and optional secret. 40 | if user_selection == "1": 41 | cisco_ios.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2], list_of_rows[rows][3]) 42 | elif user_selection == "2": 43 | cisco_asa.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2], list_of_rows[rows][3]) 44 | elif user_selection == "3": 45 | juniper.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 46 | elif user_selection == "4": 47 | vyos.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 48 | elif user_selection == "5": 49 | huawei.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 50 | elif user_selection == "6": 51 | fortinet.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 52 | elif user_selection == "7": 53 | microtik.backup(list_of_rows[rows][0], list_of_rows[rows][1], list_of_rows[rows][2]) 54 | 55 | # Asks the user what option they are going to use. 56 | print("\n1. Backup Cisco IOS devices.") 57 | print("2. Backup Cisco ASA devices.") 58 | print("3. Backup Juniper devices.") 59 | print("4. Backup VyOS routers.") 60 | print("5. Backup Huawei boxes.") 61 | print("6. Backup Fortinet devices.") 62 | print("7. Backup MicroTik devices.\n") 63 | user_selection = input("Please pick an option: ") 64 | # Pass the users choice to the main function. 65 | run_script(user_selection) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | netmiko>=4.3.0 2 | ping3>=4.0.8 3 | -------------------------------------------------------------------------------- /vendor_backups/cisco_asa.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | 9 | # Gives us the information we need to connect to Cisco devices. 10 | def backup(host, username, password, enable_secret): 11 | cisco_asa = { 12 | 'device_type': 'cisco_asa', 13 | 'host': host, 14 | 'username': username, 15 | 'password': password, 16 | 'secret': enable_secret, 17 | } 18 | # Creates the connection to the device. 19 | net_connect = ConnectHandler(**cisco_asa) 20 | net_connect.enable() 21 | # any reason not to use netmiko built-in func to find a hostname? Try it, and if you like it - replace everywhere. YW 22 | hostname = net_connect.find_prompt().replace('#', '').replace('>', '') 23 | if not hostname: 24 | # Gets and splits the hostname for the output file name. 25 | hostname = net_connect.send_command("show conf | i hostname") 26 | hostname = hostname.split() 27 | hostname = hostname[1] 28 | # Gets the running configuration. 29 | output = net_connect.send_command("show run") 30 | 31 | # Creates the file name, which is the hostname, and the date and time. 32 | fileName = hostname + "_" + dt_string 33 | # Creates the text file in the backup-config folder with the special name, and writes to it. 34 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 35 | backupFile.write(output) 36 | print("Outputted to " + fileName + ".txt") 37 | # For the GUI 38 | global gui_filename_output 39 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/cisco_ios.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to Cisco devices. 9 | def backup(host, username, password, enable_secret): 10 | cisco_ios = { 11 | 'device_type': 'cisco_ios', 12 | 'host': host, 13 | 'username': username, 14 | 'password': password, 15 | 'secret': enable_secret, 16 | } 17 | # Creates the connection to the device. 18 | net_connect = ConnectHandler(**cisco_ios) 19 | net_connect.enable() 20 | #any reason not to use netmiko built-in func to find a hostname? Try it, and if you like it - replace everywhere. YW 21 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 22 | if not hostname: 23 | # Gets and splits the hostname for the output file name. 24 | hostname = net_connect.send_command("show conf | i hostname") 25 | hostname = hostname.split() 26 | hostname = hostname[1] 27 | # Gets the running configuration. 28 | output = net_connect.send_command("show run") 29 | 30 | # Creates the file name, which is the hostname, and the date and time. 31 | fileName = hostname + "_" + dt_string 32 | # Creates the text file in the backup-config folder with the special name, and writes to it. 33 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 34 | backupFile.write(output) 35 | print("Outputted to " + fileName + ".txt") 36 | # For the GUI 37 | global gui_filename_output 38 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/fortinet.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to Fortinet devices. 9 | def backup(host, username, password): 10 | fortinet = { 11 | 'device_type': 'fortinet', 12 | 'host': host, 13 | 'username': username, 14 | 'password': password 15 | } 16 | # Creates the connection to the device. 17 | net_connect = ConnectHandler(**fortinet) 18 | net_connect.enable() 19 | # Gets the running configuration. 20 | output = net_connect.send_command("show") 21 | 22 | # Creates the file name, which is the hostname, and the date and time. 23 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 24 | if not hostname: 25 | hostname = host 26 | fileName = host + "_" + dt_string 27 | else: 28 | fileName = hostname + "_" + dt_string 29 | # Creates the text file in the backup-config folder with the special name, and writes to it. 30 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 31 | backupFile.write(output) 32 | print("Outputted to " + fileName + ".txt!") 33 | # For the GUI 34 | global gui_filename_output 35 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/huawei.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to Huawei devices. 9 | def backup(host, username, password): 10 | huawei = { 11 | "device_type": "huawei", 12 | 'host': host, 13 | 'username': username, 14 | 'password': password, 15 | } 16 | # Creates the connection to the device. 17 | net_connect = ConnectHandler (** huawei) 18 | net_connect.enable() 19 | # Gets the running configuration. 20 | output = net_connect.send_command("dis current-configuration") 21 | # Gets and splits the hostname for the output file name. 22 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 23 | if not hostname: 24 | hostname = net_connect.send_command("dis saved-configuration | inc sysname") 25 | hostname = hostname.split() 26 | hostname = hostname[1] 27 | # Creates the file name, which is the hostname, and the date and time. 28 | fileName = hostname + "_" + dt_string 29 | # Creates the text file in the backup-config folder with the special name, and writes to it. 30 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 31 | backupFile.write(output) 32 | print("Outputted to " + fileName + ".txt") 33 | # For the GUI 34 | global gui_filename_output 35 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/juniper.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to Juniper devices. 9 | def backup(host, username, password,): 10 | juniper = { 11 | 'device_type': 'juniper', 12 | 'host': host, 13 | 'username': username, 14 | 'password': password, 15 | } 16 | # Creates the connection to the device. 17 | net_connect = ConnectHandler(**juniper) 18 | net_connect.enable() 19 | # Gets the running configuration. 20 | output = net_connect.send_command("show conf | display set") 21 | # Gets and splits the hostname for the output file name. 22 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 23 | if not hostname: 24 | hostname = net_connect.send_command("show ver | match hostname") 25 | hostname = hostname.split() 26 | hostname = hostname[2] 27 | # Creates the file name, which is the hostname, and the date and time. 28 | fileName = hostname + "_" + dt_string 29 | # Creates the text file in the backup-config folder with the special name, and writes to it. 30 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 31 | backupFile.write(output) 32 | print("Outputted to " + fileName + ".txt") 33 | # For the GUI 34 | global gui_filename_output 35 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/microtik.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to MicroTik devices. 9 | def backup(host, username, password): 10 | microtik = { 11 | 'device_type': 'mikrotik_routeros', 12 | 'host': host, 13 | 'username': username, 14 | 'password': password, 15 | } 16 | # Creates the connection to the device. 17 | net_connect = ConnectHandler(**microtik) 18 | # Gets the running configuration. 19 | output = net_connect.send_command_timing("export", delay_factor=40) 20 | # Gets and splits the hostname for the output file name. 21 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 22 | if not hostname: 23 | hostname = net_connect.send_command("system identity print") 24 | hostname = hostname.split() 25 | hostname = hostname[1] 26 | # Creates the file name, which is the hostname, and the date and time. 27 | fileName = "config_backup-" + hostname + "_" + dt_string 28 | # Creates the text file in the backup-config folder with the special name, and writes to it. 29 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 30 | backupFile.write(output) 31 | print("Outputted to " + fileName + ".txt") 32 | # For the GUI 33 | global gui_filename_output 34 | gui_filename_output = fileName -------------------------------------------------------------------------------- /vendor_backups/vyos.py: -------------------------------------------------------------------------------- 1 | from netmiko import ConnectHandler 2 | from datetime import datetime 3 | 4 | # Current time and formats it to the North American time of Month, Day, and Year. 5 | now = datetime.now() 6 | dt_string = now.strftime("%m-%d-%Y_%H-%M") 7 | 8 | # Gives us the information we need to connect to VyOS devices. 9 | def backup(host, username, password): 10 | vyos = { 11 | 'device_type': 'vyos', 12 | 'host': host, 13 | 'username': username, 14 | 'password': password, 15 | } 16 | # Creates the connection to the device. 17 | net_connect = ConnectHandler(**vyos) 18 | net_connect.enable() 19 | # Gets the running configuration. 20 | output = net_connect.send_command("show conf comm") 21 | # Gets and splits the hostname for the output file name. 22 | hostname = net_connect.find_prompt().replace('#','').replace('>','') 23 | if not hostname: 24 | hostname = net_connect.send_command("sh conf | grep host-name | awk {'print $2'}") 25 | hostname = hostname.split() 26 | hostname = hostname[0] 27 | # Creates the file name, which is the hostname, and the date and time. 28 | fileName = hostname + "_" + dt_string 29 | # Creates the text file in the backup-config folder with the special name, and writes to it. 30 | backupFile = open("backup-config/" + fileName + ".txt", "w+") 31 | backupFile.write(output) 32 | print("Outputted to " + fileName + ".txt") 33 | # For the GUI 34 | global gui_filename_output 35 | gui_filename_output = fileName --------------------------------------------------------------------------------