[Unity] Manage/unmanage share server/share/snap
1. Try parse share_backend_id from export path in case it is managed share. 2. Try to take snapshot id from 'provider_location' in case this is managed snapshot 3. Try to get share server name from property 'identifier' first in case this is managed share server 4. Add property 'provider_location' when creating snapshot Implements: blueprint emc-unity-manage-unmange Change-Id: I676475d0500ecce31a1a863926accec8585ac83a Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
parent
a43f0666c8
commit
252a7e8118
@ -45,7 +45,7 @@ Mapping of share drivers and share features support
|
||||
+----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+----------------------------+--------------------------+--------------------+--------------------+
|
||||
| EMC VNX | J | \- | \- | \- | J | J | \- | \- | \- |
|
||||
+----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+----------------------------+--------------------------+--------------------+--------------------+
|
||||
| EMC Unity | N | \- | N | S | N | N | \- | S | \- |
|
||||
| EMC Unity | N | U | N | S | N | N | U | S | \- |
|
||||
+----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+----------------------------+--------------------------+--------------------+--------------------+
|
||||
| EMC Isilon | K | \- | M | \- | K | K | \- | \- | \- |
|
||||
+----------------------------------------+-----------------------+-----------------------+--------------------------+--------------------------+------------------------+----------------------------+--------------------------+--------------------+--------------------+
|
||||
|
@ -44,6 +44,9 @@ Storage Systems.
|
||||
* Create/Delete snapshot of a share.
|
||||
* Create a new share from snapshot.
|
||||
* Revert a share to a snapshot.
|
||||
* Manage/Unmanage a share server.
|
||||
* Manage/Unmanage a share.
|
||||
* Manage/Unmanage a snapshot.
|
||||
|
||||
|
||||
Supported Network Topologies
|
||||
@ -82,7 +85,7 @@ You may need root privilege to install python libraries.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
pip install storops
|
||||
$ pip install storops
|
||||
|
||||
|
||||
On Unity System
|
||||
@ -189,8 +192,8 @@ for the Unity driver.
|
||||
One of NAS server names in Unity, it is used for share creation when
|
||||
the driver is in `DHSS=False` mode.
|
||||
|
||||
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.
|
||||
|
||||
Supported MTU size
|
||||
------------------
|
||||
@ -208,11 +211,12 @@ of share network during share server creation.
|
||||
IPv6 support
|
||||
------------
|
||||
|
||||
IPv6 support for Unity driver is introduced in Queens release. The feature is divided
|
||||
into two parts:
|
||||
IPv6 support for Unity driver is introduced in Queens release. The feature
|
||||
is divided into two parts:
|
||||
|
||||
#. The driver is able to manage share or snapshot in the Neutron IPv6 network.
|
||||
#. The driver is able to connect Unity management interface using its IPv6 address.
|
||||
#. The driver is able to connect Unity management interface using its IPv6
|
||||
address.
|
||||
|
||||
Pre-Configurations for IPv6 support
|
||||
-----------------------------------
|
||||
@ -224,9 +228,10 @@ for the Unity driver:
|
||||
|
||||
- `network_plugin_ipv6_enabled` indicates IPv6 is enabled.
|
||||
|
||||
If you want to connect Unity using IPv6 address, you should configure IPv6 address
|
||||
by `/net/if/mgmt` uemcli command, `mgmtInterfaceSettings` RESTful api or the system
|
||||
settings of Unity GUI for Unity and specify the address in `/etc/manila/manila.conf`:
|
||||
If you want to connect Unity using IPv6 address, you should configure IPv6
|
||||
address by `/net/if/mgmt` uemcli command, `mgmtInterfaceSettings` RESTful api
|
||||
or the system settings of Unity GUI for Unity and specify the address in
|
||||
`/etc/manila/manila.conf`:
|
||||
|
||||
emc_nas_server = <IPv6 address>
|
||||
|
||||
@ -236,37 +241,43 @@ Supported share creation in mode that driver does not create and destroy share s
|
||||
To create a file share in this mode, you need to:
|
||||
|
||||
#. Create NAS server with network interface in Unity system.
|
||||
#. Set 'driver_handles_share_servers=False' and 'unity_share_server' in ``/etc/manila/manila.conf``:
|
||||
#. Set 'driver_handles_share_servers=False' and 'unity_share_server' in
|
||||
``/etc/manila/manila.conf``:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
driver_handles_share_servers = False
|
||||
unity_share_server = <name of NAS server in Unity system>
|
||||
|
||||
#. Specify the share type with driver_handles_share_servers = False extra specification:
|
||||
#. Specify the share type with driver_handles_share_servers = False extra
|
||||
specification:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila type-create <share_type_name> False
|
||||
$ manila type-create ${share_type_name} False
|
||||
|
||||
#. Create share.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila create <share_protocol> <size> --name <share_name> --share-type <share_type_name>
|
||||
$ manila create ${share_protocol} ${size} --name ${share_name} --share-type ${share_type_name}
|
||||
|
||||
.. note::
|
||||
|
||||
Do not specify the share network in share creation command because no share servers will be created.
|
||||
Do not specify the share network in share creation command because
|
||||
no share servers will be created.
|
||||
Driver will use the unity_share_server specified for share creation.
|
||||
|
||||
Snapshot support
|
||||
----------------
|
||||
|
||||
In the Mitaka and Newton release of OpenStack, Snapshot support is enabled by default for a newly created share type.
|
||||
Starting with the Ocata release, the snapshot_support extra spec must be set to True in order to allow snapshots for
|
||||
a share type. If the 'snapshot_support' extra_spec is omitted or if it is set to False, users would not be able to
|
||||
create snapshots on shares of this share type. The feature is divided into two parts:
|
||||
In the Mitaka and Newton release of OpenStack, Snapshot support is enabled by
|
||||
default for a newly created share type.
|
||||
Starting with the Ocata release, the snapshot_support extra spec must be set
|
||||
to True in order to allow snapshots for a share type. If the 'snapshot_support'
|
||||
extra_spec is omitted or if it is set to False, users would not be able to
|
||||
create snapshots on shares of this share type. The feature is divided into
|
||||
two parts:
|
||||
|
||||
1. The driver is able to create/delete snapshot of share.
|
||||
2. The driver is able to create share from snapshot.
|
||||
@ -279,35 +290,135 @@ The following extra specifications need to be configured with share type.
|
||||
- snapshot_support = True
|
||||
- create_share_from_snapshot_support = True
|
||||
|
||||
For new share type, these extra specifications can be set directly when creating share type:
|
||||
For new share type, these extra specifications can be set directly when
|
||||
creating share type:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
manila type-create --snapshot_support True --create_share_from_snapshot_support True ${share_type_name} True
|
||||
$ manila type-create --snapshot_support True --create_share_from_snapshot_support True ${share_type_name} True
|
||||
|
||||
Or you can update already existing share type with command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
manila type-key ${share_type_name} set snapshot_support=True
|
||||
manila type-key ${share_type_name} set create_share_from_snapshot_support=True
|
||||
$ manila type-key ${share_type_name} set snapshot_support=True
|
||||
$ manila type-key ${share_type_name} set create_share_from_snapshot_support=True
|
||||
|
||||
To snapshot a share and create share from the snapshot
|
||||
------------------------------------------------------
|
||||
|
||||
Firstly, you need create a share from share type that has extra specifications(snapshot_support=True, create_share_from_snapshot_support=True).
|
||||
Firstly, you need create a share from share type that has extra specifications
|
||||
(snapshot_support=True, create_share_from_snapshot_support=True).
|
||||
Then snapshot the share with command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
manila snapshot-create ${source_share_name} --name ${target_snapshot_name} --description " "
|
||||
$ manila snapshot-create ${source_share_name} --name ${target_snapshot_name} --description " "
|
||||
|
||||
After creating the snapshot from previous step, you can create share from that snapshot.
|
||||
Use command:
|
||||
After creating the snapshot from previous step, you can create share from that
|
||||
snapshot. Use command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
manila create nfs 1 --name ${target_share_name} --metadata source=snapshot --description " " --snapshot-id ${source_snapshot_id}
|
||||
$ manila create nfs 1 --name ${target_share_name} --metadata source=snapshot --description " " --snapshot-id ${source_snapshot_id}
|
||||
|
||||
To manage an existing share server
|
||||
----------------------------------
|
||||
|
||||
To manage a share server existing in Unity System, you need to:
|
||||
|
||||
#. Create network, subnet, port (ip address of nas server in Unity system) and
|
||||
share network in OpenStack.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ openstack network create ${network_name} --provider-network-type ${network_type}
|
||||
$ openstack subnet create ${subnet_name} --network ${network_name} --subnet-range ${subnet_range}
|
||||
$ openstack port create --network ${network_name} --fixed-ip subnet=${subnet_name},ip-address=${ip address} \
|
||||
${port_name} --device-owner=manila:share
|
||||
$ manila share-network-create --name ${share_network_name} --neutron-net-id ${network_name} \
|
||||
--neutron-subnet-id ${subnet_name}
|
||||
|
||||
#. Manage the share server in OpenStack:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila share-server-manage ${host} ${share_network_name} ${identifier}
|
||||
|
||||
.. note::
|
||||
|
||||
'${identifier}' is the nas server name in Unity system.
|
||||
|
||||
To un-manage a Manila share server
|
||||
----------------------------------
|
||||
To unmanage a share server existing in OpenStack:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila share-server-unmanage ${share_server_id}
|
||||
|
||||
To manage an existing share
|
||||
---------------------------
|
||||
|
||||
To manage a share existing in Unity System:
|
||||
|
||||
- In DHSS=True mode
|
||||
|
||||
Need make sure the related share server is existing in OpenStack, otherwise
|
||||
need to manage share server first (check the step of 'Supported Manage share
|
||||
server').
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila manage ${service_host} ${protocol} '${export_path}' --name ${share_name} --driver_options size=${share_size} \
|
||||
--share_type ${share_type} --share_server_id ${share_server_id}
|
||||
|
||||
.. note::
|
||||
|
||||
'${share_server_id}' is the id of share server in OpenStack.
|
||||
'${share_type}' should have the property 'driver_handles_share_servers=True'.
|
||||
|
||||
- In DHSS=False mode
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila manage ${service_host} ${protocol} '${export_path}' --name ${share_name} --driver_options size=${share_size} \
|
||||
--share_type ${share_type}
|
||||
|
||||
.. note::
|
||||
|
||||
'${share_type}' should have the property 'driver_handles_share_servers=False'.
|
||||
|
||||
To un-manage a Manila share
|
||||
---------------------------
|
||||
To unmanage a share existing in OpenStack:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila unmanage ${share_id}
|
||||
|
||||
To manage an existing share snapshot
|
||||
------------------------------------
|
||||
To manage a snapshot existing in Unity System, you need make sure the related
|
||||
share instance is existing in OpenStack, otherwise need to manage share first
|
||||
(check the step of 'Supported Manage share').
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila snapshot-manage --name ${name} ${share_name} ${provider_location} --driver_options size=${snapshot_size}
|
||||
|
||||
.. note::
|
||||
|
||||
'${provider_location}' is the snapshot name in Unity system.
|
||||
'${share_name}' is the share name or id in OpenStack.
|
||||
|
||||
To un-manage a Manila share snapshot
|
||||
------------------------------------
|
||||
To unmanage a snapshot existing in OpenStack:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ manila snapshot-unmanage ${snapshot_id}
|
||||
|
||||
Supported security services
|
||||
---------------------------
|
||||
|
@ -100,6 +100,109 @@ class EMCShareDriver(driver.ShareDriver):
|
||||
else:
|
||||
self.shrink_share_support = False
|
||||
|
||||
if hasattr(self.plugin, 'manage_existing_support'):
|
||||
self.manage_existing_support = self.plugin.manage_existing_support
|
||||
else:
|
||||
self.manage_existing_support = False
|
||||
|
||||
if hasattr(self.plugin, 'manage_existing_with_server_support'):
|
||||
self.manage_existing_with_server_support = (
|
||||
self.plugin.manage_existing_with_server_support)
|
||||
else:
|
||||
self.manage_existing_with_server_support = False
|
||||
|
||||
if hasattr(self.plugin, 'manage_existing_snapshot_support'):
|
||||
self.manage_existing_snapshot_support = (
|
||||
self.plugin.manage_existing_snapshot_support)
|
||||
else:
|
||||
self.manage_existing_snapshot_support = False
|
||||
|
||||
if hasattr(self.plugin, 'manage_snapshot_with_server_support'):
|
||||
self.manage_snapshot_with_server_support = (
|
||||
self.plugin.manage_snapshot_with_server_support)
|
||||
else:
|
||||
self.manage_snapshot_with_server_support = False
|
||||
|
||||
if hasattr(self.plugin, 'manage_server_support'):
|
||||
self.manage_server_support = self.plugin.manage_server_support
|
||||
else:
|
||||
self.manage_server_support = False
|
||||
|
||||
if hasattr(self.plugin, 'get_share_server_network_info_support'):
|
||||
self.get_share_server_network_info_support = (
|
||||
self.plugin.get_share_server_network_info_support)
|
||||
else:
|
||||
self.get_share_server_network_info_support = False
|
||||
|
||||
def manage_existing(self, share, driver_options):
|
||||
"""manage an existing share"""
|
||||
if self.manage_existing_support:
|
||||
return self.plugin.manage_existing(share, driver_options)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def manage_existing_with_server(self, share, driver_options,
|
||||
share_server=None):
|
||||
"""manage an existing share"""
|
||||
if self.manage_existing_with_server_support:
|
||||
return self.plugin.manage_existing_with_server(
|
||||
share, driver_options, share_server)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def manage_existing_snapshot(self, snapshot, driver_options):
|
||||
"""manage an existing share snapshot"""
|
||||
if self.manage_existing_snapshot_support:
|
||||
return self.plugin.manage_existing_snapshot(snapshot,
|
||||
driver_options)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def manage_existing_snapshot_with_server(self, snapshot, driver_options,
|
||||
share_server=None):
|
||||
"""manage an existing share snapshot"""
|
||||
if self.manage_snapshot_with_server_support:
|
||||
return self.plugin.manage_existing_snapshot_with_server(
|
||||
snapshot, driver_options, share_server=None)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def manage_server(self, context, share_server, identifier,
|
||||
driver_options):
|
||||
if self.manage_server_support:
|
||||
return self.plugin.manage_server(context, share_server,
|
||||
identifier, driver_options)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def get_share_server_network_info(
|
||||
self, context, share_server, identifier, driver_options):
|
||||
if self.get_share_server_network_info_support:
|
||||
return self.plugin.get_share_server_network_info(
|
||||
context, share_server, identifier, driver_options)
|
||||
else:
|
||||
return NotImplementedError()
|
||||
|
||||
def unmanage_server(self, server_details, security_services=None):
|
||||
LOG.info('Dell EMC driver will unmanage share server: %s out of '
|
||||
'OpenStack.', server_details.get('server_id'))
|
||||
|
||||
def unmanage(self, share):
|
||||
LOG.info('Dell EMC driver will unmanage share: %s out of '
|
||||
'OpenStack.', share.get('id'))
|
||||
|
||||
def unmanage_with_server(self, share, share_server=None):
|
||||
LOG.info('Dell EMC driver will unmanage share: %s out of '
|
||||
'OpenStack.', share.get('id'))
|
||||
|
||||
def unmanage_snapshot(self, snapshot):
|
||||
LOG.info('Dell EMC driver will unmanage snapshot: %s out of '
|
||||
'OpenStack.', snapshot.get('id'))
|
||||
|
||||
def unmanage_snapshot_with_server(self, snapshot, share_server=None):
|
||||
LOG.info('Dell EMC driver will unmanage snapshot: %s out of '
|
||||
'OpenStack.', snapshot.get('id'))
|
||||
|
||||
def create_share(self, context, share, share_server=None):
|
||||
"""Is called to create share."""
|
||||
location = self.plugin.create_share(context, share, share_server)
|
||||
@ -127,7 +230,7 @@ class EMCShareDriver(driver.ShareDriver):
|
||||
|
||||
def create_snapshot(self, context, snapshot, share_server=None):
|
||||
"""Is called to create snapshot."""
|
||||
self.plugin.create_snapshot(context, snapshot, share_server)
|
||||
return self.plugin.create_snapshot(context, snapshot, share_server)
|
||||
|
||||
def delete_share(self, context, share, share_server=None):
|
||||
"""Is called to remove share."""
|
||||
|
@ -41,9 +41,10 @@ from manila import utils
|
||||
7.0.0 - Supports DHSS=False mode
|
||||
7.0.1 - Fix parsing management IPv6 address
|
||||
7.0.2 - Bugfix: failed to delete CIFS share if wrong access was set
|
||||
8.0.0 - Supports manage/unmanage share server/share/snapshot
|
||||
"""
|
||||
|
||||
VERSION = "7.0.2"
|
||||
VERSION = "8.0.0"
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
SUPPORTED_NETWORK_TYPES = (None, 'flat', 'vlan')
|
||||
@ -100,6 +101,12 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
self.ipv6_implemented = True
|
||||
self.revert_to_snap_support = True
|
||||
self.shrink_share_support = True
|
||||
self.manage_existing_support = True
|
||||
self.manage_existing_with_server_support = True
|
||||
self.manage_existing_snapshot_support = True
|
||||
self.manage_snapshot_with_server_support = True
|
||||
self.manage_server_support = True
|
||||
self.get_share_server_network_info_support = True
|
||||
|
||||
# props from super class.
|
||||
self.driver_handles_share_servers = (True, False)
|
||||
@ -180,6 +187,151 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
def check_for_setup_error(self):
|
||||
"""Check for setup error."""
|
||||
|
||||
def manage_existing(self, share, driver_options, share_server=None):
|
||||
"""Manages a share that exists on backend.
|
||||
|
||||
:param share: Share that will be managed.
|
||||
:param driver_options: Driver-specific options provided by admin.
|
||||
:param share_server: Share server name provided by admin in DHSS=True.
|
||||
:returns: Returns a dict with share size and export location.
|
||||
"""
|
||||
export_locations = share['export_locations']
|
||||
if not export_locations:
|
||||
message = ("Failed to manage existing share: %s, missing "
|
||||
"export locations." % share['id'])
|
||||
raise exception.ManageInvalidShare(reason=message)
|
||||
|
||||
try:
|
||||
share_size = int(driver_options.get("size", 0))
|
||||
except (ValueError, TypeError):
|
||||
msg = _("The driver options' size to manage the share "
|
||||
"%(share_id)s, should be an integer, in format "
|
||||
"driver-options size=<SIZE>. Value specified: "
|
||||
"%(size)s.") % {'share_id': share['id'],
|
||||
'size': driver_options.get("size")}
|
||||
raise exception.ManageInvalidShare(reason=msg)
|
||||
|
||||
if not share_size:
|
||||
msg = _("Share %(share_id)s has no specified size. "
|
||||
"Using default value 1, set size in driver options if you "
|
||||
"want.") % {'share_id': share['id']}
|
||||
LOG.warning(msg)
|
||||
share_size = 1
|
||||
|
||||
share_id = unity_utils.get_share_backend_id(share)
|
||||
backend_share = self.client.get_share(share_id,
|
||||
share['share_proto'])
|
||||
if not backend_share:
|
||||
message = ("Could not find the share in backend, please make sure "
|
||||
"the export location is right.")
|
||||
raise exception.ManageInvalidShare(reason=message)
|
||||
|
||||
# Check the share server when in DHSS=true mode
|
||||
if share_server:
|
||||
backend_share_server = self._get_server_name(share_server)
|
||||
if not backend_share_server:
|
||||
message = ("Could not find the backend share server: %s, "
|
||||
"please make sure that share server with the "
|
||||
"specified name exists in the backend.",
|
||||
share_server)
|
||||
raise exception.BadConfigurationException(message)
|
||||
LOG.info("Share %(shr_path)s is being managed with ID "
|
||||
"%(shr_id)s.",
|
||||
{'shr_path': share['export_locations'][0]['path'],
|
||||
'shr_id': share['id']})
|
||||
# export_locations was not changed, return original value
|
||||
return {"size": share_size, 'export_locations': {
|
||||
'path': share['export_locations'][0]['path']}}
|
||||
|
||||
def manage_existing_with_server(self, share, driver_options, share_server):
|
||||
return self.manage_existing(share, driver_options, share_server)
|
||||
|
||||
def manage_existing_snapshot(self, snapshot, driver_options,
|
||||
share_server=None):
|
||||
"""Brings an existing snapshot under Manila management."""
|
||||
try:
|
||||
snapshot_size = int(driver_options.get("size", 0))
|
||||
except (ValueError, TypeError):
|
||||
msg = _("The size in driver options to manage snapshot "
|
||||
"%(snap_id)s should be an integer, in format "
|
||||
"driver-options size=<SIZE>. Value passed: "
|
||||
"%(size)s.") % {'snap_id': snapshot['id'],
|
||||
'size': driver_options.get("size")}
|
||||
raise exception.ManageInvalidShareSnapshot(reason=msg)
|
||||
|
||||
if not snapshot_size:
|
||||
msg = _("Snapshot %(snap_id)s has no specified size. "
|
||||
"Use default value 1, set size in driver options if you "
|
||||
"want.") % {'snap_id': snapshot['id']}
|
||||
LOG.info(msg)
|
||||
snapshot_size = 1
|
||||
provider_location = snapshot.get('provider_location')
|
||||
snap = self.client.get_snapshot(provider_location)
|
||||
if not snap:
|
||||
message = ("Could not find a snapshot in the backend with "
|
||||
"provider_location: %s, please make sure "
|
||||
"the snapshot exists in the backend."
|
||||
% provider_location)
|
||||
raise exception.ManageInvalidShareSnapshot(reason=message)
|
||||
|
||||
LOG.info("Snapshot %(provider_location)s in Unity will be managed "
|
||||
"with ID %(snapshot_id)s.",
|
||||
{'provider_location': snapshot.get('provider_location'),
|
||||
'snapshot_id': snapshot['id']})
|
||||
return {"size": snapshot_size, "provider_location": provider_location}
|
||||
|
||||
def manage_existing_snapshot_with_server(self, snapshot, driver_options,
|
||||
share_server):
|
||||
return self.manage_existing_snapshot(snapshot, driver_options,
|
||||
share_server)
|
||||
|
||||
def manage_server(self, context, share_server, identifier, driver_options):
|
||||
"""Manage the share server and return compiled back end details.
|
||||
|
||||
:param context: Current context.
|
||||
:param share_server: Share server model.
|
||||
:param identifier: A driver-specific share server identifier
|
||||
:param driver_options: Dictionary of driver options to assist managing
|
||||
the share server
|
||||
:return: Identifier and dictionary with back end details to be saved
|
||||
in the database.
|
||||
|
||||
Example::
|
||||
|
||||
'my_new_server_identifier',{'server_name': 'my_old_server'}
|
||||
|
||||
"""
|
||||
nas_server = self.client.get_nas_server(identifier)
|
||||
if not nas_server:
|
||||
message = ("Could not find the backend share server by server "
|
||||
"name: %s, please make sure the share server is "
|
||||
"existing in the backend." % identifier)
|
||||
raise exception.ManageInvalidShare(reason=message)
|
||||
return identifier, driver_options
|
||||
|
||||
def get_share_server_network_info(
|
||||
self, context, share_server, identifier, driver_options):
|
||||
"""Obtain network allocations used by share server.
|
||||
|
||||
:param context: Current context.
|
||||
:param share_server: Share server model.
|
||||
:param identifier: A driver-specific share server identifier
|
||||
:param driver_options: Dictionary of driver options to assist managing
|
||||
the share server
|
||||
:return: The containing IP address allocated in the backend, Unity
|
||||
only supports single IP address
|
||||
Example::
|
||||
|
||||
['10.10.10.10'] or ['fd11::2000']
|
||||
|
||||
"""
|
||||
containing_ips = []
|
||||
nas_server = self.client.get_nas_server(identifier)
|
||||
if nas_server:
|
||||
for file_interface in nas_server.file_interface:
|
||||
containing_ips.append(file_interface.ip_address)
|
||||
return containing_ips
|
||||
|
||||
def create_share(self, context, share, share_server=None):
|
||||
"""Create a share and export it based on protocol used."""
|
||||
share_name = share['id']
|
||||
@ -243,8 +395,8 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
{'server': server_name, 'share': share_name})
|
||||
LOG.exception(message)
|
||||
raise exception.EMCUnityError(err=message)
|
||||
|
||||
backend_snap = self.client.create_snap_of_snap(snapshot['id'],
|
||||
snapshot_id = unity_utils.get_snapshot_id(snapshot)
|
||||
backend_snap = self.client.create_snap_of_snap(snapshot_id,
|
||||
share_name)
|
||||
|
||||
locations = None
|
||||
@ -263,7 +415,7 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
|
||||
def delete_share(self, context, share, share_server=None):
|
||||
"""Delete a share."""
|
||||
share_name = share['id']
|
||||
share_name = unity_utils.get_share_backend_id(share)
|
||||
try:
|
||||
backend_share = self.client.get_share(share_name,
|
||||
share['share_proto'])
|
||||
@ -284,7 +436,8 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
self.client.delete_filesystem(filesystem)
|
||||
|
||||
def extend_share(self, share, new_size, share_server=None):
|
||||
backend_share = self.client.get_share(share['id'],
|
||||
share_id = unity_utils.get_share_backend_id(share)
|
||||
backend_share = self.client.get_share(share_id,
|
||||
share['share_proto'])
|
||||
|
||||
if not self._is_share_from_snapshot(backend_share):
|
||||
@ -305,7 +458,7 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
:param share_server: Data structure with share server information.
|
||||
Not used by this driver.
|
||||
"""
|
||||
share_id = share['id']
|
||||
share_id = unity_utils.get_share_backend_id(share)
|
||||
backend_share = self.client.get_share(share_id,
|
||||
share['share_proto'])
|
||||
if self._is_share_from_snapshot(backend_share):
|
||||
@ -322,7 +475,9 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
|
||||
def create_snapshot(self, context, snapshot, share_server=None):
|
||||
"""Create snapshot from share."""
|
||||
share_name = snapshot['share_id']
|
||||
share = snapshot['share']
|
||||
share_name = unity_utils.get_share_backend_id(
|
||||
share) if share else snapshot['share_id']
|
||||
share_proto = snapshot['share']['share_proto']
|
||||
backend_share = self.client.get_share(share_name, share_proto)
|
||||
|
||||
@ -332,10 +487,12 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
else:
|
||||
self.client.create_snapshot(backend_share.filesystem,
|
||||
snapshot_name)
|
||||
return {'provider_location': snapshot_name}
|
||||
|
||||
def delete_snapshot(self, context, snapshot, share_server=None):
|
||||
"""Delete a snapshot."""
|
||||
snap = self.client.get_snapshot(snapshot['id'])
|
||||
snapshot_id = unity_utils.get_snapshot_id(snapshot)
|
||||
snap = self.client.get_snapshot(snapshot_id)
|
||||
self.client.delete_snapshot(snap)
|
||||
|
||||
def update_access(self, context, share, access_rules, add_rules,
|
||||
@ -360,7 +517,7 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
|
||||
def clear_access(self, share, white_list=None):
|
||||
share_proto = share['share_proto'].upper()
|
||||
share_name = share['id']
|
||||
share_name = unity_utils.get_share_backend_id(share)
|
||||
if share_proto == 'CIFS':
|
||||
self.client.cifs_clear_access(share_name, white_list)
|
||||
elif share_proto == 'NFS':
|
||||
@ -396,7 +553,7 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
|
||||
def ensure_share(self, context, share, share_server):
|
||||
"""Ensure that the share is exported."""
|
||||
share_name = share['id']
|
||||
share_name = unity_utils.get_share_backend_id(share)
|
||||
share_proto = share['share_proto']
|
||||
|
||||
backend_share = self.client.get_share(share_name, share_proto)
|
||||
@ -641,8 +798,9 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
if not share_server:
|
||||
msg = _('Share server not provided.')
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
server_name = share_server.get(
|
||||
# Try to get share server name from property 'identifier' first in
|
||||
# case this is managed share server.
|
||||
server_name = share_server.get('identifier') or share_server.get(
|
||||
'backend_details', {}).get('share_server_name')
|
||||
|
||||
if server_name is None:
|
||||
@ -734,4 +892,5 @@ class UnityStorageConnection(driver.StorageConnection):
|
||||
def revert_to_snapshot(self, context, snapshot, share_access_rules,
|
||||
snapshot_access_rules, share_server=None):
|
||||
"""Reverts a share (in place) to the specified snapshot."""
|
||||
return self.client.restore_snapshot(snapshot['id'])
|
||||
snapshot_id = unity_utils.get_snapshot_id(snapshot)
|
||||
return self.client.restore_snapshot(snapshot_id)
|
||||
|
@ -14,12 +14,15 @@
|
||||
# under the License.
|
||||
""" Utility module for EMC Unity Manila Driver """
|
||||
|
||||
from oslo_log import log
|
||||
from oslo_utils import fnmatch
|
||||
from oslo_utils import units
|
||||
|
||||
from manila import exception
|
||||
from manila.i18n import _
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def do_match(full, matcher_list):
|
||||
matched = set()
|
||||
@ -78,3 +81,37 @@ def find_ports_by_mtu(all_ports, port_ids_conf, mtu):
|
||||
|
||||
def gib_to_byte(size_gib):
|
||||
return size_gib * units.Gi
|
||||
|
||||
|
||||
def get_share_backend_id(share):
|
||||
"""Get backend share id.
|
||||
|
||||
Try to get backend share id from path in case this is managed share,
|
||||
use share['id'] when path is empty.
|
||||
"""
|
||||
|
||||
backend_share_id = None
|
||||
try:
|
||||
export_locations = share['export_locations'][0]
|
||||
path = export_locations['path']
|
||||
if share['share_proto'].lower() == 'nfs':
|
||||
# 10.0.0.1:/example_share_name
|
||||
backend_share_id = path.split(':/')[-1]
|
||||
if share['share_proto'].lower() == 'cifs':
|
||||
# \\10.0.0.1\example_share_name
|
||||
backend_share_id = path.split('\\')[-1]
|
||||
except Exception as e:
|
||||
LOG.warning('Cannot get share name from path, make sure the path '
|
||||
'is right. Error details: %s', e)
|
||||
if backend_share_id and (backend_share_id != share['id']):
|
||||
return backend_share_id
|
||||
else:
|
||||
return share['id']
|
||||
|
||||
|
||||
def get_snapshot_id(snapshot):
|
||||
"""Get backend snapshot id.
|
||||
|
||||
Take the id from provider_location in case this is managed snapshot.
|
||||
"""
|
||||
return snapshot['provider_location'] or snapshot['id']
|
||||
|
@ -138,6 +138,7 @@ share_server:
|
||||
share_server_name: '78fd845f-8e7d-487f-bfde-051d83e78103'
|
||||
network_allocations: *network_allocations_prop
|
||||
id: '78fd845f-8e7d-487f-bfde-051d83e78103'
|
||||
identifier: 'c2e48947-98ed-4eae-999b-fa0b83731dfd'
|
||||
|
||||
share_server__no_share_server_name:
|
||||
_type: 'share_server'
|
||||
@ -170,6 +171,25 @@ cifs_share:
|
||||
export_locations: []
|
||||
is_public: False
|
||||
|
||||
managed_cifs_share:
|
||||
_type: 'share'
|
||||
_properties: &managed_cifs_share_share_prop
|
||||
share_id: '708e753c-aacb-411f-9c8a-8b8175da4e73'
|
||||
availability_zone_id: 'de628fb6-1c99-41f6-a06a-adb61ff693b5'
|
||||
share_network_id: '232d8218-2743-41d1-832b-4194626e691e'
|
||||
share_server_id: '78fd845f-8e7d-487f-bfde-051d83e78103'
|
||||
id: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
size: 10
|
||||
user_id: '19bbda71b578471a93363653dcb4c61d'
|
||||
status: 'creating'
|
||||
share_type_id: '57679eab-3e67-4052-b180-62b609670e93'
|
||||
host: 'openstack@VNX#Pool_2'
|
||||
display_name: 'cifs_share'
|
||||
share_proto: 'CIFS'
|
||||
export_locations: [path: '\\10.0.0.1\bd23121f-hg4e-432c-12cd2c5-bb93dfghe212']
|
||||
is_public: False
|
||||
snapshot_support: False
|
||||
|
||||
nfs_share:
|
||||
_type: 'share'
|
||||
_properties: &nfs_share_prop
|
||||
@ -185,9 +205,28 @@ nfs_share:
|
||||
host: 'openstack@VNX#Pool_2'
|
||||
display_name: 'nfs_share'
|
||||
share_proto: 'NFS'
|
||||
export_locations: []
|
||||
export_locations: null
|
||||
is_public: False
|
||||
|
||||
managed_nfs_share:
|
||||
_type: 'share'
|
||||
_properties: &managed_nfs_share_prop
|
||||
share_id: '12eb3777-7008-4721-8243-422507db8f9d'
|
||||
availability_zone_id: 'de628fb6-1c99-41f6-a06a-adb61ff693b5'
|
||||
share_network_id: '232d8218-2743-41d1-832b-4194626e691e'
|
||||
share_server_id: '78fd845f-8e7d-487f-bfde-051d83e78103'
|
||||
id: 'cb532599-8dc6-4c3e-bb21-74ea54be566c'
|
||||
size: 9
|
||||
user_id: '19bbda71b578471a93363653dcb4c61d'
|
||||
status: 'creating'
|
||||
share_type_id: '57679eab-3e67-4052-b180-62b609670e93'
|
||||
host: 'openstack@VNX#Pool_2'
|
||||
display_name: 'nfs_share'
|
||||
share_proto: 'NFS'
|
||||
export_locations: [path: '172.168.201.201:/ad1caddf-097e-462c-8ac6-5592ed6fe22f']
|
||||
is_public: False
|
||||
snapshot_support: False
|
||||
|
||||
dhss_false_cifs_share:
|
||||
_type: 'share'
|
||||
_properties: &dhss_false_cifs_share_prop
|
||||
@ -285,10 +324,12 @@ snapshot:
|
||||
share_instance_id: '27e4625e-c336-4749-85bc-634216755fbc'
|
||||
share:
|
||||
share_proto: 'CIFS'
|
||||
id: 's24r-3fgw2-g039ef-j029f0-nrver'
|
||||
snapshot_id: '345476cc-32ab-4565-ba88-e4733b7ffa0e'
|
||||
progress: '0%'
|
||||
id: 'ab411797-b1cf-4035-bf14-8771a7bf1805'
|
||||
share_id: '27e4625e-c336-4749-85bc-634216755fbc'
|
||||
provider_location: '23047-ef2344-4563cvw-r4323cwed'
|
||||
|
||||
cifs_rw_access:
|
||||
_type: 'access'
|
||||
|
@ -1252,3 +1252,89 @@ test_restore_snapshot:
|
||||
unity:
|
||||
_methods:
|
||||
get_snap: *snapshot_1
|
||||
|
||||
|
||||
test_manage_cifs_share_with_server:
|
||||
filesystem: &filesystem__test_manage_cifs_share_with_server
|
||||
_properties: &filesystem_prop__test_manage_cifs_share_with_server
|
||||
<<: *filesystem_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
size_total: 5368709120
|
||||
_methods:
|
||||
shrink:
|
||||
|
||||
cifs_share: &cifs_share__test_manage_cifs_share_with_server
|
||||
_properties:
|
||||
<<: *cifs_share_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
filesystem: *filesystem__test_manage_cifs_share_with_server
|
||||
|
||||
unity:
|
||||
_methods:
|
||||
<<: *unity_base_method
|
||||
get_cifs_share: *cifs_share__test_manage_cifs_share_with_server
|
||||
|
||||
test_manage_cifs_share:
|
||||
filesystem: &filesystem__test_manage_cifs_share
|
||||
_properties: &filesystem_prop__test_manage_cifs_share
|
||||
<<: *filesystem_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
size_total: 5368709120
|
||||
_methods:
|
||||
shrink:
|
||||
|
||||
cifs_share: &cifs_share__test_manage_cifs_share
|
||||
_properties:
|
||||
<<: *cifs_share_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
filesystem: *filesystem__test_manage_cifs_share
|
||||
|
||||
unity:
|
||||
_methods:
|
||||
<<: *unity_base_method
|
||||
get_cifs_share: *cifs_share__test_manage_cifs_share
|
||||
|
||||
test_manage_nfs_share_with_server:
|
||||
filesystem: &filesystem__test_manage_nfs_share_with_server
|
||||
_properties: &filesystem_prop__test_manage_nfs_share_with_server
|
||||
<<: *filesystem_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
size_total: 5368709120
|
||||
_methods:
|
||||
extend:
|
||||
|
||||
nfs_share: &nfs_share__test_manage_nfs_share_with_server
|
||||
_properties:
|
||||
<<: *nfs_share_base_prop
|
||||
name: '716100cc-e0b4-416b-ac27-d38dd019330d'
|
||||
filesystem: *filesystem__test_manage_nfs_share_with_server
|
||||
|
||||
unity:
|
||||
_methods:
|
||||
<<: *unity_base_method
|
||||
get_nfs_share: *nfs_share__test_manage_nfs_share_with_server
|
||||
|
||||
test_manage_nfs_share:
|
||||
filesystem: &filesystem__test_manage_nfs_share
|
||||
_properties: &filesystem_prop__test_manage_nfs_share
|
||||
<<: *filesystem_base_prop
|
||||
size_total: 5368709120
|
||||
_methods:
|
||||
shrink:
|
||||
|
||||
nfs_share: &nfs_share__test_manage_nfs_share
|
||||
_properties:
|
||||
<<: *nfs_share_base_prop
|
||||
filesystem: *filesystem__test_manage_nfs_share
|
||||
|
||||
unity:
|
||||
_methods:
|
||||
<<: *unity_base_method
|
||||
get_nfs_share: *nfs_share__test_manage_nfs_share
|
||||
|
||||
test_get_share_server_network_info:
|
||||
unity:
|
||||
_methods:
|
||||
<<: *unity_base_method
|
||||
get_nas_server: *nas_server
|
||||
|
||||
|
@ -116,6 +116,7 @@ class TestConnection(test.TestCase):
|
||||
share_server = {
|
||||
'backend_details': {'share_server_name': None},
|
||||
'id': 'test',
|
||||
'identifier': '',
|
||||
}
|
||||
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
@ -246,7 +247,9 @@ class TestConnection(test.TestCase):
|
||||
snapshot = mocked_input['snapshot']
|
||||
share_server = mocked_input['share_server']
|
||||
|
||||
connection.create_snapshot(None, snapshot, share_server)
|
||||
result = connection.create_snapshot(None, snapshot, share_server)
|
||||
self.assertEqual('ab411797-b1cf-4035-bf14-8771a7bf1805',
|
||||
result['provider_location'])
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
@ -739,3 +742,142 @@ class TestConnection(test.TestCase):
|
||||
exp_location = sorted(exp_location, key=lambda x: sorted(x['path']))
|
||||
location = sorted(location, key=lambda x: sorted(x['path']))
|
||||
self.assertEqual(exp_location, location)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_get_share_server_id(self, connection, mocked_input):
|
||||
share_server = mocked_input['share_server']
|
||||
result = connection._get_server_name(share_server)
|
||||
expected = 'c2e48947-98ed-4eae-999b-fa0b83731dfd'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_snapshot(self, connection, mocked_input):
|
||||
snapshot = mocked_input['snapshot']
|
||||
driver_options = {'size': 8}
|
||||
result = connection.manage_existing_snapshot(snapshot,
|
||||
driver_options, None)
|
||||
expected = {'provider_location': '23047-ef2344-4563cvw-r4323cwed',
|
||||
'size': 8}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_snapshot_wrong_size_type(self, connection, mocked_input):
|
||||
snapshot = mocked_input['snapshot']
|
||||
driver_options = {'size': 'str_size'}
|
||||
self.assertRaises(exception.ManageInvalidShareSnapshot,
|
||||
connection.manage_existing_snapshot,
|
||||
snapshot, driver_options, None)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_snapshot_with_server(self, connection, mocked_input):
|
||||
share_server = mocked_input['share_server']
|
||||
snapshot = mocked_input['snapshot']
|
||||
driver_options = {}
|
||||
result = connection.manage_existing_snapshot_with_server(
|
||||
snapshot, driver_options, share_server)
|
||||
expected = {'provider_location': '23047-ef2344-4563cvw-r4323cwed',
|
||||
'size': 1}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_get_share_server_network_info(self, connection, mocked_input):
|
||||
share_server = mocked_input['share_server']
|
||||
identifier = 'test_manage_nas_server'
|
||||
result = connection.get_share_server_network_info(None, share_server,
|
||||
identifier, None)
|
||||
expected = ['fake_ip_addr_1', 'fake_ip_addr_2']
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_server(self, connection, mocked_input):
|
||||
share_server = mocked_input['share_server']
|
||||
identifier = 'test_manage_nas_server'
|
||||
result = connection.manage_server(None, share_server, identifier, None)
|
||||
expected = (identifier, None)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_nfs_share(self, connection, mocked_input):
|
||||
share = mocked_input['managed_nfs_share']
|
||||
driver_options = {'size': 3}
|
||||
result = connection.manage_existing(share, driver_options)
|
||||
path = '172.168.201.201:/ad1caddf-097e-462c-8ac6-5592ed6fe22f'
|
||||
expected = {'export_locations': {'path': path}, 'size': 3}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_nfs_share_with_server(self, connection, mocked_input):
|
||||
share = mocked_input['managed_nfs_share']
|
||||
share_server = mocked_input['share_server']
|
||||
driver_options = {'size': 8}
|
||||
result = connection.manage_existing_with_server(share, driver_options,
|
||||
share_server)
|
||||
path = '172.168.201.201:/ad1caddf-097e-462c-8ac6-5592ed6fe22f'
|
||||
expected = {'export_locations': {'path': path}, 'size': 8}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_cifs_share(self, connection, mocked_input):
|
||||
share = mocked_input['managed_cifs_share']
|
||||
driver_options = {'size': 3}
|
||||
result = connection.manage_existing(share, driver_options)
|
||||
path = '\\\\10.0.0.1\\bd23121f-hg4e-432c-12cd2c5-bb93dfghe212'
|
||||
expected = {'export_locations': {'path': path}, 'size': 3}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_cifs_share_with_server(self, connection, mocked_input):
|
||||
connection.client.create_interface = mock.Mock(return_value=None)
|
||||
share = mocked_input['managed_cifs_share']
|
||||
share_server = mocked_input['share_server']
|
||||
driver_options = {'size': 3}
|
||||
result = connection.manage_existing_with_server(share, driver_options,
|
||||
share_server)
|
||||
path = '\\\\10.0.0.1\\bd23121f-hg4e-432c-12cd2c5-bb93dfghe212'
|
||||
expected = {'export_locations': {'path': path}, 'size': 3}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_with_wrong_size_data_type(self, connection, mocked_input):
|
||||
connection.client.create_interface = mock.Mock(return_value=None)
|
||||
share = mocked_input['managed_nfs_share']
|
||||
share_server = mocked_input['share_server']
|
||||
driver_options = {'size': 'str_size'}
|
||||
self.assertRaises(exception.ManageInvalidShare,
|
||||
connection.manage_existing_with_server,
|
||||
share, driver_options, share_server)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_without_size(self, connection, mocked_input):
|
||||
connection.client.create_interface = mock.Mock(return_value=None)
|
||||
share = mocked_input['managed_nfs_share']
|
||||
share_server = mocked_input['share_server']
|
||||
driver_options = {'size': 0}
|
||||
result = connection.manage_existing_with_server(share, driver_options,
|
||||
share_server)
|
||||
path = '172.168.201.201:/ad1caddf-097e-462c-8ac6-5592ed6fe22f'
|
||||
expected = {'export_locations': {'path': path}, 'size': 1}
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@res_mock.mock_manila_input
|
||||
@res_mock.patch_connection
|
||||
def test_manage_without_export_locations(self, connection, mocked_input):
|
||||
connection.client.create_interface = mock.Mock(return_value=None)
|
||||
share = mocked_input['nfs_share']
|
||||
share_server = mocked_input['share_server']
|
||||
driver_options = {'size': 3}
|
||||
self.assertRaises(exception.ManageInvalidShare,
|
||||
connection.manage_existing_with_server,
|
||||
share, driver_options, share_server)
|
||||
|
@ -115,3 +115,52 @@ class TestUtils(test.TestCase):
|
||||
|
||||
def test_gb_to_byte(self):
|
||||
self.assertEqual(3 * units.Gi, utils.gib_to_byte(3))
|
||||
|
||||
def test_get_snapshot_id(self):
|
||||
snapshot = {'provider_location': '23047-ef2344-4563cvw-r4323cwed',
|
||||
'id': 'test_id'}
|
||||
result = utils.get_snapshot_id(snapshot)
|
||||
expected = '23047-ef2344-4563cvw-r4323cwed'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_snapshot_id_without_pl(self):
|
||||
snapshot = {'provider_location': '', 'id': 'test_id'}
|
||||
result = utils.get_snapshot_id(snapshot)
|
||||
expected = 'test_id'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_nfs_share_id(self):
|
||||
nfs_share = {'export_locations':
|
||||
[{'path': '10.10.1.12:/addf-97e-46c-8ac6-55922f',
|
||||
'share_instance_id': 'e24-457e-47-12c6-gf345'}],
|
||||
'share_proto': 'NFS', 'id': 'test_nfs_id'}
|
||||
result = utils.get_share_backend_id(nfs_share)
|
||||
expected = 'addf-97e-46c-8ac6-55922f'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_nfs_share_id_without_path(self):
|
||||
nfs_share = {'export_locations':
|
||||
[{'path': '',
|
||||
'share_instance_id': 'ev24-7e-4-12c6-g45245'}],
|
||||
'share_proto': 'NFS', 'id': 'test_nfs_id'}
|
||||
result = utils.get_share_backend_id(nfs_share)
|
||||
expected = 'test_nfs_id'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_cifs_share_id(self):
|
||||
cifs_share = {'export_locations':
|
||||
[{'path': '\\\\17.66.5.3\\bdf-h4e-42c-122c5-b212',
|
||||
'share_instance_id': 'ev4-47e-48-126-gfbh452'}],
|
||||
'share_proto': 'CIFS', 'id': 'test_cifs_id'}
|
||||
result = utils.get_share_backend_id(cifs_share)
|
||||
expected = 'bdf-h4e-42c-122c5-b212'
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_get_cifs_share_id_without_path(self):
|
||||
cifs_share = {'export_locations':
|
||||
[{'path': '',
|
||||
'share_instance_id': 'ef4-47e-48-12c6-gf452'}],
|
||||
'share_proto': 'CIFS', 'id': 'test_cifs_id'}
|
||||
result = utils.get_share_backend_id(cifs_share)
|
||||
expected = 'test_cifs_id'
|
||||
self.assertEqual(expected, result)
|
||||
|
@ -145,3 +145,59 @@ class EMCShareFrameworkTestCase(test.TestCase):
|
||||
elif value == 'driver_handles_share_servers':
|
||||
return True
|
||||
return None
|
||||
|
||||
def test_support_manage(self):
|
||||
share = mock.Mock()
|
||||
driver_options = mock.Mock()
|
||||
share_server = mock.Mock()
|
||||
snapshot = mock.Mock()
|
||||
context = mock.Mock()
|
||||
identifier = mock.Mock()
|
||||
self.driver.plugin = mock.Mock()
|
||||
self.driver.manage_existing_support = True
|
||||
self.driver.manage_existing_with_server_support = True
|
||||
self.driver.manage_existing_snapshot_support = True
|
||||
self.driver.manage_snapshot_with_server_support = True
|
||||
self.driver.manage_server_support = True
|
||||
self.driver.manage_existing(share, driver_options)
|
||||
self.driver.manage_existing_with_server(share, driver_options,
|
||||
share_server)
|
||||
self.driver.manage_existing_snapshot(snapshot, driver_options)
|
||||
self.driver.manage_existing_snapshot_with_server(snapshot,
|
||||
driver_options,
|
||||
share_server)
|
||||
self.driver.manage_server(context, share_server, identifier,
|
||||
driver_options)
|
||||
|
||||
def test_not_support_manage(self):
|
||||
share = mock.Mock()
|
||||
driver_options = {}
|
||||
share_server = mock.Mock()
|
||||
snapshot = mock.Mock()
|
||||
identifier = mock.Mock()
|
||||
self.driver.plugin = mock.Mock()
|
||||
result = self.driver.manage_existing(share, driver_options)
|
||||
self.assertIsInstance(result, NotImplementedError)
|
||||
result = self.driver.manage_existing_with_server(
|
||||
share, driver_options, share_server)
|
||||
self.assertIsInstance(result, NotImplementedError)
|
||||
result = self.driver.manage_existing_snapshot(snapshot, driver_options)
|
||||
self.assertIsInstance(result, NotImplementedError)
|
||||
result = self.driver.manage_existing_snapshot_with_server(
|
||||
snapshot, driver_options, share_server)
|
||||
self.assertIsInstance(result, NotImplementedError)
|
||||
result = self.driver.manage_server(None, share_server, identifier,
|
||||
driver_options)
|
||||
self.assertIsInstance(result, NotImplementedError)
|
||||
|
||||
def unmanage_manage(self):
|
||||
share = mock.Mock()
|
||||
server_details = {}
|
||||
share_server = mock.Mock()
|
||||
snapshot = mock.Mock()
|
||||
self.driver.plugin = mock.Mock(share)
|
||||
self.driver.unmanage(share)
|
||||
self.driver.unmanage_with_server(share, share_server)
|
||||
self.driver.unmanage_snapshot(snapshot)
|
||||
self.driver.unmanage_snapshot_with_server(snapshot, share_server)
|
||||
self.driver.unmanage_server(server_details)
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- Dell EMC Unity Manila driver now supports manage/unmange share server,
|
||||
share instance and share snapshot.
|
Loading…
Reference in New Issue
Block a user