]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Optimize target edition when a portal is removed
authorRicardo Marques <rimarques@suse.com>
Fri, 29 Mar 2019 13:35:07 +0000 (13:35 +0000)
committerTatjana Dehler <tdehler@suse.com>
Tue, 16 Jul 2019 09:03:08 +0000 (11:03 +0200)
Fixes: https://tracker.ceph.com/issues/38794
Signed-off-by: Ricardo Marques <rimarques@suse.com>
(cherry picked from commit f345fe3f1093204af9a1783a619efbaf966c1bc7)

src/pybind/mgr/dashboard/controllers/iscsi.py
src/pybind/mgr/dashboard/services/iscsi_client.py
src/pybind/mgr/dashboard/tests/test_iscsi.py

index b58ef66a9f2ec6ddfb54793577bea786217de8cc..562a77f3d106acbc31a6058d7563743701963c84 100644 (file)
@@ -279,7 +279,7 @@ class IscsiTarget(RESTController):
         deleted_groups = []
         for group_id in list(target_config['groups'].keys()):
             if IscsiTarget._group_deletion_required(target, new_target_iqn, new_target_controls,
-                                                    new_portals, new_groups, group_id, new_clients,
+                                                    new_groups, group_id, new_clients,
                                                     new_disks):
                 deleted_groups.append(group_id)
                 IscsiClient.instance(gateway_name=gateway_name).delete_group(target_iqn,
@@ -287,22 +287,29 @@ class IscsiTarget(RESTController):
             TaskManager.current_task().inc_progress(task_progress_inc)
         for client_iqn in list(target_config['clients'].keys()):
             if IscsiTarget._client_deletion_required(target, new_target_iqn, new_target_controls,
-                                                     new_portals, new_clients, client_iqn,
+                                                     new_clients, client_iqn,
                                                      new_groups, deleted_groups):
                 IscsiClient.instance(gateway_name=gateway_name).delete_client(target_iqn,
                                                                               client_iqn)
             TaskManager.current_task().inc_progress(task_progress_inc)
         for image_id in target_config['disks']:
             if IscsiTarget._target_lun_deletion_required(target, new_target_iqn,
-                                                         new_target_controls, new_portals,
+                                                         new_target_controls,
                                                          new_disks, image_id):
                 IscsiClient.instance(gateway_name=gateway_name).delete_target_lun(target_iqn,
                                                                                   image_id)
                 pool, image = image_id.split('/', 1)
                 IscsiClient.instance(gateway_name=gateway_name).delete_disk(pool, image)
             TaskManager.current_task().inc_progress(task_progress_inc)
-        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls,
-                                                 new_portals):
+        old_portals_by_host = IscsiTarget._get_portals_by_host(target['portals'])
+        new_portals_by_host = IscsiTarget._get_portals_by_host(new_portals)
+        for old_portal_host, old_portal_ip_list in old_portals_by_host.items():
+            if IscsiTarget._target_portal_deletion_required(old_portal_host,
+                                                            old_portal_ip_list,
+                                                            new_portals_by_host):
+                IscsiClient.instance(gateway_name=gateway_name).delete_gateway(target_iqn,
+                                                                               old_portal_host)
+        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls):
             IscsiClient.instance(gateway_name=gateway_name).delete_target(target_iqn)
         TaskManager.current_task().set_progress(task_progress_end)
         return IscsiClient.instance(gateway_name=gateway_name).get_config()
@@ -315,10 +322,9 @@ class IscsiTarget(RESTController):
         return None
 
     @staticmethod
-    def _group_deletion_required(target, new_target_iqn, new_target_controls, new_portals,
+    def _group_deletion_required(target, new_target_iqn, new_target_controls,
                                  new_groups, group_id, new_clients, new_disks):
-        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls,
-                                                 new_portals):
+        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls):
             return True
         new_group = IscsiTarget._get_group(new_groups, group_id)
         if not new_group:
@@ -329,14 +335,14 @@ class IscsiTarget(RESTController):
         # Check if any client inside this group has changed
         for client_iqn in new_group['members']:
             if IscsiTarget._client_deletion_required(target, new_target_iqn, new_target_controls,
-                                                     new_portals, new_clients, client_iqn,
+                                                     new_clients, client_iqn,
                                                      new_groups, []):
                 return True
         # Check if any disk inside this group has changed
         for disk in new_group['disks']:
             image_id = '{}/{}'.format(disk['pool'], disk['image'])
             if IscsiTarget._target_lun_deletion_required(target, new_target_iqn,
-                                                         new_target_controls, new_portals,
+                                                         new_target_controls,
                                                          new_disks, image_id):
                 return True
         return False
@@ -349,10 +355,9 @@ class IscsiTarget(RESTController):
         return None
 
     @staticmethod
-    def _client_deletion_required(target, new_target_iqn, new_target_controls, new_portals,
+    def _client_deletion_required(target, new_target_iqn, new_target_controls,
                                   new_clients, client_iqn, new_groups, deleted_groups):
-        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls,
-                                                 new_portals):
+        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls):
             return True
         new_client = deepcopy(IscsiTarget._get_client(new_clients, client_iqn))
         if not new_client:
@@ -378,10 +383,9 @@ class IscsiTarget(RESTController):
         return None
 
     @staticmethod
-    def _target_lun_deletion_required(target, new_target_iqn, new_target_controls, new_portals,
+    def _target_lun_deletion_required(target, new_target_iqn, new_target_controls,
                                       new_disks, image_id):
-        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls,
-                                                 new_portals):
+        if IscsiTarget._target_deletion_required(target, new_target_iqn, new_target_controls):
             return True
         new_disk = IscsiTarget._get_disk(new_disks, image_id)
         if not new_disk:
@@ -392,13 +396,19 @@ class IscsiTarget(RESTController):
         return False
 
     @staticmethod
-    def _target_deletion_required(target, new_target_iqn, new_target_controls, new_portals):
+    def _target_portal_deletion_required(old_portal_host, old_portal_ip_list, new_portals_by_host):
+        if old_portal_host not in new_portals_by_host:
+            return True
+        if sorted(old_portal_ip_list) != sorted(new_portals_by_host[old_portal_host]):
+            return True
+        return False
+
+    @staticmethod
+    def _target_deletion_required(target, new_target_iqn, new_target_controls):
         if target['target_iqn'] != new_target_iqn:
             return True
         if target['target_controls'] != new_target_controls:
             return True
-        if target['portals'] != new_portals:
-            return True
         return False
 
     @staticmethod
@@ -503,11 +513,12 @@ class IscsiTarget(RESTController):
             if not target_config:
                 IscsiClient.instance(gateway_name=gateway_name).create_target(target_iqn,
                                                                               target_controls)
-                for host, ip_list in portals_by_host.items():
+            for host, ip_list in portals_by_host.items():
+                if not target_config or host not in target_config['portals']:
                     IscsiClient.instance(gateway_name=gateway_name).create_gateway(target_iqn,
                                                                                    host,
                                                                                    ip_list)
-                    TaskManager.current_task().inc_progress(task_progress_inc)
+                TaskManager.current_task().inc_progress(task_progress_inc)
             targetauth_action = ('enable_acl' if acl_enabled else 'disable_acl')
             IscsiClient.instance(gateway_name=gateway_name).update_targetauth(target_iqn,
                                                                               targetauth_action)
index 520b4ca30c78c8798e8193e6ee4eb37d965e821d..4d6115c31f5d3e66c959a16eb5a22f94766f4bc7 100644 (file)
@@ -109,6 +109,11 @@ class IscsiClient(RestClient):
     def get_gatewayinfo(self, request=None):
         return request()
 
+    @RestClient.api_delete('/api/gateway/{target_iqn}/{gateway_name}')
+    def delete_gateway(self, target_iqn, gateway_name, request=None):
+        logger.debug("iSCSI: Deleting gateway: %s/%s", target_iqn, gateway_name)
+        return request()
+
     @RestClient.api_put('/api/disk/{pool}/{image}')
     def create_disk(self, pool, image, backstore, request=None):
         logger.debug("iSCSI[%s] Creating disk: %s/%s", self.gateway_name, pool, image)
index e371ef368622acd709260edd2952ff813aa07e3d..c3c6c159c5c748b1b3564dfc4f5da5044e2c8d6c 100644 (file)
@@ -553,6 +553,12 @@ class IscsiClientMock(object):
             "portal_ip_address": ip_address[0]
         }
 
+    def delete_gateway(self, target_iqn, gateway_name):
+        target_config = self.config['targets'][target_iqn]
+        portal_config = target_config['portals'][gateway_name]
+        target_config['ip_list'].remove(portal_config['portal_ip_address'])
+        target_config['portals'].pop(gateway_name)
+
     def create_disk(self, pool, image, backstore):
         image_id = '{}/{}'.format(pool, image)
         self.config['disks'][image_id] = {