move deprecated files to old dir 11/71211/2
authorSam Hague <shague@redhat.com>
Mon, 23 Apr 2018 13:07:50 +0000 (09:07 -0400)
committerSam Hague <shague@redhat.com>
Mon, 23 Apr 2018 15:17:50 +0000 (15:17 +0000)
Change-Id: I2c76bc58bb1a42581e5ac6b0dbd8491cc8f82abf
Signed-off-by: Sam Hague <shague@redhat.com>
resources/tools/odltools/netvirt/ovs_get_data.py [deleted file]
resources/tools/odltools/netvirt/showOvsdbMdsal.py [deleted file]

diff --git a/resources/tools/odltools/netvirt/ovs_get_data.py b/resources/tools/odltools/netvirt/ovs_get_data.py
deleted file mode 100644 (file)
index 6508486..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-import sys
-import re
-
-from datetime import datetime as dt
-from datetime import timedelta as td
-
-base_time = '2017-07-31 20:19:00,698'
-#base_time = None
-TIME_FORMAT = '%Y-%m-%d %H:%M:%S,%f'
-
-def get_ofctl_flows(file_name='ofctl-flows.log'):
-    flow_list = []
-    with open(file_name, 'rb') as f:
-        data = f.read().splitlines()
-        for row in data:
-            meta = row.split(', ')
-            matches, actions = meta.pop().split()
-            flow_list.append(get_flow_dict(meta, matches, actions))
-    return flow_list
-
-
-def get_flow_dict(meta, matches, actions):
-    actions = actions.strip('actions=')
-    flow_dict = {}
-    flow_dict['meta'] = get_meta_dict(meta)
-    flow_dict['matches'] = get_matches_dict(matches)
-    flow_dict['actions'] = get_actions_dict(actions)
-    return flow_dict
-
-
-def get_meta_dict(meta_str):
-    meta = {}
-    for field in meta_str:
-        k, v = field.split('=')
-        if base_time and k == 'duration':
-            v = get_flow_time(v)
-            k = 'installed'
-        meta[k] = v
-    return meta
-
-
-def get_matches_dict(matches_str):
-    return matches_str
-''' Note: This mostly works requires bit of rework for matches like:
-    arp,arp_sa=abc etc.
-    matches = {}
-    for match in matches_str.split(','):
-        if '=' in match:
-            k, v = match.split('=')
-        else:
-            k, v = match, ""
-        matches[k] = v
-    return matches
-'''
-
-
-def get_flow_time(duration):
-    duration = duration.strip('s')
-    time = dt.strptime(base_time, TIME_FORMAT) + td(0, float(duration))
-    time_str = time.strftime(TIME_FORMAT)
-    return time_str
-
-
-def get_actions_dict(action_str):
-    return action_str
-''' todo: Action parsing is WiP and requires much complex logic
-    actions_dict = {}
-    actions = action_str.split(',')
-    actions = iter(actions)
-    for action in actions:
-        if ':' in action:
-            k, v = action.split(':')
-            actions_dict[k] = v
-        elif action.startswith('resubmit'):
-            k = 'resubmit'
-            port = action.strip('resubmit(')
-            try:
-                next_action = next(actions)
-                if next_action.endswith(')'):
-                    table = next_action.strip(')')
-                else:
-                    table = action
-            except StopIteration:
-                break;
-            actions_dict[k] = '('+port+','+table+')'
-    return actions_dict
-'''
-
-
-def print_flow_dict(flows):
-    for flow in flows:
-        print flow['meta'], flow['matches'], flow['actions']
\ No newline at end of file
diff --git a/resources/tools/odltools/netvirt/showOvsdbMdsal.py b/resources/tools/odltools/netvirt/showOvsdbMdsal.py
deleted file mode 100644 (file)
index 3d566eb..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
-#!/usr/bin/env python
-
-import urllib2, base64, json, sys, optparse
-
-# globals
-CONST_DEFAULT_DEBUG=0
-options = None
-state = None
-jsonTopologyNodes = []
-jsonInventoryNodes = []
-flowInfoNodes = {}
-nodeIdToDpidCache = {}
-
-CONST_OPERATIONAL = 'operational'
-CONST_CONFIG = 'config'
-CONST_NET_TOPOLOGY = 'network-topology'
-CONST_TOPOLOGY = 'topology'
-CONST_TP_OF_INTERNAL = 65534
-CONST_ALIASES = ['alpha', 'bravo', 'charlie', 'delta', 'echo', 'foxtrot', 'golf', 'hotel', 'india', 'juliet',
-                 'kilo', 'lima', 'mike', 'november', 'oscar', 'papa', 'quebec', 'romeo', 'sierra', 'tango',
-                 'uniform', 'victor', 'whiskey', 'xray', 'yankee', 'zulu']
-
-
-class State:
-    def __init__(self):
-        self.nextAliasIndex = 0
-        self.nextAliasWrap = 0
-        self.nodeIdToAlias = {}
-
-        self.bridgeNodes = {}
-        self.ovsdbNodes = {}
-        self.ofLinks = {}
-
-    def __repr__(self):
-        return 'State {}:{} {}:{} {}:{} {}:{} {}:{}'.format(
-            'nextAliasIndex', self.nextAliasIndex,
-            'nextAliasWrap', self.nextAliasWrap,
-            'bridgeNodes_ids', self.bridgeNodes.keys(),
-            'ovsdbNodes_ids', self.ovsdbNodes.keys(),
-            'nodeIdToAlias', self.nodeIdToAlias)
-
-    def registerBridgeNode(self, bridgeNode):
-        self.bridgeNodes[bridgeNode.nodeId] = bridgeNode
-
-    def registerOvsdbNode(self, ovsdbNode):
-        self.ovsdbNodes[ovsdbNode.nodeId] = ovsdbNode
-
-    def getNextAlias(self, nodeId):
-        result = CONST_ALIASES[ self.nextAliasIndex ]
-        if self.nextAliasWrap > 0:
-            result += '_' + str(self.nextAliasWrap)
-
-        if CONST_ALIASES[ self.nextAliasIndex ] == CONST_ALIASES[-1]:
-            self.nextAliasIndex = 0
-            self.nextAliasWrap += 1
-        else:
-            self.nextAliasIndex += 1
-
-        self.nodeIdToAlias[ nodeId ] = result
-        return result
-
-# --
-
-class TerminationPoint:
-    def __init__(self, name, ofPort, tpType, mac='', ifaceId=''):
-        self.name = name
-        self.ofPort = ofPort
-        self.tpType = tpType
-        self.mac = mac
-        self.ifaceId = ifaceId
-
-    def __repr__(self):
-        result = '{} {}:{}'.format(self.name, 'of', self.ofPort)
-
-        if self.tpType != '':
-            result += ' {}:{}'.format('type', self.tpType)
-        if self.mac != '':
-            result += ' {}:{}'.format('mac', self.mac)
-        if self.ifaceId != '':
-            result += ' {}:{}'.format('ifaceId', self.ifaceId)
-
-        return '{' + result + '}'
-
-# --
-
-class BridgeNode:
-    def __init__(self, nodeId, dpId, name, controllerTarget, controllerConnected):
-        global state
-        self.alias = state.getNextAlias(nodeId)
-        self.nodeId = nodeId
-        self.dpId = dpId
-        self.name = name
-        self.controllerTarget = controllerTarget
-        self.controllerConnected = controllerConnected
-        self.tps = []
-
-    def getOpenflowName(self):
-        if self.dpId is None:
-            return self.nodeId
-        return dataPathIdToOfFormat(self.dpId)
-
-    def addTerminationPoint(self, terminationPoint):
-        self.tps.append(terminationPoint)
-
-    def __repr__(self):
-        return 'BridgeNode {}:{} {}:{} {}:{} {}:{} {}:{} {}:{} {}:{} {}:{}'.format(
-            'alias', self.alias,
-            'nodeId', self.nodeId,
-            'dpId', self.dpId,
-            'openflowName', self.getOpenflowName(),
-            'name', self.name,
-            'controllerTarget', self.controllerTarget,
-            'controllerConnected', self.controllerConnected,
-            'tps', self.tps)
-
-# --
-
-class OvsdbNode:
-    def __init__(self, nodeId, inetMgr, inetNode, otherLocalIp, ovsVersion):
-        global state
-        if inetNode != '':
-            self.alias = inetNode
-        else:
-            self.alias = nodeId
-        self.nodeId = nodeId
-        self.inetMgr = inetMgr
-        self.inetNode = inetNode
-        self.otherLocalIp = otherLocalIp
-        self.ovsVersion = ovsVersion
-
-    def __repr__(self):
-        return 'OvsdbNode {}:{} {}:{} {}:{} {}:{} {}:{} {}:{}'.format(
-            'alias', self.alias,
-            'nodeId', self.nodeId,
-            'inetMgr', self.inetMgr,
-            'inetNode', self.inetNode,
-            'otherLocalIp', self.otherLocalIp,
-            'ovsVersion', self.ovsVersion)
-
-# ======================================================================
-
-def make_it_a_string(param):
-    result = ""
-    try:
-        result = str( param )
-    except:
-        pass
-    return result
-
-# ======================================================================
-
-def printError(msg):
-    sys.stderr.write(msg)
-
-# ======================================================================
-
-def prt(msg, logLevel=0):
-    prtCommon(msg, logLevel)
-def prtLn(msg, logLevel=0):
-    prtCommon('{}\n'.format(msg), logLevel)
-def prtCommon(msg, logLevel):
-    if options.debug >= logLevel:
-        sys.stdout.write(msg)
-
-# ======================================================================
-
-def getMdsalTreeType():
-    if options.useConfigTree:
-        return CONST_CONFIG
-    return CONST_OPERATIONAL
-
-# --
-
-def grabJson(url):
-
-    try:
-        request = urllib2.Request(url)
-        # You need the replace to handle encodestring adding a trailing newline
-        # (https://docs.python.org/2/library/base64.html#base64.encodestring)
-        base64string = base64.encodestring('{}:{}'.format(options.odlUsername, options.odlPassword)).replace('\n', '')
-        request.add_header('Authorization', 'Basic {}'.format(base64string))
-        result = urllib2.urlopen(request)
-    except urllib2.URLError, e:
-        printError('Unable to send request: {}\n'.format(e))
-        sys.exit(1)
-
-    if (result.code != 200):
-        printError( '{}\n{}\n\nError: unexpected code: {}\n'.format(result.info(), result.read(), result.code) )
-        sys.exit(1)
-
-    data = json.load(result)
-    prtLn(data, 4)
-    return data
-
-# --
-
-def grabInventoryJson(mdsalTreeType):
-    global jsonInventoryNodes
-
-    url = 'http://{}:{}/restconf/{}/opendaylight-inventory:nodes/'.format(options.odlIp, options.odlPort, mdsalTreeType)
-    data = grabJson(url)
-
-    if not 'nodes' in data:
-        printError( '{}\n\nError: did not find nodes in {}'.format(data, url) )
-        sys.exit(1)
-
-    data2 = data['nodes']
-    if not 'node' in data2:
-        printError( '{}\n\nError: did not find node in {}'.format(data2, url) )
-        sys.exit(1)
-
-    jsonInventoryNodes = data2['node']
-
-# --
-
-def parseInventoryJson(mdsalTreeType):
-    global jsonInventoryNodes
-    global flowInfoNodes
-
-    for nodeDict in jsonInventoryNodes:
-        if not 'id' in nodeDict:
-            continue
-
-        bridgeOfId = nodeDict.get('id')
-        prtLn('inventory node {} has keys {}'.format(bridgeOfId, nodeDict.keys()), 3)
-
-        # locate bridge Node
-        bridgeNodeId = None
-        bridgeNode = None
-        for currNodeId in state.bridgeNodes.keys():
-            if state.bridgeNodes[currNodeId].getOpenflowName() == bridgeOfId:
-                bridgeNodeId = currNodeId
-                bridgeNode = state.bridgeNodes[currNodeId]
-                break
-
-        if bridgeNodeId is None:
-            prtLn('inventory node {}'.format(bridgeOfId), 1)
-        else:
-            prtLn('inventory node {}, aka {}, aka {}'.format(bridgeOfId, bridgeNodeId, showPrettyName(bridgeNodeId)), 1)
-
-        flowInfoNode = {}
-
-        indent = ' ' * 2
-        prtLn('{}features: {}'.format(indent, nodeDict.get('flow-node-inventory:switch-features', {})), 2)
-        prt('{}sw: {}'.format(indent, nodeDict.get('flow-node-inventory:software')), 2)
-        prt('{}hw: {}'.format(indent, nodeDict.get('flow-node-inventory:hardware')), 2)
-        prt('{}manuf: {}'.format(indent, nodeDict.get('flow-node-inventory:manufacturer')), 2)
-        prtLn('{}ip: {}'.format(indent, nodeDict.get('flow-node-inventory:ip-address')), 2)
-
-
-        for inventoryEntry in nodeDict.get('flow-node-inventory:table', []):
-            if 'id' in inventoryEntry:
-                currTableId = inventoryEntry.get('id')
-                for currFlow in inventoryEntry.get('flow', []):
-                    prtLn('{}table {}: {}'.format(indent, currTableId, currFlow.get('id')), 1)
-                    prtLn('{}{}'.format(indent * 2, currFlow), 2)
-
-                    if currTableId in flowInfoNode:
-                        flowInfoNode[ currTableId ].append( currFlow.get('id') )
-                    else:
-                        flowInfoNode[ currTableId ] = [ currFlow.get('id') ]
-
-        prtLn('', 1)
-
-        for currTableId in flowInfoNode.keys():
-            flowInfoNode[currTableId].sort()
-
-        # store info collected in flowInfoNodes
-        flowInfoNodes[bridgeOfId] = flowInfoNode
-
-# --
-
-def grabTopologyJson(mdsalTreeType):
-    global jsonTopologyNodes
-
-    url = 'http://{}:{}/restconf/{}/network-topology:network-topology/'.format(options.odlIp, options.odlPort, mdsalTreeType)
-    data = grabJson(url)
-
-    if not CONST_NET_TOPOLOGY in data:
-        printError( '{}\n\nError: did not find {} in data'.format(data, CONST_NET_TOPOLOGY) )
-        sys.exit(1)
-
-    data2 = data[CONST_NET_TOPOLOGY]
-    if not CONST_TOPOLOGY in data2:
-        printError( '{}\n\nError: did not find {} in data2'.format(data2, CONST_TOPOLOGY) )
-        sys.exit(1)
-
-    jsonTopologyNodes = data2[CONST_TOPOLOGY]
-
-# --
-
-def buildDpidCache():
-    global jsonTopologyNodes
-    global nodeIdToDpidCache
-
-    # only needed if not parsing operational tree
-    if getMdsalTreeType() == CONST_OPERATIONAL:
-        return
-
-    jsonTopologyNodesSave = jsonTopologyNodes
-    grabTopologyJson(CONST_OPERATIONAL)
-    jsonTopologyNodesLocal = jsonTopologyNodes
-    jsonTopologyNodes = jsonTopologyNodesSave
-
-    for nodeDict in jsonTopologyNodesLocal:
-        if nodeDict.get('topology-id') != 'ovsdb:1':
-            continue
-        for node in nodeDict.get('node', []):
-            if node.get('node-id') is None or node.get('ovsdb:datapath-id') is None:
-                continue
-            nodeIdToDpidCache[ node.get('node-id') ] = node.get('ovsdb:datapath-id')
-
-# --
-
-def parseTopologyJson(mdsalTreeType):
-    for nodeDict in jsonTopologyNodes:
-        if not 'topology-id' in nodeDict:
-            continue
-        prtLn('{} {} keys are: {}'.format(mdsalTreeType, nodeDict['topology-id'], nodeDict.keys()), 3)
-        if 'node' in nodeDict:
-            nodeIndex = 0
-            for currNode in nodeDict['node']:
-                parseTopologyJsonNode('', mdsalTreeType, nodeDict['topology-id'], nodeIndex, currNode)
-                nodeIndex += 1
-            prtLn('', 2)
-        if (mdsalTreeType == CONST_OPERATIONAL) and (nodeDict['topology-id'] == 'flow:1') and ('link' in nodeDict):
-            parseTopologyJsonFlowLink(nodeDict['link'])
-
-    prtLn('', 1)
-
-# --
-
-def parseTopologyJsonNode(indent, mdsalTreeType, topologyId, nodeIndex, node):
-    if node.get('node-id') is None:
-        printError( 'Warning: unexpected node: {}\n'.format(node) )
-        return
-    prt('{} {} node[{}] {} '.format(indent + mdsalTreeType, topologyId, nodeIndex, node.get('node-id')), 2)
-    if 'ovsdb:bridge-name' in node:
-        prtLn('', 2)
-        parseTopologyJsonNodeBridge(indent + '  ', mdsalTreeType, topologyId, nodeIndex, node)
-    elif 'ovsdb:connection-info' in node:
-        prtLn('', 2)
-        parseTopologyJsonNodeOvsdb(indent + '  ', mdsalTreeType, topologyId, nodeIndex, node)
-    else:
-        prtLn('keys: {}'.format(node.keys()), 2)
-
-# --
-
-def parseTopologyJsonNodeOvsdb(indent, mdsalTreeType, topologyId, nodeIndex, node):
-    keys = node.keys()
-    keys.sort()
-    for k in keys:
-        prtLn('{}{} : {}'.format(indent, k, node[k]), 2)
-
-    connectionInfoRaw = node.get('ovsdb:connection-info')
-    connectionInfo = {}
-    if type(connectionInfoRaw) is dict:
-        connectionInfo['inetMgr'] = make_it_a_string(connectionInfoRaw.get('local-ip')) + ':' + make_it_a_string(connectionInfoRaw.get('local-port'))
-        connectionInfo['inetNode'] = make_it_a_string(connectionInfoRaw.get('remote-ip')) + ':' + make_it_a_string(connectionInfoRaw.get('remote-port'))
-    otherConfigsRaw = node.get('ovsdb:openvswitch-other-configs')
-    otherLocalIp = ''
-    if type(otherConfigsRaw) is list:
-        for currOtherConfig in otherConfigsRaw:
-            if type(currOtherConfig) is dict and \
-                    currOtherConfig.get('other-config-key') == 'local_ip':
-                otherLocalIp = currOtherConfig.get('other-config-value')
-                break
-
-    ovsdbNode = OvsdbNode(node.get('node-id'), connectionInfo.get('inetMgr'), connectionInfo.get('inetNode'), otherLocalIp, node.get('ovsdb:ovs-version'))
-    state.registerOvsdbNode(ovsdbNode)
-    prtLn('Added {}'.format(ovsdbNode), 1)
-
-# --
-
-def parseTopologyJsonNodeBridge(indent, mdsalTreeType, topologyId, nodeIndex, node):
-
-    controllerTarget = None
-    controllerConnected = None
-    controllerEntries = node.get('ovsdb:controller-entry')
-    if type(controllerEntries) is list:
-        for currControllerEntry in controllerEntries:
-            if type(currControllerEntry) is dict:
-                controllerTarget = currControllerEntry.get('target')
-                controllerConnected = currControllerEntry.get('is-connected')
-                break
-
-    nodeId = node.get('node-id')
-    dpId = node.get('ovsdb:datapath-id', nodeIdToDpidCache.get(nodeId))
-    bridgeNode = BridgeNode(nodeId, dpId, node.get('ovsdb:bridge-name'), controllerTarget, controllerConnected)
-
-    keys = node.keys()
-    keys.sort()
-    for k in keys:
-        if k == 'termination-point' and len(node[k]) > 0:
-            tpIndex = 0
-            for tp in node[k]:
-                terminationPoint = parseTopologyJsonNodeBridgeTerminationPoint('%stermination-point[%d] :' % (indent, tpIndex), mdsalTreeType, topologyId, nodeIndex, node, tp)
-
-                # skip boring tps
-                if terminationPoint.ofPort == CONST_TP_OF_INTERNAL and \
-                        (terminationPoint.name == 'br-ex' or terminationPoint.name == 'br-int'):
-                    pass
-                else:
-                    bridgeNode.addTerminationPoint(terminationPoint)
-
-                tpIndex += 1
-        else:
-            prtLn('{}{} : {}'.format(indent, k, node[k]), 2)
-
-    state.registerBridgeNode(bridgeNode)
-    prtLn('Added {}'.format(bridgeNode), 1)
-
-
-# --
-
-def parseTopologyJsonNodeBridgeTerminationPoint(indent, mdsalTreeType, topologyId, nodeIndex, node, tp):
-    attachedMac = ''
-    ifaceId = ''
-
-    keys = tp.keys()
-    keys.sort()
-    for k in keys:
-        if (k == 'ovsdb:port-external-ids' or k == 'ovsdb:interface-external-ids') and len(tp[k]) > 0:
-            extIdIndex = 0
-            for extId in tp[k]:
-                prtLn('{} {}[{}] {} : {}'.format(indent, k, extIdIndex, extId.get('external-id-key'), extId.get('external-id-value')), 2)
-                extIdIndex += 1
-
-                if extId.get('external-id-key') == 'attached-mac':
-                    attachedMac = extId.get('external-id-value')
-                if extId.get('external-id-key') == 'iface-id':
-                    ifaceId = extId.get('external-id-value')
-        else:
-            prtLn('{} {} : {}'.format(indent, k, tp[k]), 2)
-
-    return TerminationPoint(tp.get('ovsdb:name'),
-                            tp.get('ovsdb:ofport'),
-                            tp.get('ovsdb:interface-type', '').split('-')[-1],
-                            attachedMac, ifaceId)
-
-# --
-
-def parseTopologyJsonFlowLink(link):
-    linkCount = 0
-    spc = ' ' * 2
-    for currLinkDict in link:
-        linkCount += 1
-        linkId = currLinkDict.get('link-id')
-        linkDest = currLinkDict.get('destination', {}).get('dest-tp')
-        linkSrc = currLinkDict.get('source', {}).get('source-tp')
-
-        linkDestNode = currLinkDict.get('destination', {}).get('dest-node')
-        linkSrcNode = currLinkDict.get('source', {}).get('source-node')
-        prtLn('{} {} {} => {}:{} -> {}:{}'.format(spc, linkCount, linkId, linkSrcNode, linkSrc.split(':')[-1], linkDestNode, linkDest.split(':')[-1]), 3)
-
-        if linkId != linkSrc:
-            printError('Warning: ignoring link with unexpected id: %s != %s\n' % (linkId, linkSrc))
-            continue
-        else:
-            state.ofLinks[linkSrc] = linkDest
-
-# --
-
-def showPrettyNamesMap():
-    spc = ' ' * 2
-    if not options.useAlias or len(state.bridgeNodes) == 0:
-        return
-
-    prtLn('aliasMap:', 0)
-    resultMap = {}
-    for bridge in state.bridgeNodes.values():
-        resultMap[ bridge.alias ] = '{0: <25} {1: <7} {2}'.format(bridge.getOpenflowName(), bridge.name, bridge.dpId)
-
-    for resultMapKey in sorted(resultMap):
-        prtLn('{0}{1: <10} ->  {2}'.format(spc, resultMapKey, resultMap[resultMapKey]), 0)
-    prtLn('', 0)
-
-# --
-
-def showNodesPretty():
-    if len(state.ovsdbNodes) == 0:
-        showBridgeOnlyNodes()
-        return
-
-    aliasDict = { state.ovsdbNodes[nodeId].alias : nodeId for nodeId in state.ovsdbNodes.keys() }
-    aliasDictKeys = aliasDict.keys()
-    aliasDictKeys.sort()
-    for ovsAlias in aliasDictKeys:
-        ovsdbNode = state.ovsdbNodes[ aliasDict[ovsAlias] ]
-
-        prt('ovsdbNode:{} mgr:{} version:{}'.format(ovsAlias, ovsdbNode.inetMgr, ovsdbNode.ovsVersion), 0)
-        if ovsdbNode.inetNode.split(':')[0] != ovsdbNode.otherLocalIp:
-            prt(' **localIp:{}'.format(ovsdbNode.otherLocalIp), 0)
-        prtLn('', 0)
-        showPrettyBridgeNodes('  ', getNodeBridgeIds(ovsdbNode.nodeId), ovsdbNode)
-    showBridgeOnlyNodes(True)
-    prtLn('', 0)
-
-# --
-
-def showFlowInfoPretty():
-    global flowInfoNodes
-    spc = ' ' * 2
-
-    if not options.showFlows:
-        return
-
-    if len(flowInfoNodes) == 0:
-        prtLn('no flowInfo found\n', 0)
-        return
-
-    # translate flowKeys (openflow:123124) into their alias format
-    # then sort it and translate back, so we list them in the order
-    flowInfoNodeKeysDict = {}
-    for flowInfoNodeKey in flowInfoNodes.keys():
-        flowInfoNodeKeysDict[ showPrettyName(flowInfoNodeKey) ] = flowInfoNodeKey
-    flowInfoNodeKeysKeys = flowInfoNodeKeysDict.keys()
-    flowInfoNodeKeysKeys.sort()
-
-    flowInfoNodesKeys = [ flowInfoNodeKeysDict[ x ] for x in flowInfoNodeKeysKeys ]
-
-    nodeIdToDpidCacheReverse = {dataPathIdToOfFormat(v): k for k, v in nodeIdToDpidCache.items()}
-    nodesVisited = 0
-    for flowInfoNodeKey in flowInfoNodesKeys:
-        if nodesVisited > 0: prtLn('', 0)
-
-        nodeName = showPrettyName(flowInfoNodeKey)
-        if nodeName == flowInfoNodeKey:
-            nodeName += '  ( {} )'.format( nodeIdToDpidCacheReverse.get(flowInfoNodeKey, 'node_not_in_topology') )
-
-        prtLn('{} tree flows at {}'.format(getMdsalTreeType(), nodeName), 0)
-        flowInfoNode = flowInfoNodes[flowInfoNodeKey]
-        flowInfoTables = flowInfoNode.keys()
-        flowInfoTables.sort()
-        for flowInfoTable in flowInfoTables:
-            for rule in flowInfoNode[flowInfoTable]:
-                prtLn('{}table {}: {}'.format(spc, flowInfoTable, rule), 0)
-        nodesVisited += 1
-
-    prtLn('', 0)
-
-# --
-
-def getNodeBridgeIds(nodeIdFilter = None):
-    resultMap = {}
-    for bridge in state.bridgeNodes.values():
-        if nodeIdFilter is None or nodeIdFilter in bridge.nodeId:
-            resultMap[ bridge.alias ] = bridge.nodeId
-    resultMapKeys = resultMap.keys()
-    resultMapKeys.sort()
-    return [ resultMap[x] for x in resultMapKeys ]
-
-# --
-
-def showPrettyBridgeNodes(indent, bridgeNodeIds, ovsdbNode = None):
-    if bridgeNodeIds is None:
-        return
-
-    for nodeId in bridgeNodeIds:
-        bridgeNode = state.bridgeNodes[nodeId]
-        prt('{}{}:{}'.format(indent, showPrettyName(nodeId), bridgeNode.name), 0)
-
-        if ovsdbNode is None or \
-                bridgeNode.controllerTarget is None or \
-                bridgeNode.controllerTarget == '' or \
-                ovsdbNode.inetMgr.split(':')[0] != bridgeNode.controllerTarget.split(':')[-2] or \
-                bridgeNode.controllerConnected != True:
-            prt(' controller:{}'.format(bridgeNode.controllerTarget), 0)
-            prt(' connected:{}'.format(bridgeNode.controllerConnected), 0)
-        prtLn('', 0)
-        showPrettyTerminationPoints(indent + '  ', bridgeNode.tps)
-
-# --
-
-def showBridgeOnlyNodes(showOrphansOnly = False):
-    if len(state.bridgeNodes) == 0:
-        return
-
-    # group bridges by nodeId prefix
-    resultMap = {}
-    for bridge in state.bridgeNodes.values():
-        nodePrefix = bridge.nodeId.split('/bridge/')[0]
-
-        if showOrphansOnly and nodePrefix in state.ovsdbNodes:
-            continue
-
-        if nodePrefix in resultMap:
-            resultMap[nodePrefix][bridge.alias] = bridge.nodeId
-        else:
-            resultMap[nodePrefix] = { bridge.alias: bridge.nodeId }
-    resultMapKeys = resultMap.keys()
-    resultMapKeys.sort()
-
-    if len(resultMapKeys) == 0:
-        return  #noop
-
-    for nodePrefix in resultMapKeys:
-        nodePrefixEntriesKeys = resultMap[nodePrefix].keys()
-        nodePrefixEntriesKeys.sort()
-        # prtLn('Bridges in {}: {}'.format(nodePrefix, nodePrefixEntriesKeys), 0)
-        prtLn('Bridges in {}'.format(nodePrefix), 0)
-        nodeIds = [ resultMap[nodePrefix][nodePrefixEntry] for nodePrefixEntry in nodePrefixEntriesKeys ]
-        showPrettyBridgeNodes('  ', nodeIds)
-
-    prtLn('', 0)
-
-# --
-
-def showPrettyTerminationPoints(indent, tps):
-
-    tpsDict = {}
-    for tp in tps:
-        tpsDict[ tp.ofPort ] = tp
-
-    tpDictKeys = tpsDict.keys()
-    tpDictKeys.sort()
-    for tpKey in tpDictKeys:
-        tp = tpsDict[tpKey]
-        prt('{}of:{} {}'.format(indent, tp.ofPort, tp.name), 0)
-        if tp.mac != '':
-            prt(' {}:{}'.format('mac', tp.mac), 0)
-        if tp.ifaceId != '':
-            prt(' {}:{}'.format('ifaceId', tp.ifaceId), 0)
-
-        prtLn('', 0)
-
-# --
-
-def dataPathIdToOfFormat(dpId):
-    return 'openflow:' + str( int('0x' + dpId.replace(':',''), 16) )
-
-# --
-
-def showPrettyName(name):
-    if not options.useAlias:
-        return name
-
-    # handle both openflow:138604958315853:2 and openflow:138604958315853 (aka dpid)
-    # also handle ovsdb://uuid/5c72ec51-1e71-4a04-ab0b-b044fb5f4dc0/bridge/br-int  (aka nodeId)
-    #
-    nameSplit = name.split(':')
-    ofName = ':'.join(nameSplit[:2])
-    ofPart = ''
-    if len(nameSplit) > 2:
-        ofPart = ':' + ':'.join(nameSplit[2:])
-
-    for bridge in state.bridgeNodes.values():
-        if bridge.getOpenflowName() == ofName or bridge.nodeId == name:
-            return '{}{}'.format(bridge.alias, ofPart)
-
-    # not found, return paramIn
-    return name
-
-# --
-
-def showOfLinks():
-    spc = ' ' * 2
-    ofLinksKeys = state.ofLinks.keys()
-    ofLinksKeys.sort()
-    ofLinksKeysVisited = set()
-
-    if len(ofLinksKeys) == 0:
-        # prtLn('no ofLinks found\n', 0)
-        return
-
-    prtLn('ofLinks (discover via lldp):', 0)
-    for ofLinkKey in ofLinksKeys:
-        if ofLinkKey in ofLinksKeysVisited:
-            continue
-        if state.ofLinks.get( state.ofLinks[ofLinkKey] ) == ofLinkKey:
-            prtLn('{}{} <-> {}'.format(spc, showPrettyName(ofLinkKey), showPrettyName(state.ofLinks[ofLinkKey])), 0)
-            ofLinksKeysVisited.add(state.ofLinks[ofLinkKey])
-        else:
-            prtLn('{}{} -> {}'.format(spc, showPrettyName(ofLinkKey), showPrettyName(state.ofLinks[ofLinkKey])), 0)
-        ofLinksKeysVisited.add(ofLinkKey)
-    prtLn('', 0)
-
-# --
-
-def parseArgv():
-    global options
-
-    parser = optparse.OptionParser(version="0.1")
-    parser.add_option("-d", "--debug", action="count", dest="debug", default=CONST_DEFAULT_DEBUG,
-                      help="Verbosity. Can be provided multiple times for more debug.")
-    parser.add_option("-n", "--noalias", action="store_false", dest="useAlias", default=True,
-                      help="Do not map nodeId of bridges to an alias")
-    parser.add_option("-i", "--ip", action="store", type="string", dest="odlIp", default="localhost",
-                      help="opendaylights ip address")
-    parser.add_option("-t", "--port", action="store", type="string", dest="odlPort", default="8080",
-                      help="opendaylights listening tcp port on restconf northbound")
-    parser.add_option("-u", "--user", action="store", type="string", dest="odlUsername", default="admin",
-                      help="opendaylight restconf username")
-    parser.add_option("-p", "--password", action="store", type="string", dest="odlPassword", default="admin",
-                      help="opendaylight restconf password")
-    parser.add_option("-c", "--config", action="store_true", dest="useConfigTree", default=False,
-                      help="parse mdsal restconf config tree instead of operational tree")
-    parser.add_option("-f", "--hide-flows", action="store_false", dest="showFlows", default=True,
-                      help="hide flows")
-
-    (options, args) = parser.parse_args(sys.argv)
-    prtLn('argv options:{} args:{}'.format(options, args), 2)
-
-# --
-
-def doMain():
-    global state
-
-    state = State()
-    parseArgv()
-    buildDpidCache()
-    grabTopologyJson(getMdsalTreeType())
-    grabInventoryJson(getMdsalTreeType())
-    parseTopologyJson(getMdsalTreeType())
-    parseInventoryJson(getMdsalTreeType())
-    showPrettyNamesMap()
-    showNodesPretty()
-    showFlowInfoPretty()
-    showOfLinks()
-
-# --
-
-if __name__ == "__main__":
-    doMain()
-    sys.exit(0)