Implemented methods for share metadata
Change-Id: Ib3c27ec3d0eb102b30a80994d6cc2af4ee78f3dd
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
61
examples/shared_file_system/share_metadata.py
Normal file
61
examples/shared_file_system/share_metadata.py
Normal 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)
|
@@ -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
|
||||||
|
)
|
||||||
|
@@ -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"
|
||||||
|
@@ -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"})
|
@@ -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()
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support to list, get, create,
|
||||||
|
update, and delete share metadata
|
||||||
|
from shared file system service.
|
Reference in New Issue
Block a user