From ecf682336923d709a27ccdde23d40ab9c2c2e980 Mon Sep 17 00:00:00 2001 From: Simon Dodsley Date: Fri, 10 Nov 2023 16:12:29 -0500 Subject: [PATCH] [Pure Storage] Add support for multiple data VIPs Minor change to allow multiple data VIP addresses to be specified in the `flashblade_data_vip` parameter. Each data VIP will be used to define the file system export address for shares created. The first address in the list will be clasified as the Preferred export address, but this is not enforced. Change-Id: Ia3bfdd5ce1bfd31d10193d1f222bf27b38c8ef43 --- .../admin/purestorage_flashblade_driver.rst | 4 +- .../drivers/purestorage-flashblade-driver.rst | 2 +- .../tables/manila-purestorage-flashblade.inc | 2 +- .../share/drivers/purestorage/flashblade.py | 45 ++++++++++--------- .../drivers/purestorage/test_flashblade.py | 34 +++++++++++++- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/doc/source/admin/purestorage_flashblade_driver.rst b/doc/source/admin/purestorage_flashblade_driver.rst index 9a33b6cc1b..f564aaf907 100644 --- a/doc/source/admin/purestorage_flashblade_driver.rst +++ b/doc/source/admin/purestorage_flashblade_driver.rst @@ -121,7 +121,7 @@ of ``/etc/manila/manila.conf``: +-------------------------------------------------+-----------------------------------------------------------------------------------------------------+ | flashblade_mgmt_vip | The name (or IP address) for the Pure Storage FlashBlade storage system management VIP. | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------+ -| flashblade_data_vip | The name (or IP address) for the Pure Storage FlashBlade storage system data VIP. | +| flashblade_data_vip | The names (or IP address) for the Pure Storage FlashBlade storage system data VIPs. | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------+ | flashblade_api | API token for an administrative user account | +-------------------------------------------------+-----------------------------------------------------------------------------------------------------+ @@ -146,7 +146,7 @@ Below is an example of a valid configuration of the FlashBlade driver: share_driver = manila.share.drivers.purestorage.flashblade.FlashBladeShareDriver driver_handles_share_servers = False flashblade_mgmt_vip = 1.2.3.4 - flashblade_data_vip = 1.2.3.5 + flashblade_data_vip = 1.2.3.5,1.2.3.6 flashblade_api = T-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Restart of :term:`manila-share` service is needed for the configuration changes to take diff --git a/doc/source/configuration/shared-file-systems/drivers/purestorage-flashblade-driver.rst b/doc/source/configuration/shared-file-systems/drivers/purestorage-flashblade-driver.rst index 66d6e0c7bd..e05837a38a 100644 --- a/doc/source/configuration/shared-file-systems/drivers/purestorage-flashblade-driver.rst +++ b/doc/source/configuration/shared-file-systems/drivers/purestorage-flashblade-driver.rst @@ -63,7 +63,7 @@ Configure the driver back-end section with the parameters below. .. code-block:: ini flashblade_mgmt_vip = FlashBlade management VIP - flashblade_data_vip = FlashBlade data VIP + flashblade_data_vip = FlashBlade data VIP(s) * Configure user credentials: diff --git a/doc/source/configuration/tables/manila-purestorage-flashblade.inc b/doc/source/configuration/tables/manila-purestorage-flashblade.inc index 6371a48139..40b287ed39 100644 --- a/doc/source/configuration/tables/manila-purestorage-flashblade.inc +++ b/doc/source/configuration/tables/manila-purestorage-flashblade.inc @@ -11,7 +11,7 @@ * - ``flashblade_mgmt_vip`` = ``None`` - (String) The name (or IP address) for the Pure Storage FlashBlade storage system management port. * - ``flashblade_data_vip`` = ``None`` - - (String) The name (or IP address) for the Pure Storage FlashBlade storage system data port. + - (String) The names (or IP address) for the Pure Storage FlashBlade storage system data ports. * - ``flashblade_api`` = ``None`` - (String) API token for an administrative level user account. * - ``flashblade_eradicate`` = ``True`` diff --git a/manila/share/drivers/purestorage/flashblade.py b/manila/share/drivers/purestorage/flashblade.py index 667835af59..138059c9a4 100644 --- a/manila/share/drivers/purestorage/flashblade.py +++ b/manila/share/drivers/purestorage/flashblade.py @@ -41,10 +41,13 @@ flashblade_connection_opts = [ help="The name (or IP address) for the Pure Storage " "FlashBlade storage system management VIP.", ), - cfg.HostAddressOpt( + cfg.ListOpt( "flashblade_data_vip", - help="The name (or IP address) for the Pure Storage " - "FlashBlade storage system data VIP.", + help="The names (or IP address) for the Pure Storage " + "FlashBlade storage system data VIPs. " + "The first listed name or IP address will be considered " + "to be the preferred IP address, although is not " + "enforced.", ), ] @@ -243,10 +246,9 @@ class FlashBladeShareDriver(driver.ShareDriver): base_name = CONF.share_name_template + "-manila" return base_name % manila_share["id"] - def _get_full_nfs_export_path(self, export_path): - subnet_ip = self.data_address + def _get_full_nfs_export_path(self, export_path, location): return "{subnet_ip}:/{export_path}".format( - subnet_ip=subnet_ip, export_path=export_path + subnet_ip=location, export_path=export_path ) def _get_flashblade_filesystem_by_name(self, name): @@ -271,18 +273,6 @@ class FlashBladeShareDriver(driver.ShareDriver): LOG.exception(msg) raise exception.ManilaException(message=msg) - @purity_fb_to_manila_exceptions - def _create_filesystem_export(self, flashblade_filesystem): - flashblade_export = flashblade_filesystem.add_export(permissions=[]) - return { - "path": self._get_full_nfs_export_path( - flashblade_export.get_export_path() - ), - "is_admin_only": False, - "preferred": True, - "metadata": {}, - } - @purity_fb_to_manila_exceptions def _resize_share(self, share, new_size): dataset_name = self._make_share_name(share) @@ -360,7 +350,22 @@ class FlashBladeShareDriver(driver.ShareDriver): ), ) self._sys.file_systems.create_file_systems(flashblade_fs) - location = self._get_full_nfs_export_path(share_name) + locations = [] + preferred = True + for address in self.data_address: + export_location = { + "path": self._get_full_nfs_export_path( + share_name, + address, + ), + "is_admin_only": False, + "metadata": { + "preferred": preferred, + }, + } + LOG.debug("pref %(pref)s", {"pref": preferred}) + preferred = False + locations.append(export_location) else: message = _("Unsupported share protocol: %(proto)s.") % { "proto": share["share_proto"] @@ -369,7 +374,7 @@ class FlashBladeShareDriver(driver.ShareDriver): raise exception.InvalidShare(reason=message) LOG.info("FlashBlade created share %(name)s", {"name": share_name}) - return location + return locations def create_snapshot(self, context, snapshot, share_server=None): """Called to create a snapshot""" diff --git a/manila/tests/share/drivers/purestorage/test_flashblade.py b/manila/tests/share/drivers/purestorage/test_flashblade.py index e6d44f7ebf..33777e62c4 100644 --- a/manila/tests/share/drivers/purestorage/test_flashblade.py +++ b/manila/tests/share/drivers/purestorage/test_flashblade.py @@ -28,6 +28,31 @@ from manila import test _MOCK_SHARE_ID = 1 _MOCK_SNAPSHOT_ID = "snap" _MOCK_SHARE_SIZE = 4294967296 +_SINGLE_VIP_LOCATION = [ + { + "path": 'mockfb2:/share-1-manila', + "is_admin_only": False, + "metadata": { + "preferred": True, + } + } +] +_DUAL_VIP_LOCATION = [ + { + "path": 'mockfb2:/share-1-manila', + "is_admin_only": False, + "metadata": { + "preferred": True, + } + }, + { + "path": 'mockfb3:/share-1-manila', + "is_admin_only": False, + "metadata": { + "preferred": False, + } + } +] def _create_mock__getitem__(mock): @@ -58,7 +83,7 @@ class FlashBladeDriverTestCaseBase(test.TestCase): super(FlashBladeDriverTestCaseBase, self).setUp() self.configuration = mock.Mock() self.configuration.flashblade_mgmt_vip = "mockfb1" - self.configuration.flashblade_data_vip = "mockfb2" + self.configuration.flashblade_data_vip = ["mockfb2"] self.configuration.flashblade_api = "api" self.configuration.flashblade_eradicate = True @@ -173,7 +198,12 @@ class FlashBladeDriverTestCase(FlashBladeDriverTestCaseBase): ), ) ) - self.assertEqual("mockfb2:/share-1-manila", location) + self.assertEqual(_SINGLE_VIP_LOCATION, location) + + def test_create_nfs_share_multiple_vips(self): + self.configuration.flashblade_data_vip.append("mockfb3") + location = self.driver.create_share(None, test_nfs_share) + self.assertEqual(_DUAL_VIP_LOCATION, location) def test_delete_share(self): self.mock_object(self.driver, "_get_flashblade_filesystem_by_name")