ODLTools: Misc CLI improvements 57/71657/2
authorVishal Thapar <vthapar@redhat.com>
Wed, 2 May 2018 05:31:09 +0000 (11:01 +0530)
committerSam Hague <shague@redhat.com>
Wed, 2 May 2018 10:39:29 +0000 (10:39 +0000)
* Display table name alongwith table id in flow outputs
* Add option to print flow meta info only
* Add option to print flow URLs
* Add option to use https
* Clean-up a stray print of elan interfaces

JIRA: NETVIRT-1232
Change-Id: I719138a6945d854f650931b9e3244861dc64a99f
Signed-off-by: Vishal Thapar <vthapar@redhat.com>
resources/tools/odltools/odltools/mdsal/cli.py
resources/tools/odltools/odltools/mdsal/cmd.py
resources/tools/odltools/odltools/mdsal/models/model.py
resources/tools/odltools/odltools/netvirt/analyze.py
resources/tools/odltools/odltools/netvirt/cli.py
resources/tools/odltools/odltools/netvirt/flows.py

index b3bb804a5698a1610d130e896df51fc4e7a35c97..8e0fd0cdde89e6a6920757cba1b132dd264d3770 100644 (file)
@@ -5,16 +5,18 @@ def add_dump_parser(parsers):
     parser = parsers.add_parser("dump", description="Get and write all mdsal models")
     parser.add_argument("path",
                         help="the directory that the parsed data is written into")
+    parser.add_argument("-s", "--https", action="store_true",
+                        help="use https for secure connection")
     parser.add_argument("-i", "--ip", default="localhost",
                         help="OpenDaylight ip address")
-    parser.add_argument("-p", "--pretty_print", action="store_true",
-                        help="json dump with pretty_print")
     parser.add_argument("-t", "--port", default="8181",
                         help="OpenDaylight restconf port, defaul: 8181")
     parser.add_argument("-u", "--user", default="admin",
                         help="OpenDaylight restconf username, default: admin")
     parser.add_argument("-w", "--pw", default="admin",
                         help="OpenDaylight restconf password, default: admin")
+    parser.add_argument("-p", "--pretty_print", action="store_true",
+                        help="json dump with pretty_print")
     parser.set_defaults(func=cmd.run_dump)
 
 
index 56087c9b062febc22cbad2257517bdecfe794e60..58b6fa018a0575d7f02b2e63368776ed2d0593b7 100644 (file)
@@ -142,7 +142,7 @@ def get_all_dumps(args):
         model_path = res[DSM_PATH]
         path_split = split_model_path(model_path)
         filename = make_filename(args.path, store, path_split.name, path_split.container)
-        url = make_url(args.ip, args.port, store, path_split.name, path_split.container)
+        url = make_url(args.https, args.ip, args.port, store, path_split.name, path_split.container)
         get_model_data(filename, url, args.user, args.pw, args.pretty_print)
 
 
@@ -161,9 +161,10 @@ def make_filename(path, store, name, container):
     return "{}/{}_{}:{}.json".format(path, store, name, container.replace("/", "_"))
 
 
-def make_url(ip, port, store, name, container):
-    return "http://{}:{}/restconf/{}/{}:{}".format(ip, port, store,
-                                                   name, container)
+def make_url(https, ip, port, store, name, container):
+    http = 'https' if https else 'http'
+    return "{}://{}:{}/restconf/{}/{}:{}".format(http, ip, port, store,
+                                                 name, container)
 
 
 def get_from_odl(url, user, pw):
index fdce99f49e9381b6a16c31871939408f1138872f..198765043218a4aca478cdc8b749c75ba368e20f 100644 (file)
@@ -13,6 +13,7 @@ class Model:
         self.name = name
         self.container = container
         self.store = store
+        self.http = 'https' if args.https else 'http'
         self.ip = args.ip
         self.port = args.port
         self.url = self.make_url()
@@ -32,12 +33,14 @@ class Model:
         return "{}/{}___{}__{}___topology___{}.json".format(self.path, self.store, self.name, self.container, fmid)
 
     def make_url(self):
-        return "http://{}:{}/restconf/{}/{}:{}".format(self.ip, self.port, self.store,
-                                                       self.name, self.container)
+        return "{}://{}:{}/restconf/{}/{}:{}".format(self.http, self.ip, self.port,
+                                                     self.store, self.name,
+                                                     self.container)
 
     def make_url_type(self, mid):
-        return "http://{}:{}/restconf/{}/{}:{}/topology/{}".format(self.ip, self.port, self.store,
-                                                                   self.name, self.container, mid)
+        return "{}://{}:{}/restconf/{}/{}:{}/topology/{}".format(self.http, self.ip, self.port,
+                                                                 self.store, self.name,
+                                                                 self.container, mid)
 
     def get_from_odl(self):
         return odltools.mdsal.request.get(self.url, self.USER, self.PW)
index e814110a50b90be871170a6c9eb4e4716f3b2346..45f2d4e1c7a3d8e442a499966c660b0fc5ed5fcc 100644 (file)
@@ -1,6 +1,8 @@
 import config
 import flow_parser
 import flows
+import tables
+
 from odltools.mdsal.models import constants
 from odltools.mdsal.models import ietf_interfaces
 from odltools.mdsal.models import itm_state
@@ -130,8 +132,10 @@ def analyze_trunks(args):
         if flow.get('vlanid') and flow.get('vlanid') != vlanid:
             flow_status = 'VlanId mismatch for SubPort:{} and Flow:{}'.format(subport, flow.get('flow'))
         if subport:
-            print 'SubPort:{},Table:{},FlowStatus:{}'.format(
-                subport.get('port-id'), flow.get('table'), flow_status)
+            print 'SubPort:{},Table:{}/{},FlowStatus:{}'.format(
+                subport.get('port-id'), flow.get('table'),
+                tables.get_table_name(flow.get('table')),
+                flow_status)
 
 
 def analyze_neutron_port(port, iface, ifstate):
@@ -139,9 +143,9 @@ def analyze_neutron_port(port, iface, ifstate):
         if ((flow.get('ifname') == port['uuid']) or
                 (flow.get('lport') and ifstate and flow['lport'] == ifstate.get('if-index')) or
                 (iface['name'] == flow.get('ifname'))):
-            result = 'Table:{},FlowId:{}{}'.format(
-                flow['table'], flow['id'],
-                utils.show_optionals(flow))
+            result = 'Table:{}/{},FlowId:{}{}'.format(
+                flow['table'], tables.get_table_name(flow['table']),
+                flow['id'], utils.show_optionals(flow))
             print result
             print 'Flow:', utils.format_json(None, flow_parser.parse_flow(flow.get('flow')))
 
@@ -172,5 +176,6 @@ def analyze_inventory(args):
                 flow_list.append(flow_dict)
     flows = sorted(flow_list, key=lambda x: x['table'])
     for flow in flows:
-        print 'Table:', flow['table']
+        print 'Table:{}/{}'.format(flow['table'],
+                                   tables.get_table_name(flow['table']))
         print 'FlowId:', flow['id'], 'FlowName:', flow.get('name')
index f9efe38a4966bd4248f19555ae5a13a76e98b98c..c0a563f8ba75f6877c0c0105552b5fe398ca5092 100644 (file)
@@ -6,16 +6,18 @@ import show
 def add_common_args(parser):
     parser.add_argument("--path",
                         help="the directory that the parsed data is written into")
+    parser.add_argument("-s", "--https", action="store_true",
+                        help="use https for secure connection")
     parser.add_argument("-i", "--ip", default="localhost",
                         help="OpenDaylight ip address")
-    parser.add_argument("-p", "--pretty_print", action="store_true",
-                        help="json dump with pretty_print")
     parser.add_argument("-t", "--port", default="8181",
                         help="OpenDaylight restconf port, default: 8181")
     parser.add_argument("-u", "--user", default="admin",
                         help="OpenDaylight restconf username, default: admin")
     parser.add_argument("-w", "--pw", default="admin",
                         help="OpenDaylight restconf password, default: admin")
+    parser.add_argument("-p", "--pretty_print", action="store_true",
+                        help="json dump with pretty_print")
 
 
 def add_interface_parser(parsers):
@@ -54,6 +56,10 @@ def add_show_parser(parsers):
     parser.add_argument("--modules",
                         help="service module owning the flow")
     parser.add_argument("flowtype", choices=["all", "duplicate", "elan", "learned", "stale"])
+    parser.add_argument("--metaOnly", action="store_true",
+                        help="display flow meta info only")
+    parser.add_argument("--urls", action="store_true",
+                        help="show flow urls")
     parser.set_defaults(func=show.show_flows)
 
     parser = parsers.add_parser("id-pools")
index f9d065013d9ee9a75bdf03fc51504f98d201fe8a..634ca01762f7743c52d215d0dbd7f88764068e1d 100644 (file)
@@ -11,6 +11,7 @@ from odltools.mdsal.models.opendaylight_inventory import Nodes
 from odltools.netvirt import utils
 import config
 import flow_parser
+import tables
 
 
 logger = logging.getLogger("netvirt.flows")
@@ -252,7 +253,6 @@ def get_iface_for_lport(ifaces, ifindexes, lport):
 
 
 def get_eltag_for_iface(eifaces, einsts, iface):
-    print eifaces
     ifname = iface.get('name') if iface else None
     eiface = eifaces.get(ifname) if ifname else None
     einst_name = eiface.get('elan-instance-name') if eiface else None
@@ -329,6 +329,14 @@ def show_link_flow_binding(args):
             print 'Flow without binding: ', flow['ifname']
 
 
+def get_flow_url(args, flow):
+    base_url = 'http://{}:{}/restconf/config'.format(args.ip, args.port)
+    flow_path = 'opendaylight-inventory:nodes/node/openflow:{}/' \
+                'flow-node-inventory:table/{}/flow/{}'.format(
+        flow['dpnid'], flow['table'], flow['id'])
+    return '{}/{}'.format(base_url, flow_path)
+
+
 def show_stale_flows(args, sort_by='table'):
     config.get_models(args, {
         "elan_elan_instances",
@@ -352,13 +360,15 @@ def show_stale_flows(args, sort_by='table'):
         ip_list = get_ips_for_iface(nports, flow.get('ifname'))
         if ip_list:
             flow['iface-ips'] = ip_list
-        result = 'Table:{}, Host:{}, FlowId:{}{}'.format(
-            flow['table'], host, flow['id'],
+        result = 'Table:{}/{}, Host:{}, FlowId:{}{}'.format(
+            flow['table'], tables.get_table_name(flow.get('table')),
+            host, flow['id'],
             utils.show_optionals(flow))
         print result
-        ##path = get_data_path('flows', flow)
-        #print('http://192.168.2.32:8383/restconf/config/{}'.format(path))
-        #print 'Flow:', utils.format_json(args, flow_parser.parse_flow(flow['flow']))
+        if args.urls:
+            print('http://{}'.format(get_flow_url(args, flow)))
+        if not args.metaOnly:
+            print 'Flow:{}'.format(utils.format_json(args, flow_parser.parse_flow(flow['flow'])))
 
 
 def show_elan_flows(args):
@@ -373,11 +383,14 @@ def show_elan_flows(args):
     compute_map = config.gmodels.odl_inventory_nodes_operational.get_dpn_host_mapping()
     for flow in utils.sort(get_all_flows(args, modules=['elan']), 'id'):
         host = compute_map.get(flow.get('dpnid'), flow.get('dpnid'))
-        result = 'MacHost:{}{}, Table:{}, FlowId:{}, {}, Flow:{}'.format(
-            flow['id'][-17:], host, flow['table'], flow['id'], utils.show_optionals(flow),
+        result = 'MacHost:{}{}, Table:{}/{}, FlowId:{}, {}, Flow:{}'.format(
+            flow['id'][-17:], host, flow['table'],
+            tables.get_table_name(flow['table']),
+            flow['id'], utils.show_optionals(flow),
            utils.format_json(args, flow_parser.parse_flow(flow['flow'])))
         print result
-        #print 'Flow:', utils.format_json(args, flow_parser.parse_flow(flow['flow']))
+        if not args.metaOnly:
+            print 'Flow:{}'.format(utils.format_json(args, flow_parser.parse_flow(flow['flow'])))
 
 
 def get_matchstr(args, flow):
@@ -460,11 +473,13 @@ def show_learned_mac_flows(args):
         nports.get(flow_info.get('src-mac'))) or
                 (flow_info.get('table') == 51 and
                      not nports.get(flow_info.get('dst-mac')))):
-            result = 'Table:{}, Host:{}, FlowId:{}{}'.format(
-                flow_info.get('table'), host, flow.get('id'),
-                utils.show_optionals(flow_info))
+            result = 'Table:{}/{}, Host:{}, FlowId:{}{}'.format(
+                flow_info.get('table'),
+                tables.get_table_name(flow['table']),
+                host, flow.get('id'), utils.show_optionals(flow_info))
             print result
-            print 'Flow:{}'.format(utils.format_json(args, flow_parser.parse_flow(flow)))
+            if not args.metaOnly:
+                print 'Flow:{}'.format(utils.format_json(args,flow_parser.parse_flow(flow)))
 
 
 def get_stale_bindings(args):
@@ -488,11 +503,13 @@ def dump_flows(args, modules=None, sort_by='table', filter_by=None):
         ip_list = get_ips_for_iface(nports, flow.get('ifname'))
         if ip_list:
             flow['iface-ips'] = ip_list
-        result = 'Table:{}, Host:{}, FlowId:{}{}'.format(
-            flow['table'], host, flow['id'],
+        result = 'Table:{}/{}, Host:{}, FlowId:{}{}'.format(
+            flow['table'], tables.get_table_name(flow['table']),
+            host, flow['id'],
             utils.show_optionals(flow))
         print result
-        print 'Flow:', utils.format_json(args, flow_parser.parse_flow(flow['flow']))
+        if not args.metaOnly:
+            print 'Flow:', utils.format_json(args, flow_parser.parse_flow(flow['flow']))
 
 
 def show_all_flows(args):