NetApp: Fix export location during replica promote

During replica promote, the export location is retrieved using the
share replica cluster_client of replica under promotion instead of
active replica. This invalid cluster_client is causing NetApp API
error during _get_aggregate_node(). Fixed it.

Change-Id: I6b809e093413a9a5d574023db73bbb01023f0e9f
Closes-bug: #2104153
This commit is contained in:
Kiran Pawar
2025-03-25 17:07:27 +00:00
parent e1a0e85687
commit 0130010829
3 changed files with 33 additions and 10 deletions

View File

@@ -414,9 +414,11 @@ class NetAppCmodeFileStorageLibrary(object):
return self._client.check_snaprestore_license()
@na_utils.trace
def _get_aggregate_node(self, aggregate_name):
def _get_aggregate_node(self, aggregate_name, cluster_client=None):
"""Get home node for the specified aggregate, or None."""
if self._have_cluster_creds:
if cluster_client:
return cluster_client.get_node_for_aggregate(aggregate_name)
elif self._have_cluster_creds:
return self._client.get_node_for_aggregate(aggregate_name)
else:
return None
@@ -1814,6 +1816,7 @@ class NetAppCmodeFileStorageLibrary(object):
@na_utils.trace
def _create_export(self, share, share_server, vserver, vserver_client,
cluster_client=None,
clear_current_export_policy=True,
ensure_share_already_exists=False, replica=False,
share_host=None):
@@ -1835,7 +1838,7 @@ class NetAppCmodeFileStorageLibrary(object):
# Get LIF addresses with metadata
export_addresses = self._get_export_addresses_with_metadata(
share, share_server, interfaces, host)
share, share_server, interfaces, host, cluster_client)
# Create the share and get a callback for generating export locations
pool = share_utils.extract_host(share['host'], level='pool')
@@ -1865,7 +1868,8 @@ class NetAppCmodeFileStorageLibrary(object):
@na_utils.trace
def _get_export_addresses_with_metadata(self, share, share_server,
interfaces, share_host):
interfaces, share_host,
cluster_client=None):
"""Return interface addresses with locality and other metadata."""
# Get home nodes so we can identify preferred paths
@@ -1873,11 +1877,12 @@ class NetAppCmodeFileStorageLibrary(object):
home_node_set = set()
if self._is_flexgroup_pool(pool):
for aggregate_name in self._get_flexgroup_aggregate_list(pool):
home_node = self._get_aggregate_node(aggregate_name)
home_node = self._get_aggregate_node(
aggregate_name, cluster_client)
if home_node:
home_node_set.add(home_node)
else:
home_node = self._get_aggregate_node(pool)
home_node = self._get_aggregate_node(pool, cluster_client)
if home_node:
home_node_set.add(home_node)
@@ -3301,8 +3306,11 @@ class NetAppCmodeFileStorageLibrary(object):
return replica
try:
replica_cluster_client = self._get_api_client_for_backend(
replica_backend)
replica['export_locations'] = self._create_export(
replica, share_server, replica_vserver, replica_client,
cluster_client=replica_cluster_client,
replica=True)
except netapp_api.NaApiError:
replica['status'] = constants.STATUS_ERROR

View File

@@ -2397,6 +2397,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.mock_object(self.library,
'_is_flexgroup_pool', mock.Mock(return_value=False))
vserver_client = mock.Mock()
cluster_client = mock.Mock()
vserver_client.get_network_interfaces.return_value = fake.LIFS
fake_interface_addresses_with_metadata = copy.deepcopy(
fake.INTERFACE_ADDRESSES_WITH_METADATA)
@@ -2408,11 +2409,13 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake.SHARE_SERVER,
fake.VSERVER1,
vserver_client,
cluster_client=cluster_client,
share_host=share_host)
self.assertEqual(fake.NFS_EXPORTS, result)
mock_get_export_addresses_with_metadata.assert_called_once_with(
fake.SHARE, fake.SHARE_SERVER, fake.LIFS, expected_host)
fake.SHARE, fake.SHARE_SERVER, fake.LIFS, expected_host,
cluster_client)
protocol_helper.create_share.assert_called_once_with(
fake.SHARE, fake.SHARE_NAME, clear_current_export_policy=True,
ensure_share_already_exists=False, replica=False,
@@ -2455,9 +2458,11 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
fake.SHARE_SERVER)
if is_flexgroup:
mock_get_aggr_flexgroup.assert_called_once_with(fake.POOL_NAME)
mock_get_aggregate_node.assert_called_once_with(fake.AGGREGATE)
mock_get_aggregate_node.assert_called_once_with(
fake.AGGREGATE, None)
else:
mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
mock_get_aggregate_node.assert_called_once_with(
fake.POOL_NAME, None)
def test_get_export_addresses_with_metadata_node_unknown(self):
@@ -2478,7 +2483,7 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
value['preferred'] = False
self.assertEqual(expected, result)
mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME)
mock_get_aggregate_node.assert_called_once_with(fake.POOL_NAME, None)
mock_get_admin_addresses_for_share_server.assert_called_once_with(
fake.SHARE_SERVER)
@@ -4693,6 +4698,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
mock_backend_config = fake.get_config_cmode()
self.mock_object(data_motion, 'get_backend_configuration',
mock.Mock(return_value=mock_backend_config))
self.mock_object(self.library, '_get_api_client_for_backend',
mock.Mock(return_value=mock_client))
self.mock_object(self.client, 'cleanup_demoted_replica')
self.mock_object(self.library,
'_is_readable_replica',
@@ -5258,6 +5265,8 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
mock_backend_config.netapp_mount_replica_timeout = 30
self.mock_object(data_motion, 'get_backend_configuration',
mock.Mock(return_value=mock_backend_config))
self.mock_object(self.library, '_get_api_client_for_backend',
mock.Mock(return_value=mock_client))
replica = self.library._safe_change_replica_source(
mock_dm_session, self.fake_replica, self.fake_replica_2,

View File

@@ -0,0 +1,6 @@
---
fixes:
- |
NetApp ONTAP driver now updates correct export location after promotion of
share replica of replication type readable. For more details, please check
`Launchpad bug #2104153 <https://bugs.launchpad.net/manila/+bug/2104153>`_