From a6d7e907142350914aabce048435b0ba77b59d2a Mon Sep 17 00:00:00 2001 From: Anthony Lee Date: Thu, 29 Oct 2015 17:19:48 -0700 Subject: [PATCH] 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 --- ...hp_3par_driver.rst => hpe_3par_driver.rst} | 89 ++++---- doc/source/devref/index.rst | 2 +- ...hare_back_ends_feature_support_mapping.rst | 6 +- manila/exception.py | 6 +- manila/opts.py | 4 +- manila/share/drivers/{hp => hpe}/__init__.py | 0 .../hpe_3par_driver.py} | 207 ++++++++++-------- .../hpe_3par_mediator.py} | 149 +++++++------ manila/share/manager.py | 5 +- .../share/drivers/{hp => hpe}/__init__.py | 0 .../test_hpe_3par_constants.py} | 4 +- .../test_hpe_3par_driver.py} | 150 ++++++------- .../test_hpe_3par_mediator.py} | 133 ++++++----- 13 files changed, 396 insertions(+), 359 deletions(-) rename doc/source/devref/{hp_3par_driver.rst => hpe_3par_driver.rst} (70%) rename manila/share/drivers/{hp => hpe}/__init__.py (100%) rename manila/share/drivers/{hp/hp_3par_driver.py => hpe/hpe_3par_driver.py} (63%) rename manila/share/drivers/{hp/hp_3par_mediator.py => hpe/hpe_3par_mediator.py} (88%) rename manila/tests/share/drivers/{hp => hpe}/__init__.py (100%) rename manila/tests/share/drivers/{hp/test_hp_3par_constants.py => hpe/test_hpe_3par_constants.py} (96%) rename manila/tests/share/drivers/{hp/test_hp_3par_driver.py => hpe/test_hpe_3par_driver.py} (83%) rename manila/tests/share/drivers/{hp/test_hp_3par_mediator.py => hpe/test_hpe_3par_mediator.py} (94%) diff --git a/doc/source/devref/hp_3par_driver.rst b/doc/source/devref/hpe_3par_driver.rst similarity index 70% rename from doc/source/devref/hp_3par_driver.rst rename to doc/source/devref/hpe_3par_driver.rst index 5080d80be8..e8065deb5b 100644 --- a/doc/source/devref/hp_3par_driver.rst +++ b/doc/source/devref/hpe_3par_driver.rst @@ -13,16 +13,21 @@ License for the specific language governing permissions and limitations under the License. -HP 3PAR Driver +HPE 3PAR Driver ============== -The HP 3PAR Manila driver provides NFS and CIFS shared file systems to -OpenStack using HP 3PAR's File Persona capabilities. +The HPE 3PAR Manila driver provides NFS and CIFS shared file systems to +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 -------------------- -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 @@ -58,18 +63,18 @@ Requirements 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 - 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 Virtual File Server (VFS) must be created for the FPG - 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 -file for the HP 3PAR driver: +file for the HPE 3PAR driver: - `share_backend_name` = -- `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 -- `hp3par_fpg` = -- `hp3par_share_ip_address` = -- `hp3par_san_ip` = -- `hp3par_api_url` = <3PAR WS API Server URL> -- `hp3par_username` = <3PAR username with the 'edit' role> -- `hp3par_password` = <3PAR password for the user specified in hp3par_username> -- `hp3par_san_login` = -- `hp3par_san_password` = -- `hp3par_debug` = +- `hpe3par_fpg` = +- `hpe3par_share_ip_address` = +- `hpe3par_san_ip` = +- `hpe3par_api_url` = <3PAR WS API Server URL> +- `hpe3par_username` = <3PAR username with the 'edit' role> +- `hpe3par_password` = <3PAR password for the user specified in hpe3par_username> +- `hpe3par_san_login` = +- `hpe3par_san_password` = +- `hpe3par_debug` = -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 created. Networking must be configured to allow connectivity from clients to shares. @@ -127,23 +132,23 @@ Manila requires that the share type includes the `driver_handles_share_servers` extra-spec. This ensures that the share will be created on a backend that supports the requested 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 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 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 administrator to control which share types are allowed to use FPGs with or 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` = ' True' or ' False' +- `hpe3par_flash_cache` = ' True' or ' False' - `thin_provisioning` = ' True' or ' False' - `dedupe` = ' True' or ' 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. `thin_provisioning` will be reported as True for backends that use thin @@ -155,14 +160,16 @@ over-subscription feature. technology. Scoped extra-specs are used to influence vendor-specific implementation -details. Scoped extra-specs use a prefix followed by a colon. For HP 3PAR -these extra-specs have a prefix of `hp3par`. +details. Scoped extra-specs use a prefix followed by a colon. For HPE 3PAR +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 only the files and directories to which they have been allowed access on the @@ -188,25 +195,25 @@ or earlier. documents. * 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: * `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 - * `(in)secure` and `(no_)root_squash` are not allowed because the HP 3PAR + * `no_subtree_check` and `fsid` are not allowed per HPE 3PAR CLI support + * `(in)secure` and `(no_)root_squash` are not allowed because the HPE 3PAR driver controls those settings -All other NFS options are forwarded to the HP 3PAR as part of share creation. -The HP 3PAR will do additional validation at share creation time. Refer to -HP 3PAR CLI help for more details. +All other NFS options are forwarded to the HPE 3PAR as part of share creation. +The HPE 3PAR will do additional validation at share creation time. Refer to +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: :members: :undoc-members: diff --git a/doc/source/devref/index.rst b/doc/source/devref/index.rst index e5a441a6cc..fe1c898144 100644 --- a/doc/source/devref/index.rst +++ b/doc/source/devref/index.rst @@ -106,7 +106,7 @@ Share backends huawei_nas_driver hdfs_native_driver hds_hnas_driver - hp_3par_driver + hpe_3par_driver Indices and tables ------------------ diff --git a/doc/source/devref/share_back_ends_feature_support_mapping.rst b/doc/source/devref/share_back_ends_feature_support_mapping.rst index a58ae7b607..d306cf4b5f 100644 --- a/doc/source/devref/share_back_ends_feature_support_mapping.rst +++ b/doc/source/devref/share_back_ends_feature_support_mapping.rst @@ -49,7 +49,7 @@ Mapping of share drivers and share features support +----------------------------------------+-----------------------------+-----------------------+--------------+--------------+------------------------+----------------------------+ | 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 | \- | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -90,7 +90,7 @@ Mapping of share drivers and share access rules support +----------------------------------------+--------------+------------+------------+--------------+------------+------------+ | 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) | \- | +----------------------------------------+--------------+------------+------------+--------------+------------+------------+ @@ -125,7 +125,7 @@ Mapping of share drivers and security services support +----------------------------------------+------------------+-----------------+------------------+ | Hitachi HNAS | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ -| HP 3PAR | \- | \- | \- | +| HPE 3PAR | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ | Huawei | \- | \- | \- | +----------------------------------------+------------------+-----------------+------------------+ diff --git a/manila/exception.py b/manila/exception.py index b8fe0b12ee..ed58c9fc40 100644 --- a/manila/exception.py +++ b/manila/exception.py @@ -599,15 +599,15 @@ class EMCVnxInvalidMoverID(ManilaException): message = _("Invalid mover or vdm %(id)s.") -class HP3ParInvalidClient(Invalid): +class HPE3ParInvalidClient(Invalid): message = _("%(err)s") -class HP3ParInvalid(Invalid): +class HPE3ParInvalid(Invalid): message = _("%(err)s") -class HP3ParUnexpectedError(ManilaException): +class HPE3ParUnexpectedError(ManilaException): message = _("%(err)s") diff --git a/manila/opts.py b/manila/opts.py index 69755406ba..e325ec8374 100644 --- a/manila/opts.py +++ b/manila/opts.py @@ -60,7 +60,7 @@ import manila.share.drivers.glusterfs.layout_directory import manila.share.drivers.glusterfs.layout_volume import manila.share.drivers.hdfs.hdfs_native 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.ibm.gpfs 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.hdfs.hdfs_native.hdfs_native_share_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.ibm.gpfs.gpfs_share_opts, manila.share.drivers.netapp.options.netapp_proxy_opts, diff --git a/manila/share/drivers/hp/__init__.py b/manila/share/drivers/hpe/__init__.py similarity index 100% rename from manila/share/drivers/hp/__init__.py rename to manila/share/drivers/hpe/__init__.py diff --git a/manila/share/drivers/hp/hp_3par_driver.py b/manila/share/drivers/hpe/hpe_3par_driver.py similarity index 63% rename from manila/share/drivers/hp/hp_3par_driver.py rename to manila/share/drivers/hpe/hpe_3par_driver.py index 5f7c162158..7a9d516111 100644 --- a/manila/share/drivers/hp/hp_3par_driver.py +++ b/manila/share/drivers/hpe/hpe_3par_driver.py @@ -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 # 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 # under the License. -"""HP 3PAR Driver for OpenStack Manila.""" +"""HPE 3PAR Driver for OpenStack Manila.""" import datetime import hashlib @@ -29,79 +29,93 @@ from manila import exception from manila.i18n import _ from manila.i18n import _LI 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 import utils -HP3PAR_OPTS = [ - cfg.StrOpt('hp3par_api_url', +HPE3PAR_OPTS = [ + cfg.StrOpt('hpe3par_api_url', default='', help="3PAR WSAPI Server Url like " - "https://<3par ip>:8080/api/v1"), - cfg.StrOpt('hp3par_username', + "https://<3par ip>:8080/api/v1", + deprecated_name='hp3par_api_url'), + cfg.StrOpt('hpe3par_username', default='', - help="3PAR username with the 'edit' role"), - cfg.StrOpt('hp3par_password', + help="3PAR username with the 'edit' role", + deprecated_name='hp3par_username'), + cfg.StrOpt('hpe3par_password', default='', - help="3PAR password for the user specified in hp3par_username", - secret=True), - cfg.StrOpt('hp3par_san_ip', + help="3PAR password for the user specified in hpe3par_username", + secret=True, + deprecated_name='hp3par_password'), + cfg.StrOpt('hpe3par_san_ip', default='', - help="IP address of SAN controller"), - cfg.StrOpt('hp3par_san_login', + help="IP address of SAN controller", + deprecated_name='hp3par_san_ip'), + cfg.StrOpt('hpe3par_san_login', default='', - help="Username for SAN controller"), - cfg.StrOpt('hp3par_san_password', + help="Username for SAN controller", + deprecated_name='hp3par_san_login'), + cfg.StrOpt('hpe3par_san_password', default='', help="Password for SAN controller", - secret=True), - cfg.PortOpt('hp3par_san_ssh_port', + secret=True, + deprecated_name='hp3par_san_password'), + cfg.PortOpt('hpe3par_san_ssh_port', default=22, - help='SSH port to use with SAN'), - cfg.StrOpt('hp3par_fpg', + help='SSH port to use with SAN', + deprecated_name='hp3par_san_ssh_port'), + cfg.StrOpt('hpe3par_fpg', default="OpenStack", - help="The File Provisioning Group (FPG) to use"), - cfg.StrOpt('hp3par_share_ip_address', + help="The File Provisioning Group (FPG) to use", + deprecated_name='hp3par_fpg'), + cfg.StrOpt('hpe3par_share_ip_address', default='', - help="The IP address for shares not using a share server"), - cfg.BoolOpt('hp3par_fstore_per_share', + help="The IP address for shares not using a share server", + deprecated_name='hp3par_share_ip_address'), + cfg.BoolOpt('hpe3par_fstore_per_share', default=False, - help="Use one filestore per share"), - cfg.BoolOpt('hp3par_debug', + help="Use one filestore per share", + deprecated_name='hp3par_fstore_per_share'), + cfg.BoolOpt('hpe3par_debug', default=False, - help="Enable HTTP debugging to 3PAR"), + help="Enable HTTP debugging to 3PAR", + deprecated_name='hp3par_debug'), ] CONF = cfg.CONF -CONF.register_opts(HP3PAR_OPTS) +CONF.register_opts(HPE3PAR_OPTS) LOG = log.getLogger(__name__) -class HP3ParShareDriver(driver.ShareDriver): - """HP 3PAR driver for Manila. +class HPE3ParShareDriver(driver.ShareDriver): + """HPE 3PAR driver for Manila. Supports NFS and CIFS protocols on arrays with File Persona. Version history: - 1.0.00 - Begin Liberty development (post-Kilo) - 1.0.01 - Report thin/dedup/hp_flash_cache capabilities - 1.0.02 - Add share server/share network support + 1.0.0 - Begin Liberty development (post-Kilo) + 1.0.1 - Report thin/dedup/hp_flash_cache capabilities + 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): - super(HP3ParShareDriver, self).__init__((True, False), *args, **kwargs) + super(HPE3ParShareDriver, self).__init__((True, False), + *args, + **kwargs) 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.fpg = None self.vfs = 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): """Any initialization the share driver does while starting.""" @@ -111,46 +125,47 @@ class HP3ParShareDriver(driver.ShareDriver): 'version': self.VERSION}) 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: - raise exception.HP3ParInvalid( + raise exception.HPE3ParInvalid( _("Unsupported configuration. " - "hp3par_share_ip_address must be set when " + "hpe3par_share_ip_address must be set when " "driver_handles_share_servers is False.")) - mediator = hp_3par_mediator.HP3ParMediator( - hp3par_username=self.configuration.hp3par_username, - hp3par_password=self.configuration.hp3par_password, - hp3par_api_url=self.configuration.hp3par_api_url, - hp3par_debug=self.configuration.hp3par_debug, - hp3par_san_ip=self.configuration.hp3par_san_ip, - hp3par_san_login=self.configuration.hp3par_san_login, - hp3par_san_password=self.configuration.hp3par_san_password, - hp3par_san_ssh_port=self.configuration.hp3par_san_ssh_port, - hp3par_fstore_per_share=self.configuration.hp3par_fstore_per_share, + mediator = hpe_3par_mediator.HPE3ParMediator( + hpe3par_username=self.configuration.hpe3par_username, + hpe3par_password=self.configuration.hpe3par_password, + hpe3par_api_url=self.configuration.hpe3par_api_url, + hpe3par_debug=self.configuration.hpe3par_debug, + hpe3par_san_ip=self.configuration.hpe3par_san_ip, + hpe3par_san_login=self.configuration.hpe3par_san_login, + hpe3par_san_password=self.configuration.hpe3par_san_password, + hpe3par_san_ssh_port=self.configuration.hpe3par_san_ssh_port, + hpe3par_fstore_per_share=(self.configuration + .hpe3par_fstore_per_share), ssh_conn_timeout=self.configuration.ssh_conn_timeout, ) mediator.do_setup() # 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 # This also validates the client, connection, firmware, WSAPI, FPG... self.vfs = mediator.get_vfs_name(self.fpg) - # Don't set _hp3par until it is ready. Otherwise _update_stats fails. - self._hp3par = mediator + # Don't set _hpe3par until it is ready. Otherwise _update_stats fails. + self._hpe3par = mediator def check_for_setup_error(self): try: # Log the source SHA for support. Only do this with DEBUG. if LOG.isEnabledFor(logging.DEBUG): - LOG.debug('HP3ParShareDriver SHA1: %s', - self.sha1_hash(HP3ParShareDriver)) - LOG.debug('HP3ParMediator SHA1: %s', - self.sha1_hash(hp_3par_mediator.HP3ParMediator)) + LOG.debug('HPE3ParShareDriver SHA1: %s', + self.sha1_hash(HPE3ParShareDriver)) + LOG.debug('HPE3ParMediator SHA1: %s', + self.sha1_hash(hpe_3par_mediator.HPE3ParMediator)) except Exception as e: # Don't let any exceptions during the SHA1 logging interfere # 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']) 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 { 'share_server_name': network_info['server_id'], @@ -207,9 +222,9 @@ class HP3ParShareDriver(driver.ShareDriver): def _teardown_server(self, server_details, security_services=None): LOG.debug("begin _teardown_server with %s", server_details) - self._hp3par.remove_fsip(server_details.get('ip'), - server_details.get('fpg'), - server_details.get('vfs')) + self._hpe3par.remove_fsip(server_details.get('ip'), + server_details.get('fpg'), + server_details.get('vfs')) def _get_share_ip(self, share_server): return share_server['backend_details'].get('ip') if share_server else ( @@ -261,7 +276,7 @@ class HP3ParShareDriver(driver.ShareDriver): protocol = share['share_proto'] extra_specs = share_types.get_extra_specs_from_share(share) - path = self._hp3par.create_share( + path = self._hpe3par.create_share( share['project_id'], share['id'], protocol, @@ -282,7 +297,7 @@ class HP3ParShareDriver(driver.ShareDriver): protocol = share['share_proto'] 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'], protocol, extra_specs, @@ -300,38 +315,48 @@ class HP3ParShareDriver(driver.ShareDriver): def delete_share(self, context, share, share_server=None): """Deletes share and its fstore.""" - self._hp3par.delete_share(share['project_id'], - share['id'], - share['share_proto'], - self.fpg, - self.vfs) + self._hpe3par.delete_share(share['project_id'], + share['id'], + share['share_proto'], + self.fpg, + self.vfs) def create_snapshot(self, context, snapshot, share_server=None): """Creates a snapshot of a share.""" - self._hp3par.create_snapshot(snapshot['share']['project_id'], - snapshot['share']['id'], - snapshot['share']['share_proto'], - snapshot['id'], - self.fpg, - self.vfs) + self._hpe3par.create_snapshot(snapshot['share']['project_id'], + snapshot['share']['id'], + snapshot['share']['share_proto'], + snapshot['id'], + self.fpg, + self.vfs) def delete_snapshot(self, context, snapshot, share_server=None): """Deletes a snapshot of a share.""" - self._hp3par.delete_snapshot(snapshot['share']['project_id'], - snapshot['share']['id'], - snapshot['share']['share_proto'], - snapshot['id'], - self.fpg, - self.vfs) + self._hpe3par.delete_snapshot(snapshot['share']['project_id'], + snapshot['share']['id'], + snapshot['share']['share_proto'], + snapshot['id'], + self.fpg, + self.vfs) def ensure_share(self, context, share, share_server=None): pass def allow_access(self, context, share, access, share_server=None): """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['share_proto'], access['access_type'], @@ -339,21 +364,11 @@ class HP3ParShareDriver(driver.ShareDriver): self.fpg, 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): """Retrieve stats info from share group.""" 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') @@ -366,7 +381,7 @@ class HP3ParShareDriver(driver.ShareDriver): stats = { 'share_backend_name': backend_name, 'driver_handles_share_servers': self.driver_handles_share_servers, - 'vendor_name': 'HP', + 'vendor_name': 'HPE', 'driver_version': self.VERSION, 'storage_protocol': 'NFS_CIFS', 'total_capacity_gb': 0, @@ -378,13 +393,13 @@ class HP3ParShareDriver(driver.ShareDriver): 'thin_provisioning': True, # 3PAR default is thin } - if not self._hp3par: + if not self._hpe3par: LOG.info( _LI("Skipping capacity and capabilities update. Setup has not " "completed.")) 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) stats.update(fpg_status) - super(HP3ParShareDriver, self)._update_share_stats(stats) + super(HPE3ParShareDriver, self)._update_share_stats(stats) diff --git a/manila/share/drivers/hp/hp_3par_mediator.py b/manila/share/drivers/hpe/hpe_3par_mediator.py similarity index 88% rename from manila/share/drivers/hp/hp_3par_mediator.py rename to manila/share/drivers/hpe/hpe_3par_mediator.py index 2cdc3b807b..5db7302989 100644 --- a/manila/share/drivers/hp/hp_3par_mediator.py +++ b/manila/share/drivers/hpe/hpe_3par_mediator.py @@ -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 # 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 # 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 driver. @@ -26,14 +26,13 @@ import six from manila import exception from manila.i18n import _, _LI, _LW -hp3parclient = importutils.try_import("hp3parclient") -if hp3parclient: - from hp3parclient import file_client +hpe3parclient = importutils.try_import("hpe3parclient") +if hpe3parclient: + from hpe3parclient import file_client LOG = log.getLogger(__name__) -MIN_CLIENT_VERSION = (3, 2, 1) -MIN_SMB_CA_VERSION = (3, 2, 2) +MIN_CLIENT_VERSION = (4, 0, 0) DENY = '-' ALLOW = '+' 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. Version history: - 1.0.00 - Begin Liberty development (post-Kilo) - 1.0.01 - Report thin/dedup/hp_flash_cache capabilities - 1.0.02 - Add share server/share network support - 1.0.03 - Use hp3par prefix for share types and capabilities + 1.0.0 - Begin Liberty development (post-Kilo) + 1.0.1 - Report thin/dedup/hp_flash_cache capabilities + 1.0.2 - Add share server/share network support + 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): - self.hp3par_username = kwargs.get('hp3par_username') - self.hp3par_password = kwargs.get('hp3par_password') - self.hp3par_api_url = kwargs.get('hp3par_api_url') - self.hp3par_debug = kwargs.get('hp3par_debug') - self.hp3par_san_ip = kwargs.get('hp3par_san_ip') - self.hp3par_san_login = kwargs.get('hp3par_san_login') - self.hp3par_san_password = kwargs.get('hp3par_san_password') - self.hp3par_san_ssh_port = kwargs.get('hp3par_san_ssh_port') - self.hp3par_san_private_key = kwargs.get('hp3par_san_private_key') - self.hp3par_fstore_per_share = kwargs.get('hp3par_fstore_per_share') + self.hpe3par_username = kwargs.get('hpe3par_username') + self.hpe3par_password = kwargs.get('hpe3par_password') + self.hpe3par_api_url = kwargs.get('hpe3par_api_url') + self.hpe3par_debug = kwargs.get('hpe3par_debug') + self.hpe3par_san_ip = kwargs.get('hpe3par_san_ip') + self.hpe3par_san_login = kwargs.get('hpe3par_san_login') + self.hpe3par_san_password = kwargs.get('hpe3par_san_password') + self.hpe3par_san_ssh_port = kwargs.get('hpe3par_san_ssh_port') + self.hpe3par_san_private_key = kwargs.get('hpe3par_san_private_key') + self.hpe3par_fstore_per_share = kwargs.get('hpe3par_fstore_per_share') self.ssh_conn_timeout = kwargs.get('ssh_conn_timeout') self._client = None @@ -84,61 +84,61 @@ class HP3ParMediator(object): @staticmethod def no_client(): - return hp3parclient is None + return hpe3parclient is None def do_setup(self): if self.no_client(): - msg = _('You must install hp3parclient before using the 3PAR ' + msg = _('You must install hpe3parclient before using the 3PAR ' 'driver.') 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: - msg = (_('Invalid hp3parclient version found (%(found)s). ' + msg = (_('Invalid hpe3parclient version found (%(found)s). ' 'Version %(minimum)s or greater required.') % {'found': '.'.join(map(six.text_type, self.client_version)), 'minimum': '.'.join(map(six.text_type, MIN_CLIENT_VERSION))}) LOG.error(msg) - raise exception.HP3ParInvalidClient(message=msg) + raise exception.HPE3ParInvalidClient(message=msg) try: - self._client = file_client.HP3ParFilePersonaClient( - self.hp3par_api_url) + self._client = file_client.HPE3ParFilePersonaClient( + self.hpe3par_api_url) 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)) LOG.exception(msg) raise exception.ShareBackendException(message=msg) try: ssh_kwargs = {} - if self.hp3par_san_ssh_port: - ssh_kwargs['port'] = self.hp3par_san_ssh_port + if self.hpe3par_san_ssh_port: + ssh_kwargs['port'] = self.hpe3par_san_ssh_port if self.ssh_conn_timeout: ssh_kwargs['conn_timeout'] = self.ssh_conn_timeout - if self.hp3par_san_private_key: - ssh_kwargs['privatekey'] = self.hp3par_san_private_key + if self.hpe3par_san_private_key: + ssh_kwargs['privatekey'] = self.hpe3par_san_private_key self._client.setSSHOptions( - self.hp3par_san_ip, - self.hp3par_san_login, - self.hp3par_san_password, + self.hpe3par_san_ip, + self.hpe3par_san_login, + self.hpe3par_san_password, **ssh_kwargs ) 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)) LOG.exception(msg) raise exception.ShareBackendException(message=msg) - LOG.info(_LI("HP3ParMediator %(version)s, " - "hp3parclient %(client_version)s"), + LOG.info(_LI("HPE3ParMediator %(version)s, " + "hpe3parclient %(client_version)s"), {"version": self.VERSION, - "client_version": hp3parclient.get_version_string()}) + "client_version": hpe3parclient.get_version_string()}) try: wsapi_version = self._client.getWsApiVersion()['build'] @@ -149,17 +149,17 @@ class HP3ParMediator(object): LOG.exception(msg) raise exception.ShareBackendException(message=msg) - if self.hp3par_debug: + if self.hpe3par_debug: self._client.debug_rest(True) # Includes SSH debug (setSSH above) def _wsapi_login(self): try: - self._client.login(self.hp3par_username, self.hp3par_password) + self._client.login(self.hpe3par_username, self.hpe3par_password) except Exception as e: msg = (_("Failed to Login to 3PAR (%(url)s) as %(user)s " "because: %(err)s") % - {'url': self.hp3par_api_url, - 'user': self.hp3par_username, + {'url': self.hpe3par_api_url, + 'user': self.hpe3par_username, 'err': six.text_type(e)}) LOG.error(msg) raise exception.ShareBackendException(msg=msg) @@ -169,7 +169,7 @@ class HP3ParMediator(object): self._client.http.unauthenticate() except Exception as e: 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)}) # don't raise exception on logout() @@ -236,14 +236,15 @@ class HP3ParMediator(object): thin_provisioning = provisioning_type in (THIN, DEDUPE) flash_cache_policy = volume_set.get('flashCachePolicy', DISABLED) - hp3par_flash_cache = flash_cache_policy == ENABLED + hpe3par_flash_cache = flash_cache_policy == ENABLED status = { 'total_capacity_gb': total_capacity_gb, 'free_capacity_gb': free_capacity_gb, 'thin_provisioning': thin_provisioning, 'dedupe': dedupe, - 'hp3par_flash_cache': hp3par_flash_cache, + 'hpe3par_flash_cache': hpe3par_flash_cache, + 'hp3par_flash_cache': hpe3par_flash_cache, } if thin_provisioning: @@ -266,7 +267,7 @@ class HP3ParMediator(object): @staticmethod def other_protocol(share_proto): """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' @staticmethod @@ -275,7 +276,7 @@ class HP3ParMediator(object): return uid elif protocol: return 'osf-%s-%s' % ( - HP3ParMediator.ensure_supported_protocol(protocol), uid) + HPE3ParMediator.ensure_supported_protocol(protocol), uid) else: return 'osf-%s' % uid @@ -283,7 +284,14 @@ class HP3ParMediator(object): def _get_nfs_options(extra_specs, readonly): """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: options = nfs_options.split(',') else: @@ -304,7 +312,8 @@ class HP3ParMediator(object): ] 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 ' 'options are not allowed: %s') % invalid_options) @@ -321,6 +330,12 @@ class HP3ParMediator(object): fstore=fstore, sharedir=sharedir, 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': createfshare_kwargs['clientip'] = '127.0.0.1' options = self._get_nfs_options(extra_specs, readonly) @@ -328,13 +343,17 @@ class HP3ParMediator(object): else: createfshare_kwargs['allowip'] = '127.0.0.1' - if self.client_version < MIN_SMB_CA_VERSION: - smb_opts = (ACCESS_BASED_ENUM, CACHE) - else: - smb_opts = (ACCESS_BASED_ENUM, CONTINUOUS_AVAIL, CACHE) + smb_opts = (ACCESS_BASED_ENUM, CONTINUOUS_AVAIL, CACHE) 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: opt_key = SMB_EXTRA_SPECS_MAP[smb_opt] createfshare_kwargs[opt_key] = opt_value @@ -367,14 +386,14 @@ class HP3ParMediator(object): protocol = self.ensure_supported_protocol(share_proto) 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 if fstore: use_existing_fstore = True else: use_existing_fstore = False - if self.hp3par_fstore_per_share: + if self.hpe3par_fstore_per_share: fstore = share_name else: fstore = self.ensure_prefix(project_id, protocol) @@ -401,7 +420,7 @@ class HP3ParMediator(object): raise exception.ShareBackendException(msg) if size: - if self.hp3par_fstore_per_share: + if self.hpe3par_fstore_per_share: hcapacity = six.text_type(size * units.Ki) scapacity = hcapacity else: @@ -706,10 +725,10 @@ class HP3ParMediator(object): raise exception.InvalidInput(msg) 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) LOG.error(msg) - raise exception.HP3ParInvalid(msg) + raise exception.HPE3ParInvalid(msg) return protocol @@ -748,7 +767,7 @@ class HP3ParMediator(object): msg = (_("Unexpected error: After ensure_supported_protocol " "only 'nfs' or 'smb' strings are allowed, but found: " "%s.") % protocol) - raise exception.HP3ParUnexpectedError(msg) + raise exception.HPE3ParUnexpectedError(msg) LOG.debug("setfshare result=%s", result) except Exception as e: diff --git a/manila/share/manager.py b/manila/share/manager.py index fbc7d46d22..1576f0420f 100644 --- a/manila/share/manager.py +++ b/manila/share/manager.py @@ -98,7 +98,10 @@ CONF.import_opt('periodic_hooks_interval', 'manila.share.hook') # old/new path here to maintain backward compatibility. MAPPING = { '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 diff --git a/manila/tests/share/drivers/hp/__init__.py b/manila/tests/share/drivers/hpe/__init__.py similarity index 100% rename from manila/tests/share/drivers/hp/__init__.py rename to manila/tests/share/drivers/hpe/__init__.py diff --git a/manila/tests/share/drivers/hp/test_hp_3par_constants.py b/manila/tests/share/drivers/hpe/test_hpe_3par_constants.py similarity index 96% rename from manila/tests/share/drivers/hp/test_hp_3par_constants.py rename to manila/tests/share/drivers/hpe/test_hpe_3par_constants.py index faeae3c2a1..1e2ba04835 100644 --- a/manila/tests/share/drivers/hp/test_hp_3par_constants.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_constants.py @@ -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 # 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_FSTORE = EXPECTED_PROJECT_ID EXPECTED_VFS = 'test_vfs' -EXPECTED_HP_DEBUG = True +EXPECTED_HPE_DEBUG = True EXPECTED_EXTRA_SPECS = {} GET_FSQUOTA = {'message': None, diff --git a/manila/tests/share/drivers/hp/test_hp_3par_driver.py b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py similarity index 83% rename from manila/tests/share/drivers/hp/test_hp_3par_driver.py rename to manila/tests/share/drivers/hpe/test_hpe_3par_driver.py index f994755454..05408d7c30 100644 --- a/manila/tests/share/drivers/hp/test_hp_3par_driver.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_driver.py @@ -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 # not use this file except in compliance with the License. You may obtain @@ -16,37 +16,37 @@ import sys import ddt import mock -if 'hp3parclient' not in sys.modules: - sys.modules['hp3parclient'] = mock.Mock() +if 'hpe3parclient' not in sys.modules: + sys.modules['hpe3parclient'] = mock.Mock() from manila import exception -from manila.share.drivers.hp import hp_3par_driver as hp3pardriver -from manila.share.drivers.hp import hp_3par_mediator as hp3parmediator +from manila.share.drivers.hpe import hpe_3par_driver as hpe3pardriver +from manila.share.drivers.hpe import hpe_3par_mediator as hpe3parmediator 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 -class HP3ParDriverTestCase(test.TestCase): +class HPE3ParDriverTestCase(test.TestCase): def setUp(self): - super(HP3ParDriverTestCase, self).setUp() + super(HPE3ParDriverTestCase, self).setUp() # Create a mock configuration with attributes and a safe_get() self.conf = mock.Mock() self.conf.driver_handles_share_servers = True - self.conf.hp3par_debug = constants.EXPECTED_HP_DEBUG - self.conf.hp3par_username = constants.USERNAME - self.conf.hp3par_password = constants.PASSWORD - self.conf.hp3par_api_url = constants.API_URL - self.conf.hp3par_san_login = constants.SAN_LOGIN - self.conf.hp3par_san_password = constants.SAN_PASSWORD - self.conf.hp3par_san_ip = constants.EXPECTED_IP_1234 - self.conf.hp3par_fpg = constants.EXPECTED_FPG - self.conf.hp3par_san_ssh_port = constants.PORT + self.conf.hpe3par_debug = constants.EXPECTED_HPE_DEBUG + self.conf.hpe3par_username = constants.USERNAME + self.conf.hpe3par_password = constants.PASSWORD + self.conf.hpe3par_api_url = constants.API_URL + self.conf.hpe3par_san_login = constants.SAN_LOGIN + self.conf.hpe3par_san_password = constants.SAN_PASSWORD + self.conf.hpe3par_san_ip = constants.EXPECTED_IP_1234 + self.conf.hpe3par_fpg = constants.EXPECTED_FPG + self.conf.hpe3par_san_ssh_port = constants.PORT self.conf.ssh_conn_timeout = constants.TIMEOUT - self.conf.hp3par_share_ip_address = None - self.conf.hp3par_fstore_per_share = False + self.conf.hpe3par_share_ip_address = None + self.conf.hpe3par_fstore_per_share = False self.conf.network_config_group = 'test_network_config_group' def safe_get(attr): @@ -56,12 +56,12 @@ class HP3ParDriverTestCase(test.TestCase): return None self.conf.safe_get = safe_get - self.real_hp_3par_mediator = hp3parmediator.HP3ParMediator - self.mock_object(hp3parmediator, 'HP3ParMediator') - self.mock_mediator_constructor = hp3parmediator.HP3ParMediator + self.real_hpe_3par_mediator = hpe3parmediator.HPE3ParMediator + self.mock_object(hpe3parmediator, 'HPE3ParMediator') + self.mock_mediator_constructor = hpe3parmediator.HPE3ParMediator self.mock_mediator = self.mock_mediator_constructor() - self.driver = hp3pardriver.HP3ParShareDriver( + self.driver = hpe3pardriver.HPE3ParShareDriver( configuration=self.conf) def test_driver_setup_success(self): @@ -72,20 +72,20 @@ class HP3ParDriverTestCase(test.TestCase): self.driver.do_setup(None) conf = self.conf self.mock_mediator_constructor.assert_has_calls([ - mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, - hp3par_san_password=conf.hp3par_san_password, - hp3par_username=conf.hp3par_username, - hp3par_san_login=conf.hp3par_san_login, - hp3par_debug=conf.hp3par_debug, - hp3par_api_url=conf.hp3par_api_url, - hp3par_password=conf.hp3par_password, - hp3par_san_ip=conf.hp3par_san_ip, - hp3par_fstore_per_share=conf.hp3par_fstore_per_share, + mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port, + hpe3par_san_password=conf.hpe3par_san_password, + hpe3par_username=conf.hpe3par_username, + hpe3par_san_login=conf.hpe3par_san_login, + hpe3par_debug=conf.hpe3par_debug, + hpe3par_api_url=conf.hpe3par_api_url, + hpe3par_password=conf.hpe3par_password, + hpe3par_san_ip=conf.hpe3par_san_ip, + hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share, ssh_conn_timeout=conf.ssh_conn_timeout)]) self.mock_mediator.assert_has_calls([ 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) @@ -93,7 +93,7 @@ class HP3ParDriverTestCase(test.TestCase): """Driver do_setup without any errors with dhss=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() @@ -101,7 +101,7 @@ class HP3ParDriverTestCase(test.TestCase): """Configured IP address is required for dhss=False.""" self.conf.driver_handles_share_servers = False - self.assertRaises(exception.HP3ParInvalid, + self.assertRaises(exception.HPE3ParInvalid, self.driver.do_setup, None) def test_driver_with_setup_error(self): @@ -115,15 +115,15 @@ class HP3ParDriverTestCase(test.TestCase): conf = self.conf self.mock_mediator_constructor.assert_has_calls([ - mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, - hp3par_san_password=conf.hp3par_san_password, - hp3par_username=conf.hp3par_username, - hp3par_san_login=conf.hp3par_san_login, - hp3par_debug=conf.hp3par_debug, - hp3par_api_url=conf.hp3par_api_url, - hp3par_password=conf.hp3par_password, - hp3par_san_ip=conf.hp3par_san_ip, - hp3par_fstore_per_share=conf.hp3par_fstore_per_share, + mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port, + hpe3par_san_password=conf.hpe3par_san_password, + hpe3par_username=conf.hpe3par_username, + hpe3par_san_login=conf.hpe3par_san_login, + hpe3par_debug=conf.hpe3par_debug, + hpe3par_api_url=conf.hpe3par_api_url, + hpe3par_password=conf.hpe3par_password, + hpe3par_san_ip=conf.hpe3par_san_ip, + hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share, ssh_conn_timeout=conf.ssh_conn_timeout)]) self.mock_mediator.assert_has_calls([mock.call.do_setup()]) @@ -139,29 +139,29 @@ class HP3ParDriverTestCase(test.TestCase): conf = self.conf self.mock_mediator_constructor.assert_has_calls([ - mock.call(hp3par_san_ssh_port=conf.hp3par_san_ssh_port, - hp3par_san_password=conf.hp3par_san_password, - hp3par_username=conf.hp3par_username, - hp3par_san_login=conf.hp3par_san_login, - hp3par_debug=conf.hp3par_debug, - hp3par_api_url=conf.hp3par_api_url, - hp3par_password=conf.hp3par_password, - hp3par_san_ip=conf.hp3par_san_ip, - hp3par_fstore_per_share=conf.hp3par_fstore_per_share, + mock.call(hpe3par_san_ssh_port=conf.hpe3par_san_ssh_port, + hpe3par_san_password=conf.hpe3par_san_password, + hpe3par_username=conf.hpe3par_username, + hpe3par_san_login=conf.hpe3par_san_login, + hpe3par_debug=conf.hpe3par_debug, + hpe3par_api_url=conf.hpe3par_api_url, + hpe3par_password=conf.hpe3par_password, + hpe3par_san_ip=conf.hpe3par_san_ip, + hpe3par_fstore_per_share=conf.hpe3par_fstore_per_share, ssh_conn_timeout=conf.ssh_conn_timeout)]) self.mock_mediator.assert_has_calls([ mock.call.do_setup(), - mock.call.get_vfs_name(conf.hp3par_fpg)]) + mock.call.get_vfs_name(conf.hpe3par_fpg)]) def init_driver(self): """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.fpg = constants.EXPECTED_FPG - self.mock_object(hp3pardriver, 'share_types') - get_extra_specs = hp3pardriver.share_types.get_extra_specs_from_share + self.mock_object(hpe3pardriver, 'share_types') + get_extra_specs = hpe3pardriver.share_types.get_extra_specs_from_share get_extra_specs.return_value = constants.EXPECTED_EXTRA_SPECS 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.""" # 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.driver.check_for_setup_error() expected_calls = [ - mock.call.debug('HP3ParShareDriver SHA1: %s', mock.ANY), - mock.call.debug('HP3ParMediator SHA1: %s', mock.ANY) + mock.call.debug('HPE3ParShareDriver 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): """check_for_setup_error catch and log any exceptions.""" - # Since HP3ParMediator is mocked, we'll hit the except/log. - self.mock_object(hp3pardriver, 'LOG') + # Since HPE3ParMediator is mocked, we'll hit the except/log. + self.mock_object(hpe3pardriver, 'LOG') self.init_driver() self.driver.check_for_setup_error() 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) ] - hp3pardriver.LOG.assert_has_calls(expected_calls) + hpe3pardriver.LOG.assert_has_calls(expected_calls) def test_driver_create_cifs_share(self): self.init_driver() @@ -458,7 +458,7 @@ class HP3ParDriverTestCase(test.TestCase): def test_driver_get_share_stats_not_ready(self): """Protect against stats update before driver is ready.""" - self.mock_object(hp3pardriver, 'LOG') + self.mock_object(hpe3pardriver, 'LOG') expected_result = { 'driver_handles_share_servers': True, @@ -468,12 +468,12 @@ class HP3ParDriverTestCase(test.TestCase): 'max_over_subscription_ratio': None, 'reserved_percentage': 0, 'provisioned_capacity_gb': 0, - 'share_backend_name': 'HP_3PAR', + 'share_backend_name': 'HPE_3PAR', 'snapshot_support': True, 'storage_protocol': 'NFS_CIFS', 'thin_provisioning': True, 'total_capacity_gb': 0, - 'vendor_name': 'HP', + 'vendor_name': 'HPE', 'pools': None, } @@ -484,7 +484,7 @@ class HP3ParDriverTestCase(test.TestCase): mock.call.info('Skipping capacity and capabilities update. ' '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): """Driver does not call mediator when refresh=False.""" @@ -511,6 +511,7 @@ class HP3ParDriverTestCase(test.TestCase): 'thin_provisioning': True, 'dedupe': False, 'hpe3par_flash_cache': False, + 'hp3par_flash_cache': False, } expected_result = { @@ -522,13 +523,14 @@ class HP3ParDriverTestCase(test.TestCase): 'pools': None, 'provisioned_capacity_gb': 0, 'reserved_percentage': 0, - 'share_backend_name': 'HP_3PAR', + 'share_backend_name': 'HPE_3PAR', 'storage_protocol': 'NFS_CIFS', 'total_capacity_gb': expected_capacity, - 'vendor_name': 'HP', + 'vendor_name': 'HPE', 'thin_provisioning': True, 'dedupe': False, 'hpe3par_flash_cache': False, + 'hp3par_flash_cache': False, 'snapshot_support': True, } @@ -557,11 +559,11 @@ class HP3ParDriverTestCase(test.TestCase): 'pools': None, 'provisioned_capacity_gb': 0, 'reserved_percentage': 0, - 'share_backend_name': 'HP_3PAR', + 'share_backend_name': 'HPE_3PAR', 'storage_protocol': 'NFS_CIFS', 'thin_provisioning': True, 'total_capacity_gb': 0, - 'vendor_name': 'HP', + 'vendor_name': 'HPE', 'snapshot_support': True, } diff --git a/manila/tests/share/drivers/hp/test_hp_3par_mediator.py b/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py similarity index 94% rename from manila/tests/share/drivers/hp/test_hp_3par_mediator.py rename to manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py index 1d6b28c861..6ef30473b4 100644 --- a/manila/tests/share/drivers/hp/test_hp_3par_mediator.py +++ b/manila/tests/share/drivers/hpe/test_hpe_3par_mediator.py @@ -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 # not use this file except in compliance with the License. You may obtain @@ -16,60 +16,60 @@ import sys import ddt import mock -if 'hp3parclient' not in sys.modules: - sys.modules['hp3parclient'] = mock.Mock() +if 'hpe3parclient' not in sys.modules: + sys.modules['hpe3parclient'] = mock.Mock() 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.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 import six -CLIENT_VERSION_MIN_OK = hp3parmediator.MIN_CLIENT_VERSION +CLIENT_VERSION_MIN_OK = hpe3parmediator.MIN_CLIENT_VERSION TEST_WSAPI_VERSION_STR = '30201292' @ddt.ddt -class HP3ParMediatorTestCase(test.TestCase): +class HPE3ParMediatorTestCase(test.TestCase): def setUp(self): - super(HP3ParMediatorTestCase, self).setUp() + super(HPE3ParMediatorTestCase, self).setUp() # This is the fake client to use. self.mock_client = mock.Mock() - # Take over the hp3parclient module and stub the constructor. - hp3parclient = sys.modules['hp3parclient'] - hp3parclient.version_tuple = CLIENT_VERSION_MIN_OK + # Take over the hpe3parclient module and stub the constructor. + hpe3parclient = sys.modules['hpe3parclient'] + hpe3parclient.version_tuple = CLIENT_VERSION_MIN_OK # Need a fake constructor to return the fake client. # 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 = ( - hp3parclient.file_client.HP3ParFilePersonaClient + hpe3parclient.file_client.HPE3ParFilePersonaClient ) self.mock_client = self.mock_client_constructor() # Set the mediator to use in tests. - self.mediator = hp3parmediator.HP3ParMediator( - hp3par_username=constants.USERNAME, - hp3par_password=constants.PASSWORD, - hp3par_api_url=constants.API_URL, - hp3par_debug=constants.EXPECTED_HP_DEBUG, - hp3par_san_ip=constants.EXPECTED_IP_1234, - hp3par_san_login=constants.SAN_LOGIN, - hp3par_san_password=constants.SAN_PASSWORD, - hp3par_san_ssh_port=constants.PORT, + self.mediator = hpe3parmediator.HPE3ParMediator( + hpe3par_username=constants.USERNAME, + hpe3par_password=constants.PASSWORD, + hpe3par_api_url=constants.API_URL, + hpe3par_debug=constants.EXPECTED_HPE_DEBUG, + hpe3par_san_ip=constants.EXPECTED_IP_1234, + hpe3par_san_login=constants.SAN_LOGIN, + hpe3par_san_password=constants.SAN_PASSWORD, + hpe3par_san_ssh_port=constants.PORT, ssh_conn_timeout=constants.TIMEOUT) 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) def test_mediator_setup_client_init_error(self): @@ -154,7 +154,7 @@ class HP3ParMediatorTestCase(test.TestCase): port=constants.PORT, conn_timeout=constants.TIMEOUT), 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) @@ -175,7 +175,7 @@ class HP3ParMediatorTestCase(test.TestCase): """Test exception during logout.""" self.init_mediator() - mock_log = self.mock_object(hp3parmediator, 'LOG') + mock_log = self.mock_object(hpe3parmediator, 'LOG') fake_exception = constants.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): """Try a client with version less than minimum.""" - self.hp3parclient = sys.modules['hp3parclient'] - self.hp3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], - CLIENT_VERSION_MIN_OK[1], - CLIENT_VERSION_MIN_OK[2] - 1) - self.assertRaises(exception.HP3ParInvalidClient, + self.hpe3parclient = sys.modules['hpe3parclient'] + self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], + CLIENT_VERSION_MIN_OK[1], + CLIENT_VERSION_MIN_OK[2] - 1) + self.assertRaises(exception.HPE3ParInvalidClient, self.init_mediator) def test_mediator_client_version_supported(self): """Try a client with a version greater than the minimum.""" # The setup success already tests the min version. Try version > min. - self.hp3parclient = sys.modules['hp3parclient'] - self.hp3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], - CLIENT_VERSION_MIN_OK[1], - CLIENT_VERSION_MIN_OK[2] + 1) + self.hpe3parclient = sys.modules['hpe3parclient'] + self.hpe3parclient.version_tuple = (CLIENT_VERSION_MIN_OK[0], + CLIENT_VERSION_MIN_OK[1], + CLIENT_VERSION_MIN_OK[2] + 1) self.init_mediator() expected_calls = [ mock.call.setSSHOptions(constants.EXPECTED_IP_1234, @@ -212,7 +212,7 @@ class HP3ParMediatorTestCase(test.TestCase): port=constants.PORT, conn_timeout=constants.TIMEOUT), 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) @@ -251,7 +251,7 @@ class HP3ParMediatorTestCase(test.TestCase): createfshare_kwargs['clientip'] = '127.0.0.1' # 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(',') # Options that the mediator adds. nfs_options = ['rw', 'no_root_squash', 'insecure'] @@ -282,18 +282,14 @@ class HP3ParMediatorTestCase(test.TestCase): else: createfshare_kwargs['allowip'] = '127.0.0.1' - if client_version < hp3parmediator.MIN_SMB_CA_VERSION: - smb_opts = (hp3parmediator.ACCESS_BASED_ENUM, - hp3parmediator.CACHE) - else: - smb_opts = (hp3parmediator.ACCESS_BASED_ENUM, - hp3parmediator.CONTINUOUS_AVAIL, - hp3parmediator.CACHE) + smb_opts = (hpe3parmediator.ACCESS_BASED_ENUM, + hpe3parmediator.CONTINUOUS_AVAIL, + hpe3parmediator.CACHE) 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: - opt_key = hp3parmediator.SMB_EXTRA_SPECS_MAP[smb_opt] + opt_key = hpe3parmediator.SMB_EXTRA_SPECS_MAP[smb_opt] createfshare_kwargs[opt_key] = opt_value expected_calls = [ @@ -320,25 +316,19 @@ class HP3ParMediatorTestCase(test.TestCase): def _build_smb_extra_specs(**kwargs): extra_specs = {'driver_handles_share_servers': False} for k, v in kwargs.items(): - extra_specs['hp3par:smb_%s' % k] = v + extra_specs['hpe3par:smb_%s' % k] = v return extra_specs - @ddt.data(((3, 2, 1), None, None, None), - ((3, 2, 1), 'true', None, None), - ((3, 2, 1), None, 'false', None), - ((3, 2, 1), None, 'false', None), - ((3, 2, 1), None, None, 'optimized'), - ((3, 2, 1), '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.data(((4, 0, 0), None, None, None), + ((4, 0, 0), 'true', None, None), + ((4, 0, 0), None, 'false', None), + ((4, 0, 0), None, 'false', None), + ((4, 0, 0), None, None, 'optimized'), + ((4, 0, 0), 'true', 'false', 'optimized')) @ddt.unpack def test_mediator_create_cifs_share(self, client_version, abe, ca, cache): - self.hp3parclient = sys.modules['hp3parclient'] - self.hp3parclient.version_tuple = client_version + self.hpe3parclient = sys.modules['hpe3parclient'] + self.hpe3parclient.version_tuple = client_version self.init_mediator() 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): self.init_mediator() - extra_specs = {'hp3par:nfs_options': nfs_options} + extra_specs = {'hpe3par:nfs_options': nfs_options} self.assertRaises(exception.InvalidInput, self.mediator.create_share, @@ -411,7 +401,7 @@ class HP3ParMediatorTestCase(test.TestCase): 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, constants.EXPECTED_SHARE_ID, @@ -424,7 +414,7 @@ class HP3ParMediatorTestCase(test.TestCase): self.assertEqual(constants.EXPECTED_SHARE_PATH, location) expected_calls = self.get_expected_calls_for_create_share( - hp3parmediator.MIN_CLIENT_VERSION, + hpe3parmediator.MIN_CLIENT_VERSION, constants.EXPECTED_FPG, constants.EXPECTED_VFS, constants.NFS.lower(), @@ -853,7 +843,7 @@ class HP3ParMediatorTestCase(test.TestCase): # startfsnapclean exception (logged, not raised) self.mock_client.startfsnapclean.side_effect = Exception( 'startfsnapclean fail.') - mock_log = self.mock_object(hp3parmediator, 'LOG') + mock_log = self.mock_object(hpe3parmediator, 'LOG') self.mediator.delete_snapshot(constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, @@ -917,10 +907,11 @@ class HP3ParMediatorTestCase(test.TestCase): } self.mock_client.getVolume.return_value = { - 'provisioningType': hp3parmediator.DEDUPE} + 'provisioningType': hpe3parmediator.DEDUPE} expected_result = { 'free_capacity_gb': expected_free, + 'hpe3par_flash_cache': False, 'hp3par_flash_cache': False, 'dedupe': True, 'thin_provisioning': True, @@ -1163,7 +1154,7 @@ class HP3ParMediatorTestCase(test.TestCase): """"Allow user access to nfs share is not supported.""" self.init_mediator() - self.assertRaises(exception.HP3ParInvalid, + self.assertRaises(exception.HPE3ParInvalid, self.mediator.allow_access, constants.EXPECTED_PROJECT_ID, constants.EXPECTED_SHARE_ID, @@ -1207,13 +1198,13 @@ class HP3ParMediatorTestCase(test.TestCase): def test_other_protocol(self, protocols, expected_other): for protocol in protocols: self.assertEqual(expected_other, - hp3parmediator.HP3ParMediator().other_protocol( + hpe3parmediator.HPE3ParMediator().other_protocol( protocol)) @ddt.data('', 'bogus') def test_other_protocol_exception(self, protocol): self.assertRaises(exception.InvalidInput, - hp3parmediator.HP3ParMediator().other_protocol, + hpe3parmediator.HPE3ParMediator().other_protocol, protocol) @ddt.data(('osf-uid', None, 'osf-uid'), @@ -1223,7 +1214,7 @@ class HP3ParMediatorTestCase(test.TestCase): @ddt.unpack def test_ensure_prefix(self, uid, protocol, expected): self.assertEqual(expected, - hp3parmediator.HP3ParMediator().ensure_prefix( + hpe3parmediator.HPE3ParMediator().ensure_prefix( uid, protocol=protocol)) def test_find_fstore_search(self):