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
This commit is contained in:
parent
a07d522970
commit
6a85a6f5e3
@ -220,23 +220,31 @@ class InfiniboxShareDriver(driver.ShareDriver):
|
|||||||
network_space = self._system.network_spaces.safe_get(
|
network_space = self._system.network_spaces.safe_get(
|
||||||
name=self._network_space_name)
|
name=self._network_space_name)
|
||||||
if network_space is None:
|
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)
|
LOG.error(msg)
|
||||||
raise exception.ShareBackendException(msg=msg)
|
raise exception.ShareBackendException(msg=msg)
|
||||||
network_space_ips = network_space.get_ips()
|
network_space_ips = network_space.get_ips()
|
||||||
if not network_space_ips:
|
if not network_space_ips:
|
||||||
msg = _('INFINIDAT InfiniBox NAS Network Space "%s" has no IPs '
|
msg = _('INFINIDAT InfiniBox NAS network space "%s" has no IP '
|
||||||
'defined') % self._network_space_name
|
'addresses defined') % self._network_space_name
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.ShareBackendException(msg=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_paths(self, export_path):
|
||||||
def _get_full_nfs_export_path(self, export_path):
|
|
||||||
network_space_ips = self._get_infinidat_nas_network_space_ips()
|
network_space_ips = self._get_infinidat_nas_network_space_ips()
|
||||||
return '{network_space_ip}:{export_path}'.format(
|
return ['{network_space_ip}:{export_path}'.format(
|
||||||
network_space_ip=network_space_ips[0],
|
network_space_ip=network_space_ip,
|
||||||
export_path=export_path)
|
export_path=export_path) for network_space_ip in network_space_ips]
|
||||||
|
|
||||||
@infinisdk_to_manila_exceptions
|
@infinisdk_to_manila_exceptions
|
||||||
def _get_infinidat_filesystem_by_name(self, name):
|
def _get_infinidat_filesystem_by_name(self, name):
|
||||||
@ -310,12 +318,14 @@ class InfiniboxShareDriver(driver.ShareDriver):
|
|||||||
@infinisdk_to_manila_exceptions
|
@infinisdk_to_manila_exceptions
|
||||||
def _create_filesystem_export(self, infinidat_filesystem):
|
def _create_filesystem_export(self, infinidat_filesystem):
|
||||||
infinidat_export = infinidat_filesystem.add_export(permissions=[])
|
infinidat_export = infinidat_filesystem.add_export(permissions=[])
|
||||||
return {
|
export_paths = self._get_full_nfs_export_paths(
|
||||||
'path': self._get_full_nfs_export_path(
|
infinidat_export.get_export_path())
|
||||||
infinidat_export.get_export_path()),
|
export_locations = [{
|
||||||
|
'path': export_path,
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
}
|
} for export_path in export_paths]
|
||||||
|
return export_locations
|
||||||
|
|
||||||
@infinisdk_to_manila_exceptions
|
@infinisdk_to_manila_exceptions
|
||||||
def _delete_share(self, share, is_snapshot):
|
def _delete_share(self, share, is_snapshot):
|
||||||
@ -399,7 +409,7 @@ class InfiniboxShareDriver(driver.ShareDriver):
|
|||||||
# extending is needed
|
# extending is needed
|
||||||
self._set_manila_object_metadata(infinidat_snapshot, snapshot)
|
self._set_manila_object_metadata(infinidat_snapshot, snapshot)
|
||||||
return {'export_locations':
|
return {'export_locations':
|
||||||
[self._create_filesystem_export(infinidat_snapshot)]}
|
self._create_filesystem_export(infinidat_snapshot)}
|
||||||
|
|
||||||
def delete_share(self, context, share, share_server=None):
|
def delete_share(self, context, share, share_server=None):
|
||||||
try:
|
try:
|
||||||
@ -421,16 +431,14 @@ class InfiniboxShareDriver(driver.ShareDriver):
|
|||||||
infinidat_filesystem = self._get_infinidat_filesystem(share)
|
infinidat_filesystem = self._get_infinidat_filesystem(share)
|
||||||
try:
|
try:
|
||||||
infinidat_export = self._get_export(infinidat_filesystem)
|
infinidat_export = self._get_export(infinidat_filesystem)
|
||||||
|
return self._get_full_nfs_export_paths(
|
||||||
|
infinidat_export.get_export_path())
|
||||||
except exception.ShareBackendException:
|
except exception.ShareBackendException:
|
||||||
# export not found, need to re-export
|
# export not found, need to re-export
|
||||||
message = ("missing export for share %(share)s, trying to "
|
message = ("missing export for share %(share)s, trying to "
|
||||||
"re-export")
|
"re-export")
|
||||||
LOG.info(message, {"share": share})
|
LOG.info(message, {"share": share})
|
||||||
infinidat_export = (
|
return self._create_filesystem_export(infinidat_filesystem)
|
||||||
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())]
|
|
||||||
|
|
||||||
def update_access(self, context, share, access_rules, add_rules,
|
def update_access(self, context, share, access_rules, add_rules,
|
||||||
delete_rules, share_server=None):
|
delete_rules, share_server=None):
|
||||||
|
@ -31,6 +31,9 @@ _MOCK_CLONE_ID = 3
|
|||||||
|
|
||||||
_MOCK_SHARE_SIZE = 4
|
_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 _create_mock__getitem__(mock):
|
||||||
def mock__getitem__(self, key, default=None):
|
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 = mock.Mock()
|
||||||
self._mock_network_space.get_ips.return_value = (
|
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.network_spaces.safe_get.return_value = self._mock_network_space
|
||||||
result.pools.safe_get.return_value = self._mock_pool
|
result.pools.safe_get.return_value = self._mock_pool
|
||||||
@ -259,10 +263,21 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase):
|
|||||||
self.driver._get_infinidat_pool)
|
self.driver._get_infinidat_pool)
|
||||||
|
|
||||||
def test__get_infinidat_nas_network_space_ips(self):
|
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._system.network_spaces.safe_get.assert_called_once()
|
||||||
self._mock_network_space.get_ips.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):
|
def test__get_infinidat_nas_network_space_ips_no_network_space(self):
|
||||||
self._system.network_spaces.safe_get.return_value = None
|
self._system.network_spaces.safe_get.return_value = None
|
||||||
self.assertRaises(exception.ShareBackendException,
|
self.assertRaises(exception.ShareBackendException,
|
||||||
@ -273,12 +288,30 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase):
|
|||||||
self.assertRaises(exception.ShareBackendException,
|
self.assertRaises(exception.ShareBackendException,
|
||||||
self.driver._get_infinidat_nas_network_space_ips)
|
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):
|
def test__get_infinidat_nas_network_space_api_error(self):
|
||||||
self._system.network_spaces.safe_get.side_effect = (
|
self._system.network_spaces.safe_get.side_effect = (
|
||||||
self._raise_infinisdk)
|
self._raise_infinisdk)
|
||||||
self.assertRaises(exception.ShareBackendException,
|
self.assertRaises(exception.ShareBackendException,
|
||||||
self.driver._get_infinidat_nas_network_space_ips)
|
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):
|
def test__get_export(self):
|
||||||
# The default return value of get_exports is [mock_export, ]:
|
# The default return value of get_exports is [mock_export, ]:
|
||||||
export = self.driver._get_export(self._mock_filesystem)
|
export = self.driver._get_export(self._mock_filesystem)
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- The INFINIDAT share driver now load balances shares between the IPs
|
||||||
|
of the chosen network space.
|
Loading…
Reference in New Issue
Block a user