diff --git a/openstack/image/v2/_proxy.py b/openstack/image/v2/_proxy.py index fb5ebb499..598115f5f 100644 --- a/openstack/image/v2/_proxy.py +++ b/openstack/image/v2/_proxy.py @@ -13,6 +13,7 @@ from openstack import exceptions 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 import proxy from openstack import resource @@ -307,3 +308,43 @@ class Proxy(proxy.Proxy): image_id = resource.Resource._get_id(image) return self._update(_member.Member, member_id=member_id, image_id=image_id, **attrs) + + def get_images_schema(self): + """Get images schema + + :returns: One :class:`~openstack.image.v2.schema.Schema` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_schema.Schema, requires_id=False, + base_path='/schemas/images') + + def get_image_schema(self): + """Get single image schema + + :returns: One :class:`~openstack.image.v2.schema.Schema` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_schema.Schema, requires_id=False, + base_path='/schemas/image') + + def get_members_schema(self): + """Get image members schema + + :returns: One :class:`~openstack.image.v2.schema.Schema` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_schema.Schema, requires_id=False, + base_path='/schemas/members') + + def get_member_schema(self): + """Get image member schema + + :returns: One :class:`~openstack.image.v2.schema.Schema` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + return self._get(_schema.Schema, requires_id=False, + base_path='/schemas/member') diff --git a/openstack/image/v2/schema.py b/openstack/image/v2/schema.py new file mode 100644 index 000000000..f67e00437 --- /dev/null +++ b/openstack/image/v2/schema.py @@ -0,0 +1,25 @@ +# 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 Schema(resource.Resource): + base_path = '/schemas' + + # capabilities + allow_fetch = True + + #: Additional properties + additional_properties = resource.Body('additionalProperties', type=dict) + #: Schema properties + properties = resource.Body('properties', type=dict) diff --git a/openstack/tests/functional/image/v2/test_image.py b/openstack/tests/functional/image/v2/test_image.py index a2501f93d..11a39e009 100644 --- a/openstack/tests/functional/image/v2/test_image.py +++ b/openstack/tests/functional/image/v2/test_image.py @@ -45,3 +45,19 @@ class TestImage(base.BaseFunctionalTest): def test_get_image(self): img2 = self.conn.image.get_image(self.img) self.assertEqual(self.img, img2) + + def test_get_images_schema(self): + schema = self.conn.image.get_images_schema() + self.assertIsNotNone(schema) + + def test_get_image_schema(self): + schema = self.conn.image.get_image_schema() + self.assertIsNotNone(schema) + + def test_get_members_schema(self): + schema = self.conn.image.get_members_schema() + self.assertIsNotNone(schema) + + def test_get_member_schema(self): + schema = self.conn.image.get_member_schema() + self.assertIsNotNone(schema) diff --git a/openstack/tests/unit/image/v2/test_proxy.py b/openstack/tests/unit/image/v2/test_proxy.py index e0dc10954..19bf6f860 100644 --- a/openstack/tests/unit/image/v2/test_proxy.py +++ b/openstack/tests/unit/image/v2/test_proxy.py @@ -16,6 +16,7 @@ from openstack import exceptions from openstack.image.v2 import _proxy from openstack.image.v2 import image from openstack.image.v2 import member +from openstack.image.v2 import schema from openstack.tests.unit.image.v2 import test_image as fake_image from openstack.tests.unit import test_proxy_base @@ -154,3 +155,31 @@ class TestImageProxy(test_proxy_base.TestProxyBase): self.verify_list(self.proxy.members, member.Member, method_args=('image_1',), expected_kwargs={'image_id': 'image_1'}) + + def test_images_schema_get(self): + self._verify2("openstack.proxy.Proxy._get", + self.proxy.get_images_schema, + expected_args=[schema.Schema], + expected_kwargs={'base_path': '/schemas/images', + 'requires_id': False}) + + def test_image_schema_get(self): + self._verify2("openstack.proxy.Proxy._get", + self.proxy.get_image_schema, + expected_args=[schema.Schema], + expected_kwargs={'base_path': '/schemas/image', + 'requires_id': False}) + + def test_members_schema_get(self): + self._verify2("openstack.proxy.Proxy._get", + self.proxy.get_members_schema, + expected_args=[schema.Schema], + expected_kwargs={'base_path': '/schemas/members', + 'requires_id': False}) + + def test_member_schema_get(self): + self._verify2("openstack.proxy.Proxy._get", + self.proxy.get_member_schema, + expected_args=[schema.Schema], + expected_kwargs={'base_path': '/schemas/member', + 'requires_id': False}) diff --git a/openstack/tests/unit/image/v2/test_schema.py b/openstack/tests/unit/image/v2/test_schema.py new file mode 100644 index 000000000..88e0823cf --- /dev/null +++ b/openstack/tests/unit/image/v2/test_schema.py @@ -0,0 +1,72 @@ +# 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 schema + +IDENTIFIER = 'IDENTIFIER' +EXAMPLE = { + 'additionalProperties': { + 'type': 'string' + }, + 'links': [ + { + 'href': '{self}', + 'rel': 'self' + }, + { + 'href': '{file}', + 'rel': 'enclosure' + }, + { + 'href': '{schema}', + 'rel': 'describedby' + } + ], + 'name': 'image', + 'properties': { + 'architecture': { + 'description': 'Operating system architecture', + 'is_base': False, + 'type': 'string' + }, + 'visibility': { + 'description': 'Scope of image accessibility', + 'enum': [ + 'public', + 'private' + ], + 'type': 'string' + } + } +} + + +class TestSchema(base.TestCase): + def test_basic(self): + sot = schema.Schema() + self.assertIsNone(sot.resource_key) + self.assertIsNone(sot.resources_key) + self.assertEqual('/schemas', 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 = schema.Schema(**EXAMPLE) + self.assertEqual(EXAMPLE['properties'], sot.properties) + self.assertEqual(EXAMPLE['name'], sot.name) + self.assertEqual(EXAMPLE['additionalProperties'], + sot.additional_properties) diff --git a/releasenotes/notes/add-image-schema-9c07c2789490718a.yaml b/releasenotes/notes/add-image-schema-9c07c2789490718a.yaml new file mode 100644 index 000000000..3217f998d --- /dev/null +++ b/releasenotes/notes/add-image-schema-9c07c2789490718a.yaml @@ -0,0 +1,3 @@ +--- +features: + - Add support for schema resource in image service.