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:
parent
4bf505404a
commit
52d423f606
@ -3733,7 +3733,8 @@ class ShareDriver(object):
|
||||
"""
|
||||
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.
|
||||
|
||||
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 metadata: Dict contains key-value pair where driver will
|
||||
perform necessary action based on key.
|
||||
:param share_server: Reference to the share server.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
@ -1600,6 +1600,14 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
'Data ONTAP driver')
|
||||
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
|
||||
def enable_nfs(self, versions, nfs_config=None):
|
||||
"""Enables NFS on Vserver."""
|
||||
@ -2326,6 +2334,27 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
|
||||
|
||||
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
|
||||
@manila_utils.retry(retry_param=exception.NetAppException,
|
||||
interval=3,
|
||||
|
@ -1110,6 +1110,18 @@ class NetAppRestClient(object):
|
||||
'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
|
||||
def update_volume_efficiency_attributes(self, volume_name, dedup_enabled,
|
||||
compression_enabled,
|
||||
@ -4686,6 +4698,26 @@ class NetAppRestClient(object):
|
||||
}
|
||||
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
|
||||
def enable_nfs(self, versions, nfs_config=None):
|
||||
"""Enables NFS on Vserver."""
|
||||
|
@ -398,3 +398,8 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
|
||||
|
||||
def delete_backup(self, 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)
|
||||
|
@ -362,3 +362,8 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
|
||||
|
||||
def delete_backup(self, 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)
|
||||
|
@ -5014,3 +5014,29 @@ class NetAppCmodeFileStorageLibrary(object):
|
||||
# Delete Vserver
|
||||
if share_server is not None:
|
||||
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)
|
||||
|
@ -6759,9 +6759,10 @@ class ShareManager(manager.SchedulerDependentManager):
|
||||
def update_share_from_metadata(self, context, share_id, metadata):
|
||||
share = self.db.share_get(context, share_id)
|
||||
share_instance = self._get_share_instance(context, share)
|
||||
share_server = self._get_share_server(context, share_instance)
|
||||
try:
|
||||
self.driver.update_share_from_metadata(context, share_instance,
|
||||
metadata)
|
||||
metadata, share_server)
|
||||
self.message_api.create(
|
||||
context,
|
||||
message_field.Action.UPDATE_METADATA,
|
||||
|
@ -1054,3 +1054,10 @@ class DummyDriver(driver.ShareDriver):
|
||||
{'backup': backup['id'],
|
||||
'share': share_instance['share_id']})
|
||||
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})
|
||||
|
@ -2534,6 +2534,19 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
self.client.send_request.assert_has_calls([
|
||||
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)
|
||||
def test_enable_nfs(self, nfs_config):
|
||||
|
||||
@ -3490,6 +3503,32 @@ class NetAppClientCmodeTestCase(test.TestCase):
|
||||
|
||||
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):
|
||||
|
||||
self.mock_object(self.client, 'send_request')
|
||||
|
@ -2766,6 +2766,23 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
||||
self.client.get_job_state,
|
||||
'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)
|
||||
def test_update_volume_efficiency_attributes(self, status):
|
||||
response = {
|
||||
@ -4499,6 +4516,31 @@ class NetAppRestCmodeClientTestCase(test.TestCase):
|
||||
self.client.send_request.assert_called_once_with(
|
||||
'/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)
|
||||
def test_enable_nfs(self, nfs_config):
|
||||
self.mock_object(self.client, '_get_unique_svm_by_name',
|
||||
|
@ -8905,3 +8905,23 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
|
||||
self.mock_object(mock_des_client,
|
||||
'list_volume_snapshots',
|
||||
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)
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user