Example #1
0
def main():
    """
    Main execution routine
    """
    description = ('Simple application that logs on to the APIC'
                   ' and displays usage information for a given DN')
    creds = Credentials('apic', description)
    creds.add_argument("-d",
                       "--dn_name",
                       help="DN to query for usage information")

    args = creds.get()

    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
    url = '/api/mo/{}.json?query-target=children&target-subtree-class=relnFrom'
    url = url.format(args.dn_name)

    resp = session.get(url)

    if resp.ok:
        used_by = resp.json()['imdata']
        for item in used_by:
            kls = next(iter(item))
            attributes = item[kls]['attributes']
            data.append((attributes['tDn'], kls))
    print(tabulate(data, headers=["Used by", "Class"]))
Example #2
0
def main():
    """
    Main execution routine
    """
    description = ('Simple application that logs on to the APIC'
                   ' and displays usage information for a given DN')
    creds = Credentials('apic', description)
    creds.add_argument("-d", "--dn_name",
                       help="DN to query for usage information")

    args = creds.get()

    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
    url = '/api/mo/{}.json?query-target=children&target-subtree-class=relnFrom'
    url = url.format(args.dn_name)

    resp = session.get(url)

    if resp.ok:
        used_by = resp.json()['imdata']
        for item in used_by:
            kls = next(iter(item))
            attributes = item[kls]['attributes']
            data.append((attributes['tDn'], kls))
    print(tabulate(data, headers=["Used by", "Class"]))
Example #3
0
def main():
    """
    Main Show VM Names Routine
    :return: None
    """
    # Take login credentials from the command line if provided
    # Otherwise, take them from your environment variables file ~/.profile
    description = ('Simple application that logs on to the APIC'
                   ' and displays all of the virtual machine names.')
    creds = Credentials('apic', description)
    args = creds.get()

    # Login to APIC
    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
        return

    # Make a direct call to the APIC REST API
    # Get all of the VMs (all objects of compVM class) and include the compVNic children
    # which contain the MAC address of the NIC.
    # The advantage of using acitoolkit Session.get() instead of direct Requests.get() calls
    # is that acitoolkit will automatically handle retries and pagination for queries with
    # large response data
    class_url = '/api/node/class/compVm.json?rsp-subtree=children&rsp-subtree-class=compVNic'
    ret = session.get(class_url)
    vm_list = ret.json()['imdata']

    # Process the response. We're looking for the VM name and the associated vNIC MAC addresses.
    data = []
    for vm in vm_list:
        vm_name = vm['compVm']['attributes']['name']
        for vnic in vm['compVm']['children']:
            vm_mac = vnic['compVNic']['attributes']['mac']
            # Store the VM name and MAC address. Note that VM names may be associated with
            # multiple MAC addresses if they have multiple vNICs.
            data.append((vm_name, vm_mac))

    # Display the data downloaded
    print(tabulate(data, headers=["VMNAME", "MACADDRESS"]))
Example #4
0
class FexCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        if not self._apic.login().ok:
            self._logged_in = False
            print '%% Could not login to APIC'
        else:
            self._logged_in = True

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def get_fex_attributes(self, node_id, fex_id=None):
        if fex_id is None:
            query_url = (
                '/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                '&target-subtree-class=satmDExtCh' % node_id)
        else:
            query_url = (
                '/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                '&target-subtree-class=satmDExtCh&query-target-filter=eq(satmDExtCh.id, "%s")'
                % (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_fabric_port_attributes(self, node_id, fex_id):
        query_url = ('/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                     '&target-subtree-class=satmFabP&query-target-filter='
                     'eq(satmFabP.extChId,"%s")' % (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_transceiver_attributes(self, node_id, fab_port_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys/satm/fabp-[%s].json?'
                     'query-target=subtree&target-subtree-class=satmRemoteFcot'
                     ',satmRemoteFcotX2' % (node_id, fab_port_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_attributes(self, node_id, fex_id):
        query_url = '/api/mo/topology/pod-1/node-%s/sys/extch-%s.json' % (
            node_id, fex_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_card_attributes(self, node_id, fex_id):
        query_url = (
            '/api/mo/topology/pod-1/node-%s/sys/extch-%s.json?'
            'query-target=subtree&target-subtree-class=eqptExtChCard' %
            (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_running_attributes(self, node_id, fex_id):
        query_url = '/api/mo/topology/pod-1/node-%s/sys/extch-%s/running.json' % (
            node_id, fex_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_cpu_attributes(self, node_id, fex_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys/extch-%s.json?'
                     'query-target=subtree&target-subtree-class=eqptExtChCPU' %
                     (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_fex_ids(self, node_id):
        fex_attrs = self.get_fex_attributes(node_id)
        fex_ids = []
        print fex_attrs
        for fex_attr in fex_attrs:
            fex_ids.append(str(fex_attr['satmDExtCh']['attributes']['id']))
        return fex_ids

    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    @staticmethod
    def print_fex(fex_attr, chassis_attr, detail=False):
        print 'FEX:%s  Description: FEX0%s  state: %s' % (
            fex_attr['id'], fex_attr['id'], fex_attr['operSt'])
        print '  FEX version: %s [Switch version: %s]' % (fex_attr['ver'],
                                                          fex_attr['swVer'])

        if detail:
            print '  FEX Interim version:', fex_attr['intVer']
            print '  Switch Interim version:', fex_attr['swIntVer']
        print '  Extender Model: %s, Extender Serial: %s' % (fex_attr['model'],
                                                             fex_attr['ser'])
        print '  Part No:', chassis_attr['partNum']
        if detail:
            print '  Card Id: %s,' % fex_attr['swCId']
            print 'Mac Addr: %s,' % fex_attr['macAddr']
            print 'Num Macs:', fex_attr['numMacs']
            print '  Module Sw Gen:', fex_attr['swGen']
            print ' [Switch Sw Gen: %s]' % fex_attr['swSwGen']
        print ' pinning-mode: static    Max-links: 1'
        print '  Fabric port for control traffic:', fex_attr['controlFPort']

    @staticmethod
    def convert_to_ascii(data):
        data = str(data).split(',')
        resp = ''
        for letter in data:
            resp += str(unichr(int(letter)))
        return resp

    def print_fex_transceiver(self, node_id, fex_id):
        if fex_id is None:
            fex_ids = self.get_fex_ids(node_id)
        else:
            fex_ids = [fex_id]
        for fex_id in fex_ids:
            fab_port_num = 1
            fab_ports = self.get_fabric_port_attributes(node_id, fex_id)
            for fab_port in fab_ports:
                fab_port_attr = fab_port['satmFabP']['attributes']
                if fab_port_attr['id'].startswith('po'):
                    continue
                print 'Fex Uplink:', fab_port_num
                print '    Fabric Port :', fab_port_attr['id']
                if 'fcot-present' in fab_port_attr['flags']:
                    transceiver_attr = self.get_transceiver_attributes(
                        node_id, str(fab_port_attr['id']))
                    try:
                        transceiver_attr = transceiver_attr[0][
                            'satmRemoteFcot']['attributes']
                    except KeyError:
                        raise NotImplementedError  # probably satmRemoteFcotV2
                    print '    sfp is present'
                    print '    name is', self.convert_to_ascii(
                        transceiver_attr['vendorName'])
                    print '    type is', transceiver_attr['typeName']
                    print '    part number is', self.convert_to_ascii(
                        transceiver_attr['vendorPn'])
                    print '    revision is', self.convert_to_ascii(
                        transceiver_attr['vendorRev'])
                    print '    serial number is', self.convert_to_ascii(
                        transceiver_attr['vendorSn'])
                    print '    nominal bitrate is %s MBits/sec' % str(
                        int(transceiver_attr['brIn100MHz']) * 100)
                    print '    Link length supported for 50/125mm fiber is 0 m(s)'
                    print '    Link length supported for 62.5/125mm fiber is 0 m(s)'
                    print '    Link length supported for copper is %s m' % transceiver_attr[
                        'distIn1mForCu']
                    print '    cisco id is', transceiver_attr['xcvrId']
                    print '    cisco extended id number is', transceiver_attr[
                        'xcvrExtId']
                fab_port_num += 1

    def print_fex_version(self, node_id, fex_id):
        if fex_id is None:
            fex_ids = self.get_fex_ids(node_id)
        else:
            fex_ids = [fex_id]
        for fex_id in fex_ids:
            chassis_attr = self.get_chassis_attributes(node_id, fex_id)
            chassis_attr = chassis_attr[0]['eqptExtCh']['attributes']
            chassis_running_attr = self.get_chassis_running_attributes(
                node_id, fex_id)
            chassis_running_attr = chassis_running_attr[0][
                'firmwareExtChRunning']['attributes']
            card_attr = self.get_chassis_card_attributes(node_id, fex_id)
            card_attr = card_attr[0]['eqptExtChCard']['attributes']
            fex_attr = self.get_fex_attributes(node_id, fex_id)
            fex_attr = fex_attr[0]['satmDExtCh']['attributes']
            cpu_attr = self.get_chassis_cpu_attributes(node_id, fex_id)
            cpu_attr = cpu_attr[0]['eqptExtChCPU']['attributes']

            print 'Software'
            print '  Bootloader version:           %s' % chassis_running_attr[
                'loaderVer']
            print '  System boot mode:             primary'
            print '  System image version:         %s [build %s]' % (
                fex_attr['ver'], fex_attr['intVer'])

            print '\nHardware'
            print '  Module:                       %s' % card_attr['descr']
            print '  CPU:                          %s' % cpu_attr['model']
            print '  Serial number:                %s' % card_attr['modSerial']
            print '  Bootflash:                    locked'

            # TODO: Finish - need to add timestamping

    def show_fex(self,
                 node=None,
                 fex_id=None,
                 detail=False,
                 transceiver=False,
                 version=False):
        """
        Show fex

        :param fex_id: String containing the specific FEX id. If none, all FEXs are used
        :param detail: Boolean indicating whether a detailed report should be given.
        :param transceiver: Boolean indicating whether a transceiver report should be given.
        :param version: Boolean indicating whether a version report should be given.
        :return: None
        """
        for node_id in self.get_node_ids(node):
            if fex_id is None:
                if not (detail or transceiver or version):
                    # Show fex
                    data = []
                    for fex in self.get_fex_attributes(node_id):
                        fex_attr = fex['satmDExtCh']['attributes']
                        data.append(
                            (int(fex_attr['id']), 'FEX0' + str(fex_attr['id']),
                             fex_attr['operSt'], fex_attr['model'],
                             fex_attr['ser']))
                    data.sort(key=lambda tup: tup[0])
                    if len(data):
                        print 'Switch:', node_id
                        print tabulate(data,
                                       headers=[
                                           'Number', 'Description', 'State',
                                           'Model', 'Serial'
                                       ])
                        print '\n'
                elif detail:
                    # Show fex detail
                    fex_ids = self.get_fex_ids(node_id)
                    for fex_id in fex_ids:
                        self.print_show_fex(node_id, fex_id, detailed=True)
                elif transceiver:
                    self.print_fex_transceiver(node_id, None)
            elif detail:
                # Show fex <fex_id> detail
                self.print_show_fex(node_id, fex_id, detailed=True)
            elif transceiver:
                # Show fex <fex_id> transceiver
                self.print_fex_transceiver(node_id, fex_id)
            elif version:
                # Show fex <fex_id> version
                self.print_fex_version(node_id, fex_id)
            else:
                # Show fex <fex_id>
                self.print_show_fex(node_id, fex_id)

    def print_show_fex(self, node_id, fex_id, detailed=False):
        for fex in self.get_fex_attributes(node_id, fex_id):
            fex_attr = fex['satmDExtCh']['attributes']
            for chassis in self.get_chassis_attributes(node_id,
                                                       fex_attr['id']):
                chassis_attr = chassis['eqptExtCh']['attributes']
                self.print_fex(fex_attr, chassis_attr)
                query_url = (
                    '/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                    '&target-subtree-class=satmFabP&query-target-filter=eq(satmFabP.extChId,"%s")'
                    % (node_id, fex_attr['id']))
                resp = self._apic.get(query_url)
                if not resp.ok:
                    print 'Could not collect APIC data for switch %s.' % node_id
                    print resp.text
                    return
                if int(resp.json()['totalCount']) > 0:
                    print '  Fabric interface state:'
                    for interface in resp.json()['imdata']:
                        intf_attr = interface['satmFabP']['attributes']
                        print '    %15s - Interface %4s. State: %s' % (
                            intf_attr['id'], intf_attr['operSt'],
                            intf_attr['fsmSt'])
                        if detailed:
                            query_url = (
                                '/api/mo/topology/pod-1/node-%s/sys/satm/fabp-[%s].json?query-target=subtree'
                                '&target-subtree-class=satmHostP' %
                                (node_id, intf_attr['id']))
                            resp = self._apic.get(query_url)
                            if not resp.ok:
                                print 'Could not collect APIC data for switch %s.' % node_id
                                print resp.text
                                return
                            if int(resp.json()['totalCount']) > 0:
                                data = []
                                for port in resp.json()['imdata']:
                                    port_attr = port['satmHostP']['attributes']
                                    data.append(
                                        (port_attr['id'], port_attr['operSt'],
                                         port_attr['fabricPort']))
                                data.sort(key=lambda tup: tup[0])
                                print tabulate(data,
                                               headers=[
                                                   'Fex Port', 'State',
                                                   'Fabric Port'
                                               ])
def main():
    """
    Main execution routine

    :return: None
    """
    # Take login credentials from the command line if provided
    # Otherwise, take them from your environment variables file ~/.profile
    description = 'Simple application that logs on to the APIC and displays all of the Interfaces.'
    creds = Credentials('apic', description)
    creds.add_argument('--tenant', help='The name of Tenant')
    args = creds.get()

    # Login to APIC
    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
        sys.exit(0)

    resp = session.get('/api/class/ipv4Addr.json')
    intfs = json.loads(resp.text)['imdata']

    for i in intfs:
        ip = i['ipv4Addr']['attributes']['addr']
        op = i['ipv4Addr']['attributes']['operSt']
        cfg = i['ipv4Addr']['attributes']['operStQual']
        dn = i['ipv4Addr']['attributes']['dn']
        node = dn.split('/')[2]
        intf = re.split(r'\[|\]', dn)[1]
        vrf = re.split(r'/|dom-', dn)[7]
        tn = vrf
        if vrf.find(":") != -1:
            tn = re.search("(.*):(.*)", vrf).group(1)

        check_longest_name(node, "Node")
        check_longest_name(intf, "Interface")
        check_longest_name(ip, "IP Address")
        check_longest_name(cfg, "Admin Status")
        check_longest_name(op, "Status")

        if args.tenant is None:
            if vrf not in data.keys():
                data[vrf] = []
            else:
                data[vrf].append((node, intf, ip, cfg, op))
        else:
            if tn == args.tenant:
                if vrf not in data.keys():
                    data[vrf] = []
                else:
                    data[vrf].append((node, intf, ip, cfg, op))

    for k in data.keys():
        header = 'IP Interface Status for VRF "{}"'.format(k)
        print(header)
        template = '{0:' + str(longest_names["Node"]) + '} ' \
                   '{1:' + str(longest_names["Interface"]) + '} ' \
                   '{2:' + str(longest_names["IP Address"]) + '} ' \
                   '{3:' + str(longest_names["Admin Status"]) + '} ' \
                   '{4:' + str(longest_names["Status"]) + '}'
        print(template.format("Node", "Interface", "IP Address", "Admin Status", "Status"))
        print(template.format('-' * longest_names["Node"],
                              '-' * longest_names["Interface"],
                              '-' * longest_names["IP Address"],
                              '-' * longest_names["Admin Status"],
                              '-' * longest_names["Status"]))
        for rec in sorted(data[k]):
            print(template.format(*rec))
        print('')
Example #6
0
    sys.exit(0)

while True:
    try:
        inputnode = input("Enter the Node ID: ")
        if (len(inputnode) == 4):
            nodeidint = int(inputnode)
            break
        else:
            print("Node ID is INVALID ! try again")
            continue
    except ValueError:
        print("INVALID IP address ! Enter Numeric values only")

resp = session.get(
    "/api/class/fvRsPathAtt.json?query-target-filter=wcard(fvRsPathAtt.tDn,\""
    + inputnode + "\")")
data = json.loads(resp.text)['imdata']
datacount = int(json.loads(resp.text)['totalCount'])

fname = "EPG_Static_Ports_" + inputnode + ".csv"
#fname = "EPGpathsdetailsapinode.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow(
        ["Tenant", "APP_Profile", "EPG_Name", "Node", "port", "encap", "Mode"])

    numrow = 0
    for i in data:
        itemone = (((i['fvRsPathAtt'])['attributes']))
# Take login credentials from the command line if provided
# Otherwise, take them from your environment variables file ~/.profile
description = 'Simple application that logs on to the APIC and extracts Node IDs, Node names and their serial numbers.'
creds = Credentials('apic', description)
creds.add_argument('--tenant', help='The name of Tenant')
args = creds.get()

# Login to APIC
session = Session(args.url, args.login, args.password)
resp = session.login()
if not resp.ok:
    print('%% Could not login to APIC')
    sys.exit(0)

resp = session.get(
    '/api/class/fabricNodeIdentP.json?rsp-subtree=full&rsp-prop-include=config-only'
)
data = json.loads(resp.text)['imdata']
datacount = int(json.loads(resp.text)['totalCount'])

fname = "NodeReginfo.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow(["Node ID", "Node Name", "Serial Number"])

    numrow = 0
    for i in data:
        itemone = (((i['fabricNodeIdentP'])['attributes']))
        dnstr = itemone['dn']
        nodename = itemone['name']
Example #8
0
# Take login credentials from the command line if provided
# Otherwise, take them from your environment variables file ~/.profile
description = 'Application that logs on to the APIC, and extracts the BD information to a csv file. Only first 3 IP Subnets for a BD will be shown'
creds = Credentials('apic', description)
creds.add_argument('--tenant', help='The name of Tenant')
args = creds.get()

# Login to APIC
session = Session(args.url, args.login, args.password)
resp = session.login()
if not resp.ok:
    print('%% Could not login to APIC')
    sys.exit(0)

resp = session.get(
    '/api/class/fvBD.json?rsp-subtree=full&rsp-prop-include=config-only&order-by=fvBD.name'
)
data = json.loads(resp.text)['imdata']
datacount = int(json.loads(resp.text)['totalCount'])

#with open("./BDinfo.json") as file:
#	data = json.load(file)['imdata']

fname = "Bridge_Domain_Details.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow([
        "Tenant", "BD Name", "Description", "ARP Flooding", "IP Learning",
        "LimitIPLearnToSubnets", "Unicast Routing", "UnknownMacUnicastAct",
        "IP_Subnet-1", "Subnet-1_Scope", "IP_Subnet-2", "Subnet-2_Scope",
class InterfaceBriefCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        self._if_brief_headers = {
            'l1PhysIf': ['Ethernet Interface', 'VLAN', 'Type', 'Mode', 'Status', 'Reason', 'Speed', 'Port Ch #'],
            'pcAggrIf': ['Port-channel Interface', 'VLAN', 'Type', 'Mode', 'Status', 'Reason', 'Speed', 'Protocol'],
            'l3LbRtdIf': ['Interface', 'Status', 'Description'],
            'tunnelIf': ['Interface', 'Status', 'IP Address', 'Encap type', 'MTU'],
            'sviIf': ['Interface', 'Secondary VLAN(Type)', 'Status', 'Reason'],
            'l3EncRtdIf': [],
            'mgmtMgmtIf': ['Port', 'VRF', 'Status', 'IP Address', 'Speed', 'MTU'],
            'l2ExtIf': [],
            'l2VfcIf': ['Interface', 'Vsan', 'Admin\nMode', 'Admin Trunk Mode', 'Status',
                        'Bind Info', 'Oper Mode', 'Oper Speed (Gbps)']
        }
        self._if_types = self._if_brief_headers.keys()
        if not self._apic.login().ok:
            self._logged_in = False
            print '%% Could not login to APIC'
        else:
            self._logged_in = True
        self._interfaces = []

    @property
    def _all_if_types_as_string(self):
        resp = ''
        for if_type in self._if_types:
            if len(resp):
                resp += ','
            resp += if_type
        return resp

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def populate_interfaces(self, node_id, intf_id=None):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=%s&rsp-subtree=children&'
                     'rsp-subtree-class=ethpmPhysIf,l1RtMbrIfs,ethpmAggrIf' % (node_id, self._all_if_types_as_string))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        interfaces = self._get_query(query_url, error_message)
        if intf_id is None:
            self._interfaces = interfaces
        else:
            self._interfaces = []
            for interface in interfaces:
                for if_type in interface:
                    if interface[if_type]['attributes']['id'] == intf_id:
                        self._interfaces.append(interface)

    def _has_interface_type(self, if_type, intf_id=None):
        for interface in self._interfaces:
            if if_type in interface:
                if intf_id is None or intf_id == interface[if_type]['attributes']['id']:
                    return True
        return False

    def _get_interface_type(self, if_type):
        resp = []
        for interface in self._interfaces:
            if if_type in interface:
                resp.append(interface)
        return resp

    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    @staticmethod
    def convert_to_ascii(data):
        data = str(data).split(',')
        resp = ''
        for letter in data:
            resp += str(unichr(int(letter)))
        return resp

    def _get_interface_type_brief_data(self, if_type, intf_id=None):
        data = []
        for interface in self._interfaces:
            if if_type in interface:
                if intf_id is not None and intf_id != interface[if_type]['attributes']['id']:
                    continue
                if_attrs = interface[if_type]['attributes']
                if if_type == 'mgmtMgmtIf':
                    data.append((if_attrs['id'], '--', if_attrs['adminSt'], '', if_attrs['speed'], if_attrs['mtu']))
                elif if_type == 'l1PhysIf':
                    port_channel = '--'
                    for child in interface[if_type]['children']:
                        if 'l1RtMbrIfs' in child:
                            port_channel = child['l1RtMbrIfs']['attributes']['tSKey']
                        else:
                            oper_attrs = child['ethpmPhysIf']['attributes']
                    data.append((if_attrs['id'], '--', 'eth', oper_attrs['operMode'], oper_attrs['operSt'],
                                 oper_attrs['operStQual'], oper_attrs['operSpeed'], port_channel))
                elif if_type == 'tunnelIf':
                    data.append((if_attrs['id'], if_attrs['operSt'], '--', if_attrs['tType'], if_attrs['cfgdMtu']))
                elif if_type == 'pcAggrIf':
                    for child in interface[if_type]['children']:
                        protocol = '--'
                        if if_attrs['pcMode'] in ['active', 'passive', 'mac-pin']:
                            protocol = 'lacp'
                        elif if_attrs['pcMode'] == 'static':
                            protocol = 'none'
                        if 'ethpmAggrIf' in child:
                            oper_attrs = child['ethpmAggrIf']['attributes']
                    data.append((if_attrs['id'], '--', 'eth', oper_attrs['operMode'], oper_attrs['operSt'],
                                 oper_attrs['operStQual'], oper_attrs['operSpeed'], protocol))
                elif if_type == 'sviIf':
                    data.append((if_attrs['id'], '--', if_attrs['operSt'], if_attrs['operStQual']))
                elif if_type == 'l3LbRtdIf':
                    if len(if_attrs['descr']):
                        description = if_attrs['descr']
                    else:
                        description = '--'
                    data.append((if_attrs['id'], if_attrs['adminSt'], description))
                elif if_type == 'l2VfcIf':
                    raise NotImplementedError
                    # TODO: finish this
        return data

    def show_brief(self, node=None, intf_id=None):
        """
        show interface brief

        :param node: String containing the specific switch id. If none, all switches are used
        :param intf_id: String containing the specific interface id. If none, all interfaces are used
        :return: None
        """
        for node_id in self.get_node_ids(node):
            self.populate_interfaces(node_id, intf_id)

            for if_type in self._if_types:
                if self._has_interface_type(if_type, intf_id):
                    data = self._get_interface_type_brief_data(if_type, intf_id)
                    data.sort(key=lambda tup: tup[0])
                    if len(data):
                        print tabulate(data, headers=self._if_brief_headers[if_type])
                        print
Example #10
0
class FexCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        if not self._apic.login().ok:
            self._logged_in = False
            print '%% Could not login to APIC'
        else:
            self._logged_in = True

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def get_fex_attributes(self, node_id, fex_id=None):
        if fex_id is None:
            query_url = ('/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                         '&target-subtree-class=satmDExtCh' % node_id)
        else:
            query_url = ('/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                         '&target-subtree-class=satmDExtCh&query-target-filter=eq(satmDExtCh.id, "%s")' % (node_id,
                                                                                                           fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_fabric_port_attributes(self, node_id, fex_id):
        query_url = ('/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                     '&target-subtree-class=satmFabP&query-target-filter='
                     'eq(satmFabP.extChId,"%s")' % (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_transceiver_attributes(self, node_id, fab_port_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys/satm/fabp-[%s].json?'
                     'query-target=subtree&target-subtree-class=satmRemoteFcot'
                     ',satmRemoteFcotX2' % (node_id, fab_port_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_attributes(self, node_id, fex_id):
        query_url = '/api/mo/topology/pod-1/node-%s/sys/extch-%s.json' % (node_id, fex_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_card_attributes(self, node_id, fex_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys/extch-%s.json?'
                    'query-target=subtree&target-subtree-class=eqptExtChCard' % (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_running_attributes(self, node_id, fex_id):
        query_url = '/api/mo/topology/pod-1/node-%s/sys/extch-%s/running.json' % (node_id, fex_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_chassis_cpu_attributes(self, node_id, fex_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys/extch-%s.json?'
                    'query-target=subtree&target-subtree-class=eqptExtChCPU' % (node_id, fex_id))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        return self._get_query(query_url, error_message)

    def get_fex_ids(self, node_id):
        fex_attrs = self.get_fex_attributes(node_id)
        fex_ids = []
        print fex_attrs
        for fex_attr in fex_attrs:
            fex_ids.append(str(fex_attr['satmDExtCh']['attributes']['id']))
        return fex_ids

    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    @staticmethod
    def print_fex(fex_attr, chassis_attr, detail=False):
        print 'FEX:%s  Description: FEX0%s  state: %s' % (fex_attr['id'],
                                                          fex_attr['id'],
                                                          fex_attr['operSt'])
        print '  FEX version: %s [Switch version: %s]' % (fex_attr['ver'],
                                                          fex_attr['swVer'])

        if detail:
            print '  FEX Interim version:', fex_attr['intVer']
            print '  Switch Interim version:', fex_attr['swIntVer']
        print '  Extender Model: %s, Extender Serial: %s' % (fex_attr['model'],
                                                             fex_attr['ser'])
        print '  Part No:', chassis_attr['partNum']
        if detail:
            print '  Card Id: %s,' % fex_attr['swCId']
            print 'Mac Addr: %s,' % fex_attr['macAddr']
            print 'Num Macs:', fex_attr['numMacs']
            print '  Module Sw Gen:', fex_attr['swGen']
            print ' [Switch Sw Gen: %s]' % fex_attr['swSwGen']
        print ' pinning-mode: static    Max-links: 1'
        print '  Fabric port for control traffic:', fex_attr['controlFPort']

    @staticmethod
    def convert_to_ascii(data):
        data = str(data).split(',')
        resp = ''
        for letter in data:
            resp += str(unichr(int(letter)))
        return resp

    def print_fex_transceiver(self, node_id, fex_id):
        if fex_id is None:
            fex_ids = self.get_fex_ids(node_id)
        else:
            fex_ids = [fex_id]
        for fex_id in fex_ids:
            fab_port_num = 1
            fab_ports = self.get_fabric_port_attributes(node_id, fex_id)
            for fab_port in fab_ports:
                fab_port_attr = fab_port['satmFabP']['attributes']
                if fab_port_attr['id'].startswith('po'):
                    continue
                print 'Fex Uplink:', fab_port_num
                print '    Fabric Port :', fab_port_attr['id']
                if 'fcot-present' in fab_port_attr['flags']:
                    transceiver_attr = self.get_transceiver_attributes(node_id, str(fab_port_attr['id']))
                    try:
                        transceiver_attr = transceiver_attr[0]['satmRemoteFcot']['attributes']
                    except KeyError:
                        raise NotImplementedError  # probably satmRemoteFcotV2
                    print '    sfp is present'
                    print '    name is', self.convert_to_ascii(transceiver_attr['vendorName'])
                    print '    type is', transceiver_attr['typeName']
                    print '    part number is', self.convert_to_ascii(transceiver_attr['vendorPn'])
                    print '    revision is', self.convert_to_ascii(transceiver_attr['vendorRev'])
                    print '    serial number is', self.convert_to_ascii(transceiver_attr['vendorSn'])
                    print '    nominal bitrate is %s MBits/sec' % str(int(transceiver_attr['brIn100MHz']) * 100)
                    print '    Link length supported for 50/125mm fiber is 0 m(s)'
                    print '    Link length supported for 62.5/125mm fiber is 0 m(s)'
                    print '    Link length supported for copper is %s m' % transceiver_attr['distIn1mForCu']
                    print '    cisco id is', transceiver_attr['xcvrId']
                    print '    cisco extended id number is', transceiver_attr['xcvrExtId']
                fab_port_num += 1

    def print_fex_version(self, node_id, fex_id):
        if fex_id is None:
            fex_ids = self.get_fex_ids(node_id)
        else:
            fex_ids = [fex_id]
        for fex_id in fex_ids:
            chassis_attr = self.get_chassis_attributes(node_id, fex_id)
            chassis_attr = chassis_attr[0]['eqptExtCh']['attributes']
            chassis_running_attr = self.get_chassis_running_attributes(node_id, fex_id)
            chassis_running_attr = chassis_running_attr[0]['firmwareExtChRunning']['attributes']
            card_attr = self.get_chassis_card_attributes(node_id, fex_id)
            card_attr = card_attr[0]['eqptExtChCard']['attributes']
            fex_attr = self.get_fex_attributes(node_id, fex_id)
            fex_attr = fex_attr[0]['satmDExtCh']['attributes']
            cpu_attr = self.get_chassis_cpu_attributes(node_id, fex_id)
            cpu_attr = cpu_attr[0]['eqptExtChCPU']['attributes']

            print 'Software'
            print '  Bootloader version:           %s' % chassis_running_attr['loaderVer']
            print '  System boot mode:             primary'
            print '  System image version:         %s [build %s]' % (fex_attr['ver'], fex_attr['intVer'])

            print '\nHardware'
            print '  Module:                       %s' % card_attr['descr']
            print '  CPU:                          %s' % cpu_attr['model']
            print '  Serial number:                %s' % card_attr['modSerial']
            print '  Bootflash:                    locked'

            # TODO: Finish - need to add timestamping

    def show_fex(self, node=None, fex_id=None, detail=False, transceiver=False, version=False):
        """
        Show fex

        :param fex_id: String containing the specific FEX id. If none, all FEXs are used
        :param detail: Boolean indicating whether a detailed report should be given.
        :param transceiver: Boolean indicating whether a transceiver report should be given.
        :param version: Boolean indicating whether a version report should be given.
        :return: None
        """
        for node_id in self.get_node_ids(node):
            if fex_id is None:
                if not (detail or transceiver or version):
                    # Show fex
                    data = []
                    for fex in self.get_fex_attributes(node_id):
                        fex_attr = fex['satmDExtCh']['attributes']
                        data.append((int(fex_attr['id']),
                                     'FEX0' + str(fex_attr['id']),
                                     fex_attr['operSt'],
                                     fex_attr['model'],
                                     fex_attr['ser']))
                    data.sort(key=lambda tup: tup[0])
                    if len(data):
                        print 'Switch:', node_id
                        print tabulate(data, headers=['Number', 'Description', 'State', 'Model', 'Serial'])
                        print '\n'
                elif detail:
                    # Show fex detail
                    fex_ids = self.get_fex_ids(node_id)
                    for fex_id in fex_ids:
                        self.print_show_fex(node_id, fex_id, detailed=True)
                elif transceiver:
                    self.print_fex_transceiver(node_id, None)
            elif detail:
                # Show fex <fex_id> detail
                self.print_show_fex(node_id, fex_id, detailed=True)
            elif transceiver:
                # Show fex <fex_id> transceiver
                self.print_fex_transceiver(node_id, fex_id)
            elif version:
                # Show fex <fex_id> version
                self.print_fex_version(node_id, fex_id)
            else:
                # Show fex <fex_id>
                self.print_show_fex(node_id, fex_id)

    def print_show_fex(self, node_id, fex_id, detailed=False):
        for fex in self.get_fex_attributes(node_id, fex_id):
            fex_attr = fex['satmDExtCh']['attributes']
            for chassis in self.get_chassis_attributes(node_id, fex_attr['id']):
                chassis_attr = chassis['eqptExtCh']['attributes']
                self.print_fex(fex_attr, chassis_attr)
                query_url = ('/api/mo/topology/pod-1/node-%s.json?query-target=subtree'
                             '&target-subtree-class=satmFabP&query-target-filter=eq(satmFabP.extChId,"%s")' % (
                                 node_id,
                                 fex_attr['id']))
                resp = self._apic.get(query_url)
                if not resp.ok:
                    print 'Could not collect APIC data for switch %s.' % node_id
                    print resp.text
                    return
                if int(resp.json()['totalCount']) > 0:
                    print '  Fabric interface state:'
                    for interface in resp.json()['imdata']:
                        intf_attr = interface['satmFabP']['attributes']
                        print '    %15s - Interface %4s. State: %s' % (intf_attr['id'],
                                                                       intf_attr['operSt'],
                                                                       intf_attr['fsmSt'])
                        if detailed:
                            query_url = ('/api/mo/topology/pod-1/node-%s/sys/satm/fabp-[%s].json?query-target=subtree'
                                         '&target-subtree-class=satmHostP' % (node_id, intf_attr['id']))
                            resp = self._apic.get(query_url)
                            if not resp.ok:
                                print 'Could not collect APIC data for switch %s.' % node_id
                                print resp.text
                                return
                            if int(resp.json()['totalCount']) > 0:
                                data = []
                                for port in resp.json()['imdata']:
                                    port_attr = port['satmHostP']['attributes']
                                    data.append((port_attr['id'], port_attr['operSt'], port_attr['fabricPort']))
                                data.sort(key=lambda tup: tup[0])
                                print tabulate(data, headers=['Fex Port', 'State', 'Fabric Port'])
Example #11
0
# Otherwise, take them from your environment variables file ~/.profile
description = 'Application that logs on to the APIC, and extracts the L3outs paths along with their vlan encap and IP addresses'

creds = Credentials('apic', description)
creds.add_argument('--tenant', help='The name of Tenant')
args = creds.get()

# Login to APIC
session = Session(args.url, args.login, args.password)
resp = session.login()
if not resp.ok:
    print('%% Could not login to APIC')
    sys.exit(0)

resp = session.get(
    '/api/class/l3extRsPathL3OutAtt.json?rsp-subtree=full&rsp-prop-include=config-only&order-by=l3extRsPathL3OutAtt.dn'
)
data = json.loads(resp.text)['imdata']
datacount = int(json.loads(resp.text)['totalCount'])

#with open("./tt1l3outpaths.json") as file:
#	data = json.load(file)['imdata']

fname = "L3out_paths_IP.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow([
        "Tenant", "L3OUT Name", "Logical Node Profile",
        "Logical Interface Profile", "If inst type", "Node ID", "Port ID",
        "vlan encap", "IP address", "VIP", "SIDE A IP address",
Example #12
0
def main():
    """
    Main execution routine

    :return: None
    """
    # Take login credentials from the command line if provided
    # Otherwise, take them from your environment variables file ~/.profile
    description = 'Simple application that logs on to the APIC and displays all of the Interfaces.'
    creds = Credentials('apic', description)
    creds.add_argument('--tenant', help='The name of Tenant')
    args = creds.get()

    # Login to APIC
    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
        sys.exit(0)

    resp = session.get('/api/class/ipv4Addr.json')
    intfs = json.loads(resp.text)['imdata']

    for i in intfs:
        ip = i['ipv4Addr']['attributes']['addr']
        op = i['ipv4Addr']['attributes']['operSt']
        cfg = i['ipv4Addr']['attributes']['operStQual']
        dn = i['ipv4Addr']['attributes']['dn']
        node = dn.split('/')[2]
        intf = re.split(r'\[|\]', dn)[1]
        vrf = re.split(r'/|dom-', dn)[7]
        tn = vrf
        if vrf.find(":") != -1:
            tn = re.search("(.*):(.*)", vrf).group(1)

        check_longest_name(node, "Node")
        check_longest_name(intf, "Interface")
        check_longest_name(ip, "IP Address")
        check_longest_name(cfg, "Admin Status")
        check_longest_name(op, "Status")

        if args.tenant is None:
            if vrf not in data.keys():
                data[vrf] = []
            else:
                data[vrf].append((node, intf, ip, cfg, op))
        else:
            if tn == args.tenant:
                if vrf not in data.keys():
                    data[vrf] = []
                else:
                    data[vrf].append((node, intf, ip, cfg, op))

    for k in data.keys():
        header = 'IP Interface Status for VRF "{}"'.format(k)
        print(header)
        template = '{0:' + str(longest_names["Node"]) + '} ' \
                   '{1:' + str(longest_names["Interface"]) + '} ' \
                   '{2:' + str(longest_names["IP Address"]) + '} ' \
                   '{3:' + str(longest_names["Admin Status"]) + '} ' \
                   '{4:' + str(longest_names["Status"]) + '}'
        print(
            template.format("Node", "Interface", "IP Address", "Admin Status",
                            "Status"))
        print(
            template.format('-' * longest_names["Node"],
                            '-' * longest_names["Interface"],
                            '-' * longest_names["IP Address"],
                            '-' * longest_names["Admin Status"],
                            '-' * longest_names["Status"]))
        for rec in sorted(data[k]):
            print(template.format(*rec))
        print('')
class InterfaceDetailedCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        if not self._apic.login().ok:
            self._logged_in = False
            print '%% Could not login to APIC'
        else:
            self._logged_in = True
        self._interfaces = []

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def _populate_beacon_states(self, data):
        for beacon_data in data:
            if 'eqptLocLed' not in beacon_data:
                continue
            dn = beacon_data['eqptLocLed']['attributes']['dn']
            oper_state = beacon_data['eqptLocLed']['attributes']['operSt']
            if 'leafport-' in dn:
                port_num = dn.partition('/leafport-')[2].partition('/')[0]
                mod_num = dn.partition('/lcslot-')[2].partition('/')[0]
                node_num = dn.partition('/node-')[2].partition('/')[0]
                beacon_interface_id = 'eth' + mod_num + '/' + port_num
                beacon_node_id = '/node-%s/' % node_num
                for interface in self._interfaces:
                    if not interface.is_ether():
                        continue
                    if interface.id == beacon_interface_id:
                        if beacon_node_id in dn:
                            interface.beacon_state = oper_state

    def populate_detailed_interfaces(self, node_id, intf_id=None):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=l1PhysIf,pcAggrIf,l3LbRtdIf,tunnelIf,sviIf,l3EncRtdIf,'
                     'mgmtMgmtIf,l2ExtIf,l2VfcIf,eqptLocLed&rsp-subtree=full&'
                     'rsp-subtree-class=ethpmPhysIf,ethpmPortCap,l1RtMbrIfs,ethpmAggrIf,'
                     'rmonEtherStats,rmonIfIn,rmonIfOut,rmonIfStorm,eqptIngrTotal5min,'
                     'eqptEgrTotal5min,l1EeeP,rmonDot3Stats' % node_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        interfaces = self._get_query(query_url, error_message)
        self._interfaces = []
        if intf_id is None:
            for interface in interfaces:
                self._interfaces.append(Interface(interface))
        else:
            for interface in interfaces:
                for if_type in interface:
                    if if_type == 'eqptLocLed':
                        continue
                    if interface[if_type]['attributes']['id'] == intf_id:
                        self._interfaces.append(Interface(interface))
        self._populate_beacon_states(interfaces)


    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    def show_detailed(self, node=None, intf_id=None):
        """
        show interface

        :param node: String containing the specific switch id. If none, all switches are used
        :param intf_id: String containing the specific interface id. If none, all interfaces are used
        :return: None
        """
        for node_id in self.get_node_ids(node):
            print 'Switch', node_id
            self.populate_detailed_interfaces(node_id, intf_id)
            for interface in self._interfaces:
                if interface.if_type == 'l1PhysIf':
                    if interface.is_ether or interface.is_pc() or interface.is_tun():
                        state = interface.oper_st
                        rsn = interface.oper_st_qual
                        if state is None:
                            state = "unknown"
                            rsn = "unknown"
                        if state == 'link-up':
                            # see ethpm_copy_eth_port_log_info()
                            # link-up state is physical up, but not operationally up
                            state = 'down'
                        if state == 'up':
                            if not interface.is_tun() and interface.switching_st == 'disabled':
                                print "%s is %s (%s)" % (interface.id, state, "out-of-service")
                            else:
                                print "%s is %s" % (interface.id, state)
                        elif interface.oper_st_qual == "err-disabled":
                            print "%s is %s (%s)" % (interface.id, state, interface.oper_err_dis_qual)
                        else:
                            print "%s is %s (%s)" % (interface.id, state, rsn)

                    print 'admin state is', interface.admin_st
                    if interface.is_member_pc():
                        print "  Belongs to %s" % interface.port_channel_id
                    if not interface.descr == '':
                        print '  Port description is', interface.descr
                    print '  Hardware:', interface.port_cap_speed, 'Ethernet, address:', interface.address, \
                          '(bia', interface.backplane_mac, ')'
                    print '  MTU', interface.mtu, 'bytes, BW', interface.bw, 'Kbit, DLY', interface.delay, 'usec'
                    print '  reliability', '%s/255' % interface.reliability, \
                          'txload %d/255, rxload %d/255' %  (interface.tx_load, interface.rx_load)
                    print '  Encapsulation ARPA, medium is broadcast'
                    if interface.layer != 'Layer2':
                        print '  Port mode is routed'
                    else:
                        print "  Port mode is %s" % interface.mode
                    if not interface.is_mgmt() and interface.oper_mode == 'ips':
                        duplex = 'auto'
                    else:
                        duplex = interface.oper_duplex
                    print "  %s-duplex, %sb/s%s" % (duplex, interface.speed, interface.fcot_str)
                    if (interface.is_ether() and not interface.is_sub()) or interface.is_mgmt():
                        if not interface.is_mgmt():
                            print '  FEC (forward-error-correction) :', interface.oper_fec_mode
                        print "  Beacon is turned", interface.beacon_state
                        print "  Auto-Negotiation is turned", interface.auto_neg
                    if interface.is_ether() or interface.is_pc() or interface.is_mgmt():
                        print "  Input flow-control is off, output flow-control is off"
                        if interface.mdix == 'auto':
                            print "  Auto-mdix is turned on"
                        else:
                            print "  Auto-mdix is turned off"
                    elif interface.is_loop():
                        print "  Auto-mdix is turned off"
                    if interface.is_ether() and not interface.is_sub() and interface.port_cap_fcot_capable == '1':
                        if interface.port_cap_rate_mode == "1":
                            rateMode = "dedicated"
                        elif interface.port_cap_rate_mode == "2":
                            rateMode = "shared"
                        else:
                            rateMode = interface.port_cap_rate_mode
                        print "  Rate mode is %s" % rateMode

                    if interface.is_ether():
                        if interface.span_mode == "not-a-span-dest":
                            print '  Switchport monitor is off'
                        else:
                            print '  Switchport monitor is on'

                    if interface.is_ether() or interface.is_pc() or interface.is_mgmt():
                        print '  EtherType is', interface.dot1q_ethertype

                    if interface.is_ether():
                        if interface.eee_state == "not-applicable":
                            print "  EEE (efficient-ethernet) : n/a"
                        elif interface.eee_state == "enable":
                            print "  EEE (efficient-ethernet) : Operational"
                        elif interface.eee_state == "disable":
                            print "  EEE (efficient-ethernet) : Disabled"
                        elif interface.eee_state == "disagreed":
                            print "  EEE (efficient-ethernet) : Disagreed"

                        if interface.last_link_st_chg.startswith('1970-'):
                            print "  Last link flapped never"
                        else:
                            last_flap = dateutil.parser.parse(interface.last_link_st_chg).replace(tzinfo=None)
                            seconds_since_flap = datetime.datetime.now() - last_flap
                            print "  Last link flapped", seconds_since_flap

                    if interface.is_ether() or interface.is_pc() or interface.is_svi():
                        last_clear = 'never'
                        if interface.clear_ts != 'never':
                            last_clear = dateutil.parser.parse(interface.clear_ts).replace(tzinfo=None)
                        print '  Last clearing of "show interface" counters %s' % last_clear
                        if not interface.is_svi():
                            print '  ', interface.reset_ctr,'interface resets'
                    elif interface.is_tun():
                        pass
                    if interface.is_svi():
                        pass
                    elif interface.is_ether() or interface.is_pc():
                        print "  30 seconds input rate %d bits/sec, %d packets/sec" % \
                               (interface.input_bitrate_30sec, interface.input_packetrate_30sec)
                        print "  30 seconds output rate %d bits/sec, %d packets/sec" % \
                               (interface.output_bitrate_30sec, interface.output_packetrate_30sec)
                        print "  Load-Interval #2: 5 minute (300 seconds)"
                        print "    input rate %d bps, %d pps; output rate %d bps, %d pps" % \
                                (interface.input_bitrate_300sec, interface.input_packetrate_300sec,
                                 interface.output_bitrate_300sec, interface.output_packetrate_300sec)
                        if interface.layer == 'Layer3':
                            print "  L3 in Switched:"
                            print "    ucast: %d pkts, %d bytes - mcast: %d pkts, %d bytes" % \
                                  (0, 0, 0, 0)
                                                        # (stats.l3InSwitchedUcastPackets,
                                                        #  stats.l3InSwitchedUcastBytes,
                                                        #  stats.l3InSwitchedMcastPackets,
                                                        #  stats.l3InSwitchedMcastBytes)
                            print "  L3 out Switched:"
                            print "    ucast: %d pkts, %d bytes - mcast: %d pkts, %d bytes" % \
                                  (0, 0, 0, 0)
                                                        # (stats.l3OutSwitchedUcastPackets,
                                                        #  stats.l3OutSwitchedUcastBytes,
                                                        #  stats.l3OutSwitchedMcastPackets,
                                                        #  stats.l3OutSwitchedMcastBytes)
                    if (interface.is_ether() or interface.is_pc()) and not interface.is_sub():
                        print "  RX"
                        ucast = "%d unicast packets" % interface.rx_unicast_packets
                        mcast = "%d multicast packets" % interface.rx_multicast_packets
                        bcast = "%d broadcast packets" % interface.rx_broadcast_packets
                        print "    %s  %s  %s" % (ucast, mcast, bcast)

                        pkts = "%d input packets" % interface.rx_input_packets
                        bytes = "%d bytes" % interface.rx_input_bytes
                        print "    %s  %s" % (pkts, bytes)

                        print '   ', interface.rx_oversize_packets, 'jumbo packets ',\
                              interface.rx_storm_supression_packets, 'storm suppression bytes'

                        print '   ', interface.rx_runts, 'runts', interface.rx_oversize_packets,\
                              'giants', interface.rx_crc, 'CRC  0 no buffer'

                        print '   ', interface.rx_error_packets, 'input error',\
                              interface.rx_runts, 'short frame  0 overrun  0 underrun  0 ignored'

                        print '    0 watchdog  0 bad etype drop', interface.bad_proto_drop,\
                              'bad proto drop  0 if down drop'

                        print '    0 input with dribble', interface.rx_input_discard, 'input discard'

                        print '   ', interface.rx_pause_frames, 'Rx pause'

                        print '  TX'
                        print '   ', interface.tx_unicast_packets, 'unicast packets', interface.tx_multicast_packets,\
                              'multicast packets', interface.tx_broadcast_packets, 'broadcast packets'

                        print '   ', interface.tx_output_packets, 'output packets', interface.tx_output_bytes, 'bytes'
                        print '   ', interface.tx_oversize_packets, 'jumbo packets'
                        print '   ', interface.tx_error_packets, 'output error', interface.collisions, 'collision',\
                              interface.deferred_transmissions, 'deferred', interface.late_collisions, 'late collision'
                        print '    0 lost carrier', interface.carrier_sense_errors, '0 babble',\
                              interface.tx_output_discard, 'output discard'
                        print '   ', interface.out_pause_frames, 'Tx pause'

                    print ""
Example #14
0
class InterfaceBriefCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        self._if_brief_headers = {
            'l1PhysIf': ['Ethernet Interface', 'VLAN', 'Type', 'Mode', 'Status', 'Reason', 'Speed', 'Port Ch #'],
            'pcAggrIf': ['Port-channel Interface', 'VLAN', 'Type', 'Mode', 'Status', 'Reason', 'Speed', 'Protocol'],
            'l3LbRtdIf': ['Interface', 'Status', 'Description'],
            'tunnelIf': ['Interface', 'Status', 'IP Address', 'Encap type', 'MTU'],
            'sviIf': ['Interface', 'Secondary VLAN(Type)', 'Status', 'Reason'],
            'l3EncRtdIf': [],
            'mgmtMgmtIf': ['Port', 'VRF', 'Status', 'IP Address', 'Speed', 'MTU'],
            'l2ExtIf': [],
            'l2VfcIf': ['Interface', 'Vsan', 'Admin\nMode', 'Admin Trunk Mode', 'Status',
                        'Bind Info', 'Oper Mode', 'Oper Speed (Gbps)']
        }
        self._if_types = self._if_brief_headers.keys()
        if not self._apic.login().ok:
            self._logged_in = False
            print('%% Could not login to APIC')
        else:
            self._logged_in = True
        self._interfaces = []

    @property
    def _all_if_types_as_string(self):
        resp = ''
        for if_type in self._if_types:
            if len(resp):
                resp += ','
            resp += if_type
        return resp

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def populate_interfaces(self, node_id, intf_id=None):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=%s&rsp-subtree=children&'
                     'rsp-subtree-class=ethpmPhysIf,l1RtMbrIfs,ethpmAggrIf' % (node_id, self._all_if_types_as_string))
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        interfaces = self._get_query(query_url, error_message)
        if intf_id is None:
            self._interfaces = interfaces
        else:
            self._interfaces = []
            for interface in interfaces:
                for if_type in interface:
                    if interface[if_type]['attributes']['id'] == intf_id:
                        self._interfaces.append(interface)

    def _has_interface_type(self, if_type, intf_id=None):
        for interface in self._interfaces:
            if if_type in interface:
                if intf_id is None or intf_id == interface[if_type]['attributes']['id']:
                    return True
        return False

    def _get_interface_type(self, if_type):
        resp = []
        for interface in self._interfaces:
            if if_type in interface:
                resp.append(interface)
        return resp

    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    @staticmethod
    def convert_to_ascii(data):
        data = str(data).split(',')
        resp = ''
        for letter in data:
            resp += str(unichr(int(letter)))
        return resp

    def _get_interface_type_brief_data(self, if_type, intf_id=None):
        data = []
        for interface in self._interfaces:
            if if_type in interface:
                if intf_id is not None and intf_id != interface[if_type]['attributes']['id']:
                    continue
                if_attrs = interface[if_type]['attributes']
                if if_type == 'mgmtMgmtIf':
                    data.append((if_attrs['id'], '--', if_attrs['adminSt'], '', if_attrs['speed'], if_attrs['mtu']))
                elif if_type == 'l1PhysIf':
                    port_channel = '--'
                    for child in interface[if_type]['children']:
                        if 'l1RtMbrIfs' in child:
                            port_channel = child['l1RtMbrIfs']['attributes']['tSKey']
                        else:
                            oper_attrs = child['ethpmPhysIf']['attributes']
                    data.append((if_attrs['id'], '--', 'eth', oper_attrs['operMode'], oper_attrs['operSt'],
                                 oper_attrs['operStQual'], oper_attrs['operSpeed'], port_channel))
                elif if_type == 'tunnelIf':
                    data.append((if_attrs['id'], if_attrs['operSt'], '--', if_attrs['tType'], if_attrs['cfgdMtu']))
                elif if_type == 'pcAggrIf':
                    for child in interface[if_type]['children']:
                        protocol = '--'
                        if if_attrs['pcMode'] in ['active', 'passive', 'mac-pin']:
                            protocol = 'lacp'
                        elif if_attrs['pcMode'] == 'static':
                            protocol = 'none'
                        if 'ethpmAggrIf' in child:
                            oper_attrs = child['ethpmAggrIf']['attributes']
                    data.append((if_attrs['id'], '--', 'eth', oper_attrs['operMode'], oper_attrs['operSt'],
                                 oper_attrs['operStQual'], oper_attrs['operSpeed'], protocol))
                elif if_type == 'sviIf':
                    data.append((if_attrs['id'], '--', if_attrs['operSt'], if_attrs['operStQual']))
                elif if_type == 'l3LbRtdIf':
                    if len(if_attrs['descr']):
                        description = if_attrs['descr']
                    else:
                        description = '--'
                    data.append((if_attrs['id'], if_attrs['adminSt'], description))
                elif if_type == 'l2VfcIf':
                    raise NotImplementedError
                    # TODO: finish this
        return data

    def show_brief(self, node=None, intf_id=None):
        """
        show interface brief

        :param node: String containing the specific switch id. If none, all switches are used
        :param intf_id: String containing the specific interface id. If none, all interfaces are used
        :return: None
        """
        for node_id in self.get_node_ids(node):
            self.populate_interfaces(node_id, intf_id)

            for if_type in self._if_types:
                if self._has_interface_type(if_type, intf_id):
                    data = self._get_interface_type_brief_data(if_type, intf_id)
                    data.sort(key=lambda tup: tup[0])
                    if len(data):
                        print tabulate(data, headers=self._if_brief_headers[if_type])
                        print
Example #15
0
class InterfaceCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        if not self._apic.login().ok:
            self._logged_in = False
            print '%% Could not login to APIC'
        else:
            self._logged_in = True
        self._interfaces = []
        self._port_channels = []

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def populate_port_channels(self, node_id, intf_id=None):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=pcAggrIf&rsp-subtree=children&'
                     'rsp-subtree-class=ethpmAggrIf,pcRsMbrIfs' % node_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        port_channels = self._get_query(query_url, error_message)
        if intf_id is None:
            self._port_channels = port_channels
        else:
            self._port_channels = []
            for port_channel in port_channels:
                for if_type in port_channel:
                    if port_channel[if_type]['attributes']['id'] == intf_id:
                        self._port_channels.append(port_channel)

    def populate_interfaces(self, node_id):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=l1PhysIf&rsp-subtree=children&'
                     'rsp-subtree-class=pcAggrMbrIf' % node_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        self._interfaces = self._get_query(query_url, error_message)

    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    def _get_member_extension(self, port_channel):
        resp = ''
        for child in port_channel['pcAggrIf']['children']:
            if 'pcRsMbrIfs' in child:
                for interface in self._interfaces:
                    if child['pcRsMbrIfs']['attributes']['tDn'] == interface['l1PhysIf']['attributes']['dn']:
                        oper_attr = interface['l1PhysIf']['children'][0]['pcAggrMbrIf']['attributes']
                        if oper_attr['operSt'] == 'module-removed':
                            resp = '(r)'
                        elif oper_attr['operSt'] == 'up':
                            resp = '(P)'
                        elif oper_attr['channelingSt'] == 'individual':
                            resp = "(I)"
                        elif oper_attr['channelingSt'] == 'suspended':
                            resp = "(s)"
                        elif oper_attr['channelingSt'] == 'hot-standby':
                            resp = "(H)"
                        else:
                            resp = "(D)"
                    if resp != '':
                        break
        return resp

    def show_summary(self, node=None, intf_id=None):
        """
        show port-channel summary

        :param node: String containing the specific switch id. If none, all switches are used
        :param intf_id: String containing the specific interface id. If none, all interfaces are used
        :return: None
        """
        for node_id in self.get_node_ids(node):
            self.populate_interfaces(node_id)
            self.populate_port_channels(node_id, intf_id)
            if not len(self._port_channels):
                continue
            print "Switch:", node_id
            print "Flags:  D - Down        P - Up in port-channel (members)"
            print "        I - Individual  H - Hot-standby (LACP only)"
            print "        s - Suspended   r - Module-removed"
            print "        S - Switched    R - Routed"
            print "        U - Up (port-channel)"
            print "        M - Not in use. Min-links not met"
            print "        F - Configuration failed"
            data = []
            for interface in self._port_channels:
                intf_attr = interface['pcAggrIf']['attributes']
                name = intf_attr['id']
                if intf_attr['layer'] == 'Layer2':
                    name += "(S"
                else:
                    name += "(R"

                for child in interface['pcAggrIf']['children']:
                    if 'ethpmAggrIf' in child:
                        oper_attr = child['ethpmAggrIf']['attributes']
                        if oper_attr['operSt'] == 'up':
                            name += "U)"
                        elif intf_attr['suspMinlinks'] == 'yes':
                            name += "M)"
                        else:
                            name += "D)"
                        members = oper_attr['activeMbrs']
                        while ',unspecified,' in members:
                            members = members.replace(',unspecified,', ',')
                        members = members.replace(',unspecified', '')

                members += self._get_member_extension(interface)
                protocol = 'none'
                if intf_attr['pcMode'] in ['active', 'passive', 'mac-pin']:
                    protocol = 'lacp'
                data.append((int(intf_attr['id'][2:]), name, 'eth', protocol, members))
            data.sort(key=lambda tup: tup[0])
            headers = ['Group', 'Port channel', 'Type', 'Protocol', 'Member Ports']
            print tabulate(data, headers=headers)
Example #16
0
class InterfaceDetailedCollector(object):
    def __init__(self, url, login, password):
        # Login to APIC
        self._apic = Session(url, login, password)
        if not self._apic.login().ok:
            self._logged_in = False
            print('%% Could not login to APIC')
        else:
            self._logged_in = True
        self._interfaces = []

    def _get_query(self, query_url, error_msg):
        resp = self._apic.get(query_url)
        if not resp.ok:
            print error_msg
            print resp.text
            return []
        return resp.json()['imdata']

    def _populate_beacon_states(self, data):
        for beacon_data in data:
            if 'eqptLocLed' not in beacon_data:
                continue
            dn = beacon_data['eqptLocLed']['attributes']['dn']
            oper_state = beacon_data['eqptLocLed']['attributes']['operSt']
            if 'leafport-' in dn:
                port_num = dn.partition('/leafport-')[2].partition('/')[0]
                mod_num = dn.partition('/lcslot-')[2].partition('/')[0]
                node_num = dn.partition('/node-')[2].partition('/')[0]
                beacon_interface_id = 'eth' + mod_num + '/' + port_num
                beacon_node_id = '/node-%s/' % node_num
                for interface in self._interfaces:
                    if not interface.is_ether():
                        continue
                    if interface.id == beacon_interface_id:
                        if beacon_node_id in dn:
                            interface.beacon_state = oper_state

    def populate_detailed_interfaces(self, node_id, intf_id=None):
        query_url = ('/api/mo/topology/pod-1/node-%s/sys.json?query-target=subtree'
                     '&target-subtree-class=l1PhysIf,pcAggrIf,l3LbRtdIf,tunnelIf,sviIf,l3EncRtdIf,'
                     'mgmtMgmtIf,l2ExtIf,l2VfcIf,eqptLocLed&rsp-subtree=full&'
                     'rsp-subtree-class=ethpmPhysIf,ethpmPortCap,l1RtMbrIfs,ethpmAggrIf,'
                     'rmonEtherStats,rmonIfIn,rmonIfOut,rmonIfStorm,eqptIngrTotal5min,'
                     'eqptEgrTotal5min,l1EeeP,rmonDot3Stats' % node_id)
        error_message = 'Could not collect APIC data for switch %s.' % node_id
        interfaces = self._get_query(query_url, error_message)
        self._interfaces = []
        if intf_id is None:
            for interface in interfaces:
                self._interfaces.append(Interface(interface))
        else:
            for interface in interfaces:
                for if_type in interface:
                    if if_type == 'eqptLocLed':
                        continue
                    if interface[if_type]['attributes']['id'] == intf_id:
                        self._interfaces.append(Interface(interface))
        self._populate_beacon_states(interfaces)


    def get_node_ids(self, node_id):
        """
        Get the list of node ids from the command line arguments.
        If none, get all of the node ids
        :param args: Command line arguments
        :return: List of strings containing node ids
        """
        if node_id is not None:
            names = [node_id]
        else:
            names = []
            query_url = ('/api/node/class/fabricNode.json?'
                         'query-target-filter=eq(fabricNode.role,"leaf")')
            error_message = 'Could not get switch list from APIC.'
            nodes = self._get_query(query_url, error_message)
            for node in nodes:
                names.append(str(node['fabricNode']['attributes']['id']))
        return names

    def show_detailed(self, node=None, intf_id=None):
        """
        show interface

        :param node: String containing the specific switch id. If none, all switches are used
        :param intf_id: String containing the specific interface id. If none, all interfaces are used
        :return: None
        """
        for node_id in self.get_node_ids(node):
            print('Switch', node_id)
            self.populate_detailed_interfaces(node_id, intf_id)
            for interface in self._interfaces:
                if interface.if_type == 'l1PhysIf':
                    if interface.is_ether or interface.is_pc() or interface.is_tun():
                        state = interface.oper_st
                        rsn = interface.oper_st_qual
                        if state is None:
                            state = "unknown"
                            rsn = "unknown"
                        if state == 'link-up':
                            # see ethpm_copy_eth_port_log_info()
                            # link-up state is physical up, but not operationally up
                            state = 'down'
                        if state == 'up':
                            if not interface.is_tun() and interface.switching_st == 'disabled':
                                print "%s is %s (%s)" % (interface.id, state, "out-of-service")
                            else:
                                print "%s is %s" % (interface.id, state)
                        elif interface.oper_st_qual == "err-disabled":
                            print "%s is %s (%s)" % (interface.id, state, interface.oper_err_dis_qual)
                        else:
                            print "%s is %s (%s)" % (interface.id, state, rsn)

                    print('admin state is', interface.admin_st)
                    if interface.is_member_pc():
                        print "  Belongs to %s" % interface.port_channel_id
                    if not interface.descr == '':
                        print('  Port description is', interface.descr)
                    print('  Hardware:', interface.port_cap_speed, 'Ethernet, address:', interface.address, \)
                          '(bia', interface.backplane_mac, ')'
                    print('  MTU', interface.mtu, 'bytes, BW', interface.bw, 'Kbit, DLY', interface.delay, 'usec')
                    print('  reliability', '%s/255' % interface.reliability, \)
                          'txload %d/255, rxload %d/255' %  (interface.tx_load, interface.rx_load)
                    print('  Encapsulation ARPA, medium is broadcast')
                    if interface.layer != 'Layer2':
                        print('  Port mode is routed')
                    else:
                        print "  Port mode is %s" % interface.mode
                    if not interface.is_mgmt() and interface.oper_mode == 'ips':
                        duplex = 'auto'
                    else:
                        duplex = interface.oper_duplex
                    print "  %s-duplex, %sb/s%s" % (duplex, interface.speed, interface.fcot_str)
                    if (interface.is_ether() and not interface.is_sub()) or interface.is_mgmt():
                        if not interface.is_mgmt():
                            print('  FEC (forward-error-correction) :', interface.oper_fec_mode)
                        print "  Beacon is turned", interface.beacon_state
                        print "  Auto-Negotiation is turned", interface.auto_neg
                    if interface.is_ether() or interface.is_pc() or interface.is_mgmt():
                        print "  Input flow-control is off, output flow-control is off"
                        if interface.mdix == 'auto':
                            print "  Auto-mdix is turned on"
                        else:
                            print "  Auto-mdix is turned off"
                    elif interface.is_loop():
                        print "  Auto-mdix is turned off"
                    if interface.is_ether() and not interface.is_sub() and interface.port_cap_fcot_capable == '1':
                        if interface.port_cap_rate_mode == "1":
                            rateMode = "dedicated"
                        elif interface.port_cap_rate_mode == "2":
                            rateMode = "shared"
                        else:
                            rateMode = interface.port_cap_rate_mode
                        print "  Rate mode is %s" % rateMode

                    if interface.is_ether():
                        if interface.span_mode == "not-a-span-dest":
                            print('  Switchport monitor is off')
                        else:
                            print('  Switchport monitor is on')

                    if interface.is_ether() or interface.is_pc() or interface.is_mgmt():
                        print('  EtherType is', interface.dot1q_ethertype)

                    if interface.is_ether():
                        if interface.eee_state == "not-applicable":
                            print "  EEE (efficient-ethernet) : n/a"
                        elif interface.eee_state == "enable":
                            print "  EEE (efficient-ethernet) : Operational"
                        elif interface.eee_state == "disable":
                            print "  EEE (efficient-ethernet) : Disabled"
                        elif interface.eee_state == "disagreed":
                            print "  EEE (efficient-ethernet) : Disagreed"

                        if interface.last_link_st_chg.startswith('1970-'):
                            print "  Last link flapped never"
                        else:
                            last_flap = dateutil.parser.parse(interface.last_link_st_chg).replace(tzinfo=None)
                            seconds_since_flap = datetime.datetime.now() - last_flap
                            print "  Last link flapped", seconds_since_flap

                    if interface.is_ether() or interface.is_pc() or interface.is_svi():
                        last_clear = 'never'
                        if interface.clear_ts != 'never':
                            last_clear = dateutil.parser.parse(interface.clear_ts).replace(tzinfo=None)
                        print('  Last clearing of "show interface" counters %s' % last_clear)
                        if not interface.is_svi():
                            print('  ', interface.reset_ctr,'interface resets')
                    elif interface.is_tun():
                        pass
                    if interface.is_svi():
                        pass
                    elif interface.is_ether() or interface.is_pc():
                        print "  30 seconds input rate %d bits/sec, %d packets/sec" % \
                               (interface.input_bitrate_30sec, interface.input_packetrate_30sec)
                        print "  30 seconds output rate %d bits/sec, %d packets/sec" % \
                               (interface.output_bitrate_30sec, interface.output_packetrate_30sec)
                        print "  Load-Interval #2: 5 minute (300 seconds)"
                        print "    input rate %d bps, %d pps; output rate %d bps, %d pps" % \
                                (interface.input_bitrate_300sec, interface.input_packetrate_300sec,
                                 interface.output_bitrate_300sec, interface.output_packetrate_300sec)
                        if interface.layer == 'Layer3':
                            print "  L3 in Switched:"
                            print "    ucast: %d pkts, %d bytes - mcast: %d pkts, %d bytes" % \
                                  (0, 0, 0, 0)
                                                        # (stats.l3InSwitchedUcastPackets,
                                                        #  stats.l3InSwitchedUcastBytes,
                                                        #  stats.l3InSwitchedMcastPackets,
                                                        #  stats.l3InSwitchedMcastBytes)
                            print "  L3 out Switched:"
                            print "    ucast: %d pkts, %d bytes - mcast: %d pkts, %d bytes" % \
                                  (0, 0, 0, 0)
                                                        # (stats.l3OutSwitchedUcastPackets,
                                                        #  stats.l3OutSwitchedUcastBytes,
                                                        #  stats.l3OutSwitchedMcastPackets,
                                                        #  stats.l3OutSwitchedMcastBytes)
                    if (interface.is_ether() or interface.is_pc()) and not interface.is_sub():
                        print "  RX"
                        ucast = "%d unicast packets" % interface.rx_unicast_packets
                        mcast = "%d multicast packets" % interface.rx_multicast_packets
                        bcast = "%d broadcast packets" % interface.rx_broadcast_packets
                        print "    %s  %s  %s" % (ucast, mcast, bcast)

                        pkts = "%d input packets" % interface.rx_input_packets
                        bytes = "%d bytes" % interface.rx_input_bytes
                        print "    %s  %s" % (pkts, bytes)

                        print('   ', interface.rx_oversize_packets, 'jumbo packets ',\)
                              interface.rx_storm_supression_packets, 'storm suppression bytes'

                        print('   ', interface.rx_runts, 'runts', interface.rx_oversize_packets,\)
                              'giants', interface.rx_crc, 'CRC  0 no buffer'

                        print('   ', interface.rx_error_packets, 'input error',\)
                              interface.rx_runts, 'short frame  0 overrun  0 underrun  0 ignored'

                        print('    0 watchdog  0 bad etype drop', interface.bad_proto_drop,\)
                              'bad proto drop  0 if down drop'
Example #17
0
# Take login credentials from the command line if provided
# Otherwise, take them from your environment variables file ~/.profile
description = 'Simple application that logs on to the APIC and Extracts the L3out Static Routes information.'
creds = Credentials('apic', description)
creds.add_argument('--tenant', help='The name of Tenant')
args = creds.get()

# Login to APIC
session = Session(args.url, args.login, args.password)
resp = session.login()
if not resp.ok:
    print('%% Could not login to APIC')
    sys.exit(0)

resp = session.get(
    '/api/class/ipRouteP.json?rsp-subtree=full&rsp-prop-include=config-only&order-by=ipRouteP.dn'
)
data = json.loads(resp.text)['imdata']
datacount = int(json.loads(resp.text)['totalCount'])

fname = "Static_Route.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow([
        "Tenant", "L3OUT", "Logical Node Profile", "Node ID", "IP Prefix",
        "Route Pref", "Next Hop", "NH Pref", "Route Control"
    ])

    numrow = 0
    for i in data: