Implemented methods for share metadata

Change-Id: Ib3c27ec3d0eb102b30a80994d6cc2af4ee78f3dd
This commit is contained in:
Anvi Joshi
2023-06-23 20:02:44 +00:00
parent d264526ed1
commit 6ef2af39d5
8 changed files with 395 additions and 3 deletions

View File

@@ -134,3 +134,49 @@ Deletes a share group snapshot.
.. literalinclude:: ../examples/shared_file_system/share_group_snapshots.py .. literalinclude:: ../examples/shared_file_system/share_group_snapshots.py
:pyobject: delete_share_group_snapshot :pyobject: delete_share_group_snapshot
List Share Metadata
--------------------
Lists all metadata for a given share.
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
:pyobject: list_share_metadata
Get Share Metadata Item
-----------------------
Retrieves a specific metadata item from a shares metadata by its key.
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
:pyobject: get_share_metadata_item
Create Share Metadata
----------------------
Creates share metadata.
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
:pyobject: create_share_metadata
Update Share Metadata
----------------------
Updates metadata of a given share.
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
:pyobject: update_share_metadata
Delete Share Metadata
----------------------
Deletes a specific metadata item from a shares metadata by its key. Can
specify multiple keys to be deleted.
.. literalinclude:: ../examples/shared_file_system/share_metadata.py
:pyobject: delete_share_metadata

View File

@@ -163,3 +163,16 @@ service.
:members: share_group_snapshots, get_share_group_snapshot, create_share_group_snapshot, :members: share_group_snapshots, get_share_group_snapshot, create_share_group_snapshot,
reset_share_group_snapshot_status, update_share_group_snapshot, reset_share_group_snapshot_status, update_share_group_snapshot,
delete_share_group_snapshot delete_share_group_snapshot
Shared File System Share Metadata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
List, Get, Create, Update, and Delete metadata for shares from the
Shared File Systems service.
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
:noindex:
:members: get_share_metadata, get_share_metadata_item,
create_share_metadata, update_share_metadata,
delete_share_metadata

View File

@@ -0,0 +1,61 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def list_share_metadata(conn, share_id):
# Method returns the entire share with the metadata inside it.
returned_share = conn.get_share_metadata(share_id)
# Access metadata of share
metadata = returned_share['metadata']
print("List All Share Metadata:")
for meta_key in metadata:
print(f"{meta_key}={metadata[meta_key]}")
def get_share_metadata_item(conn, share_id, key):
# Method returns the entire share with the metadata inside it.
returned_share = conn.get_share_metadata_item(share_id, key)
# Access metadata of share
metadata = returned_share['metadata']
print("Get share metadata item given item key and share id:")
print(metadata[key])
def create_share_metadata(conn, share_id, metadata):
# Method returns the entire share with the metadata inside it.
created_share = conn.create_share_metadata(share_id, metadata)
# Access metadata of share
metadata = created_share['metadata']
print("Metadata created for given share:")
print(metadata)
def update_share_metadata(conn, share_id, metadata):
# Method returns the entire share with the metadata inside it.
updated_share = conn.update_share_metadata(share_id, metadata, True)
# Access metadata of share
metadata = updated_share['metadata']
print("Updated metadata for given share:")
print(metadata)
def delete_share_metadata(conn, share_id, keys):
# Method doesn't return anything.
conn.delete_share_metadata(share_id, keys)

View File

@@ -9,7 +9,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from openstack import exceptions
from openstack import proxy from openstack import proxy
from openstack import resource from openstack import resource
from openstack.shared_file_system.v2 import ( from openstack.shared_file_system.v2 import (
@@ -820,7 +820,7 @@ class Proxy(proxy.Proxy):
requests client requests client
""" """
res = self._get_resource(_share_access_rule.ShareAccessRule, access_id) res = self._get_resource(_share_access_rule.ShareAccessRule, access_id)
return res.delete(self, share_id, ignore_missing=ignore_missing) res.delete(self, share_id, ignore_missing=ignore_missing)
def share_group_snapshots(self, details=True, **query): def share_group_snapshots(self, details=True, **query):
"""Lists all share group snapshots. """Lists all share group snapshots.
@@ -940,3 +940,91 @@ class Proxy(proxy.Proxy):
group_snapshot_id, group_snapshot_id,
ignore_missing=ignore_missing, ignore_missing=ignore_missing,
) )
# ========= Share Metadata ==========
def get_share_metadata(self, share_id):
"""Lists all metadata for a share.
:param share_id: The ID of the share
:returns: A :class:`~openstack.shared_file_system.v2.share.Share`
with the share's metadata.
:rtype:
:class:`~openstack.shared_file_system.v2.share.Share`
"""
share = self._get_resource(_share.Share, share_id)
return share.fetch_metadata(self)
def get_share_metadata_item(self, share_id, key):
"""Retrieves a specific metadata item from a share by its key.
:param share_id: The ID of the share
:param key: The key of the share metadata
:returns: A :class:`~openstack.shared_file_system.v2.share.Share`
with the share's metadata.
:rtype:
:class:`~openstack.shared_file_system.v2.share.Share`
"""
share = self._get_resource(_share.Share, share_id)
return share.get_metadata_item(self, key)
def create_share_metadata(self, share_id, **metadata):
"""Creates share metadata as key-value pairs.
:param share_id: The ID of the share
:param metadata: The metadata to be created
:returns: A :class:`~openstack.shared_file_system.v2.share.Share`
with the share's metadata.
:rtype:
:class:`~openstack.shared_file_system.v2.share.Share`
"""
share = self._get_resource(_share.Share, share_id)
return share.set_metadata(self, metadata=metadata)
def update_share_metadata(self, share_id, metadata, replace=False):
"""Updates metadata of given share.
:param share_id: The ID of the share
:param metadata: The metadata to be created
:param replace: Boolean for whether the preexisting metadata
should be replaced
:returns: A :class:`~openstack.shared_file_system.v2.share.Share`
with the share's updated metadata.
:rtype:
:class:`~openstack.shared_file_system.v2.share.Share`
"""
share = self._get_resource(_share.Share, share_id)
return share.set_metadata(self, metadata=metadata, replace=replace)
def delete_share_metadata(self, share_id, keys, ignore_missing=True):
"""Deletes a single metadata item on a share, idetified by its key.
:param share_id: The ID of the share
:param keys: The list of share metadata keys to be deleted
:param ignore_missing: Boolean indicating if missing keys should be ignored.
:returns: None
:rtype: None
"""
share = self._get_resource(_share.Share, share_id)
keys_failed_to_delete = []
for key in keys:
try:
share.delete_metadata_item(self, key)
except exceptions.NotFoundException:
if not ignore_missing:
self._connection.log.info("Key %s not found.", key)
keys_failed_to_delete.append(key)
except exceptions.ForbiddenException:
self._connection.log.info("Key %s cannot be deleted.", key)
keys_failed_to_delete.append(key)
except exceptions.SDKException:
self._connection.log.info("Failed to delete key %s.", key)
keys_failed_to_delete.append(key)
if keys_failed_to_delete:
raise exceptions.SDKException(
"Some keys failed to be deleted %s" % keys_failed_to_delete
)

View File

@@ -10,12 +10,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from openstack.common import metadata
from openstack import exceptions from openstack import exceptions
from openstack import resource from openstack import resource
from openstack import utils from openstack import utils
class Share(resource.Resource): class Share(resource.Resource, metadata.MetadataMixin):
resource_key = "share" resource_key = "share"
resources_key = "shares" resources_key = "shares"
base_path = "/shares" base_path = "/shares"

View File

@@ -0,0 +1,120 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.shared_file_system.v2 import share as _share
from openstack.tests.functional.shared_file_system import base
class ShareMetadataTest(base.BaseSharedFileSystemTest):
def setUp(self):
super().setUp()
self.SHARE_NAME = self.getUniqueString()
my_share = self.create_share(
name=self.SHARE_NAME,
size=2,
share_type="dhss_false",
share_protocol='NFS',
description=None,
)
self.SHARE_ID = my_share.id
self.assertIsNotNone(my_share)
self.assertIsNotNone(my_share.id)
def test_create(self):
meta = {"foo": "bar"}
created_share = (
self.user_cloud.shared_file_system.create_share_metadata(
self.SHARE_ID, **meta
)
)
assert isinstance(created_share, _share.Share)
self.assertEqual(created_share['metadata'], meta)
def test_get_item(self):
meta = {"foo": "bar"}
created_share = (
self.user_cloud.shared_file_system.create_share_metadata(
self.SHARE_ID, **meta
)
)
returned_share = (
self.user_cloud.shared_file_system.get_share_metadata_item(
self.SHARE_ID, "foo"
)
)
self.assertEqual(
created_share['metadata']['foo'], returned_share['metadata']['foo']
)
def test_get(self):
meta = {"foo": "bar"}
created_share = (
self.user_cloud.shared_file_system.create_share_metadata(
self.SHARE_ID, **meta
)
)
returned_share = self.user_cloud.shared_file_system.get_share_metadata(
self.SHARE_ID
)
self.assertEqual(
created_share['metadata']['foo'], returned_share['metadata']['foo']
)
def test_update(self):
meta = {"foo": "bar"}
created_share = (
self.user_cloud.shared_file_system.create_share_metadata(
self.SHARE_ID, **meta
)
)
new_meta = {"newFoo": "newBar"}
full_meta = {"foo": "bar", "newFoo": "newBar"}
empty_meta = {}
updated_share = (
self.user_cloud.shared_file_system.update_share_metadata(
created_share, new_meta
)
)
self.assertEqual(updated_share['metadata'], new_meta)
full_metadata = self.user_cloud.shared_file_system.get_share_metadata(
created_share
)['metadata']
self.assertEqual(full_metadata, full_meta)
share_with_deleted_metadata = (
self.user_cloud.shared_file_system.update_share_metadata(
updated_share, empty_meta
)
)
self.assertEqual(share_with_deleted_metadata['metadata'], empty_meta)
def test_delete(self):
meta = {"foo": "bar", "newFoo": "newBar"}
created_share = (
self.user_cloud.shared_file_system.create_share_metadata(
self.SHARE_ID, **meta
)
)
self.user_cloud.shared_file_system.delete_share_metadata(
created_share, ["foo", "invalidKey"]
)
deleted_share = self.user_cloud.shared_file_system.get_share_metadata(
self.SHARE_ID
)
self.assertEqual(deleted_share['metadata'], {"newFoo": "newBar"})

View File

@@ -155,6 +155,63 @@ class TestSharedFileSystemStoragePool(TestSharedFileSystemProxy):
) )
class TestSharedFileSystemShareMetadata(TestSharedFileSystemProxy):
def test_get_share_metadata(self):
self._verify(
"openstack.shared_file_system.v2.share.Share.fetch_metadata",
self.proxy.get_share_metadata,
method_args=["share_id"],
expected_args=[self.proxy],
expected_result=share.Share(
id="share_id", metadata={"key": "value"}
),
)
def test_get_share_metadata_item(self):
self._verify(
"openstack.shared_file_system.v2.share.Share.get_metadata_item",
self.proxy.get_share_metadata_item,
method_args=["share_id", "key"],
expected_args=[self.proxy, "key"],
expected_result=share.Share(
id="share_id", metadata={"key": "value"}
),
)
def test_create_share_metadata(self):
metadata = {"foo": "bar", "newFoo": "newBar"}
self._verify(
"openstack.shared_file_system.v2.share.Share.set_metadata",
self.proxy.create_share_metadata,
method_args=["share_id"],
method_kwargs=metadata,
expected_args=[self.proxy],
expected_kwargs={"metadata": metadata},
expected_result=share.Share(id="share_id", metadata=metadata),
)
def test_update_share_metadata(self):
metadata = {"foo": "bar", "newFoo": "newBar"}
replace = True
self._verify(
"openstack.shared_file_system.v2.share.Share.set_metadata",
self.proxy.update_share_metadata,
method_args=["share_id", metadata, replace],
expected_args=[self.proxy],
expected_kwargs={"metadata": metadata, "replace": replace},
expected_result=share.Share(id="share_id", metadata=metadata),
)
def test_delete_share_metadata(self):
self._verify(
"openstack.shared_file_system.v2.share.Share.delete_metadata_item",
self.proxy.delete_share_metadata,
expected_result=None,
method_args=["share_id", ["key"]],
expected_args=[self.proxy, "key"],
)
class TestUserMessageProxy(test_proxy_base.TestProxyBase): class TestUserMessageProxy(test_proxy_base.TestProxyBase):
def setUp(self): def setUp(self):
super(TestUserMessageProxy, self).setUp() super(TestUserMessageProxy, self).setUp()

View File

@@ -0,0 +1,6 @@
---
features:
- |
Added support to list, get, create,
update, and delete share metadata
from shared file system service.