Example #1
0
class AclAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    def get_all_acls(self):
        cmd = 'show ip access-list'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log("info", "(%s) get_all_acls() : Attempting to retreive all ACLs" %(__name__))
        return(self.iosapi.textfsm_extractor('cisco_ios_show_access_lists.template', output)[0])
Example #2
0
 def __init__(self, iosapi=None):
     if iosapi:
         self.iosapi = iosapi
     else:
         self.iosapi = IOSAPI()
Example #3
0
class AaaAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    #Add Functions
    def add_aaa_group(self,
                      name='',
                      type='radius',
                      ip='',
                      auth_port='1812',
                      acct_port='1813'):
        """
            Creates AAA Group if the RADIUS/TACACS Server exists in the current configuration
            > name      -   Name of AAA Group
            > type      -   radius or tacacs+
            > ip        -   Old IOS Syntax - IP of current RADIUS or TACACS+ server configured
            > auth_port -   Authentication Port
            > acct_port -   Accounting Port (if RADIUS is used)
        """
        cmds = []

        if not name:
            return ("AAA Group needs name to be configured...")

        if type == 'radius':
            cmds.append('aaa group server radius %s' % (name))
            cmds.append('server %s auth-port %s acct-port %s' %
                        (ip, auth_port, acct_port))
        if type == 'tacacs+':
            cmds.append('aaa group server tacacs+ %s' % (name))
            cmds.append('server %s' % (ip))

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmds)
        self.iosapi.bcp_log(
            "info",
            "(%s) add_aaa_group() : Attempting to add aaa group %s (%s)" %
            (__name__, name, type))

        return (output)

    def add_radius_server(self,
                          server,
                          key,
                          auth_port='1812',
                          acct_port='1813'):
        """
            Add RADIUS Server if it doesn't exist (If you would like to update an existing server, use update_radius_server()
            > server    -   Server DNS/IP
            > key       -   RADIUS Secret
            > auth_port -   Authentication Port (Default: UDP 1812)
            > acct_port -   Accounting Port (Default: UDP 1813)

            Example:
            add_radius_server('169.254.1.1', 'myradiussecret')
        """

        radius_servers = self.get_radius_servers()

        for radius_server in radius_servers:
            if radius_server['ip'] == server:
                self.iosapi.bcp_log(
                    "info",
                    "(%s) add_radius_server() : RADIUS Server %s already exist"
                    % (__name__, server))
            else:

                cmd = 'radius-server host %s auth-port %s acct-port %s key %s' % (
                    server, auth_port, acct_port, key)
                output = self.iosapi.bcp_send_config_command(
                    self.iosapi.netmiko_session, cmd)

                self.iosapi.bcp_log(
                    "info",
                    "(%s) add_radius_server() : Attempting to add radius server %s"
                    % (__name__, server))
                return (server)

    def add_tacacs_server(self, server, key, port='49'):
        """
            Add TACACS+ Server if it doesn't exist (If you would like to update an existing server, use update_tacacs_server()
            > server    -   Server DNS/IP
            > key       -   TACACS+ Secret
            > port      -   TACACS+ port (Default: TCP 49)

            Example:
            add_tacacs_server('169.254.1.1', 'mytacacskey')
        """

        tacacs_servers = self.get_tacacs_servers()

        for tacacs_server in tacacs_servers:
            if tacacs_server['ip'] == server:
                self.iosapi.bcp_log(
                    "info",
                    "(%s) add_tacacs_server() : TACACS+ server %s already exist"
                    % (__name__, server))
            else:
                if port:
                    cmd = 'tacacs-server host %s port %s key %s' % (server,
                                                                    port, key)
                else:
                    cmd = 'tacacs-server host %s key %s' % (server, key)

                output = self.iosapi.bcp_send_config_command(
                    self.iosapi.netmiko_session, cmd)
                self.iosapi.bcp_log(
                    "info",
                    "(%s) add_tacacs_server() : Attempting to add tacacs server %s"
                    % (__name__, server))
                return (server)

    def add_local_user(self, username, password='', secret='', priv_level=15):
        """
            Adds a new local user. You can define the priv level if need be

            Example:
            add_local_user('cisco', 'disco', 'mySecret')
        """

        priv_valid_range = '<0-15>'
        if priv_level not in range(0, 16):
            print("Invalid priv-level, valid range is %s" % (priv_valid_range))
            return
        if password and secret:
            print("Password and Secret can not be both configured")
            return
        if password and not secret:
            cmd = "username %s priv %s password %s" % (username, priv_level,
                                                       password)
        if secret and not password:
            cmd = "username %s priv %s secret %s" % (username, priv_level,
                                                     secret)

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info", "(%s) add_local_user() : Attempting to add local user %s" %
            (__name__, username))

        return (output)

    #Set Functions
    def set_aaa_new_model(self):
        """
            Enables AAA new-model if not configured

            Example:
            set_aaa_new_model()
        """

        cmd = 'aaa new-model'
        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_aaa_new_model : Attempting to send command aaa new-model"
            % (__name__))
        return (output)

    def set_aaa_authentication_login(self,
                                     auth_list='',
                                     local=True,
                                     group=False,
                                     group_name='',
                                     local_fallback=False):
        """
            Set AAA Method for either default or specified Group
            > auth_list         -   Authentication List (NOT USED CURRENTLY)
            > local             -   Local authentication only
            > group             -   Set to TRUE if you will be using RADIUS/TACACS+
            > group_name        -   If a group will be used, define the group name (or names eg MYRADIUS MYTACACS)
            > local_fallback    -   Local database authentication fallback if TACACS/RADIUS is unreachable

            Example:
            set_aaa_authentication_login('',False,True,'ISE_GROUP',True)
        """

        if auth_list:
            if local:
                cmd = 'aaa authentication login %s local' % (auth_list)
            else:
                if group:
                    if not group_name:
                        return ("Group name needs to be configured...")
                    else:
                        cmd = 'aaa authentication login %s group %s' % (
                            auth_list, group_name)
                    if local_fallback:
                        cmd = 'aaa authentication login %s group %s local' % (
                            auth_list, group_name)
        else:
            if local:
                cmd = 'aaa authentication login %s local' % (auth_list)
            else:
                if group:
                    if not group_name:
                        return ("Group name needs to be configured...")
                    else:
                        cmd = 'aaa authentication login default group %s' % (
                            group_name)
                    if local_fallback:
                        cmd = 'aaa authentication login default group %s local' % (
                            group_name)

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_aaa_authentication_login : Attempting to send command %s"
            % (__name__, command))
        return (output)

    def set_enable(self, pwd, type='secret'):
        """
            Create enable password
            > pwd   -   Enable Secret/Password
            > type  -   Can be either secret or password

            Example:
            set_enable('dingdong')
        """

        if type == 'secret':
            cmd = 'enable secret %s' % (pwd)
        else:
            cmd = 'enable password %s' % (pwd)

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info", "(%s) set_enable : Attempting to set enable" % (__name__))
        return (output)

    #Get Functions
    def get_local_users(self):
        """
            Returns all configured local users in JSON Style Format:

            Example:
            get_local_users()

            {'password': '******',
              'password_level': '5',
              'password_type': 'secret',
              'priv_level': '',
              'username': '******'}
        """

        cmd = 'show run'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_local_users() : Attempting to retrieve local users" %
            (__name__))

        local_users = self.iosapi.textfsm_extractor(
            'cisco_ios_local_users.template', output)

        if not local_users:
            return
        else:
            return (local_users)

    def get_radius_servers(self):
        """
            Returns RADIUS Servers in JSON Style Format

            Example:
            get_radius_servers()

            {'acct_port': '1813',
              'auth_port': '1812',
              'id': '2',
              'ip': '192.168.110.226',
              'priority': '1'},
             {'acct_port': '1813',
              'auth_port': '1812',
              'id': '3',
              'ip': '192.168.110.222',
              'priority': '2'}
        """

        cmd = 'show aaa servers'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_radius_servers() : Attempting to retrieve RADIUS servers"
            % (__name__))

        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_aaa_servers.template', output))

    def get_tacacs_servers(self):
        """
            Returns TACACS Servers in JSON Style Format

            Example:
            get_tacacs_servers()

            {'failed_connections': '0',
             'ip': '192.168.110.241',
             'packet_received': '0',
             'packets_sent': '0',
             'server_port': '49',
             'socket_aborts': '0',
             'socket_closes': '0',
             'socket_errors': '0',
             'socket_opens': '0',
             'socket_timeouts': '0',
             'tacacs_name': 'ISE01'}
        """

        cmd = 'show tacacs'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_tacacs_servers() : Attempting to retrieve TACACS+ servers"
            % (__name__))

        return (self.iosapi.textfsm_extractor('cisco_ios_show_tacacs.template',
                                              output))
class SystemAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    #Set functions
    def set_hostname(self, hostname):
        cmd = 'hostname %s' % (hostname)
        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_hostname() : Attempting to set hostname" % (__name__))
        return (output)

    def set_ip_domain_name(self, domain):
        cmd = 'ip domain-name %s' % (domain)
        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_ip_domain_name() : Attempting to set IP domain name" %
            (__name__))
        return (output)

    #Banner function needs to be revised - Plan is to provide a range of templates instead of just pasting a template
    def set_banner_motd(self, message=''):
        if not message:
            message = '''
    UNAUTHORIZED ACCESS TO THIS DEVICE IS PROHIBITED

    You must have explicit, authorized permission to access or configure this device.
    Unauthorized attempts and actions to access or use this system may result in civil and/or criminal penalties.

    All activities performed on this device are logged and monitored.
    '''

    #Get functions
    def get_hostname(self):
        output = self.iosapi.bcp_find_prompt(self.iosapi.netmiko_session)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_hostname() : Attempting to get hostname" % (__name__))
        return (
            output[:-1]
        )  #Removes either > or # from the current prompt, could also use .replace()

    def get_fqdn_name(self):
        hostname = self.get_hostname()
        domain_name = self.get_ip_domain_name()

        return ("%s.%s" % (hostname, domain_name))

    def get_ip_domain_name(self):
        cmd = 'show host'  #Not supported command on older IOS below 12.something
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_ip_domain_name() : Attempting to get IP domain name" %
            (__name__))

        if "Invalid input detected" in output:
            cmd = 'show run | include ip domain-name'
            output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session,
                                                  cmd)
            return (output.replace('ip domain-name ', ''))
        else:
            return (self.iosapi.textfsm_extractor(
                'cisco_ios_show_hosts.template', output)[0]['default_domain'])

    def get_running_config(self, backup=False, path=''):
        cmd = 'show running-config'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)

        self.iosapi.bcp_log(
            "info",
            "(%s) get_running_config() : Attempting to get running-config" %
            (__name__))

        if backup:
            try:
                backup_file = open(path, 'w')
                backup_file.write(output)
                backup_file.close()
                self.iosapi.bcp_log(
                    "info",
                    "(%s) get_running_config() : Attempting to save backup in location: %s"
                    % (__name__, path))
            except:
                self.iosapi.bcp_log(
                    "info",
                    "(%s) get_running_config() : Unable to save backup in location: %s"
                    % (__name__, path))

        return (output)

    def get_ios_version(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info", "(%s) get_ios_version() : Attempting to get IOS Version" %
            (__name__))
        return (output['version'])

    def get_uptime(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info",
            "(%s) get_uptime() : Attempting to get uptime" % (__name__))
        return (output['uptime'])

    def get_running_ios_image(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info",
            "(%s) get_running_ios_image() : Attempting to get running IOS image"
            % (__name__))
        return (output['running_image'])

    def get_hardware_model(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info",
            "(%s) get_hardware_model() : Attempting to get hardware model" %
            (__name__))

        if not output['hardware']:
            return (output['hardware'])
        else:
            return (output['hardware'][0])

    def get_serial(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info",
            "(%s) get_serial() : Attempting to get serial number" % (__name__))

        if not output['serial']:
            return (output['serial'])
        else:
            return (output['serial'][0])

    def get_config_register(self):
        output = self.template_get_ios_version()[0]
        self.iosapi.bcp_log(
            "info",
            "(%s) get_config_register() : Attempting to get config register" %
            (__name__))
        return (output['config_register'])

    def template_get_ios_version(self):
        cmd = 'show version'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_version.template', output))
Example #5
0
class MacAddressAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    def get_mac_address_table(self):
        cmd = 'show mac address-table'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_mac_address_table() : Attempting to get MAC address table"
            % (__name__))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_mac_address-table.template', output))

    def get_mac_address_interface(self, interface):
        cmd = 'show mac address-table interface %s' % (interface)
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_mac_address_interface() : Attempting to get MAC addresses from interface %s"
            % (__name__, interface))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_mac_address-table.template', output))

    def get_mac_address_vlan(self, vlan):
        if vlan not in range(0, 4095):
            return
        cmd = 'show mac address-table vlan %s' % (vlan)
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_mac_address_vlan() : Attempting to get MAC addresses from VLAN %s"
            % (__name__, vlan))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_mac_address-table.template', output))

    def get_mac_address(self, macaddr):
        cmd = 'show mac address-table address %s' % (macaddr)
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_mac_address() : Attempting to get MAC address %s" %
            (__name__, macaddr))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_mac_address-table.template', output))
Example #6
0
class StpAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    #Change Functions
    def set_stp_mode(self, mode):
        modes = ['mst', 'pvst', 'rapid-pvst']

        cmd = 'spanning-tree mode %s' %(mode)

        if mode in modes:
            output = self.iosapi.bcp_send_config_command(self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log("info", "(%s) set_stp_mode() : Attempting to set STP mode to %s" %(__name__, mode))

            return(output)
        else:
            print("Mode %s is not valid" %(mode))
            self.iosapi.bcp_log("info", "(%s) set_stp_mode() : Failed - mode %s doesn't exist" %(__name__, mode))

    def set_stp_vlan_forward_timer(self, vlan, fwd_timer):
        valid_fwd_time = '<4-30>'

        if fwd_timer in range(4,31):
            cmd = 'spanning-tree vlan %s forward-time %s' %(vlan, fwd_timer)
            output = self.iosapi.bcp_send_config_set(self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_forward_timer() : Attempting to set VLAN %s STP fwd_timer to %s" %(__name__, vlan, fwd_timer))
            return(output)
        else:
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_forward_timer() : Failed to set vlan %s STP fwd_timer to %s" %(__name__, vlan, fwd_timer))
            return("%s is not a valid value. Foward Timer range is between %s" %(fwd_timer, valid_fwd_time))

    def set_stp_vlan_hello_timer(self, vlan, hello_timer):
        valid_hello_timer = '<1-10>'

        if hello_timer in range(1,11):
            cmd = 'spanning-tree vlan %s hello-time %s' %(vlan, hello_timer)
            output = self.iosapi.bcp_send_config_set(self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_hello_timer() : Attempting to set vlan %s STP hello_timer to %s" %(__name__, vlan, hello_timer))
            return(output)
        else:
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_hello_timer() : Failed to set vlan %s STP hello_timer to %s" %(__name__, vlan, hello_timer))
            return("%s is not a valid value. Hello Timer range is between %s" %(hello_timer, valid_hello_timer))

    def set_stp_vlan_max_age(self, vlan, max_age):
        valid_max_age = '<6-40>'

        if max_age in range(6,41):
            cmd = 'spanning-tree vlan %s max-age %s' %(vlan, max_age)
            output = self.iosapi.bcp_send_config_set(self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_max_age() : Attempting to set vlan %s STP max_age to %s" %(__name__, vlan, max_age))
            return(output)
        else:
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_max_age() : Failed to set vlan %s STP max_age to %s" %(__name__, vlan, max_age))
            return("%s is not a valid value. Max Age range is between %s" %(max_age, valid_max_age))

    def set_stp_vlan_priority(self, vlan, priority):
        allowed_priorities = [0, 4096, 8192, 12288, 16384, 20480, 24576, 28672,
                             32768, 36864, 40960, 45046, 49152, 53248, 57344, 61440]

        if priority in allowed_priorities:
            cmd = 'spanning-tree vlan %s priority %s' %(vlan, priority)
            output = self.iosapi.bcp_send_config_command(self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log("info", "(%s) set_stp_vlan_pirority() : Setting VLAN %s priority to %s" %(__name__, vlan, priority))
            return(output)
        else:
            return("%s is not a valid value. \nPriority must be increments of 4096, allowed priorities are: \n%s" %(priority, allowed_priorities))

    #Gather Functions

    def get_stp_mode(self):
        stp_mode = self.get_stp_bridge()['protocol']

        if stp_mode == 'ieee':
            stp_mode = 'PVST+'

        if stp_mode == 'rstp':
            stp_mode = 'RPVST+'

        if stp_mode == 'mstp':
            stp_mode = 'MST'

        self.iosapi.bcp_log("info", "(%s) get_stp_mode() : Attempting to retreive STP mode" %(__name__))
        return(stp_mode)

    def get_stp_bridge(self):
        cmd = 'show spanning-tree bridge'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log("info", "(%s) get_stp_bridge() : Attempting to retreive STP Bridge information" %(__name__))
        return(self.iosapi.textfsm_extractor('cisco_ios_show_stp_bridge.template', output)[0])
class InterfaceAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    #Replace commands
    def replace_interfaces_access_vlan(self,
                                       current_vlan,
                                       new_vlan,
                                       backup=True):
        """
            Replaces all interfaces in a specified VLAN that are set as an administrative mode Access, to a different VLAN.
            > current_vlan  -   VLAN to match access ports currently configured in this vlan
            > new_vlan      -   VLAN to assign ports
            > backup        -   Previous configuration will be saved for every interface in the script directory for the device (Default: True)

            Example:
            replace_interfaces_access_vlan(10,20)
        """

        all_interfaces = self.get_interfaces_switchport()

        current_interface_config = self.get_interfaces_config()
        interface_backup = []

        config_set = []

        for interface in all_interfaces:
            if interface['access_vlan'] == 'none':
                pass

            elif interface['administrative_mode'] == 'static access' and int(
                    interface['access_vlan']) == current_vlan:

                interface_backup.append(
                    current_interface_config[interface['interface']])
                print(
                    "Will change port: %s from ACCESS VLAN %s to ACCESS VLAN %s"
                    % (interface['interface'], current_vlan, new_vlan))

                config_set.append('interface %s' % (interface['interface']))
                config_set.append(' switchport access vlan %s' % (new_vlan))

                self.iosapi.bcp_log(
                    "info",
                    "(%s) replace_interfaces_access_vlan() : Attempting to replace interface %s access VLAN from %s to %s"
                    %
                    (__name__, interface['interface'], current_vlan, new_vlan))

        if backup:
            config_format = {
                'old_configuration': interface_backup,
                'new_configuration': config_set
            }

            self.iosapi.create_backup(
                'replace_interfaces_access_vlan',
                json.dumps(config_format, indent=4, sort_keys=True))

        return (self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, config_set))

    def replace_interfaces_voice_vlan(self,
                                      current_vlan,
                                      new_vlan,
                                      backup=True):
        """
            Replaces the voice VLAN for all interfaces configured with the specified current voice vlan
            > current_vlan  -   Current VOICE Vlan to Match
            > new_vlan      -   VLAN to assign ports
            > backup        -   Previous configuration will be saved for every interface in the script directory for the device (Default: True)

            Example:
            replace_interfaces_voice_vlan(101, 201)
        """

        all_interfaces = self.get_interfaces_switchport()

        current_interface_config = self.get_interfaces_config()
        interface_backup = []

        config_set = []

        for interface in all_interfaces:
            if interface['voice_vlan'] == 'none':
                pass

            elif interface['administrative_mode'] == 'static access' and int(
                    interface['voice_vlan']) == current_vlan:

                interface_backup.append(
                    current_interface_config[interface['interface']])
                print(
                    "Will change port: %s from VOICE VLAN %s to VOICE VLAN %s"
                    % (interface['interface'], current_vlan, new_vlan))

                config_set.append('interface %s' % (interface['interface']))
                config_set.append(' switchport voice vlan %s' % (new_vlan))

                self.iosapi.bcp_log(
                    "info",
                    "(%s) replace_interfaces_voice_vlan() : Attempting to replace interface %s voice VLAN from %s to %s"
                    %
                    (__name__, interface['interface'], current_vlan, new_vlan))

        if backup:
            config_format = {
                'old_configuration': interface_backup,
                'new_configuration': config_set
            }

            self.iosapi.create_backup(
                'replace_interfaces_voice_vlan',
                json.dumps(config_format, indent=4, sort_keys=True))

        return (self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, config_set))

    #Set Commands
    def set_interface_ip(self, interface, ip, mask):
        """
            Configure IP Address on interface - Need to improve this function for checking etc..
            > interface     -   Interface syntax
            > ip            -   IP Address
            > mask          -   Subnet Mask

            Example:
            set_interface_ip('vlan100', '169.254.100.254', '255.255.255.0')
        """

        cmds = ['interface %s' % (interface), 'ip address %s %s' % (ip, mask)]

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmds)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_interface_ip() : Attempting to set interface %s IP" %
            (__name__, interface))
        return (output)

    def set_l2_interface_mode(self, interface, mode):
        """
            Set interface mode to either Access or Trunk
            > interface     -   Interface Syntax
            > mode          -   access or trunk

            Example:
            set_l2_interface_mode('g1/0/3', 'access')
        """

        modes = ['access', 'trunk']

        if mode not in modes:
            print("%s is an Invalid mode... Valid modes are: %s" %
                  (mode, modes))
            self.iosapi.bcp_log(
                "info",
                "(%s) set_l2_interface_mode() : Invalid mode %s for interface %s"
                % (__name__, mode, interface))

        cmds = ['interface %s' % (interface), 'switchport mode %s' % (mode)]

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmds)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_l2_interface_mode() : Attempting to set interface %s to %s"
            % (__name__, interface, mode))

        if 'encapsulation is "Auto"' in output:
            self.iosapi.bcp_log(
                "info",
                "(%s) set_l2_interface_mode() : Interface with encapsulation set to Auto can not be configured to Trunk mode"
                % (__name__))
            return (output)
        else:
            return (output)

    def set_l2_stp_portfast(self, interface, enabled=True, mode='access'):
        """
            Set Portfast on either Access port or Trunk port (Need to improve this function for additional checking)
            > interface     -   Interface Syntax
            > enabled       -   Enable Portfast
            > mode          -   access or trunk (Default: access)

            Example:
            set_l2_stp_portfast('g1/0/2', True, 'access')
        """

        cmds = ['interface %s' % (interface)]

        if mode == 'access':
            cmds.append('spanning-tree portfast')
        else:
            cmds.append('spanning-tree portfast trunk')

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmds)
        self.iosapi.bcp_log(
            "info",
            "(%s) set_l2_stp_portfast() : Attempting to set interface %s portfast state: Enabled = %s, Mode = %s"
            % (__name__, interface, enabled, mode))

        return (output)

    #Get Commands
    def get_interfaces(self):
        """
            Returns JSON type format for interfaces

            Example:
            get_interfaces()

            { 
                'address': '0cd6.448e.780f',
                'bandwidth': '1000000 Kbit',
                'bia': '0cd6.448e.780f',
                'delay': '10 usec',
                'description': '',
                'duplex': 'Full-duplex',
                'encapsulation': 'ARPA',
                'hardware_type': 'iGbE',
                'input_errors': '0',
                'input_packets': '0',
                'input_rate': '0',
                'interface': 'GigabitEthernet3/3',
                'ip_address': '',
                'last_input': 'never',
                'last_output': '00:00:00',
                'last_output_hang': 'never',
                'link_status': 'up',
                'mtu': '1500',
                'output_errors': '0',
                'output_packets': '4530',
                'output_rate': '0',
                'protocol_status': 'up (connected)',
                'queue_strategy': 'fifo',
                'speed': 'Auto-speed'
            }
        """

        cmd = 'show interfaces'

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_interfaces() : Attempting to run show interfaces" %
            (__name__))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_interfaces.template', output))

    def get_interfaces_config(self):
        """
            Returns Dictionary with List of child configuration for every port (using CiscoConfParse)

            Example:
            get_interfaces_config()

            {
                'GigabitEthernet1/1': ['interface GigabitEthernet1/1',
                                        ' media-type rj45',
                                        ' negotiation auto',
                                        ' switchport mode access'],
                 'GigabitEthernet1/2': ['interface GigabitEthernet1/2',
                                        ' description ** Link to API Server **',
                                        ' switchport trunk allowed vlan 101-104,200',
                                        ' switchport trunk encapsulation dot1q',
                                        ' switchport trunk native vlan 101',
                                        ' switchport mode trunk',
                                        ' media-type rj45',
                                        ' negotiation auto',
                                        ' ip dhcp snooping trust'],
                'Tunnel10': ['interface Tunnel10',
                                        ' ip address 169.254.10.1 255.255.255.252',
                                        ' tunnel source GigabitEthernet0/0',
                                        ' tunnel key 100',
                                        ' tunnel protection ipsec profile vpn_s03'],
                }
        """

        dict_interfaces = {}
        list_interface_config = []

        cmd = 'show running-config'
        running_configuration = self.iosapi.bcp_send_command(
            self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_interfaces_config() : Attempting to get interface config"
            % (__name__))

        parser = CiscoConfParse(running_configuration.splitlines())

        interfaces = self.get_interfaces()

        for interface in interfaces:
            interface_config = parser.find_objects(r'interface %s$' %
                                                   (interface['interface']))

            for interface_object in interface_config:
                list_interface_config = interface_object.ioscfg

            dict_interfaces[interface['interface']] = list_interface_config

        return (dict_interfaces)

    def get_interfaces_description(self):
        """
            Returns JSON type format for interface descriptions and protocol/status

            Example:
            get_interfaces_description()

            {
                'descrip': '', 
                'port': 'Gi0/0', 
                'protocol': 'up', 
                'status': 'up'
            },
            {
                'descrip': '',
                'port': 'Gi0/1',
                'protocol': 'up',
                'status': 'up'
            },
            {
                'descrip': '** Link to API Server **',
                'port': 'Gi1/2',
                'protocol': 'up',
                'status': 'up'
            }
        """

        cmd = 'show interfaces description'

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_interfaces_description() : Attempting to get interfaces description"
            % (__name__))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_interfaces_description.template', output))

    def get_interfaces_only(self):
        """
            Returns List of interfaces that exist on the device (Physical and Virtual)

            Example:
            get_interfaces_only()

            {['GigabitEthernet3/0',
                'GigabitEthernet3/1',
                'GigabitEthernet3/2',
                'GigabitEthernet3/3',
                'Loopback0',
                'Loopback1',
                'Tunnel10',
                'Vlan100',
                'Vlan101']}
        """

        interfaces = {}
        interface_list = []

        output = self.get_interfaces()

        for interface in output:
            interface_list.append(interface['interface'])

        interfaces['interfaces'] = interface_list

        return (interfaces)

    def get_interfaces_status(self):
        """
            Returns JSON type format for interface status

            Example:
            get_interfaces_status()

            {
                 'duplex': 'a-full',
                 'name': '',
                 'port': 'Gi0/0',
                 'speed': 'auto',
                 'status': 'connected',
                 'type': 'RJ45',
                 'vlan': 'routed'
             },
             {
                 'duplex': 'a-full',
                 'name': '',
                 'port': 'Gi0/1',
                 'speed': 'auto',
                 'status': 'connected',
                 'type': 'RJ45',
                 'vlan': '1'
              }
        """

        cmd = 'show interfaces status'

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_interfaces_status() : Attempting to get interfaces status"
            % (__name__))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_interfaces_status.template', output))

    def get_interfaces_switchport(self):
        """
            Returns JSON type format for interface switchports

            Example:
            get_interfaces_switchport()

                {
                     'access_vlan': '1',
                     'access_vlan_name': 'default',
                     'administrative_mode': 'dynamic auto',
                     'interface': 'GigabitEthernet1/1',
                     'operational_mode': 'static access',
                     'switchport_status': 'Enabled',
                     'voice_vlan': 'none'
                  },
                 {
                     'access_vlan': '1',
                     'access_vlan_name': 'default',
                     'administrative_mode': 'trunk',
                     'interface': 'GigabitEthernet1/2',
                     'operational_mode': 'trunk',
                     'switchport_status': 'Enabled',
                     'voice_vlan': 'none'
                }
        """

        cmd = 'show interfaces switchport'

        interface_mapper = {
            'Gi': 'GigabitEthernet',
            'Fa': 'FastEthernet',
            'TenGi': 'TenGigabitEthernet'
        }

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_interfaces_switchport() : Attempting to get interfaces switchport"
            % (__name__))

        returned_output = self.iosapi.textfsm_extractor(
            'cisco_ios_show_interfaces_switchport.template', output)
        new_output = []

        for interface in returned_output:
            for item, value in interface_mapper.items():
                interface['interface'] = interface['interface'].replace(
                    item, value)
            new_output.append(interface)

        return (new_output)

    def get_ip_int_brief(self):
        """
            Returns JSON type format for show ip int brief

            Example:
            get_ip_int_brief()

            {
                'intf': 'GigabitEthernet0/0',
                'ipaddr': '169.254.10.254',
                'proto': 'up',
                'status': 'up'
            },
            {
                'intf': 'GigabitEthernet0/1',
                'ipaddr': 'unassigned',
                'proto': 'up',
                'status': 'up'
            }

        """

        cmd = 'show ip interface brief'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_ip_int_brief() : Attempting to run show ip int brief" %
            (__name__))

        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_ip_interface_brief.template', output))
Example #8
0
class CdpAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    def set_cdp(self, enabled=True, version=2):
        cmds = []

        if enabled:
            cmds.append('cdp run')
            if version == 2:
                cmds.append('cdp advertise-v2')
            else:
                cmds.append('no cdp advertise-v2')

            self.iosapi.bcp_log(
                "info",
                "(%s) set_cdp() : Attempting to set CDP enabled=%s version=%s"
                % (__name__, enabled, version))
        else:
            cmds.append('no cdp run')
            self.iosapi.bcp_log(
                "info", "(%s) set_cdp() : Attempting to set CDP enabled=%s" %
                (__name__, enabled))

        output = self.iosapi.bcp_send_config_command(
            self.iosapi.netmiko_session, cmds)
        return (output)

    def set_cdp_timer(self, time=60):
        cdp_valid_range = '<5-254>'
        cmd = 'cdp timer %s' % (time)

        if time not in range(5, 255):
            print("CDP Time %s is invalid, valid range is %s" %
                  (cdp_valid_range))
            return
        else:
            output = self.iosapi.bcp_send_config_command(
                self.iosapi.netmiko_session, cmd)
            self.iosapi.bcp_log(
                "info", "(%s) set_cdp_timer() : Attempting to set CDP timer" %
                (__name__))
            return (output)

    def set_cdp_neighbors_description(self,
                                      description_start='',
                                      padding_text=''):
        cdp_neighbors = self.get_cdp_neighbors_detail()

        commands_sent = []

        for neighbor in cdp_neighbors:
            local_interface = neighbor['local_port']
            remote_interface = neighbor['remote_port']
            remote_host = neighbor['destination_host']

            format_description = '{0} {1} {2} ({3}) {0}'.format(
                padding_text, description_start, remote_host, remote_interface)
            cmds = [
                'interface %s' % (local_interface),
                'description ' + format_description
            ]
            output = self.iosapi.bcp_send_config_command(
                self.iosapi.netmiko_session, cmds)
            self.iosapi.bcp_log(
                "info",
                "(%s) set_cdp_neighbors_description() : Attempting to set interface %s description"
                % (__name__, local_interface))
            commands_sent.append(output)

        return (commands_sent)

    def get_cdp_neighbors_detail(self):
        cmd = 'show cdp neighbors detail'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log(
            "info",
            "(%s) get_cdp_neighbors_detail() : Attempting to retreive CDP detailed facts"
            % (__name__))
        return (self.iosapi.textfsm_extractor(
            'cisco_ios_show_cdp_neighbors_detail.template', output))
class VlanAPI(object):
    def __init__(self, iosapi=None):
        if iosapi:
            self.iosapi = iosapi
        else:
            self.iosapi = IOSAPI()

    #Add Functions
    def add_vlan(self, vlanid, name=''):

        """
            Creates VLAN and returns the SSH output of the results
            > vlanid    -   VLAN number to add
            > name      -   VLAN name to assign the VLAN ID

            Example:
            add_vlan(10, 'CORP_USERS')
        """

        cmds = []

        if vlanid:
            if isinstance(vlanid, int):
                cmds.append('vlan %s' % vlanid)
            if name:
                cmds.append('name %s' %name)

        if self.check_vlan_exist(vlanid):
            self.iosapi.bcp_log("info", "(%s) add_vlan() : VLAN already exist - Renaming VLAN %s to %s" %(__name__, vlanid, name))
        else:
            self.iosapi.bcp_log("info", "(%s) add_vlans() : Attempting to create VLAN %s" %(__name__, vlanid))

        return(self.iosapi.bcp_send_config_command(self.iosapi.netmiko_session, cmds))

    #Check Functions

    def check_vlan_exist(self, vlanid):

        """
            Returns Boolean
            IOS typically returns something like: 'VLAN id 23 not found in current VLAN database'
            > vlanid    -   VLAN number to check

            Example:
            check_vlan_exist(10)

            True
        """

        cmd = 'show vlan id %s' %(vlanid)

        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log("info", "(%s) get_vlans() : Attempting to retreive all VLANs" %(__name__))

        if 'VLAN id {} not found'.format(vlanid) in output:
            return(False)
        else:
            return(True)

    #Get Functions
    def get_vlans(self):

        """
            Returns all VLANs in the database in JSON type format

            Example:
            get_vlans()

            {
                'interfaces': ['Gi0/1',
                               'Gi0/2',
                               'Gi0/3'],
                'name': 'default',
                'status': 'active',
                'vlan_id': '1'
            },
            {
                'interfaces': ['Gi1/0'],
                'name': 'CORP_USERS',
                'status': 'active',
                'vlan_id' : '10'
            }
        """

        cmd = 'show vlan brief'
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log("info", "(%s) get_vlans() : Attempting to retreive all VLANs" %(__name__))
        return(self.iosapi.textfsm_extractor('cisco_ios_show_vlan.template', output))

    def get_vlan_id(self, vlanid):

        """
            Returns JSON type format for specific VLAN
            > vlanid    -   VLAN ID to check

            Example:
            get_vlan_id(10)

            {
                'interfaces': ['Gi1/0'],
                'name': 'CORP_USERS',
                'status': 'active',
                'vlan_id' : '10'
            }
        """

        cmd = 'show vlan id %s' %(vlanid)
        output = self.iosapi.bcp_send_command(self.iosapi.netmiko_session, cmd)
        self.iosapi.bcp_log("info", "(%s) get_vlan_id() : Attempting to retreive VLAN ID %s" %(__name__, vlanid))
        return(self.iosapi.textfsm_extractor('cisco_ios_show_vlan.template', output))