From 30f3bc24437fb4c20976ac244985f05d2af6b451 Mon Sep 17 00:00:00 2001
From: Amey Bhide <abhide@vmware.com>
Date: Thu, 10 Dec 2015 13:11:58 -0800
Subject: [PATCH] Admin Utility: Add orphaned-edges resource

Added orphaned-edges as a resource with list and delete operations for it

Change-Id: I06da1326518142272c3bf8e69ab8d67d01aed847
---
 .../admin/plugins/common/constants.py         |  1 +
 .../admin/plugins/common/formatters.py        | 13 ++++++++++++
 .../admin/plugins/nsxv/resources/edges.py     | 20 ++++++++++++-------
 tools/python_nsxadmin/admin/shell.py          | 13 +++++++-----
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/tools/python_nsxadmin/admin/plugins/common/constants.py b/tools/python_nsxadmin/admin/plugins/common/constants.py
index 6dcd72377a..86eaad20f0 100644
--- a/tools/python_nsxadmin/admin/plugins/common/constants.py
+++ b/tools/python_nsxadmin/admin/plugins/common/constants.py
@@ -30,3 +30,4 @@ EDGES = 'edges'
 SPOOFGUARD_POLICY = 'spoofguard-policy'
 DHCP_BINDING = 'dhcp-binding'
 BACKUP_EDGES = 'backup-edges'
+ORPHANED_EDGES = 'orphaned-edges'
diff --git a/tools/python_nsxadmin/admin/plugins/common/formatters.py b/tools/python_nsxadmin/admin/plugins/common/formatters.py
index 0975b0436c..28c66043b1 100644
--- a/tools/python_nsxadmin/admin/plugins/common/formatters.py
+++ b/tools/python_nsxadmin/admin/plugins/common/formatters.py
@@ -56,3 +56,16 @@ def output_formatter(resource_name, resources_list, attrs):
                 result[attr] = resource[attr]
             js_output[resource_name].append(result)
         return jsonutils.dumps(js_output, sort_keys=True, indent=4)
+
+
+def tabulate_results(data):
+    """Method to format the data in a tabular format.
+
+    Expects a list of tuple with the first tuple in the list; being treated as
+    column headers.
+    """
+    columns = data.pop(0)
+    table = prettytable.PrettyTable(["%s" % col for col in columns])
+    for contents in data:
+        table.add_row(["%s" % contents])
+    return table
diff --git a/tools/python_nsxadmin/admin/plugins/nsxv/resources/edges.py b/tools/python_nsxadmin/admin/plugins/nsxv/resources/edges.py
index 99a64ab4ca..fe8cb15ee1 100644
--- a/tools/python_nsxadmin/admin/plugins/nsxv/resources/edges.py
+++ b/tools/python_nsxadmin/admin/plugins/nsxv/resources/edges.py
@@ -14,6 +14,7 @@
 
 
 import logging
+import pprint
 
 from tools.python_nsxadmin.admin.plugins.common import constants
 from tools.python_nsxadmin.admin.plugins.common import formatters
@@ -78,13 +79,17 @@ def nsx_list_orphaned_edges(resource, event, trigger, **kwargs):
     don't have a corresponding binding in Neutron DB
     """
     LOG.info(_LI("NSXv edges present on NSXv backend but not present "
-                 "in Neutron DB"))
+                 "in Neutron DB\n"))
     orphaned_edges = get_orphaned_edges()
     if not orphaned_edges:
         LOG.info(_LI("\nNo orphaned edges found."
                      "\nNeutron DB and NSXv backend are in sync\n"))
     else:
-        LOG.info(orphaned_edges)
+        LOG.info(constants.ORPHANED_EDGES)
+        data = [('edge_id',)]
+        for edge in orphaned_edges:
+            data.append((edge,))
+        LOG.info(formatters.tabulate_results(data))
 
 
 @admin_utils.output_header
@@ -107,7 +112,8 @@ def nsx_delete_orphaned_edges(resource, event, trigger, **kwargs):
         LOG.info(_LI("Deleting edge: %s"), edge)
         nsxv.delete_edge(edge)
 
-    LOG.info(_LI("After delete; Orphaned Edges: %s"), get_orphaned_edges())
+    LOG.info(_LI("After delete; Orphaned Edges: \n%s"),
+        pprint.pformat(get_orphaned_edges()))
 
 
 @admin_utils.output_header
@@ -138,15 +144,15 @@ def nsx_update_edge(resource, event, trigger, **kwargs):
 
 registry.subscribe(nsx_list_edges,
                    constants.EDGES,
-                   shell.Operations.LIST.value)
+                   shell.Operations.NSX_LIST.value)
 registry.subscribe(neutron_list_router_edge_bindings,
                    constants.EDGES,
-                   shell.Operations.LIST.value)
+                   shell.Operations.NEUTRON_LIST.value)
 registry.subscribe(nsx_list_orphaned_edges,
-                   constants.EDGES,
+                   constants.ORPHANED_EDGES,
                    shell.Operations.LIST.value)
 registry.subscribe(nsx_delete_orphaned_edges,
-                   constants.EDGES,
+                   constants.ORPHANED_EDGES,
                    shell.Operations.CLEAN.value)
 registry.subscribe(nsx_update_edge,
                    constants.EDGES,
diff --git a/tools/python_nsxadmin/admin/shell.py b/tools/python_nsxadmin/admin/shell.py
index 960ebedad9..3562b74e34 100644
--- a/tools/python_nsxadmin/admin/shell.py
+++ b/tools/python_nsxadmin/admin/shell.py
@@ -79,17 +79,20 @@ nsxv3_resources = {
 
 # Add supported NSX-V resources in this dictionary
 nsxv_resources = {
-    constants.EDGES: Resource(constants.EDGES, [Operations.LIST.value,
-                                                Operations.CLEAN.value,
+    constants.EDGES: Resource(constants.EDGES, [Operations.NSX_LIST.value,
+                                                Operations.NEUTRON_LIST.value,
                                                 Operations.NSX_UPDATE.value]),
+    constants.BACKUP_EDGES: Resource(constants.BACKUP_EDGES,
+                                     [Operations.LIST.value,
+                                      Operations.CLEAN.value]),
+    constants.ORPHANED_EDGES: Resource(constants.ORPHANED_EDGES,
+                                       [Operations.LIST.value,
+                                        Operations.CLEAN.value]),
     constants.SPOOFGUARD_POLICY: Resource(constants.SPOOFGUARD_POLICY,
                                           [Operations.LIST.value]),
     constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
                                      [Operations.LIST.value,
                                       Operations.NSX_UPDATE.value]),
-    constants.BACKUP_EDGES: Resource(constants.BACKUP_EDGES,
-                                     [Operations.LIST.value,
-                                      Operations.CLEAN.value]),
 }
 
 nsxv3_resources_names = map(lambda res: res.name, nsxv3_resources.itervalues())