Refactor HP 3PAR share driver to now be HPE

This patch refactors the HP share driver to now be
the HPE share driver.

This is being done because the company responsible for
this driver is now Hewlett Packard Enterprise (HPE).

The driver is now located in the manila/share/drivers/hpe
folder.

DocImpact
Implements: blueprint rebrand-hp-3par-share-driver
Change-Id: I36efc04fa6da088ccb06070d8cd4fe29269cd7ca
This commit is contained in:
Anthony Lee 2015-10-29 17:19:48 -07:00
parent 7566440a65
commit a6d7e90714
13 changed files with 396 additions and 359 deletions

View File

@ -13,16 +13,21 @@
License for the specific language governing permissions and limitations License for the specific language governing permissions and limitations
under the License. under the License.
HP 3PAR Driver HPE 3PAR Driver
============== ==============
The HP 3PAR Manila driver provides NFS and CIFS shared file systems to The HPE 3PAR Manila driver provides NFS and CIFS shared file systems to
OpenStack using HP 3PAR's File Persona capabilities. OpenStack using HPE 3PAR's File Persona capabilities.
.. note::
In OpenStack releases prior to Mitaka this driver was called the
HP 3PAR driver. The Liberty configuration reference can be found
at: http://docs.openstack.org/liberty/config-reference/content/hp-3par-share-driver.html
Supported Operations Supported Operations
-------------------- --------------------
The following operations are supported with HP 3PAR File Persona: The following operations are supported with HPE 3PAR File Persona:
- Create/delete NFS and CIFS shares - Create/delete NFS and CIFS shares
@ -58,18 +63,18 @@ Requirements
On the system running the Manila share service: On the system running the Manila share service:
- hp3parclient version 3.2.1 or newer from PyPI - python-3parclient 4.0.0 or newer from PyPI.
On the HP 3PAR array: On the HPE 3PAR array:
- HP 3PAR Operating System software version 3.2.1 MU3 or higher - HPE 3PAR Operating System software version 3.2.1 MU3 or higher
- A license that enables the File Persona feature - A license that enables the File Persona feature
- The array class and hardware configuration must support File Persona - The array class and hardware configuration must support File Persona
Pre-Configuration on the HP 3PAR Pre-Configuration on the HPE 3PAR
-------------------------------- --------------------------------
- HP 3PAR File Persona must be initialized and started (:code:`startfs`) - HPE 3PAR File Persona must be initialized and started (:code:`startfs`)
- A File Provisioning Group (FPG) must be created for use with Manila - A File Provisioning Group (FPG) must be created for use with Manila
- A Virtual File Server (VFS) must be created for the FPG - A Virtual File Server (VFS) must be created for the FPG
- The VFS must be configured with an appropriate share export IP address - The VFS must be configured with an appropriate share export IP address
@ -79,22 +84,22 @@ Backend Configuration
--------------------- ---------------------
The following parameters need to be configured in the Manila configuration The following parameters need to be configured in the Manila configuration
file for the HP 3PAR driver: file for the HPE 3PAR driver:
- `share_backend_name` = <backend name to enable> - `share_backend_name` = <backend name to enable>
- `share_driver` = manila.share.drivers.hp.hp_3par_driver.HP3ParShareDriver - `share_driver` = manila.share.drivers.hpe.hpe_3par_driver.HPE3ParShareDriver
- `driver_handles_share_servers` = False - `driver_handles_share_servers` = False
- `hp3par_fpg` = <FPG to use for share creation> - `hpe3par_fpg` = <FPG to use for share creation>
- `hp3par_share_ip_address` = <IP address to use for share export location> - `hpe3par_share_ip_address` = <IP address to use for share export location>
- `hp3par_san_ip` = <IP address for SSH access to the SAN controller> - `hpe3par_san_ip` = <IP address for SSH access to the SAN controller>
- `hp3par_api_url` = <3PAR WS API Server URL> - `hpe3par_api_url` = <3PAR WS API Server URL>
- `hp3par_username` = <3PAR username with the 'edit' role> - `hpe3par_username` = <3PAR username with the 'edit' role>
- `hp3par_password` = <3PAR password for the user specified in hp3par_username> - `hpe3par_password` = <3PAR password for the user specified in hpe3par_username>
- `hp3par_san_login` = <Username for SSH access to the SAN controller> - `hpe3par_san_login` = <Username for SSH access to the SAN controller>
- `hp3par_san_password` = <Password for SSH access to the SAN controller> - `hpe3par_san_password` = <Password for SSH access to the SAN controller>
- `hp3par_debug` = <False or True for extra debug logging> - `hpe3par_debug` = <False or True for extra debug logging>
The `hp3par_share_ip_address` must be a valid IP address for the configured The `hpe3par_share_ip_address` must be a valid IP address for the configured
FPG's VFS. This IP address is used in export locations for shares that are FPG's VFS. This IP address is used in export locations for shares that are
created. Networking must be configured to allow connectivity from clients to created. Networking must be configured to allow connectivity from clients to
shares. shares.
@ -127,23 +132,23 @@ Manila requires that the share type includes the
`driver_handles_share_servers` extra-spec. This ensures that the share `driver_handles_share_servers` extra-spec. This ensures that the share
will be created on a backend that supports the requested will be created on a backend that supports the requested
driver_handles_share_servers (share networks) capability. driver_handles_share_servers (share networks) capability.
For the HP 3PAR driver, this must be set to False. For the HPE 3PAR driver, this must be set to False.
Another common Manila extra-spec used to determine where a share is created Another common Manila extra-spec used to determine where a share is created
is `share_backend_name`. When this extra-spec is defined in the share type, is `share_backend_name`. When this extra-spec is defined in the share type,
the share will be created on a backend with a matching share_backend_name. the share will be created on a backend with a matching share_backend_name.
The HP 3PAR driver automatically reports capabilities based on the FPG used The HPE 3PAR driver automatically reports capabilities based on the FPG used
for each backend. Share types with extra specs can be created by an for each backend. Share types with extra specs can be created by an
administrator to control which share types are allowed to use FPGs with or administrator to control which share types are allowed to use FPGs with or
without specific capabilities. The following extra-specs are used with without specific capabilities. The following extra-specs are used with
the capabilities filter and the HP 3PAR driver: the capabilities filter and the HPE 3PAR driver:
- `hp3par_flash_cache` = '<is> True' or '<is> False' - `hpe3par_flash_cache` = '<is> True' or '<is> False'
- `thin_provisioning` = '<is> True' or '<is> False' - `thin_provisioning` = '<is> True' or '<is> False'
- `dedupe` = '<is> True' or '<is> False' - `dedupe` = '<is> True' or '<is> False'
`hp3par_flash_cache` will be reported as True for backends that have `hpe3par_flash_cache` will be reported as True for backends that have
3PAR's Adaptive Flash Cache enabled. 3PAR's Adaptive Flash Cache enabled.
`thin_provisioning` will be reported as True for backends that use thin `thin_provisioning` will be reported as True for backends that use thin
@ -155,14 +160,16 @@ over-subscription feature.
technology. technology.
Scoped extra-specs are used to influence vendor-specific implementation Scoped extra-specs are used to influence vendor-specific implementation
details. Scoped extra-specs use a prefix followed by a colon. For HP 3PAR details. Scoped extra-specs use a prefix followed by a colon. For HPE 3PAR
these extra-specs have a prefix of `hp3par`. these extra-specs have a prefix of `hpe3par`. For HP 3PAR these extra-specs
have a prefix of `hp3par`.
The following HP 3PAR extra-specs are used when creating CIFS (SMB) shares: The following HPE 3PAR extra-specs are used when creating CIFS (SMB) shares:
- `hpe3par:smb_access_based_enum` = true or false
- `hpe3par:smb_continuous_avail` = true or false
- `hpe3par:smb_cache` = off, manual, optimized or auto
- `hp3par:smb_access_based_enum` = true or false
- `hp3par:smb_continuous_avail` = true or false
- `hp3par:smb_cache` = off, manual, optimized or auto
`smb_access_based_enum` (Access Based Enumeration) specifies if users can see `smb_access_based_enum` (Access Based Enumeration) specifies if users can see
only the files and directories to which they have been allowed access on the only the files and directories to which they have been allowed access on the
@ -188,25 +195,25 @@ or earlier.
documents. documents.
* If this is not specified, the default is `manual`. * If this is not specified, the default is `manual`.
The following HP 3PAR extra-specs are used when creating NFS shares: The following HPE 3PAR extra-specs are used when creating NFS shares:
- `hp3par:nfs_options` = Comma separated list of NFS export options - `hpe3par:nfs_options` = Comma separated list of NFS export options
The NFS export options have the following limitations: The NFS export options have the following limitations:
* `ro` and `rw` are not allowed (Manila will determine the read-only option) * `ro` and `rw` are not allowed (Manila will determine the read-only option)
* `no_subtree_check` and `fsid` are not allowed per HP 3PAR CLI support * `no_subtree_check` and `fsid` are not allowed per HPE 3PAR CLI support
* `(in)secure` and `(no_)root_squash` are not allowed because the HP 3PAR * `(in)secure` and `(no_)root_squash` are not allowed because the HPE 3PAR
driver controls those settings driver controls those settings
All other NFS options are forwarded to the HP 3PAR as part of share creation. All other NFS options are forwarded to the HPE 3PAR as part of share creation.
The HP 3PAR will do additional validation at share creation time. Refer to The HPE 3PAR will do additional validation at share creation time. Refer to
HP 3PAR CLI help for more details. HPE 3PAR CLI help for more details.
The :mod:`manila.share.drivers.hp.hp_3par_driver` Module The :mod:`manila.share.drivers.hpe.hpe_3par_driver` Module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: manila.share.drivers.hp.hp_3par_driver .. automodule:: manila.share.drivers.hpe.hpe_3par_driver
:noindex: :noindex:
:members: :members:
:undoc-members: :undoc-members:

View File

@ -106,7 +106,7 @@ Share backends
huawei_nas_driver huawei_nas_driver
hdfs_native_driver hdfs_native_driver
hds_hnas_driver hds_hnas_driver
hp_3par_driver hpe_3par_driver
Indices and tables Indices and tables
------------------ ------------------

View File

@ -49,7 +49,7 @@ Mapping of share drivers and share features support
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+ +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
| Hitachi HNAS | DHSS = False (L) | L | L | \- | L | L | | Hitachi HNAS | DHSS = False (L) | L | L | \- | L | L |
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+ +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
| HP 3PAR | DHSS = True (L) & False (K) | \- | \- | \- | K | K | | HPE 3PAR | DHSS = True (L) & False (K) | \- | \- | \- | K | K |
+----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+ +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+
| Huawei | DHSS = False(K) | L | L | L | K | \- | | Huawei | DHSS = False(K) | L | L | L | K | \- |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -90,7 +90,7 @@ Mapping of share drivers and share access rules support
+----------------------------------------+--------------+------------+------------+--------------+------------+------------+ +----------------------------------------+--------------+------------+------------+--------------+------------+------------+
| Hitachi HNAS | NFS (L) | \- | \- | NFS (L) | \- | \- | | Hitachi HNAS | NFS (L) | \- | \- | NFS (L) | \- | \- |
+----------------------------------------+--------------+------------+------------+--------------+------------+------------+ +----------------------------------------+--------------+------------+------------+--------------+------------+------------+
| HP 3PAR | NFS,CIFS (K) | CIFS (K) | \- | \- | \- | \- | | HPE 3PAR | NFS,CIFS (K) | CIFS (K) | \- | \- | \- | \- |
+----------------------------------------+--------------+------------+------------+--------------+------------+------------+ +----------------------------------------+--------------+------------+------------+--------------+------------+------------+
| Huawei | NFS (K) | CIFS (K) | \- | NFS (K) | CIFS (K) | \- | | Huawei | NFS (K) | CIFS (K) | \- | NFS (K) | CIFS (K) | \- |
+----------------------------------------+--------------+------------+------------+--------------+------------+------------+ +----------------------------------------+--------------+------------+------------+--------------+------------+------------+
@ -125,7 +125,7 @@ Mapping of share drivers and security services support
+----------------------------------------+------------------+-----------------+------------------+ +----------------------------------------+------------------+-----------------+------------------+
| Hitachi HNAS | \- | \- | \- | | Hitachi HNAS | \- | \- | \- |
+----------------------------------------+------------------+-----------------+------------------+ +----------------------------------------+------------------+-----------------+------------------+
| HP 3PAR | \- | \- | \- | | HPE 3PAR | \- | \- | \- |
+----------------------------------------+------------------+-----------------+------------------+ +----------------------------------------+------------------+-----------------+------------------+
| Huawei | \- | \- | \- | | Huawei | \- | \- | \- |
+----------------------------------------+------------------+-----------------+------------------+ +----------------------------------------+------------------+-----------------+------------------+

View File

@ -599,15 +599,15 @@ class EMCVnxInvalidMoverID(ManilaException):
message = _("Invalid mover or vdm %(id)s.") message = _("Invalid mover or vdm %(id)s.")
class HP3ParInvalidClient(Invalid): class HPE3ParInvalidClient(Invalid):
message = _("%(err)s") message = _("%(err)s")
class HP3ParInvalid(Invalid): class HPE3ParInvalid(Invalid):
message = _("%(err)s") message = _("%(err)s")
class HP3ParUnexpectedError(ManilaException): class HPE3ParUnexpectedError(ManilaException):
message = _("%(err)s") message = _("%(err)s")

View File

@ -60,7 +60,7 @@ import manila.share.drivers.glusterfs.layout_directory
import manila.share.drivers.glusterfs.layout_volume import manila.share.drivers.glusterfs.layout_volume
import manila.share.drivers.hdfs.hdfs_native import manila.share.drivers.hdfs.hdfs_native
import manila.share.drivers.hitachi.hds_hnas import manila.share.drivers.hitachi.hds_hnas
import manila.share.drivers.hp.hp_3par_driver import manila.share.drivers.hpe.hpe_3par_driver
import manila.share.drivers.huawei.huawei_nas import manila.share.drivers.huawei.huawei_nas
import manila.share.drivers.ibm.gpfs import manila.share.drivers.ibm.gpfs
import manila.share.drivers.netapp.options import manila.share.drivers.netapp.options
@ -122,7 +122,7 @@ _global_opt_lists = [
manila.share.drivers.glusterfs.layout_volume.glusterfs_volume_mapped_opts, manila.share.drivers.glusterfs.layout_volume.glusterfs_volume_mapped_opts,
manila.share.drivers.hdfs.hdfs_native.hdfs_native_share_opts, manila.share.drivers.hdfs.hdfs_native.hdfs_native_share_opts,
manila.share.drivers.hitachi.hds_hnas.hds_hnas_opts, manila.share.drivers.hitachi.hds_hnas.hds_hnas_opts,
manila.share.drivers.hp.hp_3par_driver.HP3PAR_OPTS, manila.share.drivers.hpe.hpe_3par_driver.HPE3PAR_OPTS,
manila.share.drivers.huawei.huawei_nas.huawei_opts, manila.share.drivers.huawei.huawei_nas.huawei_opts,
manila.share.drivers.ibm.gpfs.gpfs_share_opts, manila.share.drivers.ibm.gpfs.gpfs_share_opts,
manila.share.drivers.netapp.options.netapp_proxy_opts, manila.share.drivers.netapp.options.netapp_proxy_opts,

View File

@ -1,4 +1,4 @@
# Copyright 2015 Hewlett Packard Development Company, L.P. # Copyright 2015 Hewlett Packard Enterprise Development LP
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""HP 3PAR Driver for OpenStack Manila.""" """HPE 3PAR Driver for OpenStack Manila."""
import datetime import datetime
import hashlib import hashlib
@ -29,79 +29,93 @@ from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.i18n import _LI from manila.i18n import _LI
from manila.share import driver from manila.share import driver
from manila.share.drivers.hp import hp_3par_mediator from manila.share.drivers.hpe import hpe_3par_mediator
from manila.share import share_types from manila.share import share_types
from manila import utils from manila import utils
HP3PAR_OPTS = [ HPE3PAR_OPTS = [
cfg.StrOpt('hp3par_api_url', cfg.StrOpt('hpe3par_api_url',
default='', default='',
help="3PAR WSAPI Server Url like " help="3PAR WSAPI Server Url like "
"https://<3par ip>:8080/api/v1"), "https://<3par ip>:8080/api/v1",
cfg.StrOpt('hp3par_username', deprecated_name='hp3par_api_url'),
cfg.StrOpt('hpe3par_username',
default='', default='',
help="3PAR username with the 'edit' role"), help="3PAR username with the 'edit' role",
cfg.StrOpt('hp3par_password', deprecated_name='hp3par_username'),
cfg.StrOpt('hpe3par_password',
default='', default='',
help="3PAR password for the user specified in hp3par_username", help="3PAR password for the user specified in hpe3par_username",
secret=True), secret=True,
cfg.StrOpt('hp3par_san_ip', deprecated_name='hp3par_password'),
cfg.StrOpt('hpe3par_san_ip',
default='', default='',
help="IP address of SAN controller"), help="IP address of SAN controller",
cfg.StrOpt('hp3par_san_login', deprecated_name='hp3par_san_ip'),
cfg.StrOpt('hpe3par_san_login',
default='', default='',
help="Username for SAN controller"), help="Username for SAN controller",
cfg.StrOpt('hp3par_san_password', deprecated_name='hp3par_san_login'),
cfg.StrOpt('hpe3par_san_password',
default='', default='',
help="Password for SAN controller", help="Password for SAN controller",
secret=True), secret=True,
cfg.PortOpt('hp3par_san_ssh_port', deprecated_name='hp3par_san_password'),
cfg.PortOpt('hpe3par_san_ssh_port',
default=22, default=22,
help='SSH port to use with SAN'), help='SSH port to use with SAN',
cfg.StrOpt('hp3par_fpg', deprecated_name='hp3par_san_ssh_port'),
cfg.StrOpt('hpe3par_fpg',
default="OpenStack", default="OpenStack",
help="The File Provisioning Group (FPG) to use"), help="The File Provisioning Group (FPG) to use",
cfg.StrOpt('hp3par_share_ip_address', deprecated_name='hp3par_fpg'),
cfg.StrOpt('hpe3par_share_ip_address',
default='', default='',
help="The IP address for shares not using a share server"), help="The IP address for shares not using a share server",
cfg.BoolOpt('hp3par_fstore_per_share', deprecated_name='hp3par_share_ip_address'),
cfg.BoolOpt('hpe3par_fstore_per_share',
default=False, default=False,
help="Use one filestore per share"), help="Use one filestore per share",
cfg.BoolOpt('hp3par_debug', deprecated_name='hp3par_fstore_per_share'),
cfg.BoolOpt('hpe3par_debug',
default=False, default=False,
help="Enable HTTP debugging to 3PAR"), help="Enable HTTP debugging to 3PAR",
deprecated_name='hp3par_debug'),
] ]
CONF = cfg.CONF CONF = cfg.CONF
CONF.register_opts(HP3PAR_OPTS) CONF.register_opts(HPE3PAR_OPTS)
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class HP3ParShareDriver(driver.ShareDriver): class HPE3ParShareDriver(driver.ShareDriver):
"""HP 3PAR driver for Manila. """HPE 3PAR driver for Manila.
Supports NFS and CIFS protocols on arrays with File Persona. Supports NFS and CIFS protocols on arrays with File Persona.
Version history: Version history:
1.0.00 - Begin Liberty development (post-Kilo) 1.0.0 - Begin Liberty development (post-Kilo)
1.0.01 - Report thin/dedup/hp_flash_cache capabilities 1.0.1 - Report thin/dedup/hp_flash_cache capabilities
1.0.02 - Add share server/share network support 1.0.2 - Add share server/share network support
2.0.0 - Rebranded HP to HPE
""" """
VERSION = "1.0.02" VERSION = "2.0.0"
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(HP3ParShareDriver, self).__init__((True, False), *args, **kwargs) super(HPE3ParShareDriver, self).__init__((True, False),
*args,
**kwargs)
self.configuration = kwargs.get('configuration', None) self.configuration = kwargs.get('configuration', None)
self.configuration.append_config_values(HP3PAR_OPTS) self.configuration.append_config_values(HPE3PAR_OPTS)
self.configuration.append_config_values(driver.ssh_opts) self.configuration.append_config_values(driver.ssh_opts)
self.fpg = None self.fpg = None
self.vfs = None self.vfs = None
self.share_ip_address = None self.share_ip_address = None
self._hp3par = None # mediator between driver and client self._hpe3par = None # mediator between driver and client
def do_setup(self, context): def do_setup(self, context):
"""Any initialization the share driver does while starting.""" """Any initialization the share driver does while starting."""
@ -111,46 +125,47 @@ class HP3ParShareDriver(driver.ShareDriver):
'version': self.VERSION}) 'version': self.VERSION})
if not self.driver_handles_share_servers: if not self.driver_handles_share_servers:
self.share_ip_address = self.configuration.hp3par_share_ip_address self.share_ip_address = self.configuration.hpe3par_share_ip_address
if not self.share_ip_address: if not self.share_ip_address:
raise exception.HP3ParInvalid( raise exception.HPE3ParInvalid(
_("Unsupported configuration. " _("Unsupported configuration. "
"hp3par_share_ip_address must be set when " "hpe3par_share_ip_address must be set when "
"driver_handles_share_servers is False.")) "driver_handles_share_servers is False."))
mediator = hp_3par_mediator.HP3ParMediator( mediator = hpe_3par_mediator.HPE3ParMediator(
hp3par_username=self.configuration.hp3par_username, hpe3par_username=self.configuration.hpe3par_username,
hp3par_password=self.configuration.hp3par_password, hpe3par_password=self.configuration.hpe3par_password,
hp3par_api_url=self.configuration.hp3par_api_url, hpe3par_api_url=self.configuration.hpe3par_api_url,
hp3par_debug=self.configuration.hp3par_debug, hpe3par_debug=self.configuration.hpe3par_debug,
hp3par_san_ip=self.configuration.hp3par_san_ip, hpe3par_san_ip=self.configuration.hpe3par_san_ip,
hp3par_san_login=self.configuration.hp3par_san_login, hpe3par_san_login=self.configuration.hpe3par_san_login,
hp3par_san_password=self.configuration.hp3par_san_password, hpe3par_san_password=self.configuration.hpe3par_san_password,
hp3par_san_ssh_port=self.configuration.hp3par_san_ssh_port, hpe3par_san_ssh_port=self.configuration.hpe3par_san_ssh_port,
hp3par_fstore_per_share=self.configuration.hp3par_fstore_per_share, hpe3par_fstore_per_share=(self.configuration
.hpe3par_fstore_per_share),
ssh_conn_timeout=self.configuration.ssh_conn_timeout, ssh_conn_timeout=self.configuration.ssh_conn_timeout,
) )
mediator.do_setup() mediator.do_setup()
# FPG must be configured and must exist. # FPG must be configured and must exist.
self.fpg = self.configuration.safe_get('hp3par_fpg') self.fpg = self.configuration.safe_get('hpe3par_fpg')
# Validate the FPG and discover the VFS # Validate the FPG and discover the VFS
# This also validates the client, connection, firmware, WSAPI, FPG... # This also validates the client, connection, firmware, WSAPI, FPG...
self.vfs = mediator.get_vfs_name(self.fpg) self.vfs = mediator.get_vfs_name(self.fpg)
# Don't set _hp3par until it is ready. Otherwise _update_stats fails. # Don't set _hpe3par until it is ready. Otherwise _update_stats fails.
self._hp3par = mediator self._hpe3par = mediator
def check_for_setup_error(self): def check_for_setup_error(self):
try: try:
# Log the source SHA for support. Only do this with DEBUG. # Log the source SHA for support. Only do this with DEBUG.
if LOG.isEnabledFor(logging.DEBUG): if LOG.isEnabledFor(logging.DEBUG):
LOG.debug('HP3ParShareDriver SHA1: %s', LOG.debug('HPE3ParShareDriver SHA1: %s',
self.sha1_hash(HP3ParShareDriver)) self.sha1_hash(HPE3ParShareDriver))
LOG.debug('HP3ParMediator SHA1: %s', LOG.debug('HPE3ParMediator SHA1: %s',
self.sha1_hash(hp_3par_mediator.HP3ParMediator)) self.sha1_hash(hpe_3par_mediator.HPE3ParMediator))
except Exception as e: except Exception as e:
# Don't let any exceptions during the SHA1 logging interfere # Don't let any exceptions during the SHA1 logging interfere
# with startup. This is just debug info to identify the source # with startup. This is just debug info to identify the source
@ -192,7 +207,7 @@ class HP3ParShareDriver(driver.ShareDriver):
subnet = utils.cidr_to_netmask(network_info['cidr']) subnet = utils.cidr_to_netmask(network_info['cidr'])
vlantag = network_info['segmentation_id'] vlantag = network_info['segmentation_id']
self._hp3par.create_fsip(ip, subnet, vlantag, self.fpg, self.vfs) self._hpe3par.create_fsip(ip, subnet, vlantag, self.fpg, self.vfs)
return { return {
'share_server_name': network_info['server_id'], 'share_server_name': network_info['server_id'],
@ -207,9 +222,9 @@ class HP3ParShareDriver(driver.ShareDriver):
def _teardown_server(self, server_details, security_services=None): def _teardown_server(self, server_details, security_services=None):
LOG.debug("begin _teardown_server with %s", server_details) LOG.debug("begin _teardown_server with %s", server_details)
self._hp3par.remove_fsip(server_details.get('ip'), self._hpe3par.remove_fsip(server_details.get('ip'),
server_details.get('fpg'), server_details.get('fpg'),
server_details.get('vfs')) server_details.get('vfs'))
def _get_share_ip(self, share_server): def _get_share_ip(self, share_server):
return share_server['backend_details'].get('ip') if share_server else ( return share_server['backend_details'].get('ip') if share_server else (
@ -261,7 +276,7 @@ class HP3ParShareDriver(driver.ShareDriver):
protocol = share['share_proto'] protocol = share['share_proto']
extra_specs = share_types.get_extra_specs_from_share(share) extra_specs = share_types.get_extra_specs_from_share(share)
path = self._hp3par.create_share( path = self._hpe3par.create_share(
share['project_id'], share['project_id'],
share['id'], share['id'],
protocol, protocol,
@ -282,7 +297,7 @@ class HP3ParShareDriver(driver.ShareDriver):
protocol = share['share_proto'] protocol = share['share_proto']
extra_specs = share_types.get_extra_specs_from_share(share) extra_specs = share_types.get_extra_specs_from_share(share)
path = self._hp3par.create_share_from_snapshot( path = self._hpe3par.create_share_from_snapshot(
share['id'], share['id'],
protocol, protocol,
extra_specs, extra_specs,
@ -300,38 +315,48 @@ class HP3ParShareDriver(driver.ShareDriver):
def delete_share(self, context, share, share_server=None): def delete_share(self, context, share, share_server=None):
"""Deletes share and its fstore.""" """Deletes share and its fstore."""
self._hp3par.delete_share(share['project_id'], self._hpe3par.delete_share(share['project_id'],
share['id'], share['id'],
share['share_proto'], share['share_proto'],
self.fpg, self.fpg,
self.vfs) self.vfs)
def create_snapshot(self, context, snapshot, share_server=None): def create_snapshot(self, context, snapshot, share_server=None):
"""Creates a snapshot of a share.""" """Creates a snapshot of a share."""
self._hp3par.create_snapshot(snapshot['share']['project_id'], self._hpe3par.create_snapshot(snapshot['share']['project_id'],
snapshot['share']['id'], snapshot['share']['id'],
snapshot['share']['share_proto'], snapshot['share']['share_proto'],
snapshot['id'], snapshot['id'],
self.fpg, self.fpg,
self.vfs) self.vfs)
def delete_snapshot(self, context, snapshot, share_server=None): def delete_snapshot(self, context, snapshot, share_server=None):
"""Deletes a snapshot of a share.""" """Deletes a snapshot of a share."""
self._hp3par.delete_snapshot(snapshot['share']['project_id'], self._hpe3par.delete_snapshot(snapshot['share']['project_id'],
snapshot['share']['id'], snapshot['share']['id'],
snapshot['share']['share_proto'], snapshot['share']['share_proto'],
snapshot['id'], snapshot['id'],
self.fpg, self.fpg,
self.vfs) self.vfs)
def ensure_share(self, context, share, share_server=None): def ensure_share(self, context, share, share_server=None):
pass pass
def allow_access(self, context, share, access, share_server=None): def allow_access(self, context, share, access, share_server=None):
"""Allow access to the share.""" """Allow access to the share."""
self._hp3par.allow_access(share['project_id'], self._hpe3par.allow_access(share['project_id'],
share['id'],
share['share_proto'],
access['access_type'],
access['access_to'],
self.fpg,
self.vfs)
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
self._hpe3par.deny_access(share['project_id'],
share['id'], share['id'],
share['share_proto'], share['share_proto'],
access['access_type'], access['access_type'],
@ -339,21 +364,11 @@ class HP3ParShareDriver(driver.ShareDriver):
self.fpg, self.fpg,
self.vfs) self.vfs)
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
self._hp3par.deny_access(share['project_id'],
share['id'],
share['share_proto'],
access['access_type'],
access['access_to'],
self.fpg,
self.vfs)
def _update_share_stats(self): def _update_share_stats(self):
"""Retrieve stats info from share group.""" """Retrieve stats info from share group."""
backend_name = self.configuration.safe_get( backend_name = self.configuration.safe_get(
'share_backend_name') or "HP_3PAR" 'share_backend_name') or "HPE_3PAR"
max_over_subscription_ratio = self.configuration.safe_get( max_over_subscription_ratio = self.configuration.safe_get(
'max_over_subscription_ratio') 'max_over_subscription_ratio')
@ -366,7 +381,7 @@ class HP3ParShareDriver(driver.ShareDriver):
stats = { stats = {
'share_backend_name': backend_name, 'share_backend_name': backend_name,
'driver_handles_share_servers': self.driver_handles_share_servers, 'driver_handles_share_servers': self.driver_handles_share_servers,
'vendor_name': 'HP', 'vendor_name': 'HPE',
'driver_version': self.VERSION, 'driver_version': self.VERSION,
'storage_protocol': 'NFS_CIFS', 'storage_protocol': 'NFS_CIFS',
'total_capacity_gb': 0, 'total_capacity_gb': 0,
@ -378,13 +393,13 @@ class HP3ParShareDriver(driver.ShareDriver):
'thin_provisioning': True, # 3PAR default is thin 'thin_provisioning': True, # 3PAR default is thin
} }
if not self._hp3par: if not self._hpe3par:
LOG.info( LOG.info(
_LI("Skipping capacity and capabilities update. Setup has not " _LI("Skipping capacity and capabilities update. Setup has not "
"completed.")) "completed."))
else: else:
fpg_status = self._hp3par.get_fpg_status(self.fpg) fpg_status = self._hpe3par.get_fpg_status(self.fpg)
LOG.debug("FPG status = %s.", fpg_status) LOG.debug("FPG status = %s.", fpg_status)
stats.update(fpg_status) stats.update(fpg_status)
super(HP3ParShareDriver, self)._update_share_stats(stats) super(HPE3ParShareDriver, self)._update_share_stats(stats)

View File

@ -1,4 +1,4 @@
# Copyright 2015 Hewlett Packard Development Company, L.P. # Copyright 2015 Hewlett Packard Enterprise Development LP
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""HP 3PAR Mediator for OpenStack Manila. """HPE 3PAR Mediator for OpenStack Manila.
This 'mediator' de-couples the 3PAR focused client from the OpenStack focused This 'mediator' de-couples the 3PAR focused client from the OpenStack focused
driver. driver.
@ -26,14 +26,13 @@ import six
from manila import exception from manila import exception
from manila.i18n import _, _LI, _LW from manila.i18n import _, _LI, _LW
hp3parclient = importutils.try_import("hp3parclient") hpe3parclient = importutils.try_import("hpe3parclient")
if hp3parclient: if hpe3parclient:
from hp3parclient import file_client from hpe3parclient import file_client
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
MIN_CLIENT_VERSION = (3, 2, 1) MIN_CLIENT_VERSION = (4, 0, 0)
MIN_SMB_CA_VERSION = (3, 2, 2)
DENY = '-' DENY = '-'
ALLOW = '+' ALLOW = '+'
OPEN_STACK_MANILA = 'OpenStack Manila' OPEN_STACK_MANILA = 'OpenStack Manila'
@ -52,31 +51,32 @@ SMB_EXTRA_SPECS_MAP = {
} }
class HP3ParMediator(object): class HPE3ParMediator(object):
"""3PAR client-facing code for the 3PAR driver. """3PAR client-facing code for the 3PAR driver.
Version history: Version history:
1.0.00 - Begin Liberty development (post-Kilo) 1.0.0 - Begin Liberty development (post-Kilo)
1.0.01 - Report thin/dedup/hp_flash_cache capabilities 1.0.1 - Report thin/dedup/hp_flash_cache capabilities
1.0.02 - Add share server/share network support 1.0.2 - Add share server/share network support
1.0.03 - Use hp3par prefix for share types and capabilities 1.0.3 - Use hp3par prefix for share types and capabilities
2.0.0 - Rebranded HP to HPE
""" """
VERSION = "1.0.03" VERSION = "2.0.0"
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.hp3par_username = kwargs.get('hp3par_username') self.hpe3par_username = kwargs.get('hpe3par_username')
self.hp3par_password = kwargs.get('hp3par_password') self.hpe3par_password = kwargs.get('hpe3par_password')
self.hp3par_api_url = kwargs.get('hp3par_api_url') self.hpe3par_api_url = kwargs.get('hpe3par_api_url')
self.hp3par_debug = kwargs.get('hp3par_debug') self.hpe3par_debug = kwargs.get('hpe3par_debug')
self.hp3par_san_ip = kwargs.get('hp3par_san_ip') self.hpe3par_san_ip = kwargs.get('hpe3par_san_ip')
self.hp3par_san_login = kwargs.get('hp3par_san_login') self.hpe3par_san_login = kwargs.get('hpe3par_san_login')
self.hp3par_san_password = kwargs.get('hp3par_san_password') self.hpe3par_san_password = kwargs.get('hpe3par_san_password')
self.hp3par_san_ssh_port = kwargs.get('hp3par_san_ssh_port') self.hpe3par_san_ssh_port = kwargs.get('hpe3par_san_ssh_port')
self.hp3par_san_private_key = kwargs.get('hp3par_san_private_key') self.hpe3par_san_private_key = kwargs.get('hpe3par_san_private_key')
self.hp3par_fstore_per_share = kwargs.get('hp3par_fstore_per_share') self.hpe3par_fstore_per_share = kwargs.get('hpe3par_fstore_per_share')
self.ssh_conn_timeout = kwargs.get('ssh_conn_timeout') self.ssh_conn_timeout = kwargs.get('ssh_conn_timeout')
self._client = None self._client = None
@ -84,61 +84,61 @@ class HP3ParMediator(object):
@staticmethod @staticmethod
def no_client(): def no_client():
return hp3parclient is None return hpe3parclient is None
def do_setup(self): def do_setup(self):
if self.no_client(): if self.no_client():
msg = _('You must install hp3parclient before using the 3PAR ' msg = _('You must install hpe3parclient before using the 3PAR '
'driver.') 'driver.')
LOG.error(msg) LOG.error(msg)
raise exception.HP3ParInvalidClient(message=msg) raise exception.HPE3ParInvalidClient(message=msg)
self.client_version = hp3parclient.version_tuple self.client_version = hpe3parclient.version_tuple
if self.client_version < MIN_CLIENT_VERSION: if self.client_version < MIN_CLIENT_VERSION:
msg = (_('Invalid hp3parclient version found (%(found)s). ' msg = (_('Invalid hpe3parclient version found (%(found)s). '
'Version %(minimum)s or greater required.') % 'Version %(minimum)s or greater required.') %
{'found': '.'.join(map(six.text_type, self.client_version)), {'found': '.'.join(map(six.text_type, self.client_version)),
'minimum': '.'.join(map(six.text_type, 'minimum': '.'.join(map(six.text_type,
MIN_CLIENT_VERSION))}) MIN_CLIENT_VERSION))})
LOG.error(msg) LOG.error(msg)
raise exception.HP3ParInvalidClient(message=msg) raise exception.HPE3ParInvalidClient(message=msg)
try: try:
self._client = file_client.HP3ParFilePersonaClient( self._client = file_client.HPE3ParFilePersonaClient(
self.hp3par_api_url) self.hpe3par_api_url)
except Exception as e: except Exception as e:
msg = (_('Failed to connect to HP 3PAR File Persona Client: %s') % msg = (_('Failed to connect to HPE 3PAR File Persona Client: %s') %
six.text_type(e)) six.text_type(e))
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(message=msg) raise exception.ShareBackendException(message=msg)
try: try:
ssh_kwargs = {} ssh_kwargs = {}
if self.hp3par_san_ssh_port: if self.hpe3par_san_ssh_port:
ssh_kwargs['port'] = self.hp3par_san_ssh_port ssh_kwargs['port'] = self.hpe3par_san_ssh_port
if self.ssh_conn_timeout: if self.ssh_conn_timeout:
ssh_kwargs['conn_timeout'] = self.ssh_conn_timeout ssh_kwargs['conn_timeout'] = self.ssh_conn_timeout
if self.hp3par_san_private_key: if self.hpe3par_san_private_key:
ssh_kwargs['privatekey'] = self.hp3par_san_private_key ssh_kwargs['privatekey'] = self.hpe3par_san_private_key
self._client.setSSHOptions( self._client.setSSHOptions(
self.hp3par_san_ip, self.hpe3par_san_ip,
self.hp3par_san_login, self.hpe3par_san_login,
self.hp3par_san_password, self.hpe3par_san_password,
**ssh_kwargs **ssh_kwargs
) )
except Exception as e: except Exception as e:
msg = (_('Failed to set SSH options for HP 3PAR File Persona ' msg = (_('Failed to set SSH options for HPE 3PAR File Persona '
'Client: %s') % six.text_type(e)) 'Client: %s') % six.text_type(e))
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(message=msg) raise exception.ShareBackendException(message=msg)
LOG.info(_LI("HP3ParMediator %(version)s, " LOG.info(_LI("HPE3ParMediator %(version)s, "
"hp3parclient %(client_version)s"), "hpe3parclient %(client_version)s"),
{"version": self.VERSION, {"version": self.VERSION,
"client_version": hp3parclient.get_version_string()}) "client_version": hpe3parclient.get_version_string()})
try: try:
wsapi_version = self._client.getWsApiVersion()['build'] wsapi_version = self._client.getWsApiVersion()['build']
@ -149,17 +149,17 @@ class HP3ParMediator(object):
LOG.exception(msg) LOG.exception(msg)
raise exception.ShareBackendException(message=msg) raise exception.ShareBackendException(message=msg)
if self.hp3par_debug: if self.hpe3par_debug:
self._client.debug_rest(True) # Includes SSH debug (setSSH above) self._client.debug_rest(True) # Includes SSH debug (setSSH above)
def _wsapi_login(self): def _wsapi_login(self):
try: try:
self._client.login(self.hp3par_username, self.hp3par_password) self._client.login(self.hpe3par_username, self.hpe3par_password)
except Exception as e: except Exception as e:
msg = (_("Failed to Login to 3PAR (%(url)s) as %(user)s " msg = (_("Failed to Login to 3PAR (%(url)s) as %(user)s "
"because: %(err)s") % "because: %(err)s") %
{'url': self.hp3par_api_url, {'url': self.hpe3par_api_url,
'user': self.hp3par_username, 'user': self.hpe3par_username,
'err': six.text_type(e)}) 'err': six.text_type(e)})
LOG.error(msg) LOG.error(msg)
raise exception.ShareBackendException(msg=msg) raise exception.ShareBackendException(msg=msg)
@ -169,7 +169,7 @@ class HP3ParMediator(object):
self._client.http.unauthenticate() self._client.http.unauthenticate()
except Exception as e: except Exception as e:
msg = _LW("Failed to Logout from 3PAR (%(url)s) because %(err)s") msg = _LW("Failed to Logout from 3PAR (%(url)s) because %(err)s")
LOG.warning(msg, {'url': self.hp3par_api_url, LOG.warning(msg, {'url': self.hpe3par_api_url,
'err': six.text_type(e)}) 'err': six.text_type(e)})
# don't raise exception on logout() # don't raise exception on logout()
@ -236,14 +236,15 @@ class HP3ParMediator(object):
thin_provisioning = provisioning_type in (THIN, DEDUPE) thin_provisioning = provisioning_type in (THIN, DEDUPE)
flash_cache_policy = volume_set.get('flashCachePolicy', DISABLED) flash_cache_policy = volume_set.get('flashCachePolicy', DISABLED)
hp3par_flash_cache = flash_cache_policy == ENABLED hpe3par_flash_cache = flash_cache_policy == ENABLED
status = { status = {
'total_capacity_gb': total_capacity_gb, 'total_capacity_gb': total_capacity_gb,
'free_capacity_gb': free_capacity_gb, 'free_capacity_gb': free_capacity_gb,
'thin_provisioning': thin_provisioning, 'thin_provisioning': thin_provisioning,
'dedupe': dedupe, 'dedupe': dedupe,
'hp3par_flash_cache': hp3par_flash_cache, 'hpe3par_flash_cache': hpe3par_flash_cache,
'hp3par_flash_cache': hpe3par_flash_cache,
} }
if thin_provisioning: if thin_provisioning:
@ -266,7 +267,7 @@ class HP3ParMediator(object):
@staticmethod @staticmethod
def other_protocol(share_proto): def other_protocol(share_proto):
"""Given 'nfs' or 'smb' (or equivalent) return the other one.""" """Given 'nfs' or 'smb' (or equivalent) return the other one."""
protocol = HP3ParMediator.ensure_supported_protocol(share_proto) protocol = HPE3ParMediator.ensure_supported_protocol(share_proto)
return 'nfs' if protocol == 'smb' else 'smb' return 'nfs' if protocol == 'smb' else 'smb'
@staticmethod @staticmethod
@ -275,7 +276,7 @@ class HP3ParMediator(object):
return uid return uid
elif protocol: elif protocol:
return 'osf-%s-%s' % ( return 'osf-%s-%s' % (
HP3ParMediator.ensure_supported_protocol(protocol), uid) HPE3ParMediator.ensure_supported_protocol(protocol), uid)
else: else:
return 'osf-%s' % uid return 'osf-%s' % uid
@ -283,7 +284,14 @@ class HP3ParMediator(object):
def _get_nfs_options(extra_specs, readonly): def _get_nfs_options(extra_specs, readonly):
"""Validate the NFS extra_specs and return the options to use.""" """Validate the NFS extra_specs and return the options to use."""
nfs_options = extra_specs.get('hp3par:nfs_options') nfs_options = extra_specs.get('hpe3par:nfs_options')
if nfs_options is None:
nfs_options = extra_specs.get('hp3par:nfs_options')
if nfs_options:
msg = _LW("hp3par:nfs_options is deprecated. Use "
"hpe3par:nfs_options instead.")
LOG.warning(msg)
if nfs_options: if nfs_options:
options = nfs_options.split(',') options = nfs_options.split(',')
else: else:
@ -304,7 +312,8 @@ class HP3ParMediator(object):
] ]
if invalid_options: if invalid_options:
raise exception.InvalidInput(_('Invalid hp3par:nfs_options in ' raise exception.InvalidInput(_('Invalid hp3par:nfs_options or '
'hpe3par:nfs_options in '
'extra-specs. The following ' 'extra-specs. The following '
'options are not allowed: %s') % 'options are not allowed: %s') %
invalid_options) invalid_options)
@ -321,6 +330,12 @@ class HP3ParMediator(object):
fstore=fstore, fstore=fstore,
sharedir=sharedir, sharedir=sharedir,
comment=comment) comment=comment)
if 'hp3par_flash_cache' in extra_specs:
msg = _LW("hp3par_flash_cache is deprecated. Use "
"hpe3par_flash_cache instead.")
LOG.warning(msg)
if protocol == 'nfs': if protocol == 'nfs':
createfshare_kwargs['clientip'] = '127.0.0.1' createfshare_kwargs['clientip'] = '127.0.0.1'
options = self._get_nfs_options(extra_specs, readonly) options = self._get_nfs_options(extra_specs, readonly)
@ -328,13 +343,17 @@ class HP3ParMediator(object):
else: else:
createfshare_kwargs['allowip'] = '127.0.0.1' createfshare_kwargs['allowip'] = '127.0.0.1'
if self.client_version < MIN_SMB_CA_VERSION: smb_opts = (ACCESS_BASED_ENUM, CONTINUOUS_AVAIL, CACHE)
smb_opts = (ACCESS_BASED_ENUM, CACHE)
else:
smb_opts = (ACCESS_BASED_ENUM, CONTINUOUS_AVAIL, CACHE)
for smb_opt in smb_opts: for smb_opt in smb_opts:
opt_value = extra_specs.get('hp3par:smb_%s' % smb_opt) opt_value = extra_specs.get('hpe3par:smb_%s' % smb_opt)
if opt_value is None:
opt_value = extra_specs.get('hp3par:smb_%s' % smb_opt)
if opt_value:
msg = _LW("hp3par:smb_* is deprecated. Use "
"hpe3par:smb_* instead.")
LOG.warning(msg)
if opt_value: if opt_value:
opt_key = SMB_EXTRA_SPECS_MAP[smb_opt] opt_key = SMB_EXTRA_SPECS_MAP[smb_opt]
createfshare_kwargs[opt_key] = opt_value createfshare_kwargs[opt_key] = opt_value
@ -367,14 +386,14 @@ class HP3ParMediator(object):
protocol = self.ensure_supported_protocol(share_proto) protocol = self.ensure_supported_protocol(share_proto)
share_name = self.ensure_prefix(share_id) share_name = self.ensure_prefix(share_id)
if not (sharedir or self.hp3par_fstore_per_share): if not (sharedir or self.hpe3par_fstore_per_share):
sharedir = share_name sharedir = share_name
if fstore: if fstore:
use_existing_fstore = True use_existing_fstore = True
else: else:
use_existing_fstore = False use_existing_fstore = False
if self.hp3par_fstore_per_share: if self.hpe3par_fstore_per_share:
fstore = share_name fstore = share_name
else: else:
fstore = self.ensure_prefix(project_id, protocol) fstore = self.ensure_prefix(project_id, protocol)
@ -401,7 +420,7 @@ class HP3ParMediator(object):
raise exception.ShareBackendException(msg) raise exception.ShareBackendException(msg)
if size: if size:
if self.hp3par_fstore_per_share: if self.hpe3par_fstore_per_share:
hcapacity = six.text_type(size * units.Ki) hcapacity = six.text_type(size * units.Ki)
scapacity = hcapacity scapacity = hcapacity
else: else:
@ -706,10 +725,10 @@ class HP3ParMediator(object):
raise exception.InvalidInput(msg) raise exception.InvalidInput(msg)
if protocol == 'nfs' and access_type != 'ip': if protocol == 'nfs' and access_type != 'ip':
msg = (_("Invalid NFS access type. HP 3PAR NFS supports 'ip'. " msg = (_("Invalid NFS access type. HPE 3PAR NFS supports 'ip'. "
"Actual '%s'.") % access_type) "Actual '%s'.") % access_type)
LOG.error(msg) LOG.error(msg)
raise exception.HP3ParInvalid(msg) raise exception.HPE3ParInvalid(msg)
return protocol return protocol
@ -748,7 +767,7 @@ class HP3ParMediator(object):
msg = (_("Unexpected error: After ensure_supported_protocol " msg = (_("Unexpected error: After ensure_supported_protocol "
"only 'nfs' or 'smb' strings are allowed, but found: " "only 'nfs' or 'smb' strings are allowed, but found: "
"%s.") % protocol) "%s.") % protocol)
raise exception.HP3ParUnexpectedError(msg) raise exception.HPE3ParUnexpectedError(msg)
LOG.debug("setfshare result=%s", result) LOG.debug("setfshare result=%s", result)
except Exception as e: except Exception as e:

View File

@ -98,7 +98,10 @@ CONF.import_opt('periodic_hooks_interval', 'manila.share.hook')
# old/new path here to maintain backward compatibility. # old/new path here to maintain backward compatibility.
MAPPING = { MAPPING = {
'manila.share.drivers.netapp.cluster_mode.NetAppClusteredShareDriver': 'manila.share.drivers.netapp.cluster_mode.NetAppClusteredShareDriver':
'manila.share.drivers.netapp.common.NetAppDriver', } 'manila.share.drivers.netapp.common.NetAppDriver',
'manila.share.drivers.hp.hp_3par_driver.HP3ParShareDriver':
'manila.share.drivers.hpe.hpe_3par_driver.HPE3ParShareDriver',
}
QUOTAS = quota.QUOTAS QUOTAS = quota.QUOTAS

View File

@ -1,4 +1,4 @@
# Copyright 2015 Hewlett Packard Development Company, L.P. # Copyright 2015 Hewlett Packard Enterprise Development LP
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
@ -48,7 +48,7 @@ EXPECTED_STATS = {'test': 'stats'}
EXPECTED_FPG = 'FPG_1' EXPECTED_FPG = 'FPG_1'
EXPECTED_FSTORE = EXPECTED_PROJECT_ID EXPECTED_FSTORE = EXPECTED_PROJECT_ID
EXPECTED_VFS = 'test_vfs' EXPECTED_VFS = 'test_vfs'
EXPECTED_HP_DEBUG = True EXPECTED_HPE_DEBUG = True
EXPECTED_EXTRA_SPECS = {} EXPECTED_EXTRA_SPECS = {}
GET_FSQUOTA = {'message': None, GET_FSQUOTA = {'message': None,

View File

@ -1,4 +1,4 @@
# Copyright 2015 Hewlett Packard Development Company, L.P. # Copyright 2015 Hewlett Packard Enterprise Development LP
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
@ -16,37 +16,37 @@ import sys
import ddt import ddt
import mock import mock
if 'hp3parclient' not in sys.modules: if 'hpe3parclient' not in sys.modules:
sys.modules['hp3parclient'] = mock.Mock() sys.modules['hpe3parclient'] = mock.Mock()
from manila import exception from manila import exception
from manila.share.drivers.hp import hp_3par_driver as hp3pardriver from manila.share.drivers.hpe import hpe_3par_driver as hpe3pardriver
from manila.share.drivers.hp import hp_3par_mediator as hp3parmediator from manila.share.drivers.hpe import hpe_3par_mediator as hpe3parmediator
from manila import test from manila import test
from manila.tests.share.drivers.hp import test_hp_3par_constants as constants from manila.tests.share.drivers.hpe import test_hpe_3par_constants as constants
@ddt.ddt @ddt.ddt
class HP3ParDriverTestCase(test.TestCase): class HPE3ParDriverTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(HP3ParDriverTestCase, self).setUp() super(HPE3ParDriverTestCase, self).setUp()
# Create a mock configuration with attributes and a safe_get() # Create a mock configuration with attributes and a safe_get()
self.conf = mock.Mock() self.conf = mock.Mock()
self.conf.driver_handles_share_servers = True self.conf.driver_handles_share_servers = True
self.conf.hp3par_debug = constants.EXPECTED_HP_DEBUG self.conf.hpe3par_debug = constants.EXPECTED_HPE_DEBUG
self.conf.hp3par_username = constants.USERNAME self.conf.hpe3par_username = constants.USERNAME
self.conf.hp3par_password = constants.PASSWORD self.conf.hpe3par_password = constants.PASSWORD
self.conf.hp3par_api_url = constants.API_URL self.conf.hpe3par_api_url = constants.API_URL
self.conf.hp3par_san_login = constants.SAN_LOGIN self.conf.hpe3par_san_login = constants.SAN_LOGIN
self.conf.hp3par_san_password = constants.SAN_PASSWORD self.conf.hpe3par_san_password = constants.SAN_PASSWORD
self.conf.hp3par_san_ip = constants.EXPECTED_IP_1234 self.conf.hpe3par_san_ip = constants.EXPECTED_IP_1234
self.conf.hp3par_fpg = constants.EXPECTED_FPG self.conf.hpe3par_fpg = constants.EXPECTED_FPG
self.conf.hp3par_san_ssh_port = constants.PORT self.conf.hpe3par_san_ssh_port = constants.PORT
self.conf.ssh_conn_timeout = constants.TIMEOUT self.conf.ssh_conn_timeout = constants.TIMEOUT
self.conf.hp3par_share_ip_address = None self.conf.hpe3par_share_ip_address = None
self.conf.hp3par_fstore_per_share = False self.conf.hpe3par_fstore_per_share = False
self.conf.network_config_group = 'test_network_config_group' self.conf.network_config_group = 'test_network_config_group'
def safe_get(attr): def safe_get(attr):
@ -56,12 +56,12 @@ class HP3ParDriverTestCase(test.TestCase):
return None return None
self.conf.safe_get = safe_get self.conf.safe_get = safe_get
self.real_hp_3par_mediator = hp3parmediator.HP3ParMediator self.real_hpe_3par_mediator = hpe3parmediator.HPE3ParMediator
self.mock_object(hp3parmediator, 'HP3ParMediator') self.mock_object(hpe3parmediator, 'HPE3ParMediator')
self.mock_mediator_constructor = hp3parmediator.HP3ParMediator self.mock_mediator_constructor = hpe3parmediator.HPE3ParMediator
self.mock_mediator = self.mock_mediator_constructor() self.mock_mediator = self.mock_mediator_constructor()
self.driver = hp3pardriver.HP3ParShareDriver( self.driver = hpe3pardriver.HPE3ParShareDriver(
configuration=self.conf) configuration=self.conf)
def test_driver_setup_success(self): def test_driver_setup_success(self):
@ -72,20 +72,20 @@ class HP3ParDriverTestCase(test.TestCase):
self.driver.do_setup(None) self.driver.do_setup(None)
conf = self.conf conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password, hpe3par_san_password=conf.hpe3par_san_password,
hp3par_username=conf.hp3par_username, hpe3par_username=conf.hpe3par_username,
hp3par_san_login=conf.hp3par_san_login, hpe3par_san_login=conf.hpe3par_san_login,
hp3par_debug=conf.hp3par_debug, hpe3par_debug=conf.hpe3par_debug,
hp3par_api_url=conf.hp3par_api_url, hpe3par_api_url=conf.hpe3par_api_url,
hp3par_password=conf.hp3par_password, hpe3par_password=conf.hpe3par_password,
hp3par_san_ip=conf.hp3par_san_ip, hpe3par_san_ip=conf.hpe3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share, hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)]) ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([ self.mock_mediator.assert_has_calls([
mock.call.do_setup(), mock.call.do_setup(),
mock.call.get_vfs_name(conf.hp3par_fpg)]) mock.call.get_vfs_name(conf.hpe3par_fpg)])
self.assertEqual(constants.EXPECTED_VFS, self.driver.vfs) self.assertEqual(constants.EXPECTED_VFS, self.driver.vfs)
@ -93,7 +93,7 @@ class HP3ParDriverTestCase(test.TestCase):
"""Driver do_setup without any errors with dhss=False.""" """Driver do_setup without any errors with dhss=False."""
self.conf.driver_handles_share_servers = False self.conf.driver_handles_share_servers = False
self.conf.hp3par_share_ip_address = constants.EXPECTED_IP_10203040 self.conf.hpe3par_share_ip_address = constants.EXPECTED_IP_10203040
self.test_driver_setup_success() self.test_driver_setup_success()
@ -101,7 +101,7 @@ class HP3ParDriverTestCase(test.TestCase):
"""Configured IP address is required for dhss=False.""" """Configured IP address is required for dhss=False."""
self.conf.driver_handles_share_servers = False self.conf.driver_handles_share_servers = False
self.assertRaises(exception.HP3ParInvalid, self.assertRaises(exception.HPE3ParInvalid,
self.driver.do_setup, None) self.driver.do_setup, None)
def test_driver_with_setup_error(self): def test_driver_with_setup_error(self):
@ -115,15 +115,15 @@ class HP3ParDriverTestCase(test.TestCase):
conf = self.conf conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password, hpe3par_san_password=conf.hpe3par_san_password,
hp3par_username=conf.hp3par_username, hpe3par_username=conf.hpe3par_username,
hp3par_san_login=conf.hp3par_san_login, hpe3par_san_login=conf.hpe3par_san_login,
hp3par_debug=conf.hp3par_debug, hpe3par_debug=conf.hpe3par_debug,
hp3par_api_url=conf.hp3par_api_url, hpe3par_api_url=conf.hpe3par_api_url,
hp3par_password=conf.hp3par_password, hpe3par_password=conf.hpe3par_password,
hp3par_san_ip=conf.hp3par_san_ip, hpe3par_san_ip=conf.hpe3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share, hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)]) ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([mock.call.do_setup()]) self.mock_mediator.assert_has_calls([mock.call.do_setup()])
@ -139,29 +139,29 @@ class HP3ParDriverTestCase(test.TestCase):
conf = self.conf conf = self.conf
self.mock_mediator_constructor.assert_has_calls([ self.mock_mediator_constructor.assert_has_calls([
mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port,
hp3par_san_password=conf.hp3par_san_password, hpe3par_san_password=conf.hpe3par_san_password,
hp3par_username=conf.hp3par_username, hpe3par_username=conf.hpe3par_username,
hp3par_san_login=conf.hp3par_san_login, hpe3par_san_login=conf.hpe3par_san_login,
hp3par_debug=conf.hp3par_debug, hpe3par_debug=conf.hpe3par_debug,
hp3par_api_url=conf.hp3par_api_url, hpe3par_api_url=conf.hpe3par_api_url,
hp3par_password=conf.hp3par_password, hpe3par_password=conf.hpe3par_password,
hp3par_san_ip=conf.hp3par_san_ip, hpe3par_san_ip=conf.hpe3par_san_ip,
hp3par_fstore_per_share=conf.hp3par_fstore_per_share, hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share,
ssh_conn_timeout=conf.ssh_conn_timeout)]) ssh_conn_timeout=conf.ssh_conn_timeout)])
self.mock_mediator.assert_has_calls([ self.mock_mediator.assert_has_calls([
mock.call.do_setup(), mock.call.do_setup(),
mock.call.get_vfs_name(conf.hp3par_fpg)]) mock.call.get_vfs_name(conf.hpe3par_fpg)])
def init_driver(self): def init_driver(self):
"""Simple driver setup for re-use with tests that need one.""" """Simple driver setup for re-use with tests that need one."""
self.driver._hp3par = self.mock_mediator self.driver._hpe3par = self.mock_mediator
self.driver.vfs = constants.EXPECTED_VFS self.driver.vfs = constants.EXPECTED_VFS
self.driver.fpg = constants.EXPECTED_FPG self.driver.fpg = constants.EXPECTED_FPG
self.mock_object(hp3pardriver, 'share_types') self.mock_object(hpe3pardriver, 'share_types')
get_extra_specs = hp3pardriver.share_types.get_extra_specs_from_share get_extra_specs = hpe3pardriver.share_types.get_extra_specs_from_share
get_extra_specs.return_value = constants.EXPECTED_EXTRA_SPECS get_extra_specs.return_value = constants.EXPECTED_EXTRA_SPECS
def do_create_share(self, protocol, share_type_id, expected_project_id, def do_create_share(self, protocol, share_type_id, expected_project_id,
@ -213,29 +213,29 @@ class HP3ParDriverTestCase(test.TestCase):
"""check_for_setup_error when things go well.""" """check_for_setup_error when things go well."""
# Generally this is always mocked, but here we reference the class. # Generally this is always mocked, but here we reference the class.
hp3parmediator.HP3ParMediator = self.real_hp_3par_mediator hpe3parmediator.HPE3ParMediator = self.real_hpe_3par_mediator
self.mock_object(hp3pardriver, 'LOG') self.mock_object(hpe3pardriver, 'LOG')
self.init_driver() self.init_driver()
self.driver.check_for_setup_error() self.driver.check_for_setup_error()
expected_calls = [ expected_calls = [
mock.call.debug('HP3ParShareDriver SHA1: %s', mock.ANY), mock.call.debug('HPE3ParShareDriver SHA1: %s', mock.ANY),
mock.call.debug('HP3ParMediator SHA1: %s', mock.ANY) mock.call.debug('HPE3ParMediator SHA1: %s', mock.ANY)
] ]
hp3pardriver.LOG.assert_has_calls(expected_calls) hpe3pardriver.LOG.assert_has_calls(expected_calls)
def test_driver_check_for_setup_error_exception(self): def test_driver_check_for_setup_error_exception(self):
"""check_for_setup_error catch and log any exceptions.""" """check_for_setup_error catch and log any exceptions."""
# Since HP3ParMediator is mocked, we'll hit the except/log. # Since HPE3ParMediator is mocked, we'll hit the except/log.
self.mock_object(hp3pardriver, 'LOG') self.mock_object(hpe3pardriver, 'LOG')
self.init_driver() self.init_driver()
self.driver.check_for_setup_error() self.driver.check_for_setup_error()
expected_calls = [ expected_calls = [
mock.call.debug('HP3ParShareDriver SHA1: %s', mock.ANY), mock.call.debug('HPE3ParShareDriver SHA1: %s', mock.ANY),
mock.call.debug('Source code SHA1 not logged due to: %s', mock.ANY) mock.call.debug('Source code SHA1 not logged due to: %s', mock.ANY)
] ]
hp3pardriver.LOG.assert_has_calls(expected_calls) hpe3pardriver.LOG.assert_has_calls(expected_calls)
def test_driver_create_cifs_share(self): def test_driver_create_cifs_share(self):
self.init_driver() self.init_driver()
@ -458,7 +458,7 @@ class HP3ParDriverTestCase(test.TestCase):
def test_driver_get_share_stats_not_ready(self): def test_driver_get_share_stats_not_ready(self):
"""Protect against stats update before driver is ready.""" """Protect against stats update before driver is ready."""
self.mock_object(hp3pardriver, 'LOG') self.mock_object(hpe3pardriver, 'LOG')
expected_result = { expected_result = {
'driver_handles_share_servers': True, 'driver_handles_share_servers': True,
@ -468,12 +468,12 @@ class HP3ParDriverTestCase(test.TestCase):
'max_over_subscription_ratio': None, 'max_over_subscription_ratio': None,
'reserved_percentage': 0, 'reserved_percentage': 0,
'provisioned_capacity_gb': 0, 'provisioned_capacity_gb': 0,
'share_backend_name': 'HP_3PAR', 'share_backend_name': 'HPE_3PAR',
'snapshot_support': True, 'snapshot_support': True,
'storage_protocol': 'NFS_CIFS', 'storage_protocol': 'NFS_CIFS',
'thin_provisioning': True, 'thin_provisioning': True,
'total_capacity_gb': 0, 'total_capacity_gb': 0,
'vendor_name': 'HP', 'vendor_name': 'HPE',
'pools': None, 'pools': None,
} }
@ -484,7 +484,7 @@ class HP3ParDriverTestCase(test.TestCase):
mock.call.info('Skipping capacity and capabilities update. ' mock.call.info('Skipping capacity and capabilities update. '
'Setup has not completed.') 'Setup has not completed.')
] ]
hp3pardriver.LOG.assert_has_calls(expected_calls) hpe3pardriver.LOG.assert_has_calls(expected_calls)
def test_driver_get_share_stats_no_refresh(self): def test_driver_get_share_stats_no_refresh(self):
"""Driver does not call mediator when refresh=False.""" """Driver does not call mediator when refresh=False."""
@ -511,6 +511,7 @@ class HP3ParDriverTestCase(test.TestCase):
'thin_provisioning': True, 'thin_provisioning': True,
'dedupe': False, 'dedupe': False,
'hpe3par_flash_cache': False, 'hpe3par_flash_cache': False,
'hp3par_flash_cache': False,
} }
expected_result = { expected_result = {
@ -522,13 +523,14 @@ class HP3ParDriverTestCase(test.TestCase):
'pools': None, 'pools': None,
'provisioned_capacity_gb': 0, 'provisioned_capacity_gb': 0,
'reserved_percentage': 0, 'reserved_percentage': 0,
'share_backend_name': 'HP_3PAR', 'share_backend_name': 'HPE_3PAR',
'storage_protocol': 'NFS_CIFS', 'storage_protocol': 'NFS_CIFS',
'total_capacity_gb': expected_capacity, 'total_capacity_gb': expected_capacity,
'vendor_name': 'HP', 'vendor_name': 'HPE',
'thin_provisioning': True, 'thin_provisioning': True,
'dedupe': False, 'dedupe': False,
'hpe3par_flash_cache': False, 'hpe3par_flash_cache': False,
'hp3par_flash_cache': False,
'snapshot_support': True, 'snapshot_support': True,
} }
@ -557,11 +559,11 @@ class HP3ParDriverTestCase(test.TestCase):
'pools': None, 'pools': None,
'provisioned_capacity_gb': 0, 'provisioned_capacity_gb': 0,
'reserved_percentage': 0, 'reserved_percentage': 0,
'share_backend_name': 'HP_3PAR', 'share_backend_name': 'HPE_3PAR',
'storage_protocol': 'NFS_CIFS', 'storage_protocol': 'NFS_CIFS',
'thin_provisioning': True, 'thin_provisioning': True,
'total_capacity_gb': 0, 'total_capacity_gb': 0,
'vendor_name': 'HP', 'vendor_name': 'HPE',
'snapshot_support': True, 'snapshot_support': True,
} }

View File

@ -1,4 +1,4 @@
# Copyright 2015 Hewlett Packard Development Company, L.P. # Copyright 2015 Hewlett Packard Enterprise Development LP
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain # not use this file except in compliance with the License. You may obtain
@ -16,60 +16,60 @@ import sys
import ddt import ddt
import mock import mock
if 'hp3parclient' not in sys.modules: if 'hpe3parclient' not in sys.modules:
sys.modules['hp3parclient'] = mock.Mock() sys.modules['hpe3parclient'] = mock.Mock()
from manila import exception from manila import exception
from manila.share.drivers.hp import hp_3par_mediator as hp3parmediator from manila.share.drivers.hpe import hpe_3par_mediator as hpe3parmediator
from manila import test from manila import test
from manila.tests.share.drivers.hp import test_hp_3par_constants as constants from manila.tests.share.drivers.hpe import test_hpe_3par_constants as constants
from oslo_utils import units from oslo_utils import units
import six import six
CLIENT_VERSION_MIN_OK = hp3parmediator.MIN_CLIENT_VERSION CLIENT_VERSION_MIN_OK = hpe3parmediator.MIN_CLIENT_VERSION
TEST_WSAPI_VERSION_STR = '30201292' TEST_WSAPI_VERSION_STR = '30201292'
@ddt.ddt @ddt.ddt
class HP3ParMediatorTestCase(test.TestCase): class HPE3ParMediatorTestCase(test.TestCase):
def setUp(self): def setUp(self):
super(HP3ParMediatorTestCase, self).setUp() super(HPE3ParMediatorTestCase, self).setUp()
# This is the fake client to use. # This is the fake client to use.
self.mock_client = mock.Mock() self.mock_client = mock.Mock()
# Take over the hp3parclient module and stub the constructor. # Take over the hpe3parclient module and stub the constructor.
hp3parclient = sys.modules['hp3parclient'] hpe3parclient = sys.modules['hpe3parclient']
hp3parclient.version_tuple = CLIENT_VERSION_MIN_OK hpe3parclient.version_tuple = CLIENT_VERSION_MIN_OK
# Need a fake constructor to return the fake client. # Need a fake constructor to return the fake client.
# This is also be used for constructor error tests. # This is also be used for constructor error tests.
self.mock_object(hp3parclient.file_client, 'HP3ParFilePersonaClient') self.mock_object(hpe3parclient.file_client, 'HPE3ParFilePersonaClient')
self.mock_client_constructor = ( self.mock_client_constructor = (
hp3parclient.file_client.HP3ParFilePersonaClient hpe3parclient.file_client.HPE3ParFilePersonaClient
) )
self.mock_client = self.mock_client_constructor() self.mock_client = self.mock_client_constructor()
# Set the mediator to use in tests. # Set the mediator to use in tests.
self.mediator = hp3parmediator.HP3ParMediator( self.mediator = hpe3parmediator.HPE3ParMediator(
hp3par_username=constants.USERNAME, hpe3par_username=constants.USERNAME,
hp3par_password=constants.PASSWORD, hpe3par_password=constants.PASSWORD,
hp3par_api_url=constants.API_URL, hpe3par_api_url=constants.API_URL,
hp3par_debug=constants.EXPECTED_HP_DEBUG, hpe3par_debug=constants.EXPECTED_HPE_DEBUG,
hp3par_san_ip=constants.EXPECTED_IP_1234, hpe3par_san_ip=constants.EXPECTED_IP_1234,
hp3par_san_login=constants.SAN_LOGIN, hpe3par_san_login=constants.SAN_LOGIN,
hp3par_san_password=constants.SAN_PASSWORD, hpe3par_san_password=constants.SAN_PASSWORD,
hp3par_san_ssh_port=constants.PORT, hpe3par_san_ssh_port=constants.PORT,
ssh_conn_timeout=constants.TIMEOUT) ssh_conn_timeout=constants.TIMEOUT)
def test_mediator_no_client(self): def test_mediator_no_client(self):
"""Test missing hp3parclient error.""" """Test missing hpe3parclient error."""
self.mock_object(hp3parmediator.HP3ParMediator, 'no_client', None) self.mock_object(hpe3parmediator.HPE3ParMediator, 'no_client', None)
self.assertRaises(exception.HP3ParInvalidClient, self.assertRaises(exception.HPE3ParInvalidClient,
self.mediator.do_setup) self.mediator.do_setup)
def test_mediator_setup_client_init_error(self): def test_mediator_setup_client_init_error(self):
@ -154,7 +154,7 @@ class HP3ParMediatorTestCase(test.TestCase):
port=constants.PORT, port=constants.PORT,
conn_timeout=constants.TIMEOUT), conn_timeout=constants.TIMEOUT),
mock.call.getWsApiVersion(), mock.call.getWsApiVersion(),
mock.call.debug_rest(constants.EXPECTED_HP_DEBUG) mock.call.debug_rest(constants.EXPECTED_HPE_DEBUG)
] ]
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -175,7 +175,7 @@ class HP3ParMediatorTestCase(test.TestCase):
"""Test exception during logout.""" """Test exception during logout."""
self.init_mediator() self.init_mediator()
mock_log = self.mock_object(hp3parmediator, 'LOG') mock_log = self.mock_object(hpe3parmediator, 'LOG')
fake_exception = constants.FAKE_EXCEPTION fake_exception = constants.FAKE_EXCEPTION
self.mock_client.http.unauthenticate.side_effect = fake_exception self.mock_client.http.unauthenticate.side_effect = fake_exception
@ -189,21 +189,21 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_client_version_unsupported(self): def test_mediator_client_version_unsupported(self):
"""Try a client with version less than minimum.""" """Try a client with version less than minimum."""
self.hp3parclient = sys.modules['hp3parclient'] self.hpe3parclient = sys.modules['hpe3parclient']
self.hp3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0],
CLIENT_VERSION_MIN_OK[1], CLIENT_VERSION_MIN_OK[1],
CLIENT_VERSION_MIN_OK[2] - 1) CLIENT_VERSION_MIN_OK[2] - 1)
self.assertRaises(exception.HP3ParInvalidClient, self.assertRaises(exception.HPE3ParInvalidClient,
self.init_mediator) self.init_mediator)
def test_mediator_client_version_supported(self): def test_mediator_client_version_supported(self):
"""Try a client with a version greater than the minimum.""" """Try a client with a version greater than the minimum."""
# The setup success already tests the min version. Try version > min. # The setup success already tests the min version. Try version > min.
self.hp3parclient = sys.modules['hp3parclient'] self.hpe3parclient = sys.modules['hpe3parclient']
self.hp3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0],
CLIENT_VERSION_MIN_OK[1], CLIENT_VERSION_MIN_OK[1],
CLIENT_VERSION_MIN_OK[2] + 1) CLIENT_VERSION_MIN_OK[2] + 1)
self.init_mediator() self.init_mediator()
expected_calls = [ expected_calls = [
mock.call.setSSHOptions(constants.EXPECTED_IP_1234, mock.call.setSSHOptions(constants.EXPECTED_IP_1234,
@ -212,7 +212,7 @@ class HP3ParMediatorTestCase(test.TestCase):
port=constants.PORT, port=constants.PORT,
conn_timeout=constants.TIMEOUT), conn_timeout=constants.TIMEOUT),
mock.call.getWsApiVersion(), mock.call.getWsApiVersion(),
mock.call.debug_rest(constants.EXPECTED_HP_DEBUG) mock.call.debug_rest(constants.EXPECTED_HPE_DEBUG)
] ]
self.mock_client.assert_has_calls(expected_calls) self.mock_client.assert_has_calls(expected_calls)
@ -251,7 +251,7 @@ class HP3ParMediatorTestCase(test.TestCase):
createfshare_kwargs['clientip'] = '127.0.0.1' createfshare_kwargs['clientip'] = '127.0.0.1'
# Options from extra-specs. # Options from extra-specs.
opt_string = extra_specs.get('hp3par:nfs_options', []) opt_string = extra_specs.get('hpe3par:nfs_options', [])
opt_list = opt_string.split(',') opt_list = opt_string.split(',')
# Options that the mediator adds. # Options that the mediator adds.
nfs_options = ['rw', 'no_root_squash', 'insecure'] nfs_options = ['rw', 'no_root_squash', 'insecure']
@ -282,18 +282,14 @@ class HP3ParMediatorTestCase(test.TestCase):
else: else:
createfshare_kwargs['allowip'] = '127.0.0.1' createfshare_kwargs['allowip'] = '127.0.0.1'
if client_version < hp3parmediator.MIN_SMB_CA_VERSION: smb_opts = (hpe3parmediator.ACCESS_BASED_ENUM,
smb_opts = (hp3parmediator.ACCESS_BASED_ENUM, hpe3parmediator.CONTINUOUS_AVAIL,
hp3parmediator.CACHE) hpe3parmediator.CACHE)
else:
smb_opts = (hp3parmediator.ACCESS_BASED_ENUM,
hp3parmediator.CONTINUOUS_AVAIL,
hp3parmediator.CACHE)
for smb_opt in smb_opts: for smb_opt in smb_opts:
opt_value = extra_specs.get('hp3par:smb_%s' % smb_opt) opt_value = extra_specs.get('hpe3par:smb_%s' % smb_opt)
if opt_value: if opt_value:
opt_key = hp3parmediator.SMB_EXTRA_SPECS_MAP[smb_opt] opt_key = hpe3parmediator.SMB_EXTRA_SPECS_MAP[smb_opt]
createfshare_kwargs[opt_key] = opt_value createfshare_kwargs[opt_key] = opt_value
expected_calls = [ expected_calls = [
@ -320,25 +316,19 @@ class HP3ParMediatorTestCase(test.TestCase):
def _build_smb_extra_specs(**kwargs): def _build_smb_extra_specs(**kwargs):
extra_specs = {'driver_handles_share_servers': False} extra_specs = {'driver_handles_share_servers': False}
for k, v in kwargs.items(): for k, v in kwargs.items():
extra_specs['hp3par:smb_%s' % k] = v extra_specs['hpe3par:smb_%s' % k] = v
return extra_specs return extra_specs
@ddt.data(((3, 2, 1), None, None, None), @ddt.data(((4, 0, 0), None, None, None),
((3, 2, 1), 'true', None, None), ((4, 0, 0), 'true', None, None),
((3, 2, 1), None, 'false', None), ((4, 0, 0), None, 'false', None),
((3, 2, 1), None, 'false', None), ((4, 0, 0), None, 'false', None),
((3, 2, 1), None, None, 'optimized'), ((4, 0, 0), None, None, 'optimized'),
((3, 2, 1), 'true', 'false', 'optimized'), ((4, 0, 0), 'true', 'false', 'optimized'))
((3, 2, 2), None, None, None),
((3, 2, 2), 'true', None, None),
((3, 2, 2), None, 'false', None),
((3, 2, 2), None, 'false', None),
((3, 2, 2), None, None, 'optimized'),
((3, 2, 2), 'true', 'false', 'optimized'))
@ddt.unpack @ddt.unpack
def test_mediator_create_cifs_share(self, client_version, abe, ca, cache): def test_mediator_create_cifs_share(self, client_version, abe, ca, cache):
self.hp3parclient = sys.modules['hp3parclient'] self.hpe3parclient = sys.modules['hpe3parclient']
self.hp3parclient.version_tuple = client_version self.hpe3parclient.version_tuple = client_version
self.init_mediator() self.init_mediator()
self.mock_client.getfshare.return_value = { self.mock_client.getfshare.return_value = {
@ -384,7 +374,7 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_mediator_create_nfs_share_bad_options(self, nfs_options): def test_mediator_create_nfs_share_bad_options(self, nfs_options):
self.init_mediator() self.init_mediator()
extra_specs = {'hp3par:nfs_options': nfs_options} extra_specs = {'hpe3par:nfs_options': nfs_options}
self.assertRaises(exception.InvalidInput, self.assertRaises(exception.InvalidInput,
self.mediator.create_share, self.mediator.create_share,
@ -411,7 +401,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.mock_client.getfsquota.return_value = constants.GET_FSQUOTA self.mock_client.getfsquota.return_value = constants.GET_FSQUOTA
extra_specs = {'hp3par:nfs_options': nfs_options} extra_specs = {'hpe3par:nfs_options': nfs_options}
location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID, location = self.mediator.create_share(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
@ -424,7 +414,7 @@ class HP3ParMediatorTestCase(test.TestCase):
self.assertEqual(constants.EXPECTED_SHARE_PATH, location) self.assertEqual(constants.EXPECTED_SHARE_PATH, location)
expected_calls = self.get_expected_calls_for_create_share( expected_calls = self.get_expected_calls_for_create_share(
hp3parmediator.MIN_CLIENT_VERSION, hpe3parmediator.MIN_CLIENT_VERSION,
constants.EXPECTED_FPG, constants.EXPECTED_FPG,
constants.EXPECTED_VFS, constants.EXPECTED_VFS,
constants.NFS.lower(), constants.NFS.lower(),
@ -853,7 +843,7 @@ class HP3ParMediatorTestCase(test.TestCase):
# startfsnapclean exception (logged, not raised) # startfsnapclean exception (logged, not raised)
self.mock_client.startfsnapclean.side_effect = Exception( self.mock_client.startfsnapclean.side_effect = Exception(
'startfsnapclean fail.') 'startfsnapclean fail.')
mock_log = self.mock_object(hp3parmediator, 'LOG') mock_log = self.mock_object(hpe3parmediator, 'LOG')
self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID, self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
@ -917,10 +907,11 @@ class HP3ParMediatorTestCase(test.TestCase):
} }
self.mock_client.getVolume.return_value = { self.mock_client.getVolume.return_value = {
'provisioningType': hp3parmediator.DEDUPE} 'provisioningType': hpe3parmediator.DEDUPE}
expected_result = { expected_result = {
'free_capacity_gb': expected_free, 'free_capacity_gb': expected_free,
'hpe3par_flash_cache': False,
'hp3par_flash_cache': False, 'hp3par_flash_cache': False,
'dedupe': True, 'dedupe': True,
'thin_provisioning': True, 'thin_provisioning': True,
@ -1163,7 +1154,7 @@ class HP3ParMediatorTestCase(test.TestCase):
""""Allow user access to nfs share is not supported.""" """"Allow user access to nfs share is not supported."""
self.init_mediator() self.init_mediator()
self.assertRaises(exception.HP3ParInvalid, self.assertRaises(exception.HPE3ParInvalid,
self.mediator.allow_access, self.mediator.allow_access,
constants.EXPECTED_PROJECT_ID, constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID, constants.EXPECTED_SHARE_ID,
@ -1207,13 +1198,13 @@ class HP3ParMediatorTestCase(test.TestCase):
def test_other_protocol(self, protocols, expected_other): def test_other_protocol(self, protocols, expected_other):
for protocol in protocols: for protocol in protocols:
self.assertEqual(expected_other, self.assertEqual(expected_other,
hp3parmediator.HP3ParMediator().other_protocol( hpe3parmediator.HPE3ParMediator().other_protocol(
protocol)) protocol))
@ddt.data('', 'bogus') @ddt.data('', 'bogus')
def test_other_protocol_exception(self, protocol): def test_other_protocol_exception(self, protocol):
self.assertRaises(exception.InvalidInput, self.assertRaises(exception.InvalidInput,
hp3parmediator.HP3ParMediator().other_protocol, hpe3parmediator.HPE3ParMediator().other_protocol,
protocol) protocol)
@ddt.data(('osf-uid', None, 'osf-uid'), @ddt.data(('osf-uid', None, 'osf-uid'),
@ -1223,7 +1214,7 @@ class HP3ParMediatorTestCase(test.TestCase):
@ddt.unpack @ddt.unpack
def test_ensure_prefix(self, uid, protocol, expected): def test_ensure_prefix(self, uid, protocol, expected):
self.assertEqual(expected, self.assertEqual(expected,
hp3parmediator.HP3ParMediator().ensure_prefix( hpe3parmediator.HPE3ParMediator().ensure_prefix(
uid, protocol=protocol)) uid, protocol=protocol))
def test_find_fstore_search(self): def test_find_fstore_search(self):