def main(): """Execution starts here """ # The following lines added to make it easily human readable print("\n" + "*"*79) print("\n Network Automation built using NORNIR Automation Framework!!! \n") print("*"*79 + "\n") # Get IP addresses of devices you want to connect with devices_txt = input("Please enter .txt file containing IP addresses [devices.txt]: ")\ or 'devices.txt' devices = read_file(devices_txt) # Generate hosts.yaml file for NORNIR generate_hosts_yaml(devices, 'inventory/hosts.yaml') # Get the list of commands to run on each device commands_txt = input("Please enter .txt file containing commands [commands_config.txt]: ")\ or 'commands_config.txt' # Accept user credentials from the user username, password = get_credentials() # Generate defaults.yaml file for NORNIR generate_defaults_yaml(username, password) # Instantiate a NORNIR object from .yaml file nr_obj = InitNornir(config_file='config.yaml') # Push the commands to the device and print the result nr_result = nr_obj.run(task=netmiko_send_config, config_file=commands_txt) print_result(nr_result) # Wipe out defaults.yaml file to remove credentials generate_defaults_yaml('cisco', 'password') # Wipe out hosts.yaml file to remove devices IP addresses devices = ['1.1.1.1', '2.2.2.2'] generate_hosts_yaml(devices, 'inventory/hosts.yaml')
def main(): """ Execution begins here """ # The following lines added to make it easy for human users to read print('\n' + '*' * 79) print( '\n Network automation built using NORNIR Automation Framework!! \n' ) print('*' * 79 + '\n') # Get IP addresses of devices you want to connect and generate hosts.yaml file devices_txt = input('Please enter .txt file containing IP addresses [devices.txt]: ')\ or 'devices.txt' devices = read_file(devices_txt) generate_hosts_yaml(devices, 'inventory/hosts.yaml') # Get the list of commands to run on each device commands_txt = input('Please enter .txt file containing commands [commands_show.txt]: ')\ or 'commands_show.txt' commands = read_file(commands_txt) # Get user credentials from the user username, password = get_credentials() # Generate 'inventory/defaults.yaml' file containing user credential generate_defaults_yaml(username, password) # Instantiate a Nornir object from .yaml file nr_obj = InitNornir(config_file='config.yaml') # Get the current time time_now = datetime.now().isoformat(timespec='seconds') # Create a Folder as a holder for the output files dirname = 'NORNIR-' + time_now.replace(':', '') os.mkdir(dirname) # Add subfolders, EXTRA and MISSING, inside the main folder dirname_extra = '/'.join((dirname, "EXTRA")) os.mkdir(dirname_extra) dirname_missing = '/'.join((dirname, "MISSING")) os.mkdir(dirname_missing) # Iterate on each command provided by the user for cmd in commands: # Run the command cmd suing netmiko send command nr_result = nr_obj.run(task=netmiko_send_command, command_string=cmd) # Print AggregatedResult to screen # If you are going to print_result, uncomment the import line: # ... import print_result and the line below # print_result(nr_result) # Replace '|' and ' ' characters with '_' for filename cmd_name = cmd.replace('|', '_').replace(' ', '_') # Create two files for each command # filename_extra: to compare the switch config with the template filename_extra = '/'.join((dirname_extra, f'result_{cmd_name}.txt')) # filename_missing: to reverse compare the template with the switch config filename_missing = '/'.join( (dirname_missing, f'result_{cmd_name}.txt')) # Retrieve the template_file list from the command to process; each of # these template files need to exist in the parent folder template_file = read_file(f'templates/{cmd_name}.txt') # Open the file you created to write to with open(filename_extra, 'w+') as new_file: # Print to a file in a human-friendly format for device, results in nr_result.items(): if not results[0].failed: # Create interim_list by comparing the output of the command with the template interim_list = difference((results[0].result.splitlines()), template_file) # Get the final_list to print; the final_list should not contain snmp-server # location or aaa password (when hashed it will be different for each device # -- even if the password is the same) final_list = [substr for substr in interim_list if not substr.startswith(\ (' key 7', 'snmp-server location'))] # Convert the final_list to a string, out_str, and write the output to # a file if it is not empty if final_list != ['']: if final_list != []: # Convert the list to a string out_str = '\n'.join(map(str, final_list)) # Write the output to a file print(f'\n"{device}": \n\n{out_str}\n\n', file=new_file) # Open the file you created to write to with open(filename_missing, 'w+') as new_file: # Print to a file in a human-friendly format for device, results in nr_result.items(): if not results[0].failed: # Create interim_list by comparing the output of the command with the template interim_list = difference(template_file, (results[0].result.splitlines())) # Get the final_list to print; the final_list should not contain snmp-server # location or aaa password (when hashed it will be different for each device # -- even if the password is the same) final_list = [substr for substr in interim_list if not substr.startswith(\ (' key 7', 'snmp-server location'))] # Convert the final_list to a string, out_str, and write the output to # a file if it is not empty if final_list != ['']: if final_list != []: # Convert the list to a string out_str = '\n'.join(map(str, final_list)) # Write the output to a file print(f'\n"{device}": \n\n{out_str}\n\n', file=new_file) # Wipe out defaults.yaml file to remove credentials # Use 'cisco' and 'password' as place holder credentials generate_defaults_yaml('cisco', 'password') # Wipe out hosts.yaml file to remove devices IP addresses # Use 1.1.1.1 and 2.2.2.2 as a place holder IP addresses devices = ['1.1.1.1', '2.2.2.2'] generate_hosts_yaml(devices, 'inventory/hosts.yaml')
def main(): """ Execution begins here """ # The following lines added to make it easy for human users to read print('\n' + '*' * 79) print( '\n Network automation built using NORNIR Automation Framework!! \n' ) print('*' * 79 + '\n') # Get IP addresses of devices you want to connect and generate hosts.yaml file devices_txt = input('Please enter .txt file containing IP addresses [devices.txt]: ')\ or 'devices.txt' devices = read_file(devices_txt) generate_hosts_yaml(devices, 'inventory/hosts.yaml') # Get the list of commands to run on each device commands_txt = input('Please enter .txt file containing commands [commands_show.txt]: ')\ or 'commands_show.txt' commands = read_file(commands_txt) # Get user credentials from the user username, password = get_credentials() # Generate 'inventory/defaults.yaml' file containing user credential generate_defaults_yaml(username, password) # Instantiate a Nornir object from .yaml file nr_obj = InitNornir(config_file='config.yaml') # Get the current time time_now = datetime.now().isoformat(timespec='seconds') # Create a Folder as a holder for the output files dirname = 'Nornir-' + time_now.replace(':', '') os.mkdir(dirname) # Iterate on each command provided by the user for cmd in commands: nr_result = nr_obj.run(task=netmiko_send_command, command_string=cmd) # Print AggregatedResult to screen print_result(nr_result) # Replace '|' and ' ' characters with '_' for filename #cmd_name = cmd.replace('|', '_').replace(' ', '_') # Create a filename from each command filename = '/'.join( (dirname, f'result_{cmd.replace("|", "_").replace(" ", "_")}.txt')) # Open the file you created to write to with open(filename, 'w+') as new_file: # Print to a file in a human-friendly format for device, results in nr_result.items(): if not results[0].failed: print(f'\n"{device}": \n\n{results[0].result}\n\n', file=new_file) # Generate placeholder username/password to delete the # real production username/password generate_defaults_yaml('cisco', 'password')
def main(): """Execution begins here """ # The following lines added to make it easy for human users to read print('\n' + '*' * 79) print( '\n Network automation built using NORNIR Automation Framework!! \n' ) print('*' * 79 + '\n') # Get IP addresses of devices you want to connect and generate hosts.yaml file devices_txt = input('Please enter .txt file containing IP addresses [devices.txt]: ')\ or 'devices.txt' devices = read_file(devices_txt) generate_hosts_yaml(devices, 'inventory/hosts.yaml') # Get the list of commands to run on each device commands_txt = input('Please enter .txt file containing commands [commands_config.txt]: ')\ or 'commands_config.txt' # Get user credentials from the user username, password = get_credentials() # Generate 'inventory/defaults.yaml' file containing user credential generate_defaults_yaml(username, password) yes_or_no = input('\nYou are about to make configuration changes. \ Are you sure about the changes(Y/N)?[default is N] ') or 'N' if yes_or_no.upper() == 'Y': second_y_or_n = input( '\nWe are asking you again. Are you sure(Y/N)?[Y] ') or 'Y' if second_y_or_n.upper() == 'N': print( '\n\nConfiguration change cancelled during second Y/N confirmation request!!\n' ) else: # Instantiate a Nornir object from .yaml file nr_obj = InitNornir(config_file='config.yaml') # Get the current time time_now = datetime.now().isoformat(timespec='seconds') # Create a Folder as a holder for the output files dirname = 'Nornir-failed-' + time_now.replace(':', '') os.mkdir(dirname) # Run configuration changes using netmiko_send_config method nr_result = nr_obj.run(task=netmiko_send_config, config_file=commands_txt) # Print the result of the change on the client monitor print_result(nr_result) # Create a filename to store failed devices filename = '/'.join((dirname, 'failed_dev.txt')) # Open the file to write the IP Addresses of failed devices with open(filename, 'w') as failed_dev: # Print out devices with failed config changes for device, results in nr_result.items(): if results[0].failed: # Split device string at "_" sign and take the IP address print(f"{device.split('_')[1]}", file=failed_dev) # Replace username/password with a placeholder account generate_defaults_yaml('cisco', 'password') else: print('\n\nConfiguration change cancelled!!\n')