Merge "Dell PowerScale: Rename Isilon to PowerScale in Manila Driver"
This commit is contained in:
1
doc/source/_extra/.htaccess
Normal file
1
doc/source/_extra/.htaccess
Normal file
@@ -0,0 +1 @@
|
||||
RedirectMatch 301 ^/drivers/emc-isilon-driver.html$ /drivers/dell-emc-powerscale-driver.html
|
@@ -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 = <IP address of Isilon cluster>
|
||||
* emc_nas_server_port = <port to use for Isilon cluster (optional)>
|
||||
* emc_share_backend = powerscale
|
||||
* emc_nas_server = <IP address of PowerScale cluster>
|
||||
* emc_nas_server_port = <port to use for PowerScale cluster (optional)>
|
||||
* emc_nas_login = <username>
|
||||
* emc_nas_password = <password>
|
||||
* emc_nas_root_dir = <root directory path to create shares (e.g./ifs/manila)>
|
||||
|
||||
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:
|
@@ -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
|
||||
|
@@ -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 | \- | \- | \- |
|
||||
+----------------------------------------+-----------+------------+--------+-------------+-------------------+--------------------+-----+----------------------------+--------------------+--------------------+--------------+--------------+-------------------------+--------------------------+
|
||||
|
@@ -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').
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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 = <IP address of Isilon cluster>
|
||||
emc_share_backend = powerscale
|
||||
emc_nas_server = <IP address of PowerScale cluster>
|
||||
emc_nas_login = <username>
|
||||
emc_nas_password = <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.
|
||||
|
@@ -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 = [
|
||||
|
@@ -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)
|
||||
|
@@ -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']] = {
|
@@ -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,
|
@@ -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': {
|
@@ -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)
|
@@ -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.
|
@@ -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
|
||||
|
Reference in New Issue
Block a user