From 4914d8d754e312a5ca8cc8a6f47a5a0d7d934498 Mon Sep 17 00:00:00 2001 From: Kafilat Adeleke Date: Thu, 17 Jun 2021 18:01:39 +0000 Subject: [PATCH] Add user message to shared file system Introduce User Message class with basic methods including list, delete, get to shared file system storage service. Change-Id: I0cc3586f6681eb0941294e0ef27edb4d7e1f409a --- .../user/proxies/shared_file_system.rst | 11 +++ .../resources/shared_file_system/index.rst | 1 + .../shared_file_system/v2/user_message.rst | 13 ++++ openstack/shared_file_system/v2/_proxy.py | 56 ++++++++++++++ .../shared_file_system/v2/user_message.py | 54 ++++++++++++++ .../shared_file_system/test_user_message.py | 29 ++++++++ .../unit/shared_file_system/v2/test_proxy.py | 28 +++++++ .../v2/test_user_message.py | 74 +++++++++++++++++++ ...ssage-to-shared-file-85d7bbccf8347c4f.yaml | 5 ++ 9 files changed, 271 insertions(+) create mode 100644 doc/source/user/resources/shared_file_system/v2/user_message.rst create mode 100644 openstack/shared_file_system/v2/user_message.py create mode 100644 openstack/tests/functional/shared_file_system/test_user_message.py create mode 100644 openstack/tests/unit/shared_file_system/v2/test_user_message.py create mode 100644 releasenotes/notes/add-user-message-to-shared-file-85d7bbccf8347c4f.yaml diff --git a/doc/source/user/proxies/shared_file_system.rst b/doc/source/user/proxies/shared_file_system.rst index 6d71a2521..1b28ad124 100644 --- a/doc/source/user/proxies/shared_file_system.rst +++ b/doc/source/user/proxies/shared_file_system.rst @@ -44,3 +44,14 @@ Systems Service. .. autoclass:: openstack.shared_file_system.v2._proxy.Proxy :noindex: :members: storage_pools + + +Shared File System User Messages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +View and manipulate asynchronous user messages emitted by the Shared +File Systems service. + +.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy + :noindex: + :members: user_messages, get_user_message, delete_user_message diff --git a/doc/source/user/resources/shared_file_system/index.rst b/doc/source/user/resources/shared_file_system/index.rst index 8eeb1e7f3..37f31da0b 100644 --- a/doc/source/user/resources/shared_file_system/index.rst +++ b/doc/source/user/resources/shared_file_system/index.rst @@ -7,3 +7,4 @@ Shared File System service resources v2/availability_zone v2/storage_pool v2/share + v2/user_message diff --git a/doc/source/user/resources/shared_file_system/v2/user_message.rst b/doc/source/user/resources/shared_file_system/v2/user_message.rst new file mode 100644 index 000000000..de3b21f66 --- /dev/null +++ b/doc/source/user/resources/shared_file_system/v2/user_message.rst @@ -0,0 +1,13 @@ +openstack.shared_file_system.v2.user_message +============================================ + +.. automodule:: openstack.shared_file_system.v2.user_message + +The UserMessage Class +--------------------- + +The ``UserMessage`` class inherits from +:class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.shared_file_system.v2.user_message.UserMessage + :members: diff --git a/openstack/shared_file_system/v2/_proxy.py b/openstack/shared_file_system/v2/_proxy.py index f64680c85..5b88e7516 100644 --- a/openstack/shared_file_system/v2/_proxy.py +++ b/openstack/shared_file_system/v2/_proxy.py @@ -17,6 +17,9 @@ from openstack.shared_file_system.v2 import ( from openstack.shared_file_system.v2 import ( storage_pool as _storage_pool ) +from openstack.shared_file_system.v2 import ( + user_message as _user_message +) from openstack.shared_file_system.v2 import share as _share @@ -168,3 +171,56 @@ class Proxy(proxy.Proxy): base_path = '/scheduler-stats/pools/detail' if details else None return self._list( _storage_pool.StoragePool, base_path=base_path, **query) + + def user_messages(self, **query): + """List shared file system user messages + + :param kwargs query: Optional query parameters to be sent to limit + the messages being returned. Available parameters include: + + * action_id: The ID of the action during which the message + was created. + * detail_id: The ID of the message detail. + * limit: The maximum number of shares to return. + * message_level: The message level. + * offset: The offset to define start point of share or share + group listing. + * sort_key: The key to sort a list of messages. + * sort_dir: The direction to sort a list of shares. + * project_id: The ID of the project for which the message + was created. + * request_id: The ID of the request during which the message + was created. + * resource_id: The UUID of the resource for which the message + was created. + * resource_type: The type of the resource for which the message + was created. + + :returns: A generator of user message resources + :rtype: :class:`~openstack.shared_file_system.v2. + user_message.UserMessage` + """ + return self._list( + _user_message.UserMessage, **query) + + def get_user_message(self, message_id): + """List details of a single user message + + :param message_id: The ID of the user message + :returns: Details of the identified user message + :rtype: :class:`~openstack.shared_file_system.v2. + user_message.UserMessage` + """ + return self._get(_user_message.UserMessage, message_id) + + def delete_user_message(self, message_id, ignore_missing=True): + """Deletes a single user message + + :param message_id: The ID of the user message + :returns: Result of the "delete" on the user message + :rtype: :class:`~openstack.shared_file_system.v2. + user_message.UserMessage` + """ + return self._delete( + _user_message.UserMessage, message_id, + ignore_missing=ignore_missing) diff --git a/openstack/shared_file_system/v2/user_message.py b/openstack/shared_file_system/v2/user_message.py new file mode 100644 index 000000000..262fc4d16 --- /dev/null +++ b/openstack/shared_file_system/v2/user_message.py @@ -0,0 +1,54 @@ +# 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 import resource + + +class UserMessage(resource.Resource): + resource_key = "message" + resources_key = "messages" + base_path = "/messages" + + # capabilities + allow_fetch = True + allow_commit = False + allow_delete = True + allow_list = True + allow_head = False + + _query_mapping = resource.QueryParameters( + "message_id" + ) + + _max_microversion = '2.37' + + #: Properties + #: The action ID of the user message + action_id = resource.Body("action_id") + #: Indicate when the user message was created + created_at = resource.Body("created_at") + #: The detail ID of the user message + detail_id = resource.Body("detail_id", type=str) + #: Indicate when the share message expires + expires_at = resource.Body("expires_at", type=str) + #: The message level of the user message + message_level = resource.Body("message_level", type=str) + #: The project ID of the user message + project_id = resource.Body("project_id", type=str) + #: The request ID of the user message + request_id = resource.Body("request_id", type=str) + #: The resource ID of the user message + resource_id = resource.Body("resource_id", type=str) + #: The resource type of the user message + resource_type = resource.Body("resource_type", type=str) + #: The message for the user message + user_message = resource.Body("user_message", type=str) diff --git a/openstack/tests/functional/shared_file_system/test_user_message.py b/openstack/tests/functional/shared_file_system/test_user_message.py new file mode 100644 index 000000000..a6b6920b6 --- /dev/null +++ b/openstack/tests/functional/shared_file_system/test_user_message.py @@ -0,0 +1,29 @@ +# 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.tests.functional.shared_file_system import base + + +class UserMessageTest(base.BaseSharedFileSystemTest): + + def test_user_messages(self): + # TODO(kafilat): We must intentionally cause an asynchronous failure to + # ensure that at least one user message exists; + u_messages = self.user_cloud.shared_file_system.user_messages() + # self.assertGreater(len(list(u_messages)), 0) + for u_message in u_messages: + for attribute in ('id', 'created_at', 'name'): + self.assertTrue(hasattr(u_message, attribute)) + self.assertIsInstance(getattr(u_message, attribute), 'str') + + self.conn.shared_file_system.delete_user_message( + u_message) diff --git a/openstack/tests/unit/shared_file_system/v2/test_proxy.py b/openstack/tests/unit/shared_file_system/v2/test_proxy.py index 3d04ad8c2..251251b44 100644 --- a/openstack/tests/unit/shared_file_system/v2/test_proxy.py +++ b/openstack/tests/unit/shared_file_system/v2/test_proxy.py @@ -15,6 +15,7 @@ from unittest import mock from openstack.shared_file_system.v2 import _proxy from openstack.shared_file_system.v2 import share from openstack.shared_file_system.v2 import storage_pool +from openstack.shared_file_system.v2 import user_message from openstack.tests.unit import test_proxy_base @@ -79,3 +80,30 @@ class TestSharedFileSystemProxy(test_proxy_base.TestProxyBase): self.proxy.storage_pools, storage_pool.StoragePool, method_kwargs={"details": False, "backend": "alpha"}, expected_kwargs={"backend": "alpha"}) + + +class TestUserMessageProxy(test_proxy_base.TestProxyBase): + + def setUp(self): + super(TestUserMessageProxy, self).setUp() + self.proxy = _proxy.Proxy(self.session) + + def test_user_messages(self): + self.verify_list(self.proxy.user_messages, user_message.UserMessage) + + def test_user_messages_queried(self): + self.verify_list( + self.proxy.user_messages, user_message.UserMessage, + method_kwargs={"action_id": "1"}, + expected_kwargs={"action_id": "1"}) + + def test_user_message_get(self): + self.verify_get(self.proxy.get_user_message, user_message.UserMessage) + + def test_delete_user_message(self): + self.verify_delete( + self.proxy.delete_user_message, user_message.UserMessage, False) + + def test_delete_user_message_true(self): + self.verify_delete( + self.proxy.delete_user_message, user_message.UserMessage, True) diff --git a/openstack/tests/unit/shared_file_system/v2/test_user_message.py b/openstack/tests/unit/shared_file_system/v2/test_user_message.py new file mode 100644 index 000000000..a718d4062 --- /dev/null +++ b/openstack/tests/unit/shared_file_system/v2/test_user_message.py @@ -0,0 +1,74 @@ +# 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 user_message +from openstack.tests.unit import base + + +IDENTIFIER = "2784bc88-b729-4220-a6bb-a8b7a8f53aad" +EXAMPLE = { + "id": IDENTIFIER, + "project_id": "dcc9de3c5fc8471ba3662dbb2b6166d5", + "action_id": "001", + "detail_id": "008", + "message_level": "ERROR", + "created_at": "2021-03-26T05:16:39.000000", + "expires_at": "2021-04-25T05:16:39.000000", + "request_id": "req-e4b3e6de-ce4d-4ef2-b1e7-0087200e4db3", + "resource_type": "SHARE", + "resource_id": "c2e4ca07-8c37-4014-92c9-2171c7813fa0", + "user_message": ( + "allocate host: No storage could be allocated" + "for this share request, Capabilities filter" + "didn't succeed.") +} + + +class TestUserMessage(base.TestCase): + + def test_basic(self): + message = user_message.UserMessage() + self.assertEqual('messages', message.resources_key) + self.assertEqual('/messages', message.base_path) + self.assertTrue(message.allow_list) + self.assertFalse(message.allow_create) + self.assertFalse(message.allow_commit) + self.assertTrue(message.allow_delete) + self.assertTrue(message.allow_fetch) + self.assertFalse(message.allow_head) + + self.assertDictEqual({ + "limit": "limit", + "marker": "marker", + "message_id": "message_id" + }, + message._query_mapping._mapping) + + def test_user_message(self): + messages = user_message.UserMessage(**EXAMPLE) + self.assertEqual(EXAMPLE['id'], messages.id) + self.assertEqual(EXAMPLE['resource_id'], messages.resource_id) + self.assertEqual( + EXAMPLE['message_level'], messages.message_level) + self.assertEqual( + EXAMPLE['user_message'], messages.user_message) + self.assertEqual(EXAMPLE['expires_at'], messages.expires_at) + self.assertEqual(EXAMPLE['detail_id'], messages.detail_id) + self.assertEqual(EXAMPLE['created_at'], messages.created_at) + self.assertEqual( + EXAMPLE['request_id'], messages.request_id) + self.assertEqual( + EXAMPLE['project_id'], messages.project_id) + self.assertEqual( + EXAMPLE['resource_type'], messages.resource_type) + self.assertEqual( + EXAMPLE['action_id'], messages.action_id) diff --git a/releasenotes/notes/add-user-message-to-shared-file-85d7bbccf8347c4f.yaml b/releasenotes/notes/add-user-message-to-shared-file-85d7bbccf8347c4f.yaml new file mode 100644 index 000000000..b4d449230 --- /dev/null +++ b/releasenotes/notes/add-user-message-to-shared-file-85d7bbccf8347c4f.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added support to list, get, and delete user messages + on the shared file system service.