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')
Example #3
0
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')
Example #4
0
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')