]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/pybind/mgr/dashboard/controllers/iscsi.py
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / pybind / mgr / dashboard / controllers / iscsi.py
index b58ef66a9f2ec6ddfb54793577bea786217de8cc..df44f889807047039fdaf25b702dbdd8610cd5bc 100644 (file)
@@ -25,7 +25,7 @@ from ..tools import TaskManager
 @UiApiController('/iscsi', Scope.ISCSI)
 class IscsiUi(BaseController):
 
-    REQUIRED_CEPH_ISCSI_CONFIG_VERSION = 9
+    REQUIRED_CEPH_ISCSI_CONFIG_VERSION = 10
 
     @Endpoint()
     @ReadPermission
@@ -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)
@@ -574,10 +585,8 @@ class IscsiTarget(RESTController):
     def _config_to_target(target_iqn, config):
         target_config = config['targets'][target_iqn]
         portals = []
-        for host in target_config['portals'].keys():
-            ips = IscsiClient.instance(gateway_name=host).get_ip_addresses()['data']
-            portal_ips = [ip for ip in ips if ip in target_config['ip_list']]
-            for portal_ip in portal_ips:
+        for host, portal_config in target_config['portals'].items():
+            for portal_ip in portal_config['portal_ip_addresses']:
                 portal = {
                     'host': host,
                     'ip': portal_ip
@@ -662,6 +671,11 @@ class IscsiTarget(RESTController):
         gateway_name = target['portals'][0]['host']
         target_info = IscsiClient.instance(gateway_name=gateway_name).get_targetinfo(target_iqn)
         target['info'] = target_info
+        for client in target['clients']:
+            client_iqn = client['client_iqn']
+            client_info = IscsiClient.instance(gateway_name=gateway_name).get_clientinfo(
+                target_iqn, client_iqn)
+            client['info'] = client_info
 
     @staticmethod
     def _sorted_portals(portals):