From 677bf27e0cd4c9c175c3b2ef78da510f8a264dbe Mon Sep 17 00:00:00 2001 From: cuiyeliu Date: Tue, 17 Jun 2025 07:31:25 +0000 Subject: [PATCH] Dell PowerScale: Rename Isilon to PowerScale in Manila Driver Because the Dell EMC Isilon driver has now been renamed to PowerScale, we should change all the relevant parts of the code. Implements: blueprint powerscale-rename-manila Change-Id: Ic377d336972c55ce3cd59549c6b1c034e062bc52 Signed-off-by: cuiyeliu --- doc/source/_extra/.htaccess | 1 + ...ver.rst => dell_emc_powerscale_driver.rst} | 46 +-- doc/source/admin/index.rst | 2 +- ...hare_back_ends_feature_support_mapping.rst | 48 +-- doc/source/conf.py | 5 +- .../shared-file-systems/drivers.rst | 2 +- .../drivers/dell-emc-powermax-driver.rst | 2 +- ...ver.rst => dell-emc-powerscale-driver.rst} | 29 +- manila/opts.py | 3 +- manila/share/drivers/dell_emc/driver.py | 7 +- .../{isilon => powerscale}/__init__.py | 0 .../isilon.py => powerscale/powerscale.py} | 86 ++--- .../powerscale_api.py} | 2 +- .../{isilon => powerscale}/__init__.py | 0 .../test_powerscale.py} | 331 ++++++++++-------- .../test_powerscale_api.py} | 301 ++++++++-------- ...isilon-to-powerscale-8e29d71c9e3629c3.yaml | 13 + setup.cfg | 2 +- 18 files changed, 470 insertions(+), 410 deletions(-) create mode 100644 doc/source/_extra/.htaccess rename doc/source/admin/{emc_isilon_driver.rst => dell_emc_powerscale_driver.rst} (64%) rename doc/source/configuration/shared-file-systems/drivers/{emc-isilon-driver.rst => dell-emc-powerscale-driver.rst} (67%) rename manila/share/drivers/dell_emc/plugins/{isilon => powerscale}/__init__.py (100%) rename manila/share/drivers/dell_emc/plugins/{isilon/isilon.py => powerscale/powerscale.py} (88%) rename manila/share/drivers/dell_emc/plugins/{isilon/isilon_api.py => powerscale/powerscale_api.py} (99%) rename manila/tests/share/drivers/dell_emc/plugins/{isilon => powerscale}/__init__.py (100%) rename manila/tests/share/drivers/dell_emc/plugins/{isilon/test_isilon.py => powerscale/test_powerscale.py} (74%) rename manila/tests/share/drivers/dell_emc/plugins/{isilon/test_isilon_api.py => powerscale/test_powerscale_api.py} (78%) create mode 100644 releasenotes/notes/bp-rename-isilon-to-powerscale-8e29d71c9e3629c3.yaml diff --git a/doc/source/_extra/.htaccess b/doc/source/_extra/.htaccess new file mode 100644 index 0000000000..8f43fbf6bd --- /dev/null +++ b/doc/source/_extra/.htaccess @@ -0,0 +1 @@ +RedirectMatch 301 ^/drivers/emc-isilon-driver.html$ /drivers/dell-emc-powerscale-driver.html diff --git a/doc/source/admin/emc_isilon_driver.rst b/doc/source/admin/dell_emc_powerscale_driver.rst similarity index 64% rename from doc/source/admin/emc_isilon_driver.rst rename to doc/source/admin/dell_emc_powerscale_driver.rst index 8290a1fed7..752365713f 100644 --- a/doc/source/admin/emc_isilon_driver.rst +++ b/doc/source/admin/dell_emc_powerscale_driver.rst @@ -14,31 +14,31 @@ License for the specific language governing permissions and limitations under the License. -Isilon Driver -============= +PowerScale Driver +================= -The EMC manila driver framework (EMCShareDriver) utilizes EMC storage products +The EMC manila driver framework (EMCShareDriver) utilizes Dell storage products to provide shared filesystems to OpenStack. The EMC manila driver is a plugin -based driver which is designed to use different plugins to manage different EMC -storage products. +based driver which is designed to use different plugins to manage different +Dell storage products. -The Isilon manila driver is a plugin for the EMC manila driver framework which -allows manila to interface with an Isilon backend to provide a shared -filesystem. The EMC driver framework with the Isilon plugin is referred to as -the "Isilon Driver" in this document. +The PowerScale manila driver is a plugin for the EMC manila driver framework +which allows manila to interface with an PowerScale backend to provide a shared +filesystem. The EMC driver framework with the PowerScale plugin is referred to +as the "PowerScale Driver" in this document. -This Isilon Driver interfaces with an Isilon cluster via the REST Isilon -Platform API (PAPI) and the RESTful Access to Namespace API (RAN). +This PowerScale Driver interfaces with an PowerScale cluster via the REST +PowerScale Platform API (PAPI) and the RESTful Access to Namespace API (RAN). Requirements ------------ -- Isilon cluster running OneFS 7.2 or higher +- PowerScale cluster running OneFS 9.10 or higher Supported Operations -------------------- -The following operations are supported on an Isilon cluster: +The following operations are supported on an PowerScale cluster: * Create CIFS/NFS Share * Delete CIFS/NFS Share @@ -55,24 +55,24 @@ Backend Configuration --------------------- The following parameters need to be configured in the manila configuration file -for the Isilon driver: +for the PowerScale driver: * share_driver = manila.share.drivers.dell_emc.driver.EMCShareDriver * driver_handles_share_servers = False -* emc_share_backend = isilon -* emc_nas_server = -* emc_nas_server_port = +* emc_share_backend = powerscale +* emc_nas_server = +* emc_nas_server_port = * emc_nas_login = * emc_nas_password = * emc_nas_root_dir = -Restart of :term:`manila-share` service is needed for the configuration changes to take -effect. +Restart of :term:`manila-share` service is needed for the configuration changes +to take effect. Restrictions ------------ -The Isilon driver has the following restrictions: +The PowerScale driver has the following restrictions: - Only IP access type is supported for NFS and CIFS. @@ -87,10 +87,10 @@ The :mod:`manila.share.drivers.dell_emc.driver` Module :undoc-members: :show-inheritance: -The :mod:`manila.share.drivers.dell_emc.plugins.isilon.isilon` Module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The :mod:`manila.share.drivers.dell_emc.plugins.powerscale.powerscale` Module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. automodule:: manila.share.drivers.dell_emc.plugins.isilon.isilon +.. automodule:: manila.share.drivers.dell_emc.plugins.powerscale.powerscale :noindex: :members: :undoc-members: diff --git a/doc/source/admin/index.rst b/doc/source/admin/index.rst index 1df9a62ca8..8bd7531827 100644 --- a/doc/source/admin/index.rst +++ b/doc/source/admin/index.rst @@ -86,8 +86,8 @@ each back end. container_driver zfs_on_linux_driver netapp_cluster_mode_driver - emc_isilon_driver emc_vnx_driver + dell_emc_powerscale_driver ../configuration/shared-file-systems/drivers/dell-emc-unity-driver ../configuration/shared-file-systems/drivers/dell-emc-powerstore-driver ../configuration/shared-file-systems/drivers/dell-emc-powerflex-driver diff --git a/doc/source/admin/share_back_ends_feature_support_mapping.rst b/doc/source/admin/share_back_ends_feature_support_mapping.rst index 3498bff1be..f3d6504ec9 100644 --- a/doc/source/admin/share_back_ends_feature_support_mapping.rst +++ b/doc/source/admin/share_back_ends_feature_support_mapping.rst @@ -43,17 +43,17 @@ Mapping of share drivers and share features support +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ | NetApp Clustered Data ONTAP | J | L | L | L | J |same pool (J), across back ends (U)| N | O | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| Dell EMC PowerMax | O | \- | O | \- | O | O | \- | \- | \- | +| Dell PowerMax | O | \- | O | \- | O | O | \- | \- | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| EMC VNX | J | \- | \- | \- | J | J | \- | \- | \- | +| Dell VNX | J | \- | \- | \- | J | J | \- | \- | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| EMC Unity | N | U | N | S | N | N | U | S | \- | +| Dell Unity | N | U | N | S | N | N | U | S | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| EMC Isilon | K | \- | M | \- | K | K | \- | \- | \- | +| Dell PowerScale | K | \- | M | \- | K | K | \- | \- | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| Dell EMC PowerStore | B | \- | B | B | B | B | \- | B | \- | +| Dell PowerStore | B | \- | B | B | B | B | \- | B | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ -| Dell EMC PowerFlex | B | \- | B | \- | B | \- | \- | \- | \- | +| Dell PowerFlex | B | \- | B | \- | B | \- | \- | \- | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ | GlusterFS | J | \- | directory layout (T) | directory layout (T) | volume layout (L) | volume layout (L) | \- | \- | \- | +----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+-----------------------------------+--------------------------+--------------------+--------------------+ @@ -122,17 +122,17 @@ Mapping of share drivers and share access rules support +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ | NetApp Clustered Data ONTAP | NFS (J) | NFS (Q) | CIFS (J) | \- | \- | NFS (K) | NFS (Q) | CIFS (M) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| Dell EMC PowerMax | NFS (O) | NFS (R) | CIFS (O) | \- | \- | NFS (O) | NFS (R) | CIFS (O) | \- | \- | +| Dell PowerMax | NFS (O) | NFS (R) | CIFS (O) | \- | \- | NFS (O) | NFS (R) | CIFS (O) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| EMC VNX | NFS (J) | NFS (Q) | CIFS (J) | \- | \- | NFS (L) | NFS (Q) | CIFS (L) | \- | \- | +| Dell VNX | NFS (J) | NFS (Q) | CIFS (J) | \- | \- | NFS (L) | NFS (Q) | CIFS (L) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| EMC Unity | NFS (N) | NFS (Q) | CIFS (N) | \- | \- | NFS (N) | NFS (Q) | CIFS (N) | \- | \- | +| Dell Unity | NFS (N) | NFS (Q) | CIFS (N) | \- | \- | NFS (N) | NFS (Q) | CIFS (N) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| EMC Isilon | NFS,CIFS (K) | NFS (F) | CIFS (M) | \- | \- | NFS (M) | \- | CIFS (M) | \- | \- | +| Dell PowerScale | NFS,CIFS (K) | \- | CIFS (M) | \- | \- | NFS (M) | \- | CIFS (M) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| Dell EMC PowerStore | NFS (B) | \- | CIFS (B) | \- | \- | NFS (B) | \- | CIFS (B) | \- | \- | +| Dell PowerStore | NFS (B) | \- | CIFS (B) | \- | \- | NFS (B) | \- | CIFS (B) | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ -| Dell EMC PowerFlex | NFS (B) | \- | \- | \- | \- | NFS (B) | \- | \- | \- | \- | +| Dell PowerFlex | NFS (B) | \- | \- | \- | \- | NFS (B) | \- | \- | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ | GlusterFS | NFS (J) | \- | \- | \- | \- | \- | \- | \- | \- | \- | +----------------------------------------+--------------+--------------+----------------+------------+--------------+--------------+--------------+----------------+------------+------------+ @@ -199,17 +199,17 @@ Mapping of share drivers and security services support +----------------------------------------+------------------+-----------------+------------------+ | NetApp Clustered Data ONTAP | J | J | J | +----------------------------------------+------------------+-----------------+------------------+ -| Dell EMC PowerMax | O | \- | \- | +| Dell PowerMax | O | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| EMC VNX | J | \- | \- | +| Dell VNX | J | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| EMC Unity | N | \- | \- | +| Dell Unity | N | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| EMC Isilon | \- | \- | \- | +| EMC PowerScale | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| Dell EMC PowerStore | B | \- | \- | +| Dell PowerStore | B | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| Dell EMC PowerFlex | \- | \- | \- | +| Dell PowerFlex | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ | GlusterFS | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ @@ -278,17 +278,17 @@ More information: :ref:`capabilities_and_extra_specs` +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ | NetApp Clustered Data ONTAP | J | K | M | M | M | L | P | J | O | \- | P | Q | \- | Y | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| Dell EMC PowerMax | O | \- | \- | \- | \- | \- | \- | O | \- | \- | P | R | \- | \- | +| Dell PowerMax | O | \- | \- | \- | \- | \- | \- | O | \- | \- | P | R | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| EMC VNX | J | \- | \- | \- | \- | L | \- | J | \- | \- | P | Q | \- | \- | +| Dell VNX | J | \- | \- | \- | \- | L | \- | J | \- | \- | P | Q | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| EMC Unity | N | T | \- | \- | N | \- | \- | N | S | \- | P | Q | \- | \- | +| Dell Unity | N | T | \- | \- | N | \- | \- | N | S | \- | P | Q | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| EMC Isilon | \- | K | \- | \- | F | \- | \- | K | \- | \- | P | \- | \- | \- | +| Dell PowerScale | \- | K | \- | \- | \- | L | \- | K | \- | \- | P | \- | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| Dell EMC PowerStore | \- | B | \- | \- | B | \- | \- | B | B | \- | B | \- | \- | \- | +| Dell PowerStore | \- | B | \- | \- | B | \- | \- | B | B | \- | B | \- | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ -| Dell EMC PowerFlex | \- | B | \- | \- | B | \- | \- | \- | \- | \- | B | \- | \- | \- | +| Dell PowerFlex | \- | B | \- | \- | B | \- | \- | \- | \- | \- | B | \- | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ | GlusterFS | \- | J | \- | \- | \- | L | \- | volume layout (L) | \- | \- | P | \- | \- | \- | +----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+ diff --git a/doc/source/conf.py b/doc/source/conf.py index bdceef33ed..87b3671d92 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -87,7 +87,6 @@ master_doc = 'index' # General information about the project. copyright = '2010-present, Manila contributors' - # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None @@ -175,6 +174,9 @@ html_theme_options = { # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ['_static'] +# Add any paths that contain "extra" files, such as .htaccess. +html_extra_path = ['_extra'] + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' @@ -213,7 +215,6 @@ html_theme_options = { # Output file base name for HTML help builder. htmlhelp_basename = 'maniladoc' - # -- Options for LaTeX output ------------------------------------------------- # The paper size ('letter' or 'a4'). diff --git a/doc/source/configuration/shared-file-systems/drivers.rst b/doc/source/configuration/shared-file-systems/drivers.rst index 05c4a98d33..1ce1494a6a 100644 --- a/doc/source/configuration/shared-file-systems/drivers.rst +++ b/doc/source/configuration/shared-file-systems/drivers.rst @@ -23,7 +23,7 @@ Share drivers drivers/lvm-driver.rst drivers/zfs-on-linux-driver.rst drivers/zfssa-manila-driver.rst - drivers/emc-isilon-driver.rst + drivers/dell-emc-powerscale-driver.rst drivers/hitachi-hnas-driver.rst drivers/hitachi-hsp-driver.rst drivers/hpe-3par-share-driver.rst diff --git a/doc/source/configuration/shared-file-systems/drivers/dell-emc-powermax-driver.rst b/doc/source/configuration/shared-file-systems/drivers/dell-emc-powermax-driver.rst index f77d554deb..2ab75db991 100644 --- a/doc/source/configuration/shared-file-systems/drivers/dell-emc-powermax-driver.rst +++ b/doc/source/configuration/shared-file-systems/drivers/dell-emc-powermax-driver.rst @@ -276,7 +276,7 @@ The following parameters need to be configured in the - `emc_share_backend` The plug-in name. Set it to ``powermax`` for the PowerMax driver. - Other values are ``isilon``, ``vnx`` and ``unity``. + Other values are ``powerscale``, ``vnx`` and ``unity``. - `emc_nas_server` The control station IP address of the PowerMax system to be managed. diff --git a/doc/source/configuration/shared-file-systems/drivers/emc-isilon-driver.rst b/doc/source/configuration/shared-file-systems/drivers/dell-emc-powerscale-driver.rst similarity index 67% rename from doc/source/configuration/shared-file-systems/drivers/emc-isilon-driver.rst rename to doc/source/configuration/shared-file-systems/drivers/dell-emc-powerscale-driver.rst index 52abda7b4a..20107a04df 100644 --- a/doc/source/configuration/shared-file-systems/drivers/emc-isilon-driver.rst +++ b/doc/source/configuration/shared-file-systems/drivers/dell-emc-powerscale-driver.rst @@ -1,18 +1,19 @@ -================= -EMC Isilon driver -================= +====================== +Dell PowerScale driver +====================== The EMC Shared File Systems driver framework (EMCShareDriver) utilizes -EMC storage products to provide shared file systems to OpenStack. The +Dell storage products to provide shared file systems to OpenStack. The EMC driver is a plug-in based driver which is designed to use different -plug-ins to manage different EMC storage products. +plug-ins to manage different Dell storage products. -The Isilon driver is a plug-in for the EMC framework which allows the -Shared File Systems service to interface with an Isilon back end to -provide a shared filesystem. The EMC driver framework with the Isilon -plug-in is referred to as the ``Isilon Driver`` in this document. +The PowerScale driver is a plug-in for the EMC framework which allows the +Shared File Systems service to interface with an PowerScale back end to +provide a shared filesystem. The EMC driver framework with the PowerScale +plug-in is referred to as the ``PowerScale Driver`` in this document. -This Isilon Driver interfaces with an Isilon cluster via the REST Isilon +This PowerScale Driver interfaces with an PowerScale cluster via the REST +PowerScale Platform API (PAPI) and the RESTful Access to Namespace API (RAN). Requirements @@ -52,13 +53,13 @@ Back end configuration ~~~~~~~~~~~~~~~~~~~~~~ The following parameters need to be configured in the Shared File -Systems service configuration file for the Isilon driver: +Systems service configuration file for the PowerScale driver: .. code-block:: ini share_driver = manila.share.drivers.emc.driver.EMCShareDriver - emc_share_backend = isilon - emc_nas_server = + emc_share_backend = powerscale + emc_nas_server = emc_nas_login = emc_nas_password = @@ -75,7 +76,7 @@ Add the parameter below to set an advisory limit. Restrictions ~~~~~~~~~~~~ -The Isilon driver has the following restrictions: +The PowerScale driver has the following restrictions: - Only IP access type is supported for NFS and CIFS. diff --git a/manila/opts.py b/manila/opts.py index d0c8c8611b..c3860adc47 100644 --- a/manila/opts.py +++ b/manila/opts.py @@ -55,8 +55,8 @@ import manila.share.drivers.cephfs.driver import manila.share.drivers.container.driver import manila.share.drivers.container.storage_helper import manila.share.drivers.dell_emc.driver -import manila.share.drivers.dell_emc.plugins.isilon.isilon import manila.share.drivers.dell_emc.plugins.powermax.connection +import manila.share.drivers.dell_emc.plugins.powerscale.powerscale import manila.share.drivers.generic import manila.share.drivers.glusterfs import manila.share.drivers.glusterfs.common @@ -95,7 +95,6 @@ import manila.volume import manila.volume.cinder import manila.wsgi.eventlet_server - # List of *all* options in [DEFAULT] namespace of manila. # Any new option list or option needs to be registered here. _global_opt_lists = [ diff --git a/manila/share/drivers/dell_emc/driver.py b/manila/share/drivers/dell_emc/driver.py index be0745892f..d70701081a 100644 --- a/manila/share/drivers/dell_emc/driver.py +++ b/manila/share/drivers/dell_emc/driver.py @@ -42,7 +42,7 @@ EMC_NAS_OPTS = [ help='Use secure connection to server.'), cfg.StrOpt('emc_share_backend', ignore_case=True, - choices=['isilon', 'vnx', 'unity', 'powermax', + choices=['powerscale', 'isilon', 'vnx', 'unity', 'powermax', 'powerstore', 'powerflex'], help='Share backend.'), cfg.StrOpt('emc_nas_root_dir', @@ -81,6 +81,11 @@ class EMCShareDriver(driver.ShareDriver): if self.backend_name == 'vnx': LOG.warning('Dell EMC VNX share driver has been deprecated and is ' 'expected to be removed in a future release.') + if self.backend_name == 'isilon': + self.backend_name = 'powerscale' + LOG.warning('Dell EMC isilon share driver has been deprecated and ' + 'is renamed to powerscale.It is expected' + 'to be removed in a future release.') self.plugin = self.plugin_manager.load_plugin( self.backend_name, configuration=self.configuration) diff --git a/manila/share/drivers/dell_emc/plugins/isilon/__init__.py b/manila/share/drivers/dell_emc/plugins/powerscale/__init__.py similarity index 100% rename from manila/share/drivers/dell_emc/plugins/isilon/__init__.py rename to manila/share/drivers/dell_emc/plugins/powerscale/__init__.py diff --git a/manila/share/drivers/dell_emc/plugins/isilon/isilon.py b/manila/share/drivers/dell_emc/plugins/powerscale/powerscale.py similarity index 88% rename from manila/share/drivers/dell_emc/plugins/isilon/isilon.py rename to manila/share/drivers/dell_emc/plugins/powerscale/powerscale.py index a1040cf5d5..c6133073a6 100644 --- a/manila/share/drivers/dell_emc/plugins/isilon/isilon.py +++ b/manila/share/drivers/dell_emc/plugins/powerscale/powerscale.py @@ -14,7 +14,7 @@ # under the License. """ -Isilon specific NAS backend plugin. +PowerScale specific NAS backend plugin. """ import os @@ -26,7 +26,7 @@ from manila.common import constants as const from manila import exception from manila.i18n import _ from manila.share.drivers.dell_emc.plugins import base -from manila.share.drivers.dell_emc.plugins.isilon import isilon_api +from manila.share.drivers.dell_emc.plugins.powerscale import powerscale_api """Version history: 0.1.0 - Initial version @@ -34,8 +34,9 @@ from manila.share.drivers.dell_emc.plugins.isilon import isilon_api 1.0.1 - Add support for update share stats 1.0.2 - Add support for ensure shares 1.0.3 - Add support for thin provisioning + 1.0.4 - Rename isilon to powerscale """ -VERSION = "1.0.3" +VERSION = "1.0.4" CONF = cfg.CONF @@ -53,11 +54,11 @@ POWERSCALE_OPTS = [ ] -class IsilonStorageConnection(base.StorageConnection): - """Implements Isilon specific functionality for EMC Manila driver.""" +class PowerScaleStorageConnection(base.StorageConnection): + """Implements PowerScale specific functionality for EMC Manila driver.""" def __init__(self, *args, **kwargs): - super(IsilonStorageConnection, self).__init__(*args, **kwargs) + super(PowerScaleStorageConnection, self).__init__(*args, **kwargs) LOG.debug('Setting up attributes for Manila ' 'Dell PowerScale Driver.') if 'configuration' in kwargs: @@ -75,7 +76,7 @@ class IsilonStorageConnection(base.StorageConnection): self._shares = {} self._snapshots = {} - self._isilon_api = None + self._powerscale_api = None self.driver_handles_share_servers = False self.ipv6_implemented = True # props for share status update @@ -104,7 +105,7 @@ class IsilonStorageConnection(base.StorageConnection): # apply directory quota based on share size max_share_size = share['size'] * units.Gi - self._isilon_api.quota_create( + self._powerscale_api.quota_create( self._get_container_path(share), 'directory', max_share_size) return location @@ -118,7 +119,7 @@ class IsilonStorageConnection(base.StorageConnection): # Clone snapshot to new location fq_target_dir = self._get_container_path(share) - self._isilon_api.clone_snapshot(snapshot['name'], fq_target_dir) + self._powerscale_api.clone_snapshot(snapshot['name'], fq_target_dir) return location @@ -129,7 +130,7 @@ class IsilonStorageConnection(base.StorageConnection): container_path = self._get_container_path(share) self._create_directory(container_path) # Create nfs share - share_created = self._isilon_api.create_nfs_export(container_path) + share_created = self._powerscale_api.create_nfs_export(container_path) if not share_created: message = ( _('The requested NFS share "%(share)s" was not created.') % @@ -146,7 +147,7 @@ class IsilonStorageConnection(base.StorageConnection): container_path = self._get_container_path(share) self._create_directory(container_path) # Create smb share - share_created = self._isilon_api.create_smb_share( + share_created = self._powerscale_api.create_smb_share( share['name'], container_path) if not share_created: message = ( @@ -159,7 +160,7 @@ class IsilonStorageConnection(base.StorageConnection): def _create_directory(self, path, recursive=False): """Is called to create a directory.""" - dir_created = self._isilon_api.create_directory(path, recursive) + dir_created = self._powerscale_api.create_directory(path, recursive) if not dir_created: message = ( _('Failed to create directory "%(dir)s".') % @@ -171,7 +172,7 @@ class IsilonStorageConnection(base.StorageConnection): """Is called to create snapshot.""" LOG.debug(f'Creating snapshot {snapshot["name"]}.') snapshot_path = os.path.join(self._root_dir, snapshot['share_name']) - snap_created = self._isilon_api.create_snapshot( + snap_created = self._powerscale_api.create_snapshot( snapshot['name'], snapshot_path) if not snap_created: message = ( @@ -201,10 +202,10 @@ class IsilonStorageConnection(base.StorageConnection): def _delete_quota(self, path): """Is called to remove quota.""" - quota = self._isilon_api.quota_get(path, 'directory') + quota = self._powerscale_api.quota_get(path, 'directory') if quota: LOG.debug(f'Removing quota {quota["id"]}') - deleted = self._isilon_api.delete_quota(quota['id']) + deleted = self._powerscale_api.delete_quota(quota['id']) if not deleted: message = ( _('Failed to delete quota "%(quota_id)s" for ' @@ -216,10 +217,10 @@ class IsilonStorageConnection(base.StorageConnection): def _delete_directory(self, path): """Is called to remove directory.""" - path_exist = self._isilon_api.is_path_existent(path) + path_exist = self._powerscale_api.is_path_existent(path) if path_exist: LOG.debug(f'Removing directory {path}') - deleted = self._isilon_api.delete_path(path, recursive=True) + deleted = self._powerscale_api.delete_path(path, recursive=True) if not deleted: message = ( _('Failed to delete directory "%(dir)s".') % @@ -230,7 +231,7 @@ class IsilonStorageConnection(base.StorageConnection): def _delete_nfs_share(self, share): """Is called to remove nfs share.""" - share_id = self._isilon_api.lookup_nfs_export( + share_id = self._powerscale_api.lookup_nfs_export( self._get_container_path(share)) if share_id is None: @@ -239,7 +240,7 @@ class IsilonStorageConnection(base.StorageConnection): LOG.warning(lw, share['name']) else: # attempt to delete the share - export_deleted = self._isilon_api.delete_nfs_share(share_id) + export_deleted = self._powerscale_api.delete_nfs_share(share_id) if not export_deleted: message = _('Error deleting NFS share: %s') % share['name'] LOG.error(message) @@ -247,13 +248,14 @@ class IsilonStorageConnection(base.StorageConnection): def _delete_cifs_share(self, share): """Is called to remove CIFS share.""" - smb_share = self._isilon_api.lookup_smb_share(share['name']) + smb_share = self._powerscale_api.lookup_smb_share(share['name']) if smb_share is None: lw = ('Attempted to delete CIFS Share "%s", but the share does ' 'not appear to exist.') LOG.warning(lw, share['name']) else: - share_deleted = self._isilon_api.delete_smb_share(share['name']) + share_deleted = self._powerscale_api.delete_smb_share( + share['name']) if not share_deleted: message = _('Error deleting CIFS share: %s') % share['name'] LOG.error(message) @@ -262,7 +264,7 @@ class IsilonStorageConnection(base.StorageConnection): def delete_snapshot(self, context, snapshot, share_server): """Is called to remove snapshot.""" LOG.debug(f'Deleting snapshot {snapshot["name"]}') - deleted = self._isilon_api.delete_snapshot(snapshot['name']) + deleted = self._powerscale_api.delete_snapshot(snapshot['name']) if not deleted: message = ( _('Failed to delete snapshot "%(snap)s".') % @@ -280,7 +282,7 @@ class IsilonStorageConnection(base.StorageConnection): 'name': share['name'], 'size': new_size }) new_quota_size = new_size * units.Gi - self._isilon_api.quota_set( + self._powerscale_api.quota_set( self._get_container_path(share), 'directory', new_quota_size) def allow_access(self, context, share, access, share_server): @@ -295,7 +297,7 @@ class IsilonStorageConnection(base.StorageConnection): """Check for setup error.""" def connect(self, emc_share_driver, context): - """Connect to an Isilon cluster.""" + """Connect to an PowerScale cluster.""" LOG.debug('Reading configuration parameters for Manila' ' Dell PowerScale Driver.') config = emc_share_driver.configuration @@ -320,13 +322,13 @@ class IsilonStorageConnection(base.StorageConnection): if self._verify_ssl_cert: self._ssl_cert_path = config.safe_get("emc_ssl_cert_path") self._dir_permission = config.safe_get("powerscale_dir_permission") - self._isilon_api = isilon_api.IsilonApi( + self._powerscale_api = powerscale_api.PowerScaleApi( self._server_url, self._username, self._password, self._verify_ssl_cert, self._ssl_cert_path, self._dir_permission, self._threshold_limit) - if not self._isilon_api.is_path_existent(self._root_dir): + if not self._powerscale_api.is_path_existent(self._root_dir): self._create_directory(self._root_dir, recursive=True) # configuration for share status update @@ -367,11 +369,11 @@ class IsilonStorageConnection(base.StorageConnection): self.max_over_subscription_ratio, 'thin_provisioning': True, } - spaces = self._isilon_api.get_space_stats() + spaces = self._powerscale_api.get_space_stats() if spaces: pool_stat['total_capacity_gb'] = spaces['total'] // units.Gi pool_stat['free_capacity_gb'] = spaces['free'] // units.Gi - allocated_space = self._isilon_api.get_allocated_space() + allocated_space = self._powerscale_api.get_allocated_space() pool_stat['allocated_capacity_gb'] = allocated_space stats_dict['pools'] = [pool_stat] @@ -415,7 +417,7 @@ class IsilonStorageConnection(base.StorageConnection): elif rule['access_level'] == const.ACCESS_LEVEL_RO: nfs_ro_ips.add(rule['access_to']) - export_id = self._isilon_api.lookup_nfs_export( + export_id = self._powerscale_api.lookup_nfs_export( self._get_container_path(share)) if export_id is None: # share does not exist on backend (set all rules to error state) @@ -424,7 +426,7 @@ class IsilonStorageConnection(base.StorageConnection): LOG.error(message) return rule_state_map - r = self._isilon_api.modify_nfs_export_access( + r = self._powerscale_api.modify_nfs_export_access( export_id, ro_ips=list(nfs_ro_ips), rw_ips=list(nfs_rw_ips)) if not r: return rule_state_map @@ -449,20 +451,22 @@ class IsilonStorageConnection(base.StorageConnection): ) % {'type': rule['access_type']}) LOG.error(message) rule_state_map.update({rule['access_id']: {'state': 'error'}}) - ips = self._get_cifs_ip_list(ip_access_rules, rule_state_map) user_permissions = self._get_cifs_user_permissions( user_access_rules, rule_state_map) - share_updated = self._isilon_api.modify_smb_share_access( + share_updated = self._powerscale_api.modify_smb_share_access( share['name'], host_acl=ips, permissions=user_permissions) if not share_updated: message = ( - _('Failed to update access rules for CIFS share "%(share)s".' - ) % {'share': share['name']}) + _( + 'Failed to update access rules for CIFS share ' + '"%(share)s".' + ) % {'share': share['name']} + ) LOG.error(message) for rule in access_rules: rule_state_map[rule['access_id']] = { @@ -490,9 +494,9 @@ class IsilonStorageConnection(base.StorageConnection): cifs_user_permissions = [] for rule in access_rules: if rule['access_level'] == const.ACCESS_LEVEL_RW: - smb_permission = isilon_api.SmbPermission.rw + smb_permission = powerscale_api.SmbPermission.rw elif rule['access_level'] == const.ACCESS_LEVEL_RO: - smb_permission = isilon_api.SmbPermission.ro + smb_permission = powerscale_api.SmbPermission.ro else: message = ('Only RW and RO access levels are supported ' 'for CIFS user access.') @@ -500,7 +504,7 @@ class IsilonStorageConnection(base.StorageConnection): rule_state_map.update({rule['access_id']: {'state': 'error'}}) continue - user_sid = self._isilon_api.get_user_sid(rule['access_to']) + user_sid = self._powerscale_api.get_user_sid(rule['access_to']) if user_sid: cifs_user_permissions.append({ 'permission': smb_permission.value, @@ -521,7 +525,7 @@ class IsilonStorageConnection(base.StorageConnection): :returns: A dictionary containing driver-specific info. """ LOG.debug("Retrieving PowerScale backend info.") - cluster_version = self._isilon_api.get_cluster_version() + cluster_version = self._powerscale_api.get_cluster_version() return {'driver_version': VERSION, 'cluster_version': cluster_version, 'rest_server': self._server, @@ -538,7 +542,8 @@ class IsilonStorageConnection(base.StorageConnection): for share in shares: if share['share_proto'] == 'NFS': container_path = self._get_container_path(share) - share_id = self._isilon_api.lookup_nfs_export(container_path) + share_id = self._powerscale_api.lookup_nfs_export( + container_path) if share_id: location = self._format_nfs_path(container_path) updates[share['id']] = { @@ -549,7 +554,8 @@ class IsilonStorageConnection(base.StorageConnection): else: LOG.warning(f'NFS Share {share["name"]} is not found.') elif share['share_proto'] == 'CIFS': - smb_share = self._isilon_api.lookup_smb_share(share['name']) + smb_share = self._powerscale_api.lookup_smb_share( + share['name']) if smb_share: location = self._format_smb_path(share['name']) updates[share['id']] = { diff --git a/manila/share/drivers/dell_emc/plugins/isilon/isilon_api.py b/manila/share/drivers/dell_emc/plugins/powerscale/powerscale_api.py similarity index 99% rename from manila/share/drivers/dell_emc/plugins/isilon/isilon_api.py rename to manila/share/drivers/dell_emc/plugins/powerscale/powerscale_api.py index 4491937f45..1b521bc059 100644 --- a/manila/share/drivers/dell_emc/plugins/isilon/isilon_api.py +++ b/manila/share/drivers/dell_emc/plugins/powerscale/powerscale_api.py @@ -27,7 +27,7 @@ from manila.i18n import _ LOG = log.getLogger(__name__) -class IsilonApi(object): +class PowerScaleApi(object): def __init__(self, api_url, username, password, verify_ssl_cert=False, diff --git a/manila/tests/share/drivers/dell_emc/plugins/isilon/__init__.py b/manila/tests/share/drivers/dell_emc/plugins/powerscale/__init__.py similarity index 100% rename from manila/tests/share/drivers/dell_emc/plugins/isilon/__init__.py rename to manila/tests/share/drivers/dell_emc/plugins/powerscale/__init__.py diff --git a/manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon.py b/manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale.py similarity index 74% rename from manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon.py rename to manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale.py index ecefca70f3..a59f31e827 100644 --- a/manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon.py +++ b/manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale.py @@ -22,18 +22,18 @@ from oslo_utils import units from manila.common import constants as const from manila import exception from manila.i18n import _ -from manila.share.drivers.dell_emc.plugins.isilon import isilon +from manila.share.drivers.dell_emc.plugins.powerscale import powerscale from manila import test LOG = log.getLogger(__name__) @ddt.ddt -class IsilonTest(test.TestCase): - """Integration test for the Isilon Manila driver.""" +class PowerScaleTest(test.TestCase): + """Integration test for the PowerScale Manila driver.""" - ISILON_ADDR = '10.0.0.1' - API_URL = 'https://%s:8080' % ISILON_ADDR + POWERSCALE_ADDR = '10.0.0.1' + API_URL = 'https://%s:8080' % POWERSCALE_ADDR AUTH = ('admin', 'admin') ROOT_DIR = '/ifs/manila-test' @@ -75,14 +75,13 @@ class IsilonTest(test.TestCase): return None @mock.patch( - 'manila.share.drivers.dell_emc.plugins.isilon.isilon.isilon_api.' - 'IsilonApi', - autospec=True) + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.' + 'powerscale_api.PowerScaleApi', autospec=True) def setUp(self, mock_isi_api): - super(IsilonTest, self).setUp() + super(PowerScaleTest, self).setUp() - self._mock_isilon_api = mock_isi_api.return_value - self.storage_connection = isilon.IsilonStorageConnection(LOG) + self._mock_powerscale_api = mock_isi_api.return_value + self.storage_connection = powerscale.PowerScaleStorageConnection(LOG) self.mock_context = mock.Mock('Context') self.mock_emc_driver = mock.Mock('EmcDriver') @@ -113,8 +112,8 @@ class IsilonTest(test.TestCase): def test_create_share_nfs(self): share_path = self.SHARE_DIR - self.assertFalse(self._mock_isilon_api.create_directory.called) - self.assertFalse(self._mock_isilon_api.create_nfs_export.called) + self.assertFalse(self._mock_powerscale_api.create_directory.called) + self.assertFalse(self._mock_powerscale_api.create_nfs_export.called) # create the share share = {"name": self.SHARE_NAME, "share_proto": 'NFS', "size": 8} @@ -122,42 +121,42 @@ class IsilonTest(test.TestCase): share, None) # verify location and API call made - path = '%s:%s' % (self.ISILON_ADDR, self.SHARE_DIR) + path = '%s:%s' % (self.POWERSCALE_ADDR, self.SHARE_DIR) expected_location = [{'is_admin_only': False, 'metadata': {"preferred": True}, 'path': path}] self.assertEqual(expected_location, location) - self._mock_isilon_api.create_directory.assert_called_with( + self._mock_powerscale_api.create_directory.assert_called_with( share_path, False) - self._mock_isilon_api.create_nfs_export.assert_called_with(share_path) + self._mock_powerscale_api.create_nfs_export.assert_called_with( + share_path) # verify directory quota call made - self._mock_isilon_api.quota_create.assert_called_with( + self._mock_powerscale_api.quota_create.assert_called_with( share_path, 'directory', 8 * units.Gi) def test_create_share_cifs(self): - self.assertFalse(self._mock_isilon_api.create_directory.called) - self.assertFalse(self._mock_isilon_api.create_smb_share.called) + self.assertFalse(self._mock_powerscale_api.create_directory.called) + self.assertFalse(self._mock_powerscale_api.create_smb_share.called) # create the share share = {"name": self.SHARE_NAME, "share_proto": 'CIFS', "size": 8} location = self.storage_connection.create_share(self.mock_context, share, None) - - path = '\\\\{0}\\{1}'.format(self.ISILON_ADDR, self.SHARE_NAME) + path = '\\\\{0}\\{1}'.format(self.POWERSCALE_ADDR, self.SHARE_NAME) expected_location = [{'is_admin_only': False, 'metadata': {"preferred": True}, 'path': path}] self.assertEqual(expected_location, location) - self._mock_isilon_api.create_directory.assert_called_once_with( + self._mock_powerscale_api.create_directory.assert_called_once_with( self.SHARE_DIR, False) - self._mock_isilon_api.create_smb_share.assert_called_once_with( + self._mock_powerscale_api.create_smb_share.assert_called_once_with( self.SHARE_NAME, self.SHARE_DIR) # verify directory quota call made - self._mock_isilon_api.quota_create.assert_called_with( + self._mock_powerscale_api.quota_create.assert_called_with( self.SHARE_DIR, 'directory', 8 * units.Gi) def test_create_share_invalid_share_protocol(self): @@ -169,7 +168,7 @@ class IsilonTest(test.TestCase): def test_create_share_nfs_backend_failure(self): share = {"name": self.SHARE_NAME, "share_proto": 'NFS'} - self._mock_isilon_api.create_nfs_export.return_value = False + self._mock_powerscale_api.create_nfs_export.return_value = False self.assertRaises( exception.ShareBackendException, @@ -178,7 +177,7 @@ class IsilonTest(test.TestCase): def test_create_share_cifs_backend_failure(self): share = {"name": self.SHARE_NAME, "share_proto": 'CIFS'} - self._mock_isilon_api.create_smb_share.return_value = False + self._mock_powerscale_api.create_smb_share.return_value = False self.assertRaises( exception.ShareBackendException, @@ -187,7 +186,7 @@ class IsilonTest(test.TestCase): def test_create_directory_backend_failure(self): share = {"name": self.SHARE_NAME, "share_proto": 'NFS'} - self._mock_isilon_api.create_directory.return_value = False + self._mock_powerscale_api.create_directory.return_value = False self.assertRaises( exception.ShareBackendException, @@ -204,14 +203,14 @@ class IsilonTest(test.TestCase): None) # verify the create snapshot API call is executed - self._mock_isilon_api.create_snapshot.assert_called_with(snapshot_name, - snapshot_path) + self._mock_powerscale_api.create_snapshot.assert_called_with( + snapshot_name, snapshot_path) def test_create_snapshot_backend_failure(self): snapshot_name = "snapshot01" snapshot_path = '/ifs/home/admin' snapshot = {'name': snapshot_name, 'share_name': snapshot_path} - self._mock_isilon_api.create_snapshot.return_value = False + self._mock_powerscale_api.create_snapshot.return_value = False self.assertRaises( exception.ShareBackendException, @@ -220,8 +219,8 @@ class IsilonTest(test.TestCase): def test_create_share_from_snapshot_nfs(self): # assertions - self.assertFalse(self._mock_isilon_api.create_nfs_export.called) - self.assertFalse(self._mock_isilon_api.clone_snapshot.called) + self.assertFalse(self._mock_powerscale_api.create_nfs_export.called) + self.assertFalse(self._mock_powerscale_api.clone_snapshot.called) snapshot_name = "snapshot01" snapshot_path = '/ifs/home/admin' @@ -233,14 +232,14 @@ class IsilonTest(test.TestCase): self.mock_context, share, snapshot, None) # verify NFS export created at expected location - self._mock_isilon_api.create_nfs_export.assert_called_with( + self._mock_powerscale_api.create_nfs_export.assert_called_with( self.SHARE_DIR) # verify clone_directory(container_path) method called - self._mock_isilon_api.clone_snapshot.assert_called_once_with( + self._mock_powerscale_api.clone_snapshot.assert_called_once_with( snapshot_name, self.SHARE_DIR) path = '{0}:{1}'.format( - self.ISILON_ADDR, self.SHARE_DIR) + self.POWERSCALE_ADDR, self.SHARE_DIR) expected_location = {'is_admin_only': False, 'metadata': {"preferred": True}, 'path': path} @@ -248,13 +247,13 @@ class IsilonTest(test.TestCase): self.assertEqual(expected_location, location[0]) # verify directory quota call made - self._mock_isilon_api.quota_create.assert_called_with( + self._mock_powerscale_api.quota_create.assert_called_with( self.SHARE_DIR, 'directory', 5 * units.Gi) def test_create_share_from_snapshot_cifs(self): # assertions - self.assertFalse(self._mock_isilon_api.create_smb_share.called) - self.assertFalse(self._mock_isilon_api.clone_snapshot.called) + self.assertFalse(self._mock_powerscale_api.create_smb_share.called) + self.assertFalse(self._mock_powerscale_api.clone_snapshot.called) # setup snapshot_name = "snapshot01" snapshot_path = '/ifs/home/admin' @@ -267,11 +266,11 @@ class IsilonTest(test.TestCase): self.mock_context, share, snapshot, None) # verify call made to create new CIFS share - self._mock_isilon_api.create_smb_share.assert_called_once_with( + self._mock_powerscale_api.create_smb_share.assert_called_once_with( new_share_name, self.CLONE_DIR) - self._mock_isilon_api.clone_snapshot.assert_called_once_with( + self._mock_powerscale_api.clone_snapshot.assert_called_once_with( snapshot_name, self.CLONE_DIR) - path = '\\\\{0}\\{1}'.format(self.ISILON_ADDR, new_share_name) + path = '\\\\{0}\\{1}'.format(self.POWERSCALE_ADDR, new_share_name) expected_location = {'is_admin_only': False, 'metadata': {"preferred": True}, 'path': path} @@ -279,34 +278,36 @@ class IsilonTest(test.TestCase): # verify directory quota call made expected_share_path = '{0}/{1}'.format(self.ROOT_DIR, new_share_name) - self._mock_isilon_api.quota_create.assert_called_with( + self._mock_powerscale_api.quota_create.assert_called_with( expected_share_path, 'directory', 2 * units.Gi) def test_delete_share_nfs(self): share = {"name": self.SHARE_NAME, "share_proto": 'NFS'} fake_share_num = 42 - self._mock_isilon_api.lookup_nfs_export.return_value = fake_share_num - self.assertFalse(self._mock_isilon_api.delete_nfs_share.called) + self._mock_powerscale_api.lookup_nfs_export.return_value = ( + fake_share_num) + self.assertFalse(self._mock_powerscale_api.delete_nfs_share.called) # delete the share self.storage_connection.delete_share(self.mock_context, share, None) # verify share delete - self._mock_isilon_api.delete_nfs_share.assert_called_with( + self._mock_powerscale_api.delete_nfs_share.assert_called_with( fake_share_num) def test_delete_share_cifs(self): - self.assertFalse(self._mock_isilon_api.delete_smb_share.called) + self.assertFalse(self._mock_powerscale_api.delete_smb_share.called) # delete the share share = {"name": self.SHARE_NAME, "share_proto": 'CIFS'} self.storage_connection.delete_share(self.mock_context, share, None) # verify share deleted - self._mock_isilon_api.delete_smb_share.assert_called_with( + self._mock_powerscale_api.delete_smb_share.assert_called_with( self.SHARE_NAME) - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG') def test_delete_share_invalid_share_proto(self, mock_log): share = {"name": self.SHARE_NAME, "share_proto": 'FOO_PROTOCOL'} @@ -317,7 +318,7 @@ class IsilonTest(test.TestCase): def test_delete_nfs_share_backend_failure(self): share = {"name": self.SHARE_NAME, "share_proto": 'NFS'} - self._mock_isilon_api.delete_nfs_share.return_value = False + self._mock_powerscale_api.delete_nfs_share.return_value = False self.assertRaises( exception.ShareBackendException, self.storage_connection.delete_share, @@ -325,7 +326,7 @@ class IsilonTest(test.TestCase): ) def test_delete_nfs_share_share_does_not_exist(self): - self._mock_isilon_api.lookup_nfs_export.return_value = None + self._mock_powerscale_api.lookup_nfs_export.return_value = None share = {"name": self.SHARE_NAME, "share_proto": 'NFS'} # verify the calling delete on a non-existent share returns and does @@ -335,7 +336,7 @@ class IsilonTest(test.TestCase): def test_delete_cifs_share_backend_failure(self): share = {"name": self.SHARE_NAME, "share_proto": 'CIFS'} - self._mock_isilon_api.delete_smb_share.return_value = False + self._mock_powerscale_api.delete_smb_share.return_value = False self.assertRaises( exception.ShareBackendException, self.storage_connection.delete_share, @@ -344,37 +345,43 @@ class IsilonTest(test.TestCase): def test_delete_cifs_share_share_does_not_exist(self): share = {"name": self.SHARE_NAME, "share_proto": 'CIFS'} - self._mock_isilon_api.lookup_smb_share.return_value = None + self._mock_powerscale_api.lookup_smb_share.return_value = None # verify the calling delete on a non-existent share returns and does # not throw exception self.storage_connection.delete_share(self.mock_context, share, None) - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_quota_success(self, mock_log): path = '/path/to/quota' quota_id = '123' quota_data = {'id': quota_id} - self._mock_isilon_api.quota_get.return_value = quota_data - self._mock_isilon_api.delete_quota.return_value = True + self._mock_powerscale_api.quota_get.return_value = quota_data + self._mock_powerscale_api.delete_quota.return_value = True self.storage_connection._delete_quota(path) - self._mock_isilon_api.quota_get.assert_called_once_with( + self._mock_powerscale_api.quota_get.assert_called_once_with( path, 'directory') - self._mock_isilon_api.delete_quota.assert_called_once_with(quota_id) + self._mock_powerscale_api.delete_quota.assert_called_once_with( + quota_id) mock_log.debug.assert_called_once_with(f'Removing quota {quota_id}') mock_log.warning.assert_not_called() - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_quota_failure(self, mock_log): path = '/path/to/quota' quota_id = '123' quota_data = {'id': quota_id} - self._mock_isilon_api.quota_get.return_value = quota_data - self._mock_isilon_api.delete_quota.return_value = False + self._mock_powerscale_api.quota_get.return_value = quota_data + self._mock_powerscale_api.delete_quota.return_value = False self.storage_connection._delete_quota(path) - self._mock_isilon_api.quota_get.assert_called_once_with( + self._mock_powerscale_api.quota_get.assert_called_once_with( path, 'directory') - self._mock_isilon_api.delete_quota.assert_called_once_with(quota_id) + self._mock_powerscale_api.delete_quota.assert_called_once_with( + quota_id) mock_log.debug.assert_called_once_with(f'Removing quota {quota_id}') mock_log.error.assert_called_once_with( _('Failed to delete quota "%(quota_id)s" for ' @@ -382,35 +389,41 @@ class IsilonTest(test.TestCase): {'quota_id': quota_id, 'dir': path}) mock_log.warning.assert_not_called() - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_quota_not_found(self, mock_log): path = '/path/to/quota' - self._mock_isilon_api.quota_get.return_value = None + self._mock_powerscale_api.quota_get.return_value = None self.storage_connection._delete_quota(path) - self._mock_isilon_api.quota_get.assert_called_once_with( + self._mock_powerscale_api.quota_get.assert_called_once_with( path, 'directory') - self._mock_isilon_api.delete_quota.assert_not_called() + self._mock_powerscale_api.delete_quota.assert_not_called() mock_log.debug.assert_not_called() mock_log.warning.assert_called_once_with(f'Quota not found for {path}') - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_directory_success(self, mock_log): path = '/path/to/directory' - self._mock_isilon_api.is_path_existent.return_value = True - self._mock_isilon_api.delete_path.return_value = True + self._mock_powerscale_api.is_path_existent.return_value = True + self._mock_powerscale_api.delete_path.return_value = True self.storage_connection._delete_directory(path) - self._mock_isilon_api.delete_path.assert_called_once_with( + self._mock_powerscale_api.delete_path.assert_called_once_with( path, recursive=True) mock_log.debug.assert_called_once_with(f'Removing directory {path}') mock_log.warning.assert_not_called() - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_directory_failure(self, mock_log): path = '/path/to/directory' - self._mock_isilon_api.is_path_existent.return_value = True - self._mock_isilon_api.delete_path.return_value = False + self._mock_powerscale_api.is_path_existent.return_value = True + self._mock_powerscale_api.delete_path.return_value = False self.storage_connection._delete_directory(path) - self._mock_isilon_api.delete_path.assert_called_once_with( + self._mock_powerscale_api.delete_path.assert_called_once_with( path, recursive=True) mock_log.debug.assert_called_once_with(f'Removing directory {path}') mock_log.error.assert_called_once_with( @@ -418,12 +431,14 @@ class IsilonTest(test.TestCase): {'dir': path}) mock_log.warning.assert_not_called() - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.isilon.LOG') + @mock.patch( + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.LOG' + ) def test_delete_directory_not_found(self, mock_log): path = '/path/to/directory' - self._mock_isilon_api.is_path_existent.return_value = False + self._mock_powerscale_api.is_path_existent.return_value = False self.storage_connection._delete_directory(path) - self._mock_isilon_api.delete_path.assert_not_called() + self._mock_powerscale_api.delete_path.assert_not_called() mock_log.warning.assert_called_once_with( _('Directory not found for %s') % path) @@ -432,24 +447,24 @@ class IsilonTest(test.TestCase): snapshot_name = "snapshot01" snapshot_path = '/ifs/home/admin' snapshot = {'name': snapshot_name, 'share_name': snapshot_path} - self.assertFalse(self._mock_isilon_api.delete_snapshot.called) + self.assertFalse(self._mock_powerscale_api.delete_snapshot.called) # delete the created snapshot self.storage_connection.delete_snapshot(self.mock_context, snapshot, None) # verify the API call was made to delete the snapshot - self._mock_isilon_api.delete_snapshot.assert_called_once_with( + self._mock_powerscale_api.delete_snapshot.assert_called_once_with( snapshot_name) def test_delete_snapshot_failure(self): snapshot = {'name': 'test_snapshot'} - self._mock_isilon_api.delete_snapshot.return_value = False + self._mock_powerscale_api.delete_snapshot.return_value = False self.assertRaises( exception.ShareBackendException, self.storage_connection.delete_snapshot, self.mock_context, snapshot, None) - self._mock_isilon_api.delete_snapshot.assert_called_once_with( + self._mock_powerscale_api.delete_snapshot.assert_called_once_with( snapshot['name']) def test_ensure_share(self): @@ -459,11 +474,10 @@ class IsilonTest(test.TestCase): self.mock_context, share, None) @mock.patch( - 'manila.share.drivers.dell_emc.plugins.isilon.isilon.isilon_api.' - 'IsilonApi', - autospec=True) + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.' + 'powerscale_api.PowerScaleApi', autospec=True) def test_connect(self, mock_isi_api): - storage_connection = isilon.IsilonStorageConnection(LOG) + storage_connection = powerscale.PowerScaleStorageConnection(LOG) # execute method under test storage_connection.connect( @@ -488,18 +502,17 @@ class IsilonTest(test.TestCase): storage_connection._dir_permission) @mock.patch( - 'manila.share.drivers.dell_emc.plugins.isilon.isilon.isilon_api.' - 'IsilonApi', - autospec=True) + 'manila.share.drivers.dell_emc.plugins.powerscale.powerscale.' + 'powerscale_api.PowerScaleApi', autospec=True) def test_connect_root_dir_does_not_exist(self, mock_isi_api): - mock_isilon_api = mock_isi_api.return_value - mock_isilon_api.is_path_existent.return_value = False - storage_connection = isilon.IsilonStorageConnection(LOG) + mock_powerscale_api = mock_isi_api.return_value + mock_powerscale_api.is_path_existent.return_value = False + storage_connection = powerscale.PowerScaleStorageConnection(LOG) # call method under test storage_connection.connect(self.mock_emc_driver, self.mock_context) - mock_isilon_api.create_directory.assert_called_once_with( + mock_powerscale_api.create_directory.assert_called_once_with( self.ROOT_DIR, recursive=True) def test_connect_invalid_config(self): @@ -513,11 +526,11 @@ class IsilonTest(test.TestCase): ) def test_update_share_stats(self): - self._mock_isilon_api.get_space_stats.return_value = { + self._mock_powerscale_api.get_space_stats.return_value = { 'total': 1000 * units.Gi, 'free': 100 * units.Gi, } - self._mock_isilon_api.get_allocated_space.return_value = 2110.0 + self._mock_powerscale_api.get_allocated_space.return_value = 2110.0 stats_dict = {'share_backend_name': 'PowerScale_backend'} self.storage_connection.update_share_stats(stats_dict) @@ -535,7 +548,7 @@ class IsilonTest(test.TestCase): } expected_stats = { 'share_backend_name': 'PowerScale_backend', - 'driver_version': isilon.VERSION, + 'driver_version': powerscale.VERSION, 'storage_protocol': 'NFS_CIFS', 'pools': [expected_pool_stats] } @@ -555,14 +568,14 @@ class IsilonTest(test.TestCase): "share_proto": 'NFS', "size": new_share_size } - self._mock_isilon_api.quota_get.return_value = {'id': quota_id} - self.assertFalse(self._mock_isilon_api.quota_set.called) + self._mock_powerscale_api.quota_get.return_value = {'id': quota_id} + self.assertFalse(self._mock_powerscale_api.quota_set.called) self.storage_connection.extend_share(share, new_share_size) share_path = '{0}/{1}'.format(self.ROOT_DIR, self.SHARE_NAME) expected_quota_size = new_share_size * units.Gi - self._mock_isilon_api.quota_set.assert_called_once_with( + self._mock_powerscale_api.quota_set.assert_called_once_with( share_path, 'directory', expected_quota_size) def test_update_access_add_nfs(self): @@ -571,8 +584,9 @@ class IsilonTest(test.TestCase): "share_proto": 'NFS', } fake_export_id = 4 - self._mock_isilon_api.lookup_nfs_export.return_value = fake_export_id - self._mock_isilon_api.get_nfs_export.return_value = { + self._mock_powerscale_api.lookup_nfs_export.return_value = ( + fake_export_id) + self._mock_powerscale_api.get_nfs_export.return_value = { 'clients': [], 'read_only_clients': [] } @@ -583,7 +597,7 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [nfs_access] - self._mock_isilon_api.modify_nfs_export_access.return_value = True + self._mock_powerscale_api.modify_nfs_export_access.return_value = True rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], [], share_server=None) @@ -592,8 +606,8 @@ class IsilonTest(test.TestCase): 'state': 'active' } } - self._mock_isilon_api.modify_nfs_export_access.assert_called_once_with( - fake_export_id, [], ['10.1.1.10']) + self._mock_powerscale_api.modify_nfs_export_access. \ + assert_called_once_with(fake_export_id, [], ['10.1.1.10']) self.assertEqual(expected_rule_map, rule_map) def test_update_access_add_cifs(self): @@ -609,7 +623,7 @@ class IsilonTest(test.TestCase): } access_rules = [access] - self._mock_isilon_api.get_user_sid.return_value = { + self._mock_powerscale_api.get_user_sid.return_value = { 'id': 'SID:S-1-5-22', 'name': 'foo', 'type': 'user', @@ -628,8 +642,9 @@ class IsilonTest(test.TestCase): } } ] - self._mock_isilon_api.modify_smb_share_access.assert_called_once_with( - self.SHARE_NAME, host_acl=[], permissions=expected_permissions) + self._mock_powerscale_api.modify_smb_share_access.\ + assert_called_once_with( + self.SHARE_NAME, host_acl=[], permissions=expected_permissions) expected_rule_map = { '09960614-8574-4e03-89cf-7cf267b0bd08': { 'state': 'active' @@ -643,20 +658,21 @@ class IsilonTest(test.TestCase): "share_proto": 'NFS', } fake_export_id = 4 - self._mock_isilon_api.lookup_nfs_export.return_value = fake_export_id + self._mock_powerscale_api.lookup_nfs_export.return_value = ( + fake_export_id) # simulate an IP added to the whitelist ip_addr = '10.0.0.4' ip_addr_ro = '10.0.0.50' - self._mock_isilon_api.get_nfs_export.return_value = { + self._mock_powerscale_api.get_nfs_export.return_value = { 'clients': [ip_addr], 'read_only_clients': [ip_addr_ro]} access_rules = [] - self._mock_isilon_api.modify_nfs_export_access.return_value = True + self._mock_powerscale_api.modify_nfs_export_access.return_value = True rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) - self._mock_isilon_api.modify_nfs_export_access.assert_called_once_with( - fake_export_id, [], []) + self._mock_powerscale_api.modify_nfs_export_access. \ + assert_called_once_with(fake_export_id, [], []) self.assertEqual({}, rule_map) def test_update_access_delete_cifs(self): @@ -665,7 +681,7 @@ class IsilonTest(test.TestCase): "share_proto": 'CIFS', } access_rules = [] - self._mock_isilon_api.lookup_smb_share.return_value = { + self._mock_powerscale_api.lookup_smb_share.return_value = { 'permissions': [ { 'permission': 'change', @@ -680,12 +696,13 @@ class IsilonTest(test.TestCase): ] } - self._mock_isilon_api.modify_smb_share_access.return_value = None + self._mock_powerscale_api.modify_smb_share_access.return_value = None rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) - self._mock_isilon_api.modify_smb_share_access.assert_called_once_with( - self.SHARE_NAME, host_acl=[], permissions=[]) + self._mock_powerscale_api.modify_smb_share_access.\ + assert_called_once_with( + self.SHARE_NAME, host_acl=[], permissions=[]) self.assertEqual({}, rule_map) def test_update_access_nfs_share_not_found(self): @@ -700,7 +717,7 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [access] - self._mock_isilon_api.lookup_nfs_export.return_value = None + self._mock_powerscale_api.lookup_nfs_export.return_value = None rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) @@ -724,7 +741,7 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [access] - self._mock_isilon_api.modify_nfs_export_access.return_value = False + self._mock_powerscale_api.modify_nfs_export_access.return_value = False rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) @@ -748,7 +765,7 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [access] - self._mock_isilon_api.modify_smb_share_access.return_value = False + self._mock_powerscale_api.modify_smb_share_access.return_value = False rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, None, None) @@ -772,7 +789,7 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [access] - self._mock_isilon_api.modify_smb_share_access.return_value = True + self._mock_powerscale_api.modify_smb_share_access.return_value = True rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) @@ -796,8 +813,8 @@ class IsilonTest(test.TestCase): 'access_id': '09960614-8574-4e03-89cf-7cf267b0bd08' } access_rules = [access] - self._mock_isilon_api.get_user_sid.return_value = None - self._mock_isilon_api.modify_smb_share_access.return_value = True + self._mock_powerscale_api.get_user_sid.return_value = None + self._mock_powerscale_api.modify_smb_share_access.return_value = True rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) @@ -839,8 +856,9 @@ class IsilonTest(test.TestCase): "share_proto": 'NFS', } fake_export_id = 4 - self._mock_isilon_api.lookup_nfs_export.return_value = fake_export_id - self._mock_isilon_api.get_nfs_export.return_value = { + self._mock_powerscale_api.lookup_nfs_export.return_value = ( + fake_export_id) + self._mock_powerscale_api.get_nfs_export.return_value = { 'clients': ['10.1.1.8'], 'read_only_clients': ['10.2.0.2'] } @@ -858,7 +876,7 @@ class IsilonTest(test.TestCase): } access_rules = [nfs_access_1, nfs_access_2] - self._mock_isilon_api.modify_nfs_export_access.return_value = True + self._mock_powerscale_api.modify_nfs_export_access.return_value = True rule_map = self.storage_connection.update_access( self.mock_context, share, access_rules, [], []) @@ -871,8 +889,10 @@ class IsilonTest(test.TestCase): 'state': 'active' } } - self._mock_isilon_api.modify_nfs_export_access.assert_called_once_with( - fake_export_id, ['10.1.1.2'], ['10.1.1.10']) + self._mock_powerscale_api.modify_nfs_export_access. \ + assert_called_once_with(fake_export_id, + ['10.1.1.2'], + ['10.1.1.10']) self.assertEqual(expected_rule_map, rule_map) def test_update_access_recover_cifs(self): @@ -880,12 +900,12 @@ class IsilonTest(test.TestCase): "name": self.SHARE_NAME, "share_proto": 'CIFS', } - self._mock_isilon_api.get_user_sid.return_value = { + self._mock_powerscale_api.get_user_sid.return_value = { 'id': 'SID:S-1-5-22', 'name': 'testuser', 'type': 'user', } - self._mock_isilon_api.modify_smb_share_access.return_value = True + self._mock_powerscale_api.modify_smb_share_access.return_value = True access_1 = { 'access_type': 'ip', 'access_to': '10.1.1.10', @@ -925,13 +945,15 @@ class IsilonTest(test.TestCase): 'state': 'active' } } - self._mock_isilon_api.lookup_smb_share.assert_not_called() - self._mock_isilon_api.get_user_sid.assert_called_once_with('testuser') - self._mock_isilon_api.modify_smb_share_access.assert_called_once_with( - self.SHARE_NAME, - host_acl=expected_data['host_acl'], - permissions=expected_data['permissions'] - ) + self._mock_powerscale_api.lookup_smb_share.assert_not_called() + self._mock_powerscale_api.get_user_sid.assert_called_once_with( + 'testuser') + self._mock_powerscale_api.modify_smb_share_access.\ + assert_called_once_with( + self.SHARE_NAME, + host_acl=expected_data['host_acl'], + permissions=expected_data['permissions'] + ) self.assertEqual(expected_rule_map, rule_map) def test_update_access_with_cifs_ip_readonly(self): @@ -951,46 +973,47 @@ class IsilonTest(test.TestCase): path = '/path/to/quota' quota_id = '123' quota_data = {'id': quota_id} - self._mock_isilon_api.quota_get.return_value = quota_data - self._mock_isilon_api.delete_quota.return_value = True + self._mock_powerscale_api.quota_get.return_value = quota_data + self._mock_powerscale_api.delete_quota.return_value = True self.storage_connection._delete_quota(path) - self._mock_isilon_api.quota_get.assert_called_once_with( + self._mock_powerscale_api.quota_get.assert_called_once_with( path, 'directory') - self._mock_isilon_api.delete_quota.assert_called_once_with(quota_id) + self._mock_powerscale_api.delete_quota.assert_called_once_with( + quota_id) def test_delete_quota_when_quota_does_not_exist(self): path = '/path/to/quota' - self._mock_isilon_api.quota_get.return_value = None + self._mock_powerscale_api.quota_get.return_value = None self.storage_connection._delete_quota(path) - self._mock_isilon_api.quota_get.assert_called_once_with( + self._mock_powerscale_api.quota_get.assert_called_once_with( path, 'directory') - self._mock_isilon_api.delete_quota.assert_not_called() + self._mock_powerscale_api.delete_quota.assert_not_called() def test_delete_directory_when_path_exists(self): path = '/path/to/directory' self.storage_connection._delete_directory(path) - self._mock_isilon_api.is_path_existent.assert_called_with(path) - self._mock_isilon_api.delete_path.assert_called_with( + self._mock_powerscale_api.is_path_existent.assert_called_with(path) + self._mock_powerscale_api.delete_path.assert_called_with( path, recursive=True) def test_delete_directory_when_path_does_not_exist(self): path = '/path/to/directory' - self._mock_isilon_api.is_path_existent.return_value = False + self._mock_powerscale_api.is_path_existent.return_value = False self.storage_connection._delete_directory(path) - self._mock_isilon_api.is_path_existent.assert_called_with(path) - self._mock_isilon_api.delete_path.assert_not_called() + self._mock_powerscale_api.is_path_existent.assert_called_with(path) + self._mock_powerscale_api.delete_path.assert_not_called() def test_get_backend_info(self): - self._mock_isilon_api.get_cluster_version.return_value = '1.0' + self._mock_powerscale_api.get_cluster_version.return_value = '1.0' result = self.storage_connection.get_backend_info(None) expected_info = { - 'driver_version': isilon.VERSION, + 'driver_version': powerscale.VERSION, 'cluster_version': '1.0', - 'rest_server': self.ISILON_ADDR, + 'rest_server': self.POWERSCALE_ADDR, 'rest_port': '8080', } self.assertEqual(expected_info, result) @@ -1005,7 +1028,7 @@ class IsilonTest(test.TestCase): location = '10.0.0.1:/ifs/my_share' self.storage_connection._get_container_path = mock.MagicMock( return_value=container_path) - self._mock_isilon_api.lookup_nfs_export.return_value = '123' + self._mock_powerscale_api.lookup_nfs_export.return_value = '123' result = self.storage_connection.ensure_shares(None, [share]) expected_result = { @@ -1024,7 +1047,7 @@ class IsilonTest(test.TestCase): 'name': 'my_share', } location = '\\\\10.0.0.1\\my_share' - self._mock_isilon_api.lookup_smb_share.return_value = share + self._mock_powerscale_api.lookup_smb_share.return_value = share result = self.storage_connection.ensure_shares(None, [share]) expected_result = { @@ -1042,7 +1065,7 @@ class IsilonTest(test.TestCase): 'share_proto': 'NFS', 'name': 'my_share', } - self._mock_isilon_api.lookup_nfs_export.return_value = None + self._mock_powerscale_api.lookup_nfs_export.return_value = None result = self.storage_connection.ensure_shares(None, [share]) expected_result = { '123': { @@ -1059,7 +1082,7 @@ class IsilonTest(test.TestCase): 'share_proto': 'CIFS', 'name': 'my_share', } - self._mock_isilon_api.lookup_smb_share.return_value = None + self._mock_powerscale_api.lookup_smb_share.return_value = None result = self.storage_connection.ensure_shares(None, [share]) expected_result = { '123': { diff --git a/manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon_api.py b/manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale_api.py similarity index 78% rename from manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon_api.py rename to manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale_api.py index cfdd2de993..341bf0ec2e 100644 --- a/manila/tests/share/drivers/dell_emc/plugins/isilon/test_isilon_api.py +++ b/manila/tests/share/drivers/dell_emc/plugins/powerscale/test_powerscale_api.py @@ -21,40 +21,40 @@ import requests import requests_mock from manila import exception -from manila.share.drivers.dell_emc.plugins.isilon import isilon_api +from manila.share.drivers.dell_emc.plugins.powerscale import powerscale_api from manila import test @ddt.ddt -class IsilonApiTest(test.TestCase): +class PowerScaleApiTest(test.TestCase): - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.' - 'isilon_api.IsilonApi.create_session') + @mock.patch('manila.share.drivers.dell_emc.plugins.powerscale.' + 'powerscale_api.PowerScaleApi.create_session') def setUp(self, mockup_create_session): - super(IsilonApiTest, self).setUp() + super(PowerScaleApiTest, self).setUp() mockup_create_session.return_value = True self._mock_url = 'https://localhost:8080' self.username = 'admin' self.password = 'pwd' self.dir_permission = '0777' - self.isilon_api = isilon_api.IsilonApi( + self.powerscale_api = powerscale_api.PowerScaleApi( self._mock_url, self.username, self.password, dir_permission=self.dir_permission ) - self.isilon_api_threshold = isilon_api.IsilonApi( + self.powerscale_api_threshold = powerscale_api.PowerScaleApi( self._mock_url, self.username, self.password, dir_permission=self.dir_permission, threshold_limit=80 ) - @mock.patch('manila.share.drivers.dell_emc.plugins.isilon.' - 'isilon_api.IsilonApi.create_session') + @mock.patch('manila.share.drivers.dell_emc.plugins.powerscale.' + 'powerscale_api.PowerScaleApi.create_session') def test__init__login_failure(self, mockup_create_session): mockup_create_session.return_value = False self.assertRaises( exception.BadConfigurationException, - self.isilon_api.__init__, + self.powerscale_api.__init__, self._mock_url, self.username, self.password, @@ -64,14 +64,14 @@ class IsilonApiTest(test.TestCase): ) def test__verify_cert(self): - verify_cert = self.isilon_api.verify_ssl_cert - certificate_path = self.isilon_api.certificate_path - self.isilon_api.verify_ssl_cert = True - self.isilon_api.certificate_path = "fake_certificate_path" - self.assertEqual(self.isilon_api._verify_cert, - self.isilon_api.certificate_path) - self.isilon_api.verify_ssl_cert = verify_cert - self.isilon_api.certificate_path = certificate_path + verify_cert = self.powerscale_api.verify_ssl_cert + certificate_path = self.powerscale_api.certificate_path + self.powerscale_api.verify_ssl_cert = True + self.powerscale_api.certificate_path = "fake_certificate_path" + self.assertEqual(self.powerscale_api._verify_cert, + self.powerscale_api.certificate_path) + self.powerscale_api.verify_ssl_cert = verify_cert + self.powerscale_api.certificate_path = certificate_path @mock.patch('requests.Session.request') def test_create_session_success(self, mock_request): @@ -80,7 +80,8 @@ class IsilonApiTest(test.TestCase): mock_response.cookies = {'isisessid': 'test_session_token', 'isicsrf': 'test_csrf_token'} mock_request.return_value = mock_response - result = self.isilon_api.create_session(self.username, self.password) + result = self.powerscale_api.create_session( + self.username, self.password) mock_request.assert_called_once_with( 'POST', self._mock_url + '/session/1/session', headers={"Content-type": "application/json"}, @@ -90,8 +91,9 @@ class IsilonApiTest(test.TestCase): verify=False ) self.assertTrue(result) - self.assertEqual(self.isilon_api.session_token, 'test_session_token') - self.assertEqual(self.isilon_api.csrf_token, 'test_csrf_token') + self.assertEqual(self.powerscale_api.session_token, + 'test_session_token') + self.assertEqual(self.powerscale_api.csrf_token, 'test_csrf_token') @mock.patch('requests.Session.request') def test_create_session_failure(self, mock_request): @@ -100,10 +102,11 @@ class IsilonApiTest(test.TestCase): mock_response.json.return_value = { 'message': 'Username or password is incorrect.'} mock_request.return_value = mock_response - result = self.isilon_api.create_session(self.username, self.password) + result = self.powerscale_api.create_session( + self.username, self.password) self.assertFalse(result) - self.assertIsNone(self.isilon_api.session_token) - self.assertIsNone(self.isilon_api.csrf_token) + self.assertIsNone(self.powerscale_api.session_token) + self.assertIsNone(self.powerscale_api.csrf_token) @ddt.data(False, True) def test_create_directory(self, is_recursive): @@ -112,8 +115,8 @@ class IsilonApiTest(test.TestCase): self.assertEqual(0, len(m.request_history)) self._add_create_directory_response(m, path, is_recursive) - r = self.isilon_api.create_directory(path, - recursive=is_recursive) + r = self.powerscale_api.create_directory(path, + recursive=is_recursive) self.assertTrue(r) self.assertEqual(1, len(m.request_history)) @@ -123,14 +126,14 @@ class IsilonApiTest(test.TestCase): def test_create_directory_no_permission(self): with requests_mock.Mocker() as m: path = '/ifs/test' - self.isilon_api.dir_permission = None + self.powerscale_api.dir_permission = None self.assertEqual(0, len(m.request_history)) self._add_create_directory_response(m, path, True) - r = self.isilon_api.create_directory(path, - recursive=True) + r = self.powerscale_api.create_directory(path, + recursive=True) - self.isilon_api.dir_permission = '0777' + self.powerscale_api.dir_permission = '0777' self.assertTrue(r) self.assertEqual(1, len(m.request_history)) request = m.request_history[0] @@ -195,7 +198,7 @@ class IsilonApiTest(test.TestCase): snapshot_name) # Call method under test - self.isilon_api.clone_snapshot(snapshot_name, fq_target_dir) + self.powerscale_api.clone_snapshot(snapshot_name, fq_target_dir) # Verify calls needed to clone the source snapshot to the target dir expected_calls = [] @@ -203,8 +206,8 @@ class IsilonApiTest(test.TestCase): 'file1', 'file2', 'dir1/file11', 'dir1/file12', 'dir2/file21', 'dir2/file22'] for path in clone_path_list: - expected_call = IsilonApiTest.ExpectedCall( - IsilonApiTest.ExpectedCall.FILE_CLONE, + expected_call = PowerScaleApiTest.ExpectedCall( + PowerScaleApiTest.ExpectedCall.FILE_CLONE, self._mock_url + '/namespace/ifs/admin/target/' + path, ['/ifs/admin/target/' + path, '/ifs/admin/source/' + path, snapshot_name]) @@ -214,8 +217,8 @@ class IsilonApiTest(test.TestCase): ('/dir2?recursive', '/dir2'), ('?recursive=', '')] for url, path in dir_path_list: - expected_call = IsilonApiTest.ExpectedCall( - IsilonApiTest.ExpectedCall.DIR_CREATION, + expected_call = PowerScaleApiTest.ExpectedCall( + PowerScaleApiTest.ExpectedCall.DIR_CREATION, self._mock_url + '/namespace/ifs/admin/target' + url, ['/ifs/admin/target' + path, False]) expected_calls.append(expected_call) @@ -258,7 +261,7 @@ class IsilonApiTest(test.TestCase): json_str = '{"my_json": "test123"}' self._add_get_directory_listing_response(m, fq_dir_path, json_str) - actual_json = self.isilon_api.get_directory_listing(fq_dir_path) + actual_json = self.powerscale_api.get_directory_listing(fq_dir_path) self.assertEqual(1, len(m.request_history)) self.assertEqual(json.loads(json_str), actual_json) @@ -272,7 +275,7 @@ class IsilonApiTest(test.TestCase): m.head('{0}/namespace{1}'.format(self._mock_url, path), status_code=status_code) - r = self.isilon_api.is_path_existent(path) + r = self.powerscale_api.is_path_existent(path) self.assertEqual(expected_return_value, r) self.assertEqual(1, len(m.request_history)) @@ -284,7 +287,8 @@ class IsilonApiTest(test.TestCase): status_code=400) self.assertRaises( - requests.exceptions.HTTPError, self.isilon_api.is_path_existent, + requests.exceptions.HTTPError, + self.powerscale_api.is_path_existent, '/ifs/home/admin') @ddt.data( @@ -300,7 +304,7 @@ class IsilonApiTest(test.TestCase): self._add_get_snapshot_response(m, snapshot_name, json_body, status=status_code) - r = self.isilon_api.get_snapshot(snapshot_name) + r = self.powerscale_api.get_snapshot(snapshot_name) self.assertEqual(1, len(m.request_history)) self.assertEqual(expected_return_value, r) @@ -313,7 +317,7 @@ class IsilonApiTest(test.TestCase): m, snapshot_name, json_body, status=400) self.assertRaises( - requests.exceptions.HTTPError, self.isilon_api.get_snapshot, + requests.exceptions.HTTPError, self.powerscale_api.get_snapshot, snapshot_name) @requests_mock.mock() @@ -323,7 +327,7 @@ class IsilonApiTest(test.TestCase): m.get('{0}/platform/1/snapshot/snapshots'.format(self._mock_url), status_code=200, json=json.loads(snapshot_json)) - r = self.isilon_api.get_snapshots() + r = self.powerscale_api.get_snapshots() self.assertEqual(1, len(m.request_history)) self.assertEqual(json.loads(snapshot_json), r) @@ -335,7 +339,7 @@ class IsilonApiTest(test.TestCase): status_code=404) self.assertRaises(requests.exceptions.HTTPError, - self.isilon_api.get_snapshots) + self.powerscale_api.get_snapshots) self.assertEqual(1, len(m.request_history)) @@ -355,7 +359,7 @@ class IsilonApiTest(test.TestCase): share_path.replace('/', '%2F')), json=json.loads(response_json)) - r = self.isilon_api.lookup_nfs_export(share_path) + r = self.powerscale_api.lookup_nfs_export(share_path) self.assertEqual(1, len(m.request_history)) self.assertEqual(expected_return, r) @@ -370,7 +374,7 @@ class IsilonApiTest(test.TestCase): .format(self._mock_url, export_id), json=json.loads(response_json), status_code=status_code) - r = self.isilon_api.get_nfs_export(export_id) + r = self.powerscale_api.get_nfs_export(export_id) self.assertEqual(1, len(m.request_history)) self.assertEqual(json.loads('{"id": 1}'), r) @@ -385,7 +389,7 @@ class IsilonApiTest(test.TestCase): .format(self._mock_url, export_id), json=json.loads(response_json), status_code=status_code) - r = self.isilon_api.get_nfs_export(export_id) + r = self.powerscale_api.get_nfs_export(export_id) self.assertEqual(1, len(m.request_history)) self.assertIsNone(r) @@ -400,7 +404,7 @@ class IsilonApiTest(test.TestCase): .format(self._mock_url, share_name), status_code=200, json=json.loads(response_json)) - r = self.isilon_api.lookup_smb_share(share_name) + r = self.powerscale_api.lookup_smb_share(share_name) self.assertEqual(1, len(m.request_history)) self.assertEqual(json.loads(share_json), r) @@ -412,7 +416,7 @@ class IsilonApiTest(test.TestCase): m.get('{0}/platform/1/protocols/smb/shares/{1}'.format( self._mock_url, share_name), status_code=404) - r = self.isilon_api.lookup_smb_share(share_name) + r = self.powerscale_api.lookup_smb_share(share_name) self.assertEqual(1, len(m.request_history)) self.assertIsNone(r) @@ -426,7 +430,7 @@ class IsilonApiTest(test.TestCase): m.post(self._mock_url + '/platform/1/protocols/nfs/exports', status_code=status_code) - r = self.isilon_api.create_nfs_export(export_path) + r = self.powerscale_api.create_nfs_export(export_path) self.assertEqual(1, len(m.request_history)) call = m.request_history[0] @@ -445,7 +449,7 @@ class IsilonApiTest(test.TestCase): m.post(self._mock_url + '/platform/1/protocols/smb/shares', status_code=status_code) - r = self.isilon_api.create_smb_share(share_name, share_path) + r = self.powerscale_api.create_smb_share(share_name, share_path) self.assertEqual(expected_return_value, r) self.assertEqual(1, len(m.request_history)) @@ -465,7 +469,7 @@ class IsilonApiTest(test.TestCase): m.post(self._mock_url + '/platform/1/snapshot/snapshots', status_code=201) - r = self.isilon_api.create_snapshot(snapshot_name, snapshot_path) + r = self.powerscale_api.create_snapshot(snapshot_name, snapshot_path) self.assertEqual(1, len(m.request_history)) self.assertTrue(r) @@ -485,7 +489,7 @@ class IsilonApiTest(test.TestCase): status_code=404) self.assertEqual( - self.isilon_api.create_snapshot(snapshot_name, snapshot_path), + self.powerscale_api.create_snapshot(snapshot_name, snapshot_path), False ) @@ -497,7 +501,8 @@ class IsilonApiTest(test.TestCase): m.delete(self._mock_url + '/namespace' + fq_path + '?recursive=' + str(is_recursive_delete), status_code=204) - self.isilon_api.delete_path(fq_path, recursive=is_recursive_delete) + self.powerscale_api.delete_path( + fq_path, recursive=is_recursive_delete) self.assertEqual(1, len(m.request_history)) @@ -507,8 +512,9 @@ class IsilonApiTest(test.TestCase): m.delete(self._mock_url + '/namespace' + fq_path + '?recursive=False', status_code=403) - self.assertEqual(self.isilon_api.delete_path(fq_path, recursive=False), - False) + self.assertEqual( + self.powerscale_api.delete_path( + fq_path, recursive=False), False) @ddt.data((204, True), (404, False)) def test_delete_nfs_share(self, data): @@ -520,7 +526,7 @@ class IsilonApiTest(test.TestCase): .format(self._mock_url, share_number), status_code=status_code) - r = self.isilon_api.delete_nfs_share(share_number) + r = self.powerscale_api.delete_nfs_share(share_number) self.assertEqual(1, len(m.request_history)) self.assertEqual(expected_return_value, r) @@ -536,7 +542,7 @@ class IsilonApiTest(test.TestCase): .format(self._mock_url, share_name), status_code=status_code) - r = self.isilon_api.delete_smb_share(share_name) + r = self.powerscale_api.delete_smb_share(share_name) self.assertEqual(1, len(m.request_history)) self.assertEqual(expected_return_value, r) @@ -547,7 +553,7 @@ class IsilonApiTest(test.TestCase): m.delete(self._mock_url + '/platform/1/snapshot/snapshots/my_snapshot', status_code=204) - self.isilon_api.delete_snapshot("my_snapshot") + self.powerscale_api.delete_snapshot("my_snapshot") self.assertEqual(1, len(m.request_history)) @@ -557,7 +563,7 @@ class IsilonApiTest(test.TestCase): status_code=403) self.assertEqual( - self.isilon_api.delete_snapshot("my_snapshot"), False) + self.powerscale_api.delete_snapshot("my_snapshot"), False) @requests_mock.mock() def test_quota_create(self, m): @@ -566,7 +572,7 @@ class IsilonApiTest(test.TestCase): self.assertEqual(0, len(m.request_history)) m.post(self._mock_url + '/platform/1/quota/quotas', status_code=201) - self.isilon_api.quota_create(quota_path, 'directory', quota_size) + self.powerscale_api.quota_create(quota_path, 'directory', quota_size) self.assertEqual(1, len(m.request_history)) expected_request_json = { @@ -586,11 +592,14 @@ class IsilonApiTest(test.TestCase): quota_size = 100 self.assertEqual(0, len(m.request_history)) m.post(self._mock_url + '/platform/1/quota/quotas', status_code=201) - self.isilon_api_threshold.quota_create(quota_path, - 'directory', - quota_size) + self.powerscale_api_threshold.quota_create( + quota_path, + 'directory', + quota_size + ) + advisory_size = round( - (quota_size * self.isilon_api_threshold.threshold_limit) / 100) + (quota_size * self.powerscale_api_threshold.threshold_limit) / 100) self.assertEqual(1, len(m.request_history)) expected_request_json = { 'path': quota_path, @@ -612,7 +621,7 @@ class IsilonApiTest(test.TestCase): self.assertRaises( requests.exceptions.HTTPError, - self.isilon_api.quota_create, + self.powerscale_api.quota_create, quota_path, 'directory', 2 ) @@ -625,7 +634,7 @@ class IsilonApiTest(test.TestCase): quota_path = "/ifs/manila/test" quota_type = "directory" - self.isilon_api.quota_get(quota_path, quota_type) + self.powerscale_api.quota_get(quota_path, quota_type) self.assertEqual(1, len(m.request_history)) request_query_string = m.request_history[0].qs @@ -637,7 +646,7 @@ class IsilonApiTest(test.TestCase): self.assertEqual(0, len(m.request_history)) m.get(self._mock_url + '/platform/1/quota/quotas', status_code=404) - response = self.isilon_api.quota_get( + response = self.powerscale_api.quota_get( '/ifs/does_not_exist', 'directory') self.assertIsNone(response) @@ -650,7 +659,7 @@ class IsilonApiTest(test.TestCase): m.put('{0}/platform/1/quota/quotas/{1}'.format( self._mock_url, quota_id), status_code=204) - self.isilon_api.quota_modify_size(quota_id, new_size) + self.powerscale_api.quota_modify_size(quota_id, new_size) self.assertEqual(1, len(m.request_history)) expected_request_body = {'thresholds': {'hard': new_size}} @@ -663,10 +672,10 @@ class IsilonApiTest(test.TestCase): quota_id = "ADEF1G" new_size = 1024 advisory_size = round( - (new_size * self.isilon_api_threshold.threshold_limit) / 100) + (new_size * self.powerscale_api_threshold.threshold_limit) / 100) m.put('{0}/platform/1/quota/quotas/{1}'.format( self._mock_url, quota_id), status_code=204) - self.isilon_api_threshold.quota_modify_size(quota_id, new_size) + self.powerscale_api_threshold.quota_modify_size(quota_id, new_size) self.assertEqual(1, len(m.request_history)) expected_request_body = {'thresholds': {'hard': new_size, 'advisory': advisory_size}} @@ -681,7 +690,7 @@ class IsilonApiTest(test.TestCase): self.assertRaises( requests.exceptions.HTTPError, - self.isilon_api.quota_modify_size, + self.powerscale_api.quota_modify_size, quota_id, 1024 ) @@ -700,7 +709,7 @@ class IsilonApiTest(test.TestCase): status_code=204 ) - self.isilon_api.quota_set(quota_path, quota_type, quota_size) + self.powerscale_api.quota_set(quota_path, quota_type, quota_size) expected_quota_modify_json = {'thresholds': {'hard': quota_size}} quota_put_json = json.loads(m.request_history[1].body) @@ -717,7 +726,7 @@ class IsilonApiTest(test.TestCase): quota_type = 'directory' quota_size = 256 - self.isilon_api.quota_set(quota_path, quota_type, quota_size) + self.powerscale_api.quota_set(quota_path, quota_type, quota_size) # verify a call is made to create a quota expected_create_json = { @@ -737,7 +746,7 @@ class IsilonApiTest(test.TestCase): e = self.assertRaises( requests.exceptions.HTTPError, - self.isilon_api.quota_set, + self.powerscale_api.quota_set, '/ifs/does_not_exist', 'directory', 2048 ) self.assertEqual(400, e.response.status_code) @@ -746,29 +755,29 @@ class IsilonApiTest(test.TestCase): sid = {"id": "SID:S-1-22-1-0", "name": "foo", "type": "user"} - self.isilon_api.auth_lookup_user = mock.MagicMock( + self.powerscale_api.auth_lookup_user = mock.MagicMock( return_value={ "mapping": [{"user": {"sid": sid}}] } ) - expected_sid = self.isilon_api.get_user_sid('foo') + expected_sid = self.powerscale_api.get_user_sid('foo') self.assertEqual(expected_sid, sid) def test_get_user_sid_wrong_mappings(self): - self.isilon_api.auth_lookup_user = mock.MagicMock( + self.powerscale_api.auth_lookup_user = mock.MagicMock( return_value={ "mapping": [{"user": {"sid": 'fake_sid1'}}, {"user": {"sid": 'fake_sid2'}}] } ) - expected_sid = self.isilon_api.get_user_sid('foo') + expected_sid = self.powerscale_api.get_user_sid('foo') self.assertIsNone(expected_sid) def test_get_user_sid_user_not_found(self): - self.isilon_api.auth_lookup_user = mock.MagicMock( + self.powerscale_api.auth_lookup_user = mock.MagicMock( return_value=None ) - expected_sid = self.isilon_api.get_user_sid('foo') + expected_sid = self.powerscale_api.get_user_sid('foo') self.assertIsNone(expected_sid) @requests_mock.mock() @@ -789,7 +798,7 @@ class IsilonApiTest(test.TestCase): } m.get(auth_url, status_code=200, json=auth_json) - returned_auth_json = self.isilon_api.auth_lookup_user(user) + returned_auth_json = self.powerscale_api.auth_lookup_user(user) self.assertEqual(auth_json, returned_auth_json) @requests_mock.mock() @@ -798,7 +807,7 @@ class IsilonApiTest(test.TestCase): auth_url = '{0}/platform/1/auth/mapping/users/lookup?user={1}'.format( self._mock_url, user) m.get(auth_url, status_code=404) - self.assertIsNone(self.isilon_api.auth_lookup_user(user)) + self.assertIsNone(self.powerscale_api.auth_lookup_user(user)) @requests_mock.mock() def test_auth_lookup_user_with_backend_error(self, m): @@ -806,7 +815,7 @@ class IsilonApiTest(test.TestCase): auth_url = '{0}/platform/1/auth/mapping/users/lookup?user={1}'.format( self._mock_url, user) m.get(auth_url, status_code=400) - self.assertIsNone(self.isilon_api.auth_lookup_user(user)) + self.assertIsNone(self.powerscale_api.auth_lookup_user(user)) def _add_create_directory_response(self, m, path, is_recursive): url = '{0}/namespace{1}?recursive={2}'.format( @@ -854,87 +863,87 @@ class IsilonApiTest(test.TestCase): request.headers['x-isi-ifs-copy-source']) def test_modify_nfs_export_access_success(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_id = '123' ro_ips = ['10.0.0.1', '10.0.0.2'] rw_ips = ['10.0.0.3', '10.0.0.4'] - self.isilon_api.modify_nfs_export_access(share_id, ro_ips, rw_ips) + self.powerscale_api.modify_nfs_export_access(share_id, ro_ips, rw_ips) expected_url = '{0}/platform/1/protocols/nfs/exports/{1}'.format( - self.isilon_api.host_url, share_id) + self.powerscale_api.host_url, share_id) expected_data = {'read_only_clients': ro_ips, 'clients': rw_ips} - self.isilon_api.send_put_request.assert_called_once_with( + self.powerscale_api.send_put_request.assert_called_once_with( expected_url, data=expected_data) def test_modify_nfs_export_access_no_ro_ips(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_id = '123' rw_ips = ['10.0.0.3', '10.0.0.4'] - self.isilon_api.modify_nfs_export_access(share_id, None, rw_ips) + self.powerscale_api.modify_nfs_export_access(share_id, None, rw_ips) expected_url = '{0}/platform/1/protocols/nfs/exports/{1}'.format( - self.isilon_api.host_url, share_id) + self.powerscale_api.host_url, share_id) expected_data = {'clients': rw_ips} - self.isilon_api.send_put_request.assert_called_once_with( + self.powerscale_api.send_put_request.assert_called_once_with( expected_url, data=expected_data) def test_modify_nfs_export_access_no_rw_ips(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_id = '123' ro_ips = ['10.0.0.1', '10.0.0.2'] - self.isilon_api.modify_nfs_export_access(share_id, ro_ips, None) + self.powerscale_api.modify_nfs_export_access(share_id, ro_ips, None) expected_url = '{0}/platform/1/protocols/nfs/exports/{1}'.format( - self.isilon_api.host_url, share_id) + self.powerscale_api.host_url, share_id) expected_data = {'read_only_clients': ro_ips} - self.isilon_api.send_put_request.assert_called_once_with( + self.powerscale_api.send_put_request.assert_called_once_with( expected_url, data=expected_data) @mock.patch('requests.Session.request') def test_request_with_401_response(self, mock_request): """Test sending a request with a 401 Unauthorized response.""" mock_request.return_value.status_code = 401 - self.isilon_api.create_session = mock.MagicMock(return_value=True) - self.isilon_api.request('GET', 'http://example.com/api/data') + self.powerscale_api.create_session = mock.MagicMock(return_value=True) + self.powerscale_api.request('GET', 'http://example.com/api/data') self.assertEqual(mock_request.call_count, 2) def test_delete_quota_sends_delete_request(self): - self.isilon_api.send_delete_request = mock.MagicMock() + self.powerscale_api.send_delete_request = mock.MagicMock() quota_id = '123' - self.isilon_api.delete_quota(quota_id) - self.isilon_api.send_delete_request.assert_called_once_with( + self.powerscale_api.delete_quota(quota_id) + self.powerscale_api.send_delete_request.assert_called_once_with( '{0}/platform/1/quota/quotas/{1}'.format( - self.isilon_api.host_url, quota_id) + self.powerscale_api.host_url, quota_id) ) def test_delete_quota_raises_exception_on_error(self): quota_id = '123' - self.isilon_api.send_delete_request = mock.MagicMock( + self.powerscale_api.send_delete_request = mock.MagicMock( side_effect=requests.exceptions.HTTPError) self.assertRaises(requests.exceptions.HTTPError, - self.isilon_api.delete_quota, + self.powerscale_api.delete_quota, quota_id) def test_get_space_stats_success(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 200 - self.isilon_api.send_get_request.return_value.json.return_value = { + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 200 + self.powerscale_api.send_get_request.return_value.json.return_value = { 'stats': [ {'key': 'ifs.bytes.free', 'value': 1000}, {'key': 'ifs.bytes.total', 'value': 2000}, {'key': 'ifs.bytes.used', 'value': 500} ] } - result = self.isilon_api.get_space_stats() + result = self.powerscale_api.get_space_stats() self.assertEqual(result, {'total': 2000, 'free': 1000, 'used': 500}) def test_get_space_stats_failure(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 400 + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 400 self.assertRaises(exception.ShareBackendException, - self.isilon_api.get_space_stats) + self.powerscale_api.get_space_stats) def test_get_allocated_space_success(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 200 - self.isilon_api.send_get_request.return_value.json.return_value = { + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 200 + self.powerscale_api.send_get_request.return_value.json.return_value = { 'quotas': [ { 'path': '/ifs/home', @@ -962,86 +971,88 @@ class IsilonApiTest(test.TestCase): } ] } - result = self.isilon_api.get_allocated_space() + result = self.powerscale_api.get_allocated_space() self.assertEqual(result, 2110.0) def test_get_allocated_space_failure(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 400 + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 400 self.assertRaises(exception.ShareBackendException, - self.isilon_api.get_allocated_space) + self.powerscale_api.get_allocated_space) def test_get_cluster_version_success(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 200 - self.isilon_api.send_get_request.return_value.json.return_value = { + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 200 + self.powerscale_api.send_get_request.return_value.json.return_value = { 'nodes': [{'release': '1.0'}]} - version = self.isilon_api.get_cluster_version() + version = self.powerscale_api.get_cluster_version() self.assertEqual(version, '1.0') - self.isilon_api.send_get_request.assert_called_once_with( - '{0}/platform/12/cluster/version'.format(self.isilon_api.host_url) + self.powerscale_api.send_get_request.assert_called_once_with( + '{0}/platform/12/cluster/version'.format( + self.powerscale_api.host_url) ) def test_get_cluster_version_failure(self): - self.isilon_api.send_get_request = mock.MagicMock() - self.isilon_api.send_get_request.return_value.status_code = 404 + self.powerscale_api.send_get_request = mock.MagicMock() + self.powerscale_api.send_get_request.return_value.status_code = 404 self.assertRaises(exception.ShareBackendException, - self.isilon_api.get_cluster_version) + self.powerscale_api.get_cluster_version) - self.isilon_api.send_get_request.assert_called_once_with( - '{0}/platform/12/cluster/version'.format(self.isilon_api.host_url) + self.powerscale_api.send_get_request.assert_called_once_with( + '{0}/platform/12/cluster/version'.format( + self.powerscale_api.host_url) ) def test_modify_smb_share_access_with_host_acl_and_smb_permission(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_name = 'my_share' host_acl = 'host1,host2' smb_permission = 'read' - self.isilon_api.modify_smb_share_access( + self.powerscale_api.modify_smb_share_access( share_name, host_acl, smb_permission) expected_url = '{0}/platform/1/protocols/smb/shares/{1}'.format( - self.isilon_api.host_url, share_name) + self.powerscale_api.host_url, share_name) expected_data = {'host_acl': host_acl, 'permissions': smb_permission} - self.isilon_api.send_put_request.assert_called_with( + self.powerscale_api.send_put_request.assert_called_with( expected_url, data=expected_data) def test_modify_smb_share_access_with_host_acl_only(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_name = 'my_share' host_acl = 'host1,host2' - self.isilon_api.modify_smb_share_access(share_name, host_acl) + self.powerscale_api.modify_smb_share_access(share_name, host_acl) expected_url = '{0}/platform/1/protocols/smb/shares/{1}'.format( - self.isilon_api.host_url, share_name) + self.powerscale_api.host_url, share_name) expected_data = {'host_acl': host_acl} - self.isilon_api.send_put_request.assert_called_with( + self.powerscale_api.send_put_request.assert_called_with( expected_url, data=expected_data) def test_modify_smb_share_access_with_smb_permission_only(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_name = 'my_share' smb_permission = 'read' - self.isilon_api.modify_smb_share_access( + self.powerscale_api.modify_smb_share_access( share_name, permissions=smb_permission) expected_url = '{0}/platform/1/protocols/smb/shares/{1}'.format( - self.isilon_api.host_url, share_name) + self.powerscale_api.host_url, share_name) expected_data = {'permissions': smb_permission} - self.isilon_api.send_put_request.assert_called_with( + self.powerscale_api.send_put_request.assert_called_with( expected_url, data=expected_data) def test_modify_smb_share_access_with_no_arguments(self): - self.isilon_api.send_put_request = mock.MagicMock() + self.powerscale_api.send_put_request = mock.MagicMock() share_name = 'my_share' - self.isilon_api.modify_smb_share_access(share_name) + self.powerscale_api.modify_smb_share_access(share_name) expected_url = '{0}/platform/1/protocols/smb/shares/{1}'.format( - self.isilon_api.host_url, share_name) + self.powerscale_api.host_url, share_name) expected_data = {} - self.isilon_api.send_put_request.assert_called_with( + self.powerscale_api.send_put_request.assert_called_with( expected_url, data=expected_data) def test_modify_smb_share_access_with_http_error(self): - self.isilon_api.send_put_request = mock.MagicMock( + self.powerscale_api.send_put_request = mock.MagicMock( side_effect=requests.exceptions.HTTPError ) share_name = 'my_share' @@ -1049,5 +1060,5 @@ class IsilonApiTest(test.TestCase): smb_permission = 'read' self.assertRaises(requests.exceptions.HTTPError, - self.isilon_api.modify_smb_share_access, + self.powerscale_api.modify_smb_share_access, share_name, host_acl, smb_permission) diff --git a/releasenotes/notes/bp-rename-isilon-to-powerscale-8e29d71c9e3629c3.yaml b/releasenotes/notes/bp-rename-isilon-to-powerscale-8e29d71c9e3629c3.yaml new file mode 100644 index 0000000000..7bd553be65 --- /dev/null +++ b/releasenotes/notes/bp-rename-isilon-to-powerscale-8e29d71c9e3629c3.yaml @@ -0,0 +1,13 @@ +--- +features: + - | + Rebrand from Isilon to PowerScale includes changing of tag names, directory + structure, file names and documentation. +upgrade: + - | + Dell PowerScale Driver was previously the EMC Isilon Driver. If the + extra-spec``share_backend_name`` was set to ``isilon`` in share types + in the past, this needs to be changed to ``powerscale``. + ``emc_share_backend`` configuration option must be switched from + ``isilon`` to ``powerscale`` in manila.conf when you add the storage + backend. diff --git a/setup.cfg b/setup.cfg index ec5ce839f5..e704e18d06 100644 --- a/setup.cfg +++ b/setup.cfg @@ -76,7 +76,7 @@ oslo.policy.policies = manila.share.drivers.dell_emc.plugins = vnx = manila.share.drivers.dell_emc.plugins.vnx.connection:VNXStorageConnection unity = manila.share.drivers.dell_emc.plugins.unity.connection:UnityStorageConnection - isilon = manila.share.drivers.dell_emc.plugins.isilon.isilon:IsilonStorageConnection + powerscale = manila.share.drivers.dell_emc.plugins.powerscale.powerscale:PowerScaleStorageConnection powermax = manila.share.drivers.dell_emc.plugins.powermax.connection:PowerMaxStorageConnection powerstore = manila.share.drivers.dell_emc.plugins.powerstore.connection:PowerStoreStorageConnection powerflex = manila.share.drivers.dell_emc.plugins.powerflex.connection:PowerFlexStorageConnection