From 248baf2d7d4b0c9aa9639d504f285bb5b5536b0b Mon Sep 17 00:00:00 2001
From: Amey Bhide <abhide@vmware.com>
Date: Thu, 3 Dec 2015 15:18:10 -0800
Subject: [PATCH] Admin Utility: Add command for delete-backup-edge

$ nsxadmin -r backup-edges -o clean --property edge-id=edge-9

Change-Id: I9e26110854f0fe12c52f3c26738d30def4dc74cc
---
 .../plugins/nsxv/resources/backup_edges.py    | 50 +++++++++++++++++++
 tools/python_nsxadmin/admin/shell.py          |  3 +-
 vmware_nsx/plugins/nsx_v/vshield/vcns.py      |  4 ++
 .../tests/unit/nsx_v/vshield/fake_vcns.py     | 12 +++++
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/tools/python_nsxadmin/admin/plugins/nsxv/resources/backup_edges.py b/tools/python_nsxadmin/admin/plugins/nsxv/resources/backup_edges.py
index 1154a6fcc6..1305343ee8 100644
--- a/tools/python_nsxadmin/admin/plugins/nsxv/resources/backup_edges.py
+++ b/tools/python_nsxadmin/admin/plugins/nsxv/resources/backup_edges.py
@@ -23,6 +23,11 @@ import tools.python_nsxadmin.admin.plugins.nsxv.resources.utils as utils
 import tools.python_nsxadmin.admin.shell as shell
 
 from neutron.callbacks import registry
+from neutron.common import exceptions
+
+from vmware_nsx._i18n import _LE, _LI
+from vmware_nsx.common import locking
+from vmware_nsx.db import nsxv_db
 
 
 LOG = logging.getLogger(__name__)
@@ -47,6 +52,51 @@ def nsx_list_backup_edges(resource, event, trigger, **kwargs):
                                          ['id']))
 
 
+def nsx_clean_backup_edge(resource, event, trigger, **kwargs):
+    """Delete backup edge"""
+    errmsg = ("Need to specify edge-id property. Add --property "
+              "edge-id=<edge-id>")
+    if not kwargs.get('property'):
+        LOG.error(_LE("%s"), errmsg)
+        return
+    properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
+    edge_id = properties.get('edge-id')
+    if not edge_id:
+        LOG.error(_LE("%s"), errmsg)
+        return
+    try:
+        edge = nsxv.get_edge(edge_id)
+    except exceptions.NeutronException as e:
+        LOG.error(_LE("%s"), str(e))
+    else:
+        # edge[0] is response status code
+        # edge[1] is response body
+        if not edge[1]['name'].startswith('backup-'):
+            LOG.error(
+                _LE('Edge: %s is not a backup edge; aborting delete'), edge_id)
+            return
+
+        confirm = admin_utils.query_yes_no(
+            "Do you want to delete edge: %s" % edge_id, default="no")
+        if not confirm:
+            LOG.info(_LI("Backup edge deletion aborted by user"))
+            return
+        try:
+            with locking.LockManager.get_lock(
+                'nsx-edge-request', lock_file_prefix='get-'):
+                # Delete from NSXv backend
+                nsxv.delete_edge(edge_id)
+                # Remove bindings from Neutron DB
+                edgeapi = utils.NeutronDbClient()
+                nsxv_db.delete_nsxv_router_binding(
+                    edgeapi.context.session, edge[1]['name'])
+        except Exception as e:
+            LOG.error(_LE("%s"), str(e))
+
+
 registry.subscribe(nsx_list_backup_edges,
                    constants.BACKUP_EDGES,
                    shell.Operations.LIST.value)
+registry.subscribe(nsx_clean_backup_edge,
+                   constants.BACKUP_EDGES,
+                   shell.Operations.CLEAN.value)
diff --git a/tools/python_nsxadmin/admin/shell.py b/tools/python_nsxadmin/admin/shell.py
index 5873a1952f..960ebedad9 100644
--- a/tools/python_nsxadmin/admin/shell.py
+++ b/tools/python_nsxadmin/admin/shell.py
@@ -88,7 +88,8 @@ nsxv_resources = {
                                      [Operations.LIST.value,
                                       Operations.NSX_UPDATE.value]),
     constants.BACKUP_EDGES: Resource(constants.BACKUP_EDGES,
-                                     [Operations.LIST.value]),
+                                     [Operations.LIST.value,
+                                      Operations.CLEAN.value]),
 }
 
 nsxv3_resources_names = map(lambda res: res.name, nsxv3_resources.itervalues())
diff --git a/vmware_nsx/plugins/nsx_v/vshield/vcns.py b/vmware_nsx/plugins/nsx_v/vshield/vcns.py
index 35f46a2baa..c572a0eadf 100644
--- a/vmware_nsx/plugins/nsx_v/vshield/vcns.py
+++ b/vmware_nsx/plugins/nsx_v/vshield/vcns.py
@@ -207,6 +207,10 @@ class Vcns(object):
         uri = "%s/%s/status?getlatest=false" % (URI_PREFIX, edge_id)
         return self.do_request(HTTP_GET, uri, decode=True)
 
+    def get_edge(self, edge_id):
+        uri = "%s/%s" % (URI_PREFIX, edge_id)
+        return self.do_request(HTTP_GET, uri, decode=True)
+
     def get_edges(self):
         uri = URI_PREFIX
         return self.do_request(HTTP_GET, uri, decode=True)
diff --git a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py
index c369b97586..3702e3e3a8 100644
--- a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py
+++ b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py
@@ -397,6 +397,18 @@ class FakeVcns(object):
         }
         return (header, response)
 
+    def get_edge(self, edge_id):
+        if edge_id not in self._edges:
+            raise Exception(_("Edge %s does not exist!") % edge_id)
+        header = {
+            'status': 200
+        }
+        response = {
+            'name': 'fake-edge',
+            'id': edge_id
+        }
+        return (header, response)
+
     def get_edges(self):
         header = {
             'status': 200