From 6a85a6f5e320ccb087f6ba0fc51e4ad5f10ef2d0 Mon Sep 17 00:00:00 2001 From: Amit Oren Date: Sun, 28 Jan 2018 18:25:18 +0200 Subject: [PATCH] INFINIDAT: load-balance shares inside network space Instead of always using the first IP from the INFINIDAT InfiniBox network space, utilize the export_locations attribute of the share and return the IPs of all enabled network space IPs. Change-Id: I2319d574cb95f8cc688e608a7e455743e4e63f93 --- manila/share/drivers/infinidat/infinibox.py | 46 +++++++++++-------- .../share/drivers/infinidat/test_infinidat.py | 37 ++++++++++++++- ...e-network-spaces-ips-25a9f1e587b87156.yaml | 4 ++ 3 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 releasenotes/notes/infinidat-balance-network-spaces-ips-25a9f1e587b87156.yaml diff --git a/manila/share/drivers/infinidat/infinibox.py b/manila/share/drivers/infinidat/infinibox.py index 303804da0f..5c65511cb6 100644 --- a/manila/share/drivers/infinidat/infinibox.py +++ b/manila/share/drivers/infinidat/infinibox.py @@ -220,23 +220,31 @@ class InfiniboxShareDriver(driver.ShareDriver): network_space = self._system.network_spaces.safe_get( name=self._network_space_name) if network_space is None: - msg = _('Network space "%s" not found') % self._network_space_name + msg = _('INFINIDAT InfiniBox NAS network space "%s" ' + 'not found') % self._network_space_name LOG.error(msg) raise exception.ShareBackendException(msg=msg) network_space_ips = network_space.get_ips() if not network_space_ips: - msg = _('INFINIDAT InfiniBox NAS Network Space "%s" has no IPs ' - 'defined') % self._network_space_name + msg = _('INFINIDAT InfiniBox NAS network space "%s" has no IP ' + 'addresses defined') % self._network_space_name LOG.error(msg) raise exception.ShareBackendException(msg=msg) - return [ip_munch.ip_address for ip_munch in network_space_ips] + ip_addresses = ( + [ip_munch.ip_address for ip_munch in network_space_ips if + ip_munch.enabled]) + if not ip_addresses: + msg = _('INFINIDAT InfiniBox NAS network space "%s" has no ' + 'enabled IP addresses') % self._network_space_name + LOG.error(msg) + raise exception.ShareBackendException(msg=msg) + return ip_addresses - @infinisdk_to_manila_exceptions - def _get_full_nfs_export_path(self, export_path): + def _get_full_nfs_export_paths(self, export_path): network_space_ips = self._get_infinidat_nas_network_space_ips() - return '{network_space_ip}:{export_path}'.format( - network_space_ip=network_space_ips[0], - export_path=export_path) + return ['{network_space_ip}:{export_path}'.format( + network_space_ip=network_space_ip, + export_path=export_path) for network_space_ip in network_space_ips] @infinisdk_to_manila_exceptions def _get_infinidat_filesystem_by_name(self, name): @@ -310,12 +318,14 @@ class InfiniboxShareDriver(driver.ShareDriver): @infinisdk_to_manila_exceptions def _create_filesystem_export(self, infinidat_filesystem): infinidat_export = infinidat_filesystem.add_export(permissions=[]) - return { - 'path': self._get_full_nfs_export_path( - infinidat_export.get_export_path()), + export_paths = self._get_full_nfs_export_paths( + infinidat_export.get_export_path()) + export_locations = [{ + 'path': export_path, 'is_admin_only': False, 'metadata': {}, - } + } for export_path in export_paths] + return export_locations @infinisdk_to_manila_exceptions def _delete_share(self, share, is_snapshot): @@ -399,7 +409,7 @@ class InfiniboxShareDriver(driver.ShareDriver): # extending is needed self._set_manila_object_metadata(infinidat_snapshot, snapshot) return {'export_locations': - [self._create_filesystem_export(infinidat_snapshot)]} + self._create_filesystem_export(infinidat_snapshot)} def delete_share(self, context, share, share_server=None): try: @@ -421,16 +431,14 @@ class InfiniboxShareDriver(driver.ShareDriver): infinidat_filesystem = self._get_infinidat_filesystem(share) try: infinidat_export = self._get_export(infinidat_filesystem) + return self._get_full_nfs_export_paths( + infinidat_export.get_export_path()) except exception.ShareBackendException: # export not found, need to re-export message = ("missing export for share %(share)s, trying to " "re-export") LOG.info(message, {"share": share}) - infinidat_export = ( - self._create_filesystem_export(infinidat_filesystem)) - return [self._get_full_nfs_export_path(infinidat_export['path'])] - return [self._get_full_nfs_export_path( - infinidat_export.get_export_path())] + return self._create_filesystem_export(infinidat_filesystem) def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): diff --git a/manila/tests/share/drivers/infinidat/test_infinidat.py b/manila/tests/share/drivers/infinidat/test_infinidat.py index 0376921525..89870da530 100644 --- a/manila/tests/share/drivers/infinidat/test_infinidat.py +++ b/manila/tests/share/drivers/infinidat/test_infinidat.py @@ -31,6 +31,9 @@ _MOCK_CLONE_ID = 3 _MOCK_SHARE_SIZE = 4 +_MOCK_NETWORK_SPACE_IP_1 = '1.2.3.4' +_MOCK_NETWORK_SPACE_IP_2 = '1.2.3.5' + def _create_mock__getitem__(mock): def mock__getitem__(self, key, default=None): @@ -137,7 +140,8 @@ class InfiniboxDriverTestCaseBase(test.TestCase): self._mock_network_space = mock.Mock() self._mock_network_space.get_ips.return_value = ( - [mock.Mock(ip_address='1.2.3.4'), mock.Mock(ip_address='1.2.3.5')]) + [mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_1, enabled=True), + mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_2, enabled=True)]) result.network_spaces.safe_get.return_value = self._mock_network_space result.pools.safe_get.return_value = self._mock_pool @@ -259,10 +263,21 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): self.driver._get_infinidat_pool) def test__get_infinidat_nas_network_space_ips(self): - self.driver._get_infinidat_nas_network_space_ips() + network_space_ips = self.driver._get_infinidat_nas_network_space_ips() self._system.network_spaces.safe_get.assert_called_once() self._mock_network_space.get_ips.assert_called_once() + for network_space_ip in \ + (_MOCK_NETWORK_SPACE_IP_1, _MOCK_NETWORK_SPACE_IP_2): + self.assertIn(network_space_ip, network_space_ips) + + def test__get_infinidat_nas_network_space_ips_only_one_ip_enabled(self): + self._mock_network_space.get_ips.return_value = ( + [mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_1, enabled=True), + mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_2, enabled=False)]) + self.assertEqual([_MOCK_NETWORK_SPACE_IP_1], + self.driver._get_infinidat_nas_network_space_ips()) + def test__get_infinidat_nas_network_space_ips_no_network_space(self): self._system.network_spaces.safe_get.return_value = None self.assertRaises(exception.ShareBackendException, @@ -273,12 +288,30 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): self.assertRaises(exception.ShareBackendException, self.driver._get_infinidat_nas_network_space_ips) + def test__get_infinidat_nas_network_space_ips_no_ips_enabled(self): + self._mock_network_space.get_ips.return_value = ( + [mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_1, enabled=False), + mock.Mock(ip_address=_MOCK_NETWORK_SPACE_IP_2, enabled=False)]) + self.assertRaises(exception.ShareBackendException, + self.driver._get_infinidat_nas_network_space_ips) + def test__get_infinidat_nas_network_space_api_error(self): self._system.network_spaces.safe_get.side_effect = ( self._raise_infinisdk) self.assertRaises(exception.ShareBackendException, self.driver._get_infinidat_nas_network_space_ips) + def test__get_full_nfs_export_paths(self): + export_paths = self.driver._get_full_nfs_export_paths( + self._mock_export.get_export_path()) + for network_space_ip in \ + (_MOCK_NETWORK_SPACE_IP_1, _MOCK_NETWORK_SPACE_IP_2): + self.assertIn( + "{network_space_ip}:{export_path}".format( + network_space_ip=network_space_ip, + export_path=self._mock_export.get_export_path()), + export_paths) + def test__get_export(self): # The default return value of get_exports is [mock_export, ]: export = self.driver._get_export(self._mock_filesystem) diff --git a/releasenotes/notes/infinidat-balance-network-spaces-ips-25a9f1e587b87156.yaml b/releasenotes/notes/infinidat-balance-network-spaces-ips-25a9f1e587b87156.yaml new file mode 100644 index 0000000000..7d2d8bbbc0 --- /dev/null +++ b/releasenotes/notes/infinidat-balance-network-spaces-ips-25a9f1e587b87156.yaml @@ -0,0 +1,4 @@ +--- +features: + - The INFINIDAT share driver now load balances shares between the IPs + of the chosen network space.