NetApp: Implement share metadata update method

Consider two metadata keys i.e. snapshot_policy and showmount.

Partially-implements: blueprint pass-resource-metadata-updates-to-backend-drivers
Depends-on: If4297cca3249359f72976800db2112ea9c61c06f
Change-Id: I042a2caa5884ddea09ecfa0028d01758c18af5a3
This commit is contained in:
Kiran Pawar 2024-07-29 14:40:43 +00:00
parent 4bf505404a
commit 52d423f606
12 changed files with 216 additions and 2 deletions

View File

@ -3733,7 +3733,8 @@ class ShareDriver(object):
""" """
raise NotImplementedError() raise NotImplementedError()
def update_share_from_metadata(self, context, share, metadata): def update_share_from_metadata(self, context, share, metadata,
share_server=None):
"""Update the share from metadata. """Update the share from metadata.
Driver must implement this method if needs to perform some action Driver must implement this method if needs to perform some action
@ -3743,5 +3744,6 @@ class ShareDriver(object):
:param share: Share instance model with share data. :param share: Share instance model with share data.
:param metadata: Dict contains key-value pair where driver will :param metadata: Dict contains key-value pair where driver will
perform necessary action based on key. perform necessary action based on key.
:param share_server: Reference to the share server.
""" """
raise NotImplementedError() raise NotImplementedError()

View File

@ -1600,6 +1600,14 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
'Data ONTAP driver') 'Data ONTAP driver')
raise exception.NetAppException(msg % security_service['type']) raise exception.NetAppException(msg % security_service['type'])
@na_utils.trace
def update_showmount(self, showmount):
"""Update show mount for vserver. """
nfs_service_modify_arg = {
'showmount': showmount
}
self.send_request('nfs-service-modify', nfs_service_modify_arg)
@na_utils.trace @na_utils.trace
def enable_nfs(self, versions, nfs_config=None): def enable_nfs(self, versions, nfs_config=None):
"""Enables NFS on Vserver.""" """Enables NFS on Vserver."""
@ -2326,6 +2334,27 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
return api_args return api_args
@na_utils.trace
def update_volume_snapshot_policy(self, volume_name, snapshot_policy):
"""Set snapshot policy for the specified volume."""
api_args = {
'query': {
'volume-attributes': {
'volume-id-attributes': {
'name': volume_name,
},
},
},
'attributes': {
'volume-attributes': {
'volume-snapshot-attributes': {
'snapshot-policy': snapshot_policy,
},
},
},
}
self.send_request('volume-modify-iter', api_args)
@na_utils.trace @na_utils.trace
@manila_utils.retry(retry_param=exception.NetAppException, @manila_utils.retry(retry_param=exception.NetAppException,
interval=3, interval=3,

View File

@ -1110,6 +1110,18 @@ class NetAppRestClient(object):
'compression': compression, 'compression': compression,
} }
@na_utils.trace
def update_volume_snapshot_policy(self, volume_name, snapshot_policy):
"""Set snapshot policy for the specified volume."""
volume = self._get_volume_by_args(vol_name=volume_name)
uuid = volume['uuid']
body = {
'snapshot_policy.name': snapshot_policy
}
# update snapshot policy
self.send_request(f'/storage/volumes/{uuid}', 'patch', body=body)
@na_utils.trace @na_utils.trace
def update_volume_efficiency_attributes(self, volume_name, dedup_enabled, def update_volume_efficiency_attributes(self, volume_name, dedup_enabled,
compression_enabled, compression_enabled,
@ -4686,6 +4698,26 @@ class NetAppRestClient(object):
} }
raise exception.NetAppException(msg % msg_args) raise exception.NetAppException(msg % msg_args)
@na_utils.trace
def update_showmount(self, showmount):
"""Update show mount for vserver. """
# Get SVM UUID.
query = {
'name': self.vserver,
'fields': 'uuid'
}
res = self.send_request('/svm/svms', 'get', query=query)
if not res.get('records'):
msg = _('Vserver %s not found.') % self.vserver
raise exception.NetAppException(msg)
svm_id = res.get('records')[0]['uuid']
body = {
'showmount_enabled': showmount,
}
self.send_request(f'/protocols/nfs/services/{svm_id}', 'patch',
body=body)
@na_utils.trace @na_utils.trace
def enable_nfs(self, versions, nfs_config=None): def enable_nfs(self, versions, nfs_config=None):
"""Enables NFS on Vserver.""" """Enables NFS on Vserver."""

View File

@ -398,3 +398,8 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
def delete_backup(self, context, backup, share, **kwargs): def delete_backup(self, context, backup, share, **kwargs):
return self.library.delete_backup(context, backup, share, **kwargs) return self.library.delete_backup(context, backup, share, **kwargs)
def update_share_from_metadata(self, context, share, metadata,
share_server=None):
self.library.update_share_from_metadata(
context, share, metadata, share_server=share_server)

View File

@ -362,3 +362,8 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
def delete_backup(self, context, backup, share, **kwargs): def delete_backup(self, context, backup, share, **kwargs):
return self.library.delete_backup(context, backup, share, **kwargs) return self.library.delete_backup(context, backup, share, **kwargs)
def update_share_from_metadata(self, context, share, metadata,
share_server=None):
self.library.update_share_from_metadata(
context, share, metadata, share_server=share_server)

View File

@ -5014,3 +5014,29 @@ class NetAppCmodeFileStorageLibrary(object):
# Delete Vserver # Delete Vserver
if share_server is not None: if share_server is not None:
self._delete_backup_vserver(backup, des_vserver) self._delete_backup_vserver(backup, des_vserver)
@na_utils.trace
def update_volume_snapshot_policy(self, share, snapshot_policy,
share_server=None):
share_name = self._get_backend_share_name(share['id'])
_, vserver_client = self._get_vserver(share_server=share_server)
vserver_client.update_volume_snapshot_policy(share_name,
snapshot_policy)
@na_utils.trace
def update_showmount(self, share, showmount, share_server=None):
_, vserver_client = self._get_vserver(share_server=share_server)
vserver_client.update_showmount(showmount)
@na_utils.trace
def update_share_from_metadata(self, context, share, metadata,
share_server=None):
metadata_update_func_map = {
"snapshot_policy": "update_volume_snapshot_policy",
"showmount": "update_showmount",
}
for k, v in metadata.items():
update_func = getattr(self, metadata_update_func_map.get(k))
if update_func:
update_func(share, v, share_server=share_server)

View File

@ -6759,9 +6759,10 @@ class ShareManager(manager.SchedulerDependentManager):
def update_share_from_metadata(self, context, share_id, metadata): def update_share_from_metadata(self, context, share_id, metadata):
share = self.db.share_get(context, share_id) share = self.db.share_get(context, share_id)
share_instance = self._get_share_instance(context, share) share_instance = self._get_share_instance(context, share)
share_server = self._get_share_server(context, share_instance)
try: try:
self.driver.update_share_from_metadata(context, share_instance, self.driver.update_share_from_metadata(context, share_instance,
metadata) metadata, share_server)
self.message_api.create( self.message_api.create(
context, context,
message_field.Action.UPDATE_METADATA, message_field.Action.UPDATE_METADATA,

View File

@ -1054,3 +1054,10 @@ class DummyDriver(driver.ShareDriver):
{'backup': backup['id'], {'backup': backup['id'],
'share': share_instance['share_id']}) 'share': share_instance['share_id']})
return {'total_progress': '100'} return {'total_progress': '100'}
def update_share_from_metadata(self, context, share_instance, metadata,
share_server=None):
LOG.debug("Updated share %(share)s. Metadata %(metadata)s "
"applied successfully.",
{'share': share_instance['share_id'],
'metadata': metadata})

View File

@ -2534,6 +2534,19 @@ class NetAppClientCmodeTestCase(test.TestCase):
self.client.send_request.assert_has_calls([ self.client.send_request.assert_has_calls([
mock.call('vserver-modify', vserver_modify_args)]) mock.call('vserver-modify', vserver_modify_args)])
def test_update_showmount(self):
self.mock_object(self.client, 'send_request')
fake_showmount = 'true'
self.client.update_showmount(fake_showmount)
nfs_service_modify_args = {
'showmount': fake_showmount,
}
self.client.send_request.assert_called_once_with(
'nfs-service-modify', nfs_service_modify_args)
@ddt.data({'tcp-max-xfer-size': 10000}, {}, None) @ddt.data({'tcp-max-xfer-size': 10000}, {}, None)
def test_enable_nfs(self, nfs_config): def test_enable_nfs(self, nfs_config):
@ -3490,6 +3503,32 @@ class NetAppClientCmodeTestCase(test.TestCase):
self.assertFalse(result) self.assertFalse(result)
def test_update_volume_snapshot_policy(self):
self.mock_object(self.client, 'send_request')
self.client.update_volume_snapshot_policy(fake.SHARE_NAME,
fake.SNAPSHOT_POLICY_NAME)
volume_modify_iter_api_args = {
'query': {
'volume-attributes': {
'volume-id-attributes': {
'name': fake.SHARE_NAME,
},
},
},
'attributes': {
'volume-attributes': {
'volume-snapshot-attributes': {
'snapshot-policy': fake.SNAPSHOT_POLICY_NAME,
},
},
},
}
self.client.send_request.assert_called_once_with(
'volume-modify-iter', volume_modify_iter_api_args)
def test_enable_dedup(self): def test_enable_dedup(self):
self.mock_object(self.client, 'send_request') self.mock_object(self.client, 'send_request')

View File

@ -2766,6 +2766,23 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
self.client.get_job_state, self.client.get_job_state,
'fake_uuid') 'fake_uuid')
def test_update_volume_snapshot_policy(self):
return_uuid = {
'uuid': 'fake_uuid'
}
mock_get_vol = self.mock_object(self.client, '_get_volume_by_args',
mock.Mock(return_value=return_uuid))
mock_sr = self.mock_object(self.client, 'send_request')
self.client.update_volume_snapshot_policy('fake_volume_name',
fake.SNAPSHOT_POLICY_NAME)
body = {
'snapshot_policy.name': fake.SNAPSHOT_POLICY_NAME
}
mock_sr.assert_called_once_with('/storage/volumes/fake_uuid',
'patch', body=body)
mock_get_vol.assert_called_once_with(vol_name='fake_volume_name')
@ddt.data(True, False) @ddt.data(True, False)
def test_update_volume_efficiency_attributes(self, status): def test_update_volume_efficiency_attributes(self, status):
response = { response = {
@ -4499,6 +4516,31 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
self.client.send_request.assert_called_once_with( self.client.send_request.assert_called_once_with(
'/svm/peers/fake_uuid', 'delete', enable_tunneling=False) '/svm/peers/fake_uuid', 'delete', enable_tunneling=False)
def test_update_showmount(self):
query = {
'name': fake.VSERVER_NAME,
'fields': 'uuid'
}
response_svm = fake.SVMS_LIST_SIMPLE_RESPONSE_REST
self.client.vserver = fake.VSERVER_NAME
self.mock_object(self.client,
'send_request',
mock.Mock(side_effect=[response_svm, None]))
fake_showmount = 'true'
self.client.update_showmount(fake_showmount)
svm_id = response_svm.get('records')[0]['uuid']
body = {
'showmount_enabled': fake_showmount,
}
self.client.send_request.assert_has_calls([
mock.call('/svm/svms', 'get', query=query),
mock.call(f'/protocols/nfs/services/{svm_id}',
'patch', body=body)
])
@ddt.data({'tcp-max-xfer-size': 10000}, {}, None) @ddt.data({'tcp-max-xfer-size': 10000}, {}, None)
def test_enable_nfs(self, nfs_config): def test_enable_nfs(self, nfs_config):
self.mock_object(self.client, '_get_unique_svm_by_name', self.mock_object(self.client, '_get_unique_svm_by_name',

View File

@ -8905,3 +8905,23 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.mock_object(mock_des_client, self.mock_object(mock_des_client,
'list_volume_snapshots', 'list_volume_snapshots',
mock.Mock(return_value=snap_list)) mock.Mock(return_value=snap_list))
def test_update_share_from_metadata(self):
metadata = {
"snapshot_policy": "daily",
"showmount": "True",
}
share_instance = fake.SHARE_INSTANCE
mock_update_volume_snapshot_policy = self.mock_object(
self.library, 'update_volume_snapshot_policy')
mock_update_showmount = self.mock_object(
self.library, 'update_showmount')
self.library.update_share_from_metadata(self.context, share_instance,
metadata)
mock_update_volume_snapshot_policy.assert_called_once_with(
share_instance, "daily", share_server=None)
mock_update_showmount.assert_called_once_with(
share_instance, "True", share_server=None)

View File

@ -0,0 +1,6 @@
---
fixes:
- |
The NetApp ONTAP driver is now able to update the current `snapshot_policy`
and/or both `showmount` configurations in a pre-created share. Please use
the share metadata set feature to update these values.