Hello community,

here is the log from the commit of package ceph-iscsi for openSUSE:Factory 
checked in at 2019-03-12 09:54:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ceph-iscsi (Old)
 and      /work/SRC/openSUSE:Factory/.ceph-iscsi.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ceph-iscsi"

Tue Mar 12 09:54:27 2019 rev:5 rq:683769 version:3.0+1552304123.g67b0d30

Changes:
--------
--- /work/SRC/openSUSE:Factory/ceph-iscsi/ceph-iscsi.changes    2019-02-28 
21:44:59.653484338 +0100
+++ /work/SRC/openSUSE:Factory/.ceph-iscsi.new.28833/ceph-iscsi.changes 
2019-03-12 09:54:30.479524984 +0100
@@ -1,0 +2,6 @@
+Mon Mar 11 11:35:48 UTC 2019 - ncut...@suse.com
+
+- Update to 3.0+1552304123.g67b0d30:
+  + add support for 'rbd' backstore (Ricardo Marques) 
+
+-------------------------------------------------------------------

Old:
----
  ceph-iscsi-3.0+1551361389.g157b5fd.tar.gz

New:
----
  ceph-iscsi-3.0+1552304123.g67b0d30.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ceph-iscsi.spec ++++++
--- /var/tmp/diff_new_pack.8jAQz8/_old  2019-03-12 09:54:31.803524721 +0100
+++ /var/tmp/diff_new_pack.8jAQz8/_new  2019-03-12 09:54:31.835524715 +0100
@@ -20,7 +20,7 @@
 
 
 Name:           ceph-iscsi
-Version:        3.0+1551361389.g157b5fd
+Version:        3.0+1552304123.g67b0d30
 Release:        1%{?dist}
 Group:          System/Filesystems
 Summary:        Python modules for Ceph iSCSI gateway configuration management

++++++ ceph-iscsi-3.0+1551361389.g157b5fd.tar.gz -> 
ceph-iscsi-3.0+1552304123.g67b0d30.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph-iscsi.spec 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph-iscsi.spec
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph-iscsi.spec      2019-02-28 
14:43:09.980709800 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph-iscsi.spec      2019-03-11 
12:35:23.551649077 +0100
@@ -20,7 +20,7 @@
 
 
 Name:           ceph-iscsi
-Version:        3.0+1551361389.g157b5fd
+Version:        3.0+1552304123.g67b0d30
 Release:        1%{?dist}
 Group:          System/Filesystems
 Summary:        Python modules for Ceph iSCSI gateway configuration management
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/backstore.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/backstore.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/backstore.py       
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/backstore.py       
2019-03-11 12:35:23.211647200 +0100
@@ -1,2 +1,16 @@
+from rtslib_fb import UserBackedStorageObject, RBDStorageObject
+
+from ceph_iscsi_config.utils import CephiSCSIError
+
 USER_RBD = 'user:rbd'
 RBD = 'rbd'
+
+
+def lookup_storage_object(name, backstore):
+    if backstore == USER_RBD:
+        return UserBackedStorageObject(name=name)
+    elif backstore == RBD:
+        return RBDStorageObject(name=name)
+    else:
+        raise CephiSCSIError("Could not lookup storage object - "
+                             "Unsupported backstore {}".format(backstore))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/client.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/client.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/client.py  
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/client.py  
2019-03-11 12:35:23.215647222 +0100
@@ -276,7 +276,7 @@
 
         tpg.set_attribute('authentication', '0')
 
-    def configure_auth(self, chap_credentials, chap_mutual_credentials):
+    def configure_auth(self, chap_credentials, chap_mutual_credentials, 
target_config):
         """
         Attempt to configure authentication for the client
         :return:
@@ -362,6 +362,15 @@
         else:
             self.change_count += 1
 
+        self._update_acl(target_config)
+
+    def _update_acl(self, target_config):
+        if self.tpg.node_acls:
+            self.tpg.set_attribute('generate_node_acls', 0)
+            if not target_config['acl_enabled']:
+                target_config['acl_enabled'] = True
+                self.change_count += 1
+
     def _add_lun(self, image, lun):
         """
         Add a given image to the client ACL
@@ -576,7 +585,7 @@
                 self.logger.warning("(main) client '{}' configured without"
                                     " security".format(self.iqn))
 
-            self.configure_auth(self.chap, self.chap_mutual)
+            self.configure_auth(self.chap, self.chap_mutual, target_config)
             if self.error:
                 return
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/common.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/common.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/common.py  
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/common.py  
2019-03-11 12:35:23.215647222 +0100
@@ -30,10 +30,7 @@
         self.error = False
         self.error_msg = ''
         self.cluster = rados.Rados(conffile=settings.config.cephconf,
-                                   name=settings.config.cluster_client_name,
-                                   conf=dict(keyring="{}/{}".format(
-                                             settings.config.ceph_config_dir,
-                                             settings.config.gateway_keyring)))
+                                   name=settings.config.cluster_client_name)
         try:
             self.cluster.connect()
         except rados.Error as err:
@@ -54,7 +51,7 @@
                    "targets": {},
                    "discovery_auth": {'chap': '',
                                       'chap_mutual': ''},
-                   "version": 6,
+                   "version": 7,
                    "epoch": 0,
                    "created": '',
                    "updated": ''
@@ -221,10 +218,16 @@
             self.update_item("version", None, 5)
 
         if self.config['version'] == 5:
+            for target_iqn, target in self.config['targets'].items():
+                target['acl_enabled'] = True
+                self.update_item("targets", target_iqn, target)
+            self.update_item("version", None, 6)
+
+        if self.config['version'] == 6:
             for disk_id, disk in self.config['disks'].items():
                 disk['backstore_object_name'] = disk_id
                 self.update_item("disks", disk_id, disk)
-            self.update_item("version", None, 6)
+            self.update_item("version", None, 7)
 
         self.commit("retain")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/gateway.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/gateway.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/gateway.py 
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/gateway.py 
2019-03-11 12:35:23.215647222 +0100
@@ -2,7 +2,6 @@
 
 from rtslib_fb.target import Target, TPG, NetworkPortal, LUN
 from rtslib_fb.fabric import ISCSIFabricModule
-from rtslib_fb import root
 from rtslib_fb.utils import RTSLibError, normalize_wwn
 from rtslib_fb.alua import ALUATargetPortGroup
 
@@ -16,6 +15,7 @@
 from ceph_iscsi_config.alua import alua_create_group, alua_format_group_name
 from ceph_iscsi_config.client import GWClient
 from ceph_iscsi_config.gateway_object import GWObject
+from ceph_iscsi_config.backstore import lookup_storage_object
 
 __author__ = 'pcuz...@redhat.com'
 
@@ -229,6 +229,14 @@
             self.error = True
             self.error_msg = "Unable to delete target - {}".format(err)
 
+    def update_acl(self, config):
+        target_config = config.config["targets"][self.iqn]
+        for tpg in self.tpg_list:
+            if target_config['acl_enabled']:
+                tpg.set_attribute('generate_node_acls', 0)
+            else:
+                tpg.set_attribute('generate_node_acls', 1)
+
     def create_tpg(self, ip):
 
         try:
@@ -316,10 +324,11 @@
         """
 
         try:
+            self.target = Target(ISCSIFabricModule(), self.iqn, "lookup")
 
-            lio_root = root.RTSRoot()
-            self.target = [tgt for tgt in lio_root.targets
-                           if tgt.wwn == self.iqn][0]
+            # clear list so we can rebuild with the current values below
+            if self.tpg_list:
+                del self.tpg_list[:]
 
             # there could/should be multiple tpg's for the target
             for tpg in self.target.tpgs:
@@ -402,65 +411,61 @@
                                                            tpg.tag,
                                                            alua_tpg.name))
 
-    def map_luns(self, config):
-        """
-        LIO will have objects already defined by the lun module,
-        so this method, brings those objects into the gateways TPG
-        """
+    def _map_lun(self, config, stg_object):
+        for tpg in self.tpg_list:
+            self.logger.debug("processing tpg{}".format(tpg.tag))
 
-        lio_root = root.RTSRoot()
-        target_config = config.config["targets"][self.iqn]
-        backstore_object_names = [disk['backstore_object_name'] for disk_id, 
disk in config.config['disks'].items()
-                                  if disk_id in target_config['disks']]
-        target_stg_object = [stg_object for stg_object in 
lio_root.storage_objects
-                             if stg_object.name in backstore_object_names]
-
-        # process each storage object added to the gateway, and map to the tpg
-        for stg_object in target_stg_object:
-
-            for tpg in self.tpg_list:
-                self.logger.debug("processing tpg{}".format(tpg.tag))
-
-                if not self.lun_mapped(tpg, stg_object):
-                    self.logger.debug("{} needed mapping to "
-                                      "tpg{}".format(stg_object.name,
-                                                     tpg.tag))
+            lun_id = int(stg_object.path.split('/')[-2].split('_')[1])
 
-                    lun_id = int(stg_object.path.split('/')[-2].split('_')[1])
+            try:
+                mapped_lun = LUN(tpg, lun=lun_id, storage_object=stg_object)
+                self.changes_made = True
+            except RTSLibError as err:
+                if "already exists in configFS" not in err:
+                    self.logger.error("LUN mapping failed: {}".format(err))
+                    self.error = True
+                    self.error_msg = err
+                    return
 
-                    try:
-                        mapped_lun = LUN(tpg, lun=lun_id, 
storage_object=stg_object)
-                        self.changes_made = True
-                    except RTSLibError as err:
-                        self.logger.error("LUN mapping failed: {}".format(err))
-                        self.error = True
-                        self.error_msg = err
-                        return
+                # Already created. Ignore and loop to the next tpg.
+                continue
 
-                    try:
-                        self.bind_alua_group_to_lun(config, mapped_lun)
-                    except CephiSCSIInval as err:
-                        self.logger.error("Could not bind LUN to ALUA group: "
-                                          "{}".format(err))
-                        self.error = True
-                        self.error_msg = err
-                        return
+            try:
+                self.bind_alua_group_to_lun(config, mapped_lun)
+            except CephiSCSIInval as err:
+                self.logger.error("Could not bind LUN to ALUA group: "
+                                  "{}".format(err))
+                self.error = True
+                self.error_msg = err
+                return
 
-    def lun_mapped(self, tpg, storage_object):
+    def map_lun(self, config, stg_object):
+        self.load_config()
+        self._map_lun(config, stg_object)
+
+    def map_luns(self, config):
         """
-        Check to see if a given storage object (i.e. block device) is already
-        mapped to the gateway's TPG
-        :param storage_object: storage object to look for
-        :return: boolean - is the storage object mapped or not
+        LIO will have objects already defined by the lun module,
+        so this method, brings those objects into the gateways TPG
         """
 
-        mapped_state = False
-        for l in tpg.luns:
-            if l.storage_object.name == storage_object.name:
-                mapped_state = True
-                break
+        target_config = config.config["targets"][self.iqn]
+
+        for disk in target_config['disks']:
+            backstore = config.config["disks"][disk]["backstore"]
+            backstore_object_name = 
config.config["disks"][disk]["backstore_object_name"]
+
+            try:
+                stg_object = lookup_storage_object(backstore_object_name, 
backstore)
+            except (RTSLibError, CephiSCSIError) as err:
+                self.logger.error("Could not map {} to LUN: {}".format(disk, 
err))
+                self.error = True
+                self.error_msg = err
+                return
 
-        return mapped_state
+            self._map_lun(config, stg_object)
+            if self.error:
+                return
 
     def delete(self):
         self.target.delete()
@@ -552,6 +557,8 @@
 
                 self.map_luns(config)
 
+                self.update_acl(config)
+
             else:
                 self.error = True
                 self.error_msg = ("Attempted to map to a gateway '{}' that "
@@ -572,6 +579,7 @@
                 seed_target = {
                     'disks': [],
                     'clients': {},
+                    'acl_enabled': True,
                     'portals': {},
                     'groups': {},
                     'controls': {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/lun.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/lun.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/lun.py     
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/lun.py     
2019-03-11 12:35:23.215647222 +0100
@@ -22,6 +22,7 @@
 from ceph_iscsi_config.gateway import GWTarget
 from ceph_iscsi_config.client import GWClient, CHAP
 from ceph_iscsi_config.group import Group
+from ceph_iscsi_config.backstore import lookup_storage_object
 
 __author__ = 'pcuz...@redhat.com'
 
@@ -450,20 +451,26 @@
 
             self.config.commit()
 
-    def map_lun(self, target_iqn, owner, disk):
-        target_config = self.config.config['targets'][target_iqn]
+    def map_lun(self, gateway, owner, disk):
+        target_config = self.config.config['targets'][gateway.iqn]
         disk_metadata = self.config.config['disks'][disk]
         disk_metadata['owner'] = owner
         self.config.update_item("disks", disk, disk_metadata)
 
         target_config['disks'].append(disk)
-        self.config.update_item("targets", target_iqn, target_config)
+        self.config.update_item("targets", gateway.iqn, target_config)
 
         gateway_dict = self.config.config['gateways'][owner]
         gateway_dict['active_luns'] += 1
         self.config.update_item('gateways', owner, gateway_dict)
 
-        self.allocate()
+        so = self.allocate()
+        if self.error:
+            raise CephiSCSIError(self.error_msg)
+
+        gateway.map_lun(self.config, so)
+        if gateway.error:
+            raise CephiSCSIError(gateway.error_msg)
 
     def manage(self, desired_state):
 
@@ -576,6 +583,14 @@
                 raise CephiSCSIError(client_err)
 
     def allocate(self, keep_dev_in_lio=True):
+        """
+        Create image and add to LIO and config.
+
+        :param keep_dev_in_lio: (bool) false if the LIO so should be removed
+                                 after allocating the wwn.
+        :return: LIO storage object if successful and keep_dev_in_lio=True
+                 else None.
+        """
         self.logger.debug("LUN.allocate starting, listing rbd devices")
         disk_list = RBDDev.rbd_list(pool=self.pool)
         self.logger.debug("rados pool '{}' contains the following - "
@@ -605,7 +620,7 @@
                 else:
                     self.error = True
                     self.error_msg = rbd_image.error_msg
-                    return
+                    return None
 
             else:
                 # the image isn't there, and this isn't the 'owning' host
@@ -619,7 +634,7 @@
                         self.error = True
                         self.error_msg = ("(LUN.allocate) timed out waiting "
                                           "for rbd to show up")
-                        return
+                        return None
         else:
             # requested image is already defined to ceph
 
@@ -637,7 +652,7 @@
                                   "with LIO\nOnly image features {} are"
                                   " supported".format(self.image, features))
                 self.logger.error(self.error_msg)
-                return
+                return None
 
         self.logger.debug("Check the rbd image size matches the request")
 
@@ -651,7 +666,7 @@
                 self.logger.critical(rbd_image.error_msg)
                 self.error = True
                 self.error_msg = rbd_image.error_msg
-                return
+                return None
 
             if rbd_image.changed:
                 self.logger.info("rbd image {} resized "
@@ -681,17 +696,17 @@
                 if wwn == '':
                     # disk hasn't been defined to LIO yet, it' not been defined
                     # to the config yet and this is the allocating host
-                    lun = self.add_dev_to_lio()
+                    so = self.add_dev_to_lio()
                     if self.error:
-                        return
+                        return None
 
                     # lun is now in LIO, time for some housekeeping :P
-                    wwn = lun._get_wwn()
+                    wwn = so._get_wwn()
 
                     if not keep_dev_in_lio:
                         self.remove_dev_from_lio()
                         if self.error:
-                            return
+                            return None
 
                     disk_attr = {"wwn": wwn,
                                  "image": self.image,
@@ -716,9 +731,9 @@
 
                 else:
                     # config object already had wwn for this rbd image
-                    self.add_dev_to_lio(wwn)
+                    so = self.add_dev_to_lio(wwn)
                     if self.error:
-                        return
+                        return None
 
                     self.update_controls()
                     self.logger.debug("(LUN.allocate) registered '{}' to LIO "
@@ -750,13 +765,13 @@
                     self.error_msg = ("(LUN.allocate) waited too long for the "
                                       "wwn information on image {} to "
                                       "arrive".format(self.image))
-                    return
+                    return None
 
                 # At this point we have a wwn from the config for this rbd
                 # image, so just add to LIO
-                self.add_dev_to_lio(wwn)
+                so = self.add_dev_to_lio(wwn)
                 if self.error:
-                    return
+                    return None
 
                 self.logger.info("(LUN.allocate) added {} to LIO using wwn "
                                  "'{}' defined by {}".format(self.image,
@@ -771,7 +786,7 @@
                 self.error = True
                 self.error_msg = "Unable to sync the rbd device size with LIO"
                 self.logger.critical(self.error_msg)
-                return
+                return None
 
         self.logger.debug("config meta data for this disk is "
                           
"{}".format(self.config.config['disks'][self.config_key]))
@@ -785,6 +800,10 @@
             self.config.commit()
             self.error = self.config.error
             self.error_msg = self.config.error_msg
+            if self.error:
+                return None
+
+        return so
 
     def lio_size_ok(self, rbd_object, stg_object):
         """
@@ -827,18 +846,11 @@
         return size_ok
 
     def lio_stg_object(self):
-        found_it = False
-        rtsroot = root.RTSRoot()
-        for stg_object in rtsroot.storage_objects:
-
-            # First match on name, but then check the pool incase the same
-            # name exists in multiple pools
-            if stg_object.name == self.backstore_object_name:
-
-                found_it = True
-                break
-
-        return stg_object if found_it else None
+        try:
+            return lookup_storage_object(self.backstore_object_name, 
self.backstore)
+        except RTSLibError as err:
+            self.logger.debug("lio stg lookup failed {}".format(err))
+            return None
 
     def add_dev_to_lio(self, in_wwn=None):
         """
@@ -1009,19 +1021,21 @@
                     else:
                         break       # continue to the next tpg
 
-        for stg_object in lio_root.storage_objects:
-            if stg_object.name == self.backstore_object_name:
-                try:
-                    stg_object.delete()
-                    if self.backstore == RBD:
-                        self._rbd_device_unmap()
-                except Exception as e:
-                    self.error = True
-                    self.error_msg = ("Delete from LIO/backstores failed - "
-                                      "{}".format(e))
-                    return
+        so = self.lio_stg_object()
+        if not so:
+            self.error = True
+            self.error_msg = ("Removal failed. Could not find LIO object.")
+            return
 
-                break
+        try:
+            so.delete()
+            if self.backstore == RBD:
+                self._rbd_device_unmap()
+        except Exception as err:
+            self.error = True
+            self.error_msg = ("Delete from LIO/backstores failed - "
+                              "{}".format(err))
+            return
 
     @staticmethod
     def valid_disk(ceph_iscsi_config, logger, **kwargs):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/settings.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/settings.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/ceph_iscsi_config/settings.py        
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/ceph_iscsi_config/settings.py        
2019-03-11 12:35:23.215647222 +0100
@@ -94,9 +94,8 @@
         return v
 
     defaults = {"cluster_name": "ceph",
-                "cluster_client_name": "client.admin",
-                "gateway_keyring": "ceph.client.admin.keyring",
                 "pool": "rbd",
+                "cluster_client_name": "client.admin",
                 "time_out": 30,
                 "api_host": "::",
                 "api_port": 5000,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/ceph.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/ceph.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/ceph.py        2019-02-28 
14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/ceph.py        2019-03-11 
12:35:23.215647222 +0100
@@ -1,8 +1,6 @@
 from .node import UIGroup, UINode
 import json
 import rados
-import glob
-import os
 
 from gwcli.utils import console_message, os_cmd
 import ceph_iscsi_config.settings as settings
@@ -32,75 +30,15 @@
     default_ceph_conf = '{}/ceph.conf'.format(ceph_config_dir)
 
     def __init__(self, parent):
-        UIGroup.__init__(self, 'clusters', parent)
-        self.cluster_map = self.get_clusters()
-        self.local_ceph = None
-
-        for cluster_name in self.cluster_map.keys():
-
-            keyring = self.cluster_map[cluster_name]['keyring']
-            cluster_client_name = None
-            if cluster_name == settings.config.cluster_name:
-
-                if settings.config.gateway_keyring:
-                    keyring = settings.config.gateway_keyring
-                    self.cluster_map[cluster_name]['keyring'] = keyring
-
-                if settings.config.cluster_client_name:
-                    cluster_client_name = settings.config.cluster_client_name
-                    self.cluster_map[cluster_name]['client_name'] = 
cluster_client_name
-
-            # define the cluster object
-            self.logger.debug("Adding ceph cluster '{}' to the 
UI".format(cluster_name))
-            cluster = CephCluster(self,
-                                  cluster_name,
-                                  self.cluster_map[cluster_name]['conf_file'],
-                                  cluster_client_name,
-                                  keyring)
-
-            self.cluster_map[cluster_name]['object'] = cluster
-            if self.cluster_map[cluster_name]['local']:
-                self.local_ceph = cluster
-
-    def get_clusters(self):
-        """
-        Look at the /etc/ceph dir to generate a dict of clusters that are
-        defined/known to the gateway
-        :return: (dict) ceph_name -> conf_file, keyring
-        """
-
-        clusters = {}       # dict ceph_name -> conf_file, keyring
-
-        conf_files = glob.glob(os.path.join(CephGroup.ceph_config_dir,
-                               '*.conf'))
-
-        valid_conf_files = [conf for conf in conf_files
-                            if CephGroup.valid_conf(conf)]
-        for conf in valid_conf_files:
-            name = os.path.basename(conf).split('.')[0]
-            keyring = glob.glob(os.path.join(CephGroup.ceph_config_dir,
-                                             '{}*.keyring'.format(name)))
-            if not keyring:
-                self.logger.debug("Skipping {} - no keyring 
found".format(conf))
-                continue
-
-            keyring = keyring[0]  # select the first one
-
-            client_name = None
-            if keyring.startswith("ceph.client."):
-                begin_idx = keyring.find(".")
-                end_idx = keyring.find(".keyring")
-                client_name = keyring[begin_idx+1:end_idx]
-
-            local = True if name == settings.config.cluster_name else False
-
-            clusters[name] = {'conf_file': conf,
-                              'keyring': keyring,
-                              'client_name': client_name,
-                              'name': name,
-                              'local': local}
+        UIGroup.__init__(self, 'cluster', parent)
 
-        return clusters
+        self.logger.debug("Adding ceph cluster '{}' to the UI"
+                          .format(settings.config.cluster_name))
+        self.cluster = CephCluster(self,
+                                   settings.config.cluster_name,
+                                   
"{}/{}.conf".format(settings.config.ceph_config_dir,
+                                                       
settings.config.cluster_name),
+                                   settings.config.cluster_client_name)
 
     @staticmethod
     def valid_conf(config_file):
@@ -136,11 +74,10 @@
 
 class CephCluster(UIGroup):
 
-    def __init__(self, parent, cluster_name, conf_file, client_name, keyring):
+    def __init__(self, parent, cluster_name, conf_file, client_name):
 
         self.conf = conf_file
         self.client_name = client_name
-        self.keyring = keyring
         self.cluster_name = cluster_name
         UIGroup.__init__(self, cluster_name, parent)
 
@@ -194,8 +131,6 @@
         output += "Raw capacity: {}\n".format(human_size(raw))
         output += "\nConfig : {}\n".format(self.conf)
         output += "Client Name: {}\n".format(self.client_name)
-        output += "Keyring: 
{}\n".format(os.path.join(CephGroup.ceph_config_dir,
-                                                      self.keyring))
 
         console_message(output, color=color[self.health_status])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/client.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/client.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/client.py      2019-02-28 
14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/client.py      2019-03-11 
12:35:23.215647222 +0100
@@ -1,6 +1,6 @@
 from gwcli.node import UIGroup, UINode
 
-from gwcli.utils import response_message, APIRequest
+from gwcli.utils import response_message, APIRequest, get_config
 
 from ceph_iscsi_config.client import CHAP
 import ceph_iscsi_config.settings as settings
@@ -43,6 +43,8 @@
             self.shell.log.debug("Bookmarked %s as %s."
                                  % (self.path, 'hosts'))
 
+        self.config = get_config()
+
     def load(self, client_info):
         for client_iqn, client_settings in client_info.items():
             Client(self, client_iqn, client_settings)
@@ -85,6 +87,7 @@
 
         if api.response.status_code == 200:
             Client(self, client_iqn, cli_seed)
+            self.config = get_config()
             self.logger.debug("- Client '{}' added".format(client_iqn))
             self.logger.info('ok')
 
@@ -185,29 +188,50 @@
         del self.client_map[child.client_iqn]
         self.remove_child(child)
 
-    def ui_command_auth(self, chap=None):
+    def ui_command_auth(self, action=None):
         """
-        Clear CHAP settings for all clients on the target.
+        Disable/enable ACL authentication or clear CHAP settings for all 
clients on the target.
+
+        - disable_acl ... Disable initiator name based ACL authentication.
 
-        Specifying 'nochap' will remove chap authentication for all clients
-        across all gateways. Initiator name based authentication will then be
-        used.
+        - enable_acl .... Enable initiator name based ACL authentication.
+
+        - nochap ........ Remove chap authentication for all clients across 
all gateways.
+                          Initiator name based authentication will then be 
used.
 
         e.g.
-        auth nochap
+        auth disable_acl
 
         """
 
-        if not chap:
-            self.logger.error("Missing auth argument. Use 'auth nochap'")
+        if not action:
+            self.logger.error("Missing auth argument. Use 'auth 
nochap|disable_acl|enable_acl'")
             return
 
-        if chap != 'nochap':
-            self.logger.error("Invalid auth argument. Use 'auth nochap'")
+        if action not in ['nochap', 'enable_acl', 'disable_acl']:
+            self.logger.error("Invalid auth argument. Use 'auth 
nochap|disable_acl|enable_acl'")
             return
 
-        for client in self.children:
-            client.set_auth(chap, None)
+        if action == 'nochap':
+            for client in self.children:
+                client.set_auth(action, None)
+        else:
+            target_iqn = self.parent.name
+            api_vars = {'action': action}
+            targetauth_api = ('{}://localhost:{}/api/'
+                              'targetauth/{}'.format(self.http_mode,
+                                                     settings.config.api_port,
+                                                     target_iqn))
+            api = APIRequest(targetauth_api, data=api_vars)
+            api.put()
+            if api.response.status_code == 200:
+                self.config = get_config()
+                self.logger.info('ok')
+            else:
+                self.logger.error("Failed to {}: "
+                                  "{}".format(action, 
response_message(api.response,
+                                                                       
self.logger)))
+                return
 
     def summary(self):
         chap_enabled = False
@@ -215,9 +239,8 @@
         chap_mutual_enabled = False
         chap_mutual_disabled = False
         status = False
-        # initiator name based ACL is the default with the current kernel
-        # settings.
-        auth_stat_str = "None"
+        target_iqn = self.parent.name
+        auth_stat_str = "ACL" if 
self.config['targets'][target_iqn]['acl_enabled'] else "None"
 
         for client in self.children:
             if client.auth['chap'] == 'None':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/storage.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/storage.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/gwcli/storage.py     2019-02-28 
14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/gwcli/storage.py     2019-03-11 
12:35:23.215647222 +0100
@@ -266,10 +266,7 @@
 
         # first check that the intended pool is compatible with rbd images
         root = self.get_ui_root()
-        clusters = root.ceph.cluster_map
-        local_cluster = [clusters[cluster_name] for cluster_name in clusters
-                         if clusters[cluster_name]['local']][0]['object']
-        pools = local_cluster.pools
+        pools = root.ceph.cluster.pools
         pool_object = pools.pool_lookup.get(pool, None)
         if pool_object:
             if pool_object.type == 'replicated':
@@ -349,7 +346,7 @@
                     raise GatewayAPIError("Unable to retrieve disk details "
                                           "for '{}' from the 
API".format(disk_key))
 
-            ceph_pools = self.parent.ceph.local_ceph.pools
+            ceph_pools = self.parent.ceph.cluster.pools
             ceph_pools.refresh()
 
         else:
@@ -517,7 +514,7 @@
                                                            self.logger)))
             return
 
-        ceph_pools = self.parent.ceph.local_ceph.pools
+        ceph_pools = self.parent.ceph.cluster.pools
         ceph_pools.refresh()
 
         self.logger.info('ok')
@@ -534,7 +531,7 @@
         ui_root = self.get_ui_root()
         state = True
         discovered_pools = [rados_pool.name for rados_pool in
-                            ui_root.ceph.local_ceph.pools.children]
+                            ui_root.ceph.cluster.pools.children]
         existing_rbds = self.disk_info.keys()
 
         storage_key = "{}.{}".format(pool, image)
@@ -591,7 +588,7 @@
         self.backstore_object_name = image_config['backstore_object_name']
         self.controls = {}
         self.control_values = {}
-        self.ceph_cluster = self.parent.parent.ceph.local_ceph.name
+        self.ceph_cluster = self.parent.parent.ceph.cluster.name
 
         disk_map = self.parent.disk_info
         if image_id not in disk_map:
@@ -875,7 +872,7 @@
         """
         root = self.parent.parent
         ceph_group = root.ceph
-        cluster = ceph_group.local_ceph
+        cluster = ceph_group.cluster
         pool = cluster.pools.pool_lookup.get(self.pool)
 
         if pool:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/iscsi-gateway.cfg_sample 
new/ceph-iscsi-3.0+1552304123.g67b0d30/iscsi-gateway.cfg_sample
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/iscsi-gateway.cfg_sample     
2019-02-28 14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/iscsi-gateway.cfg_sample     
2019-03-11 12:35:23.215647222 +0100
@@ -3,12 +3,11 @@
 # cluster from the gateway node is required.
 cluster_name = <ceph cluster name>
 
-# Place a copy of the ceph cluster's admin keyring in the gateway's /etc/ceph
-# drectory and reference the filename here
-gateway_keyring = <client.admin.keyring>
-
-cluster_client_name = client.<rados_id>  # E.g. client.admin
+# Pool name where internal `gateway.conf` object is stored
+# pool = rbd
 
+# CephX client name
+# cluster_client_name = client.<rados_id>  # E.g.: client.admin
 
 # API settings.
 # The api supports a number of options that allow you to tailor it to your
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1551361389.g157b5fd/rbd-target-api.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/rbd-target-api.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/rbd-target-api.py    2019-02-28 
14:43:09.700708236 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/rbd-target-api.py    2019-03-11 
12:35:23.215647222 +0100
@@ -826,19 +826,13 @@
                          "{}".format(lun.error_msg))
             return jsonify(message="Error establishing LUN instance"), 500
 
-        lun.map_lun(target_iqn, owner, disk)
-        if lun.error:
-            status_code = 400 if lun.error_msg else 500
-            logger.error("LUN add failed : {}".format(lun.error_msg))
+        try:
+            lun.map_lun(gateway, owner, disk)
+        except CephiSCSIError as err:
+            status_code = 400 if str(err) else 500
+            logger.error("LUN add failed : {}".format(err))
             return jsonify(message="Failed to add the LUN - "
-                                   "{}".format(lun.error_msg)), status_code
-
-        logger.info("Syncing TPG to LUN mapping")
-        gateway.manage('map')
-        if gateway.error:
-            return jsonify(message="Failed to sync LUNs on gateway, "
-                                   "Err {}.".format(gateway.error_msg)), 500
-
+                                   "{}".format(err)), status_code
     else:
         # DELETE gateway request
 
@@ -1497,6 +1491,79 @@
 
     return jsonify(message='OK'), 200
 
+
+@app.route('/api/targetauth/<target_iqn>', methods=['PUT'])
+@requires_restricted_auth
+def targetauth(target_iqn=None):
+    """
+    Coordinate the gen-acls across each gateway node
+    :param target_iqn: (str) IQN of the target
+    :param action: (str) action to be performed
+    **RESTRICTED**
+    Examples:
+    curl --insecure --user admin:admin -d auth='disable_acl'
+        -X PUT 
https://192.168.122.69:5000/api/targetauth/iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw
+    """
+
+    action = request.form.get('action')
+    if action not in ['disable_acl', 'enable_acl']:
+        return jsonify(message='Invalid auth {}'.format(action)), 400
+
+    target_config = config.config['targets'][target_iqn]
+
+    if action == 'disable_acl' and target_config['clients'].keys():
+        return jsonify(message='Cannot disable ACL authentication '
+                               'because target has clients'), 400
+
+    try:
+        gateways = get_remote_gateways(target_config['portals'], logger)
+    except CephiSCSIError as err:
+        return jsonify(message="{}".format(err)), 400
+    local_gw = this_host()
+    gateways.insert(0, local_gw)
+
+    # Apply to all gateways
+    api_vars = {
+        "committing_host": local_gw,
+        "action": action
+    }
+    resp_text, resp_code = call_api(gateways, '_targetauth',
+                                    target_iqn,
+                                    http_method='put',
+                                    api_vars=api_vars)
+
+    return jsonify(message="target auth {} - {}".format(action, resp_text)), 
resp_code
+
+
+@app.route('/api/_targetauth/<target_iqn>', methods=['PUT'])
+@requires_restricted_auth
+def _targetauth(target_iqn=None):
+    """
+    Apply gen-acls on the local gateway
+    Internal Use ONLY
+    **RESTRICTED**
+    """
+
+    local_gw = this_host()
+    committing_host = request.form['committing_host']
+    action = request.form['action']
+
+    target = GWTarget(logger, target_iqn, [])
+
+    target_config = config.config['targets'][target_iqn]
+    if action in ['disable_acl', 'enable_acl']:
+        target_config['acl_enabled'] = (action == 'enable_acl')
+    config.update_item('targets', target_iqn, target_config)
+
+    if target.exists():
+        target.load_config()
+        target.update_acl(config)
+
+    if committing_host == local_gw:
+        config.commit("retain")
+
+    return jsonify(message='OK'), 200
+
 
 @app.route('/api/clients/<target_iqn>', methods=['GET'])
 @requires_restricted_auth
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1551361389.g157b5fd/test/test_common.py 
new/ceph-iscsi-3.0+1552304123.g67b0d30/test/test_common.py
--- old/ceph-iscsi-3.0+1551361389.g157b5fd/test/test_common.py  2019-02-28 
14:43:09.704708260 +0100
+++ new/ceph-iscsi-3.0+1552304123.g67b0d30/test/test_common.py  2019-03-11 
12:35:23.215647222 +0100
@@ -190,6 +190,7 @@
                         }
                     }
                 },
+                "acl_enabled": True,
                 "controls": {
                     "immediate_data": False,
                     "nopin_response_timeout": 17
@@ -242,5 +243,5 @@
             }
         },
         "updated": "2018/12/07 09:18:13",
-        "version": 5
+        "version": 7
     }


Reply via email to