Created
June 26, 2018 07:37
-
-
Save lanbugs/4dbed5e0e8a7d5b6d29c4ea9b9e93bb2 to your computer and use it in GitHub Desktop.
Commandline Tool for exporting Cisco Hardware Inventory via SNMP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Need following pip packages | |
# - easysnmp | |
# - tabulate | |
# Checkout blog article to tool | |
# https://lanbugs.de/netzwerktechnik/hersteller/cisco/commandline-tool-for-exporting-cisco-hardware-inventory-via-snmp/ | |
from easysnmp import Session | |
import argparse | |
from tabulate import tabulate | |
from operator import itemgetter | |
from pprint import pprint | |
def main(): | |
#### | |
# ARGS | |
#### | |
description = """ | |
Cisco inventory grabber\nVersion 0.1\nWritten by Maximilian Thoma 2018 | |
""" | |
aparser = argparse.ArgumentParser(description=description) | |
aparser.add_argument('-H', dest='host', help='WLC IP address', required=True) | |
aparser.add_argument('-v', dest='snmp_version', help='SNMP version, valid are 2 or 3', required=True) | |
aparser.add_argument('-C', dest='snmp_community', help='SNMP Community (only v2)') | |
aparser.add_argument('-u', dest='snmp_user', help='SNMP user (v3)') | |
aparser.add_argument('-A', dest='snmp_auth', help='SNMP auth password (v3)') | |
aparser.add_argument('-a', dest='snmp_auth_method', help='SNMP auth method, valid are MD5 or SHA (v3)') | |
aparser.add_argument('-X', dest='snmp_privacy', help='SNMP privacy password (v3)') | |
aparser.add_argument('-x', dest='snmp_privacy_method', help='SNMP privacy method, valid are AES or DES (v3)') | |
aparser.add_argument('-L', dest='snmp_security', | |
help='SNMP security level, valid are no_auth_or_privacy, auth_without_privacy or auth_with_privacy (v3)') | |
aparser.add_argument('--csv', dest='csv', help='Result should be CSV', action='store_true') | |
args = aparser.parse_args() | |
#### | |
# Setup SNMP connection | |
#### | |
if args.snmp_version == "2": | |
try: | |
snmp = Session(hostname=args.host, version=2, use_numeric=True) | |
except Exception as e: | |
print e | |
if args.snmp_version == "3": | |
try: | |
snmp = Session( | |
hostname=args.host, | |
version=3, | |
security_level=args.snmp_security, | |
security_username=args.snmp_user, | |
auth_protocol=args.snmp_auth_method, | |
auth_password=args.snmp_auth, | |
privacy_protocol=args.snmp_privacy_method, | |
privacy_password=args.snmp_privacy, | |
use_numeric=True | |
) | |
except Exception as e: | |
print e | |
#### | |
# Init Data Buffer | |
#### | |
inventory = {} | |
inv_print = [] | |
#### | |
# SNMP Walk inventory | |
#### | |
port = { | |
0: "-", | |
1: "other", | |
2: "unknown", | |
3: "chassis", | |
4: "backplane", | |
5: "container", | |
6: "powerSupply", | |
7: "fan", | |
8: "sensor", | |
9: "module", | |
10: "port", | |
11: "stack", | |
12: "cpu" | |
} | |
## Get inventory | |
result_ids = snmp.walk(".1.3.6.1.2.1.47.1.1.1.1") | |
def stripper(string): | |
if "NoneType" not in str(type(string)): | |
return string.strip() | |
else: | |
return string | |
for r in result_ids: | |
if r.oid_index in inventory: | |
element_id = r.oid.replace(".1.3.6.1.2.1.47.1.1.1.1.","") | |
if element_id == "16": # fru | |
fru = "true" if "1" in r.value else "false" | |
inventory[r.oid_index][element_id] = fru | |
elif element_id == "5": # class | |
classx = port[int(r.value)] if len(r.value) is 1 else port[0] | |
inventory[r.oid_index][element_id] = classx | |
else: # everything else | |
inventory[r.oid_index][element_id] = r.value | |
else: | |
element_id = r.oid.replace(".1.3.6.1.2.1.47.1.1.1.1.","") | |
inventory[r.oid_index] = {} | |
inventory[r.oid_index][element_id] = r.value | |
for elements, values in inventory.iteritems(): | |
if len(values['11']) >= 1: | |
#print elements | |
#2 entPhysicalDescr | |
#3 entPhysicalVendorType | |
#4 entPhysicalContainedIn | |
#5 entPhysicalClass | |
#6 entPhysicalParentRelPos | |
#7 entPhysicalName | |
#8 entPhysicalHardwareRev | |
#9 entPhysicalFirmwareRev | |
#10 entPhysicalSoftwareRev | |
#11 entPhysicalSerialNum | |
#12 entPhysicalMfgName | |
#13 entPhysicalModelName | |
#14 entPhysicalAlias | |
#15 entPhysicalAssetID | |
#16 entPhysicalIsFRU | |
inv_print.append([stripper(values.get('2')), | |
stripper(values.get('5')), | |
stripper(values.get('7')), | |
stripper(values.get('8')), | |
stripper(values.get('9')), | |
stripper(values.get('10')), | |
stripper(values.get('11')), | |
stripper(values.get('12')), | |
stripper(values.get('13')), | |
stripper(values.get('16'))]) | |
#### | |
# Sort table | |
#### | |
inv = sorted(inv_print, key=itemgetter(0)) | |
#### | |
# Result | |
#### | |
if args.csv is True: | |
print 'Description;Class;Name;HWRev;FWRev;SWRev;Serial;Manufactor;Model;FRU?' | |
for line in inv: | |
print ';'.join(str(l) for l in line) | |
else: | |
print tabulate(inv, headers=['Description', 'Class', 'Name', 'HWRev', 'FWRev', 'SWRev', 'Serial', 'Manufactor', 'Model', 'FRU?'], tablefmt="orgtbl") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment