diff --git a/.cache/v/cache/lastfailed b/.cache/v/cache/lastfailed new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.cache/v/cache/lastfailed @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f2cf3e2..79df73a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ netgrphdev.ini netgrphtest.ini neo4j-queries.txt build-commands +.vscode/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a7ce59..5c10ec9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ These are the early days of NetGrph, but I fully plan to support this program going forward and am looking for contributors. I am also the primary maintainer of the [Network Tracking Database (NetDB)](http://netdbtracking.sourceforge.net/), which is in production on some -extremely large network. NetGrph is currently serving as our internal model for +extremely large networks. NetGrph is currently serving as our internal model for network automation tasks, and we hope others find it useful as well. It's primary purpose is to do work at this time, from automation to troubleshooting tasks. diff --git a/csv/vrfs.csv b/csv/vrfs.csv index c1a8345..fe52f2f 100644 --- a/csv/vrfs.csv +++ b/csv/vrfs.csv @@ -3,3 +3,4 @@ guest,10,Guest Network outside,1,External Networks perim,25,Perimeter DMZ Network utility,150,Utility Network +test,1,Test Empty VRF diff --git a/cypher/constraints.cyp b/cypher/constraints.cyp index 653feae..9b49299 100644 --- a/cypher/constraints.cyp +++ b/cypher/constraints.cyp @@ -1,7 +1,6 @@ -- Create constraints on DB for consistency and performance --CREATE Garbage CREATE CONSTRAINT ON (n:Network) ASSERT n.vrfcidr IS UNIQUE -CREATE CONSTRAINT ON (m:MgmtGroup) ASSERT m.name IS UNIQUE CREATE CONSTRAINT ON (s:Switch) ASSERT s.name IS UNIQUE CREATE CONSTRAINT ON (v:VRF) ASSERT v.name IS UNIQUE CREATE CONSTRAINT ON (v:VLAN) ASSERT v.name IS UNIQUE diff --git a/docs/CHANGES.md b/docs/CHANGES.md index f8387b7..ec0e59a 100644 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -1,6 +1,11 @@ +### v0.7.3 +- Added vrf and dev to ngreport +- Added nfilter to netgrph to pass in custom filters at runtime +- Cleaned up debug netgrph.ini handling +- VLAN Group printing follows terminal size -### 7/1/16 +### v0.7.0 - Created public repo - Added lots of documentation - Cleaned up config files diff --git a/docs/INSTALL.md b/docs/INSTALL.md index b7a0a07..e0594f9 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -51,14 +51,16 @@ sudo pip3 install -r requirements.txt - Browse to the database web interface and run `MATCH (s:Switch) RETURN s` - Try out some sample commands -## Sample netgrph for use with test data +## Sample commands for use with test data ``` +./netgrph.py -nf all +./netgrph.py -nf all -o tree +./ngreport.py -dev ".*" ./netgrph.py abc4mdf -./netgrph.py abc4mdf -o csv ./netgrph.py abc4mdf -o json ./netgrph.py abc4mdf -o yaml ./netgrph.py -sp abc2sw1 xyz2sw1 -./netgrph.py -sp abc.* xyz.* +./netgrph.py -sp abc.* xyz.* -o csv ./netgrph.py 120 ./netgrph.py 1246 ./netgrph.py -fp 10.1.120.50 8.8.8.8 diff --git a/docs/TODO b/docs/TODO index a17f3ad..e52db7b 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,21 +1,21 @@ NetDB: -- Add CIDR usage for scope usage reporting +- Add CIDR scope usage reporting - Add more extensive device reporting Reporting: - - VRF Report - - Switch Report - No name, no root, no router report Other: - Add VRF to -rpath - Add master -path to netgrph +- Add tabular output option +- built-in paging support +- Group report takes up entire console Maintenance: - Add switch skip on certain neighbors - Rewrite nglib.net_update using Bolt as Pythonic - Emulate dict with ngtree -- built-in paging support -- Group report takes up entire console + diff --git a/docs/VERSION b/docs/VERSION index 2c0a9c7..3d105a6 100644 --- a/docs/VERSION +++ b/docs/VERSION @@ -1 +1 @@ -v0.7.2 +v0.7.3 diff --git a/netgrph.py b/netgrph.py index 37420ab..156411f 100755 --- a/netgrph.py +++ b/netgrph.py @@ -39,6 +39,7 @@ import argparse import nglib + # Default Config File Location config_file = '/etc/netgrph.ini' alt_config = './docs/netgrph.ini' @@ -48,7 +49,7 @@ if re.search(r'\/dev$', dirname): config_file = 'netgrphdev.ini' elif re.search(r'\/test$', dirname): - config_file = "netgrphtest.ini" + config_file = "netgrphdev.ini" parser = argparse.ArgumentParser() @@ -70,6 +71,8 @@ action="store_true") parser.add_argument("-nlist", help="Get all networks in an alert group", action="store_true") +parser.add_argument("-nfilter", help="Get all networks on a filter (see netgrph.ini)", + action="store_true") parser.add_argument("-dev", help="Get the Details for a Device (Switch/Router/FW)", action="store_true") parser.add_argument("-fpath", metavar="src", @@ -134,16 +137,19 @@ if args.fpath: nglib.query.path.get_fw_path(args.fpath, args.search) + elif args.spath: rtype = "TREE" if args.output: rtype = args.output nglib.query.path.get_switch_path(args.spath, args.search, rtype=rtype) + elif args.rpath: rtype = "TREE" if args.output: rtype = args.output nglib.query.path.get_routed_path(args.rpath, args.search, rtype=rtype) + elif args.dev: rtype = "TREE" if args.output: @@ -167,7 +173,13 @@ rtype = "CSV" if args.output: rtype = args.output - nglib.query.net.get_networks_on_group(args.search, rtype=rtype) + nglib.query.net.get_networks_on_filter(args.search, rtype=rtype) + +elif args.nfilter: + rtype = "CSV" + if args.output: + rtype = args.output + nglib.query.net.get_networks_on_filter(nFilter=args.search, rtype=rtype) elif args.group: nglib.query.vlan.get_vlans_on_group(args.search, args.vrange) diff --git a/nglib/query/__init__.py b/nglib/query/__init__.py index dd6109e..752be1c 100644 --- a/nglib/query/__init__.py +++ b/nglib/query/__init__.py @@ -114,11 +114,11 @@ def get_net_filter(group): raise Exception("No Group Filter Found", group) -def check_net_filter(netDict, group): +def check_net_filter(netDict, group=None, nFilter=None): """ Filters Networks based on vrf:role (from supernets) - Needs optimization + Pass in a group filter to read from config, or a custom nFilter Examples: nst = all (all networks) @@ -136,7 +136,10 @@ def check_net_filter(netDict, group): com = default:printer """ - vDict = get_filter_dict(group) + if group: + vDict = get_filter_dict(group=group) + elif nFilter: + vDict = get_filter_dict(nFilter=nFilter) # Check filter against vDict for vrf in vDict.keys(): @@ -164,13 +167,19 @@ def check_net_filter(netDict, group): @functools.lru_cache(maxsize=1) -def get_filter_dict(group): - """Process config for group and cache it for each call""" +def get_filter_dict(group=None, nFilter=None): + """Process config for group or custom filter and cache it for each call""" vDict = dict() + gFilter = None - gFilter = config['NetAlertFilter'][group] - + if group: + gFilter = config['NetAlertFilter'][group] + elif nFilter: + gFilter = nFilter + else: + raise Exception("Must pass in group or filter") + # Split all VRFs by spaces vrfFilters = gFilter.rsplit() @@ -213,7 +222,7 @@ def universal_text_search(text, vrange, rtype="TREE"): #Look for group filter first try: get_net_filter(text) - nglib.query.net.get_networks_on_group(text, rtype=rtype) + nglib.query.net.get_networks_on_filter(text, rtype=rtype) found = True except: pass diff --git a/nglib/query/dev.py b/nglib/query/dev.py index 1e7f43d..7835ce6 100644 --- a/nglib/query/dev.py +++ b/nglib/query/dev.py @@ -34,6 +34,7 @@ """ import logging import re +import sys import nglib import nglib.ngtree import nglib.ngtree.export @@ -42,7 +43,7 @@ verbose = 0 -def get_device(dev, rtype="TREE", vrange=None): +def get_device(dev, rtype="NGTREE", vrange=None): """Get Switch perspective (neighbors, vlans, routed networks)""" rtypes = ('TREE', 'JSON', 'YAML', 'NGTREE') @@ -52,7 +53,8 @@ def get_device(dev, rtype="TREE", vrange=None): ngtree = nglib.ngtree.get_ngtree(dev, tree_type="Device") - logger.info("Query: Device %s for %s", dev, nglib.user) + if rtype != "NGTREE": + logger.info("Query: Device %s for %s", dev, nglib.user) switch = nglib.bolt_ses.run( @@ -62,7 +64,12 @@ def get_device(dev, rtype="TREE", vrange=None): for sw in switch: - ngtree['Distance'] = int(sw['distance']) + try: + ngtree['Distance'] = int(sw['distance']) + except TypeError: + print("Error, device not part of the topology:", dev, file=sys.stderr) + return + ngtree['MGMT Group'] = sw['mgmt'] if vrange: ngtree['VLAN Range'] = vrange @@ -131,7 +138,7 @@ def get_device(dev, rtype="TREE", vrange=None): nglib.query.exp_ngtree(ngtree, rtype) return ngtree - print("No results found for device:", dev) + print("No results found for device:", dev, file=sys.stderr) def get_neighbors(dev): """ @@ -252,4 +259,21 @@ def get_vlans(dev, vrange=None): if vlan['mcount']: vt['MAC Count'] = vlan['mcount'] return vtree + + +def get_devlist_vrf(vrf): + """Returns a list of devices that route a VRF""" + + devices = nglib.bolt_ses.run( + 'MATCH(v:VRF)-[e:VRF_ON]-(r:Router) WHERE v.name = {vrf} ' + + 'RETURN r.name AS name ORDER BY name', + {"vrf": vrf}) + + devlist = [] + + for r in devices: + devlist.append(r["name"]) + + return devlist + #END diff --git a/nglib/query/net.py b/nglib/query/net.py index 48d8564..48f0445 100644 --- a/nglib/query/net.py +++ b/nglib/query/net.py @@ -30,7 +30,7 @@ """ NetGrph Query Network data """ - +import sys import ipaddress import logging import nglib @@ -60,12 +60,16 @@ def get_net(ip, rtype="TREE", days=7): netdbtree = nglib.netdb.ip.get_netdb_ip(ip, hours=hours) if netdbtree: nglib.ngtree.add_child_ngtree(ngtree, netdbtree) + # Export NGTree - ngtree = nglib.query.exp_ngtree(ngtree, rtype) - return ngtree + if ngtree: + ngtree = nglib.query.exp_ngtree(ngtree, rtype) + return ngtree + else: + print("No CIDR results for IP search:", ip, file=sys.stderr) else: - print("Unsupport RType, try", str(rtypes)) + print("Unsupport RType, try", str(rtypes), file=sys.stderr) def get_net_extended_tree(net, ip=None, ngtree=None, ngname="Networks"): @@ -93,7 +97,7 @@ def get_net_extended_tree(net, ip=None, ngtree=None, ngname="Networks"): if n.sr: standby = getJSONProperties(n.sr)['name'] - # Not already found + # Cache: Not already found if nProp['vrfcidr'] not in matches.keys(): matches[nProp['vrfcidr']] = 1 cngt = nglib.ngtree.get_ngtree(nProp['cidr'], tree_type="CIDR") @@ -125,36 +129,46 @@ def get_net_extended_tree(net, ip=None, ngtree=None, ngname="Networks"): elif verbose > 3: print("Existing Matches", nProp['vrfcidr']) + else: + return return ngtree -def get_networks_on_group(group, rtype="CSV"): +def get_networks_on_filter(group=None, nFilter=None, rtype="NGTREE"): """ Get list of networks as CSV for a group in netgraph.ini """ - rtypes = ('CSV', 'TREE', 'JSON', 'YAML') + rtypes = ('CSV', 'TREE', 'JSON', 'YAML', 'NGTREE') if rtype in rtypes: - logger.info("Query: Network List %s for %s", group, nglib.user) + if rtype != "NGTREE": + logger.info("Query: Network List %s for %s", group, nglib.user) netList = [] ngtree = nglib.ngtree.get_ngtree("Networks", tree_type="NET") - ngtree['Group'] = group - try: - ngtree['Filter'] = nglib.query.get_net_filter(group) - except KeyError: - print("Error: No Group Found in Config", group) - return - except: - raise + if group: + ngtree['Group'] = group - # Get all networks - #networks = nglib.bolt_ses.run('MATCH (n:Network) RETURN n.vrfcidr as vrfcidr') + try: + ngtree['Filter'] = nglib.query.get_net_filter(group) + except KeyError: + print("Error: No Group Found in Config", group) + return + except: + raise + # Custom Filter + elif nFilter: + ngtree['Filter'] = nFilter + else: + raise Exception("Must pass in group or nFilter") + + + # Get all networks networks = nglib.bolt_ses.run( 'MATCH(n:Network), (n)--(v:VRF), (n)-[:ROUTED_BY]->(r:Switch:Router) ' + 'OPTIONAL MATCH (n)--(s:Supernet) OPTIONAL MATCH (n)-[:ROUTED_STANDBY]->(rs:Switch:Router) ' @@ -172,7 +186,7 @@ def get_networks_on_group(group, rtype="CSV"): netDict[key] = net[key] # Matches Filter - if len(netDict) and nglib.query.check_net_filter(netDict, group): + if len(netDict) and nglib.query.check_net_filter(netDict, group=group, nFilter=nFilter): netList.append(netDict) netDict['_type'] = "CIDR" @@ -197,7 +211,7 @@ def get_networks_on_group(group, rtype="CSV"): ngtree = nglib.query.exp_ngtree(ngtree, rtype) return ngtree else: - print("No results found for filter:", ngtree['Filter']) + print("No results found for filter:", ngtree['Filter'], file=sys.stderr) else: raise Exception("RType Not Allowed, try: ", str(rtypes)) @@ -263,7 +277,7 @@ def get_networks_on_cidr(cidr, rtype="CSV"): print("No Results for", cidr) else: - raise Exception("RType Not Allowed, try: ", str(rtypes)) + raise Exception("RType Not Allowed, try: ", str(rtypes), file=sys.stderr) @@ -283,6 +297,7 @@ def find_cidr(ip): print(ip + " in " + r.cidr) mostSpecific = compare_cidr(mostSpecific, r.cidr) + return mostSpecific diff --git a/nglib/query/path.py b/nglib/query/path.py index a5a9e8a..28b7b31 100644 --- a/nglib/query/path.py +++ b/nglib/query/path.py @@ -32,6 +32,7 @@ """ import re +import sys import logging import subprocess import nglib @@ -64,7 +65,9 @@ def get_switch_path(switch1, switch2, rtype="NGTREE"): switch1, switch2, nglib.user) pathList = [] - ngtree = nglib.ngtree.get_ngtree("Switched Paths", tree_type="SPATHS") + ngtree = nglib.ngtree.get_ngtree("Switched Paths", tree_type="SPATHs") + ngtree["Path"] = switch1 + " -> " + switch2 + dist = dict() swp = nglib.py2neo_ses.cypher.execute( @@ -117,7 +120,7 @@ def get_switch_path(switch1, switch2, rtype="NGTREE"): def get_routed_path(net1, net2, rtype="NGTREE"): """ Find the routed path between two CIDRs and return all interfaces and - devices between the two. This query is currently highly unoptimized. + devices between the two. This query need optimization. - net1 and net2 can be IPs, and it will find the CIDR - Uses Neo4j All Shortest Paths on ROUTED Relationships @@ -140,14 +143,18 @@ def get_routed_path(net1, net2, rtype="NGTREE"): if re.search(r'^\d+\.\d+\.\d+\.\d+$', net2): n2tree = nglib.query.net.get_net(net2, rtype="NGTREE") - net2 = n2tree['_child001']['Name'] + if n2tree: + net2 = n2tree['_child001']['Name'] + + + ngtree = nglib.ngtree.get_ngtree("Routed Paths", tree_type="RPATHs") + ngtree["Path"] = net1 + " -> " + net2 pathList = [] pathRec = [] - ngtree = nglib.ngtree.get_ngtree("Routed Paths", tree_type="RPATHS") - + # Finds all paths, then finds the relationships rtrp = nglib.py2neo_ses.cypher.execute( 'MATCH (sn:Network), (dn:Network), rp = allShortestPaths ' + '((sn)-[:ROUTED|ROUTED_BY|ROUTED_STANDBY*0..12]-(dn)) ' @@ -221,7 +228,7 @@ def get_routed_path(net1, net2, rtype="NGTREE"): ngtree = nglib.query.exp_ngtree(ngtree, rtype) return ngtree else: - print("No results found for path between {:} and {:}".format(net1, net2)) + print("No results found for path between {:} and {:}".format(net1, net2), file=sys.stderr) return @@ -231,7 +238,7 @@ def get_fw_path(src, dst): srcnet = nglib.query.net.find_cidr(src) dstnet = nglib.query.net.find_cidr(dst) - logger.info("Query: Tracing %s --> %s for %s", src, dst, nglib.user) + logger.info("Query: Tracing %s -> %s for %s", src, dst, nglib.user) if verbose: print("\nFinding security path from {:} -> {:}:\n".format(srcnet, dstnet)) @@ -253,7 +260,7 @@ def get_fw_path(src, dst): dn = r.d dnp = nglib.query.nNode.getJSONProperties(dn) - path = snp['cidr'] + " --> " + path = snp['cidr'] + " -> " # Path nodes = r.p.nodes @@ -261,10 +268,10 @@ def get_fw_path(src, dst): nProp = nglib.query.nNode.getJSONProperties(node) label = nglib.query.nNode.getLabel(node) if re.search('VRF', label): - path = path + "VRF:" + nProp['name'] + " --> " + path = path + "VRF:" + nProp['name'] + " -> " if re.search('FW', label): - path = path + nProp['name'] + " --> " + path = path + nProp['name'] + " -> " fwsearch[nProp['name']] = nProp['hostname'] + "," + nProp['logIndex'] path = path + dnp['cidr'] diff --git a/nglib/query/vlan.py b/nglib/query/vlan.py index e1c0286..ed0decd 100644 --- a/nglib/query/vlan.py +++ b/nglib/query/vlan.py @@ -32,6 +32,7 @@ """ import sys +import os import logging import nglib from nglib.query.nNode import getJSONProperties @@ -421,13 +422,23 @@ def get_vlans_on_group(group, vrange): print("Total: " + str(vtotal)) print() print(" VID Name Sw/Macs/Ports Root Switches") - print("------------------------------------------------------------------------------------------------") + + # Header Size + try: + tsize = os.get_terminal_size() + tsize = tsize.columns + except OSError: + tsize = 80 + print("-" * tsize) + for en in sortedList: + slen = tsize - 65 + swl = '' for sw in en['switches']: swl = swl + " " + sw - swlt = (swl[:36] + '..') if len(swl) > 36 else swl + swlt = (swl[:slen] + '..') if len(swl) > slen else swl counts = "{:3>}/{:4>}/{:<4}".format( str(en['scount']), str(en['mcount']), str(en['pcount'])) diff --git a/nglib/report/__init__.py b/nglib/report/__init__.py index 4b54f4b..4133a3c 100644 --- a/nglib/report/__init__.py +++ b/nglib/report/__init__.py @@ -82,6 +82,7 @@ def get_vlan_report(vrange, report="all", rtype="TREE"): if '_ccount' in etree.keys(): etree['Empty VLAN Count'] = etree['_ccount'] nglib.query.exp_ngtree(etree, rtype) + return etree else: print("No Empty Vlans in Range", vrange) @@ -133,9 +134,88 @@ def get_vlan_data(vrange, rtype): for v in vlans: vtree = nglib.query.vlan.search_vlan_id(v['vid'], allSwitches=allSwitches) nglib.ngtree.add_child_ngtree(pngtree, vtree) - return pngtree + +def get_vrf_report(vrf, rtype="NGTREE"): + """ + Get a report on vrfs that match regex + """ + rtypes = ('TREE', 'JSON', 'YAML', 'NGTREE') + + if rtype in rtypes: + logger.info("Query: Generating VRF Report (%s) for %s", vrf, nglib.user) + + vrfs = nglib.bolt_ses.run( + 'MATCH(v:VRF) WHERE v.name =~ {vrf} ' + + 'RETURN v.name AS name ORDER BY name', + {"vrf": vrf}) + + ngtree = nglib.ngtree.get_ngtree("Report", tree_type="VRFs") + ngtree['VRF Regex'] = vrf + + # Process VRFs + tree_count = 0 + for v in vrfs: + tree_count += 1 + cngtree = nglib.query.net.get_networks_on_filter(nFilter=v["name"], rtype="NGTREE") + if cngtree: + devlist = nglib.query.dev.get_devlist_vrf(v["name"]) + cngtree["Routers"] = devlist + tree_count += 1 + nglib.ngtree.add_child_ngtree(ngtree, cngtree) + + # Return output + if not tree_count: + print("No VRFs found on regex:", vrf, file=sys.stderr) + elif tree_count == 1: + nglib.query.exp_ngtree(cngtree, rtype) + return ngtree + else: + nglib.query.exp_ngtree(ngtree, rtype) + return ngtree + else: + raise Exception("RType Not Supported, use:" + str(rtypes)) + + +def get_dev_report(dev, rtype="NGTREE"): + """ + Get all devices on a regex + + Note: Only returns devices in a mgmt group + """ + + rtypes = ('TREE', 'JSON', 'YAML', 'NGTREE') + + if rtype in rtypes: + logger.info("Query: Generating Device Report (%s) for %s", dev, nglib.user) + + devices = nglib.bolt_ses.run( + 'MATCH(s:Switch) WHERE s.name =~ {dev} ' + + 'RETURN s.name AS name, s.mgmt AS mgmt ORDER BY name', + {"dev": dev}) + + ngtree = nglib.ngtree.get_ngtree("Report", tree_type="DEVs") + ngtree['Device Regex'] = dev + + for d in devices: + if d["mgmt"]: + cngtree = nglib.query.dev.get_device(d["name"]) + if cngtree: + nglib.ngtree.add_child_ngtree(ngtree, cngtree) + + # Found Devices, count and print + if '_ccount' in ngtree.keys(): + ngtree['Device Count'] = ngtree['_ccount'] + nglib.query.exp_ngtree(ngtree, rtype) + return ngtree + else: + print("No Devices found on regex:", dev) + + else: + raise Exception("RType Not Supported, use:" + str(rtypes)) + + def get_children(ngtree): """Return list of children and count in ngtree""" diff --git a/ngreport.py b/ngreport.py index d9cd342..dcc39c9 100755 --- a/ngreport.py +++ b/ngreport.py @@ -38,23 +38,23 @@ # Default Config File Location config_file = '/etc/netgrph.ini' +alt_config = './docs/netgrph.ini' # Test/Dev Config dirname = os.path.dirname(os.path.realpath(__file__)) if re.search(r'\/dev$', dirname): config_file = 'netgrphdev.ini' elif re.search(r'\/test$', dirname): - config_file = "netgrphtest.ini" + config_file = "netgrphdev.ini" parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(prog='ngreport', description='Generate Reports from NetGrph') -parser.add_argument("-vrf", metavar='name', help="Generate a Report on a VRF", +parser.add_argument("-vrf", metavar='name', + help="Generate a Report on a VRF (.* for all)", type=str) -parser.add_argument("-vrfs", help="VRF Report on all VRFs", - action="store_true") parser.add_argument("-vlans", help="VLAN ID Report (combine with -vra and -e)", action="store_true") @@ -69,7 +69,7 @@ action="store_true") parser.add_argument("--conf", metavar='file', help="Alternate Config File", type=str) parser.add_argument("--debug", help="Set debugging level", type=int) -parser.add_argument("--verbose", help="Verbose Output", action="store_true") +parser.add_argument("-v", help="Verbose Output", action="store_true") args = parser.parse_args() @@ -77,8 +77,15 @@ if args.conf: config_file = args.conf +# Test configuration exists +if not os.path.exists(config_file): + if not os.path.exists(alt_config): + raise Exception("Configuration File not found", config_file) + else: + config_file = alt_config + verbose = 0 -if args.verbose: +if args.v: verbose = 1 if args.debug: verbose = args.debug @@ -108,6 +115,19 @@ nglib.report.get_vlan_report(args.vrange, report=report, rtype=rtype) +elif args.vrf: + rtype = "TREE" + if args.output: + rtype = args.output + + nglib.report.get_vrf_report(args.vrf, rtype=rtype) + +elif args.dev: + rtype = "TREE" + if args.output: + rtype = args.output + + nglib.report.get_dev_report(args.dev, rtype=rtype) else: parser.print_help() diff --git a/ngtest.py b/ngtest.py index f5a25fd..197a2bc 100755 --- a/ngtest.py +++ b/ngtest.py @@ -73,7 +73,8 @@ # qtest['-rp 10.33.1.100 10.26.76.1'] = 'core1' rtest = dict() #rtest['-vlans -empty -vra 200'] = 'v6test' - +rtest['-vlans -vrange 120 -o yaml'] = 'Root: abc4mdf' +rtest['-v -dev "xyz.*" -o json'] = '"parent_switch": "core1"' # Update Tests (check for errors) utest = ('-ivrf', '-id', '-ind', '-inet', '-isnet', '-iasa', '-ivlan', '-uvlan') diff --git a/ngupdate.py b/ngupdate.py index eb0ef6d..76662b5 100755 --- a/ngupdate.py +++ b/ngupdate.py @@ -52,7 +52,7 @@ if re.search(r'\/dev$', dirname): config_file = 'netgrphdev.ini' elif re.search(r'\/test$', dirname): - config_file = "netgrphtest.ini" + config_file = "netgrphdev.ini" #print("Config:",config_file,dirname) @@ -107,7 +107,6 @@ if args.conf: config_file = args.conf - # Test configuration exists if not os.path.exists(config_file): if not os.path.exists(alt_config): diff --git a/test/first_import.sh b/test/first_import.sh index 7681090..95f9b97 100755 --- a/test/first_import.sh +++ b/test/first_import.sh @@ -1,4 +1,5 @@ #!/bin/sh +./ngupdate.py -v --dropDatabase ./ngupdate.py -ivrf -v ./ngupdate.py -id -v ./ngupdate.py -ind -v @@ -9,3 +10,5 @@ ./ngupdate.py -ifw -v ./ngupdate.py -v -ifile ./cypher/buildfw.cyp ./ngupdate.py -v -ifile ./cypher/constraints.cyp +./ngupdate.py -full -v +./test/test_full.sh diff --git a/test/test_full.sh b/test/test_full.sh index 720666e..c39472e 100755 --- a/test/test_full.sh +++ b/test/test_full.sh @@ -1,2 +1,11 @@ #/bin/sh -py.test-3 --resultlog=/tmp/pytest.log ngtest.py + +# Check for Ubuntu Python3 +export pytestcmd="py.test-3" + +# Revert to default pytest +if ! type "$pytestcmd" 2> /dev/null; then + export pytestcmd="py.test" +fi + +$pytestcmd --resultlog=/tmp/pytest.log ngtest.py diff --git a/test/test_queries.sh b/test/test_queries.sh index e8bdadd..7989218 100755 --- a/test/test_queries.sh +++ b/test/test_queries.sh @@ -1,2 +1,9 @@ #/bin/sh -py.test-3 --resultlog=/tmp/pytest.log ngtest.py::test_queries + +export pytestcmd="py.test-3" + +if ! type "$pytestcmd" 2> /dev/null; then + export pytestcmd="py.test" +fi + +$pytestcmd --resultlog=/tmp/pytest.log ngtest.py::test_queries