From e9e1bbe9ce0d537d7f1e520954a695def1393893 Mon Sep 17 00:00:00 2001 From: Artem Goncharov Date: Wed, 20 Feb 2019 18:37:22 +0100 Subject: [PATCH] Add image.service_info resources Add service info discovery resources for image service: - import (import constraints) - store (supported image stores) Change-Id: I978c156f41386ce05feed9d6b3e92a7a675b70c9 --- doc/source/user/proxies/image_v2.rst | 8 +++ doc/source/user/resources/image/index.rst | 1 + .../user/resources/image/v2/service_info.rst | 20 ++++++ openstack/image/v2/_proxy.py | 18 +++++ openstack/image/v2/service_info.py | 36 ++++++++++ openstack/tests/unit/image/v2/test_proxy.py | 12 ++++ .../tests/unit/image/v2/test_service_info.py | 68 +++++++++++++++++++ ...d-image-service-info-90d6063b5ba0735d.yaml | 3 + 8 files changed, 166 insertions(+) create mode 100644 doc/source/user/resources/image/v2/service_info.rst create mode 100644 openstack/image/v2/service_info.py create mode 100644 openstack/tests/unit/image/v2/test_service_info.py create mode 100644 releasenotes/notes/add-image-service-info-90d6063b5ba0735d.yaml diff --git a/doc/source/user/proxies/image_v2.rst b/doc/source/user/proxies/image_v2.rst index 9b8a9b9d9..97c3cc65d 100644 --- a/doc/source/user/proxies/image_v2.rst +++ b/doc/source/user/proxies/image_v2.rst @@ -64,3 +64,11 @@ Schema Operations .. automethod:: openstack.image.v2._proxy.Proxy.get_member_schema .. automethod:: openstack.image.v2._proxy.Proxy.get_tasks_schema .. automethod:: openstack.image.v2._proxy.Proxy.get_task_schema + +Service Info Discovery Operations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: openstack.image.v2._proxy.Proxy + + .. automethod:: openstack.image.v2._proxy.Proxy.stores + .. automethod:: openstack.image.v2._proxy.Proxy.get_import_info diff --git a/doc/source/user/resources/image/index.rst b/doc/source/user/resources/image/index.rst index dcafdcd3b..4e09af0e2 100644 --- a/doc/source/user/resources/image/index.rst +++ b/doc/source/user/resources/image/index.rst @@ -15,3 +15,4 @@ Image v2 Resources v2/image v2/member v2/task + v2/service_info diff --git a/doc/source/user/resources/image/v2/service_info.rst b/doc/source/user/resources/image/v2/service_info.rst new file mode 100644 index 000000000..92bae8988 --- /dev/null +++ b/doc/source/user/resources/image/v2/service_info.rst @@ -0,0 +1,20 @@ +openstack.image.v2.service_info +=============================== + +.. automodule:: openstack.image.v2.service_info + +The Store Class +---------------- + +The ``Store`` class inherits from :class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.image.v2.service_info.Store + :members: + +The Import Info Class +--------------------- + +The ``Import`` class inherits from :class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.image.v2.service_info.Import + :members: diff --git a/openstack/image/v2/_proxy.py b/openstack/image/v2/_proxy.py index 359905731..360843260 100644 --- a/openstack/image/v2/_proxy.py +++ b/openstack/image/v2/_proxy.py @@ -23,6 +23,7 @@ from openstack.image.v2 import image as _image from openstack.image.v2 import member as _member from openstack.image.v2 import schema as _schema from openstack.image.v2 import task as _task +from openstack.image.v2 import service_info as _si from openstack import resource from openstack import utils @@ -660,3 +661,20 @@ class Proxy(_base_proxy.BaseImageProxy): """ return self._get(_schema.Schema, requires_id=False, base_path='/schemas/task') + + def stores(self, **query): + """Return a generator of supported image stores + + :returns: A generator of store objects + :rtype: :class:`~openstack.image.v2.service_info.Store` + """ + return self._list(_si.Store, **query) + + def get_import_info(self): + """Get a info about image constraints + + :returns: One :class:`~openstack.image.v2.service_info.Import` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_si.Import, require_id=False) diff --git a/openstack/image/v2/service_info.py b/openstack/image/v2/service_info.py new file mode 100644 index 000000000..733e8a34b --- /dev/null +++ b/openstack/image/v2/service_info.py @@ -0,0 +1,36 @@ +# 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 Import(resource.Resource): + base_path = '/info/import' + + # capabilities + allow_fetch = True + + #: import methods + import_methods = resource.Body('import-methods', type=dict) + + +class Store(resource.Resource): + resources_key = 'stores' + base_path = '/info/stores' + + # capabilities + allow_list = True + + #: Description of the store + description = resource.Body('description') + #: default + is_default = resource.Body('default', type=bool) diff --git a/openstack/tests/unit/image/v2/test_proxy.py b/openstack/tests/unit/image/v2/test_proxy.py index ff905e074..0690206ca 100644 --- a/openstack/tests/unit/image/v2/test_proxy.py +++ b/openstack/tests/unit/image/v2/test_proxy.py @@ -18,6 +18,7 @@ from openstack.image.v2 import image from openstack.image.v2 import member from openstack.image.v2 import schema from openstack.image.v2 import task +from openstack.image.v2 import service_info as si from openstack.tests.unit.image.v2 import test_image as fake_image from openstack.tests.unit import test_proxy_base @@ -229,3 +230,14 @@ class TestImageProxy(test_proxy_base.TestProxyBase): expected_args=[schema.Schema], expected_kwargs={'base_path': '/schemas/task', 'requires_id': False}) + + def test_stores(self): + self.verify_list(self.proxy.stores, si.Store) + + def test_import_info(self): + self._verify2("openstack.proxy.Proxy._get", + self.proxy.get_import_info, + method_args=[], + method_kwargs={}, + expected_args=[si.Import], + expected_kwargs={'require_id': False}) diff --git a/openstack/tests/unit/image/v2/test_service_info.py b/openstack/tests/unit/image/v2/test_service_info.py new file mode 100644 index 000000000..6d8c85f92 --- /dev/null +++ b/openstack/tests/unit/image/v2/test_service_info.py @@ -0,0 +1,68 @@ +# 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.unit import base + +from openstack.image.v2 import service_info as si + +IDENTIFIER = 'IDENTIFIER' +EXAMPLE_IMPORT = { + 'import-methods': { + 'description': 'Import methods available.', + 'type': 'array', + 'value': [ + 'glance-direct', + 'web-download' + ] + } +} +EXAMPLE_STORE = { + 'id': 'fast', + 'description': 'Fast access to rbd store', + 'default': True +} + + +class TestStore(base.TestCase): + def test_basic(self): + sot = si.Store() + self.assertIsNone(sot.resource_key) + self.assertEqual('stores', sot.resources_key) + self.assertEqual('/info/stores', sot.base_path) + self.assertFalse(sot.allow_create) + self.assertFalse(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertFalse(sot.allow_delete) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = si.Store(**EXAMPLE_STORE) + self.assertEqual(EXAMPLE_STORE['id'], sot.id) + self.assertEqual(EXAMPLE_STORE['description'], sot.description) + self.assertEqual(EXAMPLE_STORE['default'], sot.is_default) + + +class TestImport(base.TestCase): + def test_basic(self): + sot = si.Import() + self.assertIsNone(sot.resource_key) + self.assertIsNone(sot.resources_key) + self.assertEqual('/info/import', sot.base_path) + self.assertFalse(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertFalse(sot.allow_commit) + self.assertFalse(sot.allow_delete) + self.assertFalse(sot.allow_list) + + def test_make_it(self): + sot = si.Import(**EXAMPLE_IMPORT) + self.assertEqual(EXAMPLE_IMPORT['import-methods'], sot.import_methods) diff --git a/releasenotes/notes/add-image-service-info-90d6063b5ba0735d.yaml b/releasenotes/notes/add-image-service-info-90d6063b5ba0735d.yaml new file mode 100644 index 000000000..ea84d0d09 --- /dev/null +++ b/releasenotes/notes/add-image-service-info-90d6063b5ba0735d.yaml @@ -0,0 +1,3 @@ +--- +features: + - Add image service info discovery (import constraints and supported stores)