From 4da9eb7a86646313e6e21338b9703c3b3b60aa69 Mon Sep 17 00:00:00 2001 From: Steve Lewis Date: Tue, 16 Dec 2014 15:27:48 -0800 Subject: [PATCH] Add image v2 tags Tags created and deleted through this endpoint only, browse available through image retrieve. Change-Id: I9d801337c3775e8dc802eecf5d6bca07df55ac1f --- openstack/image/v2/tag.py | 35 +++++++++++++++++++ openstack/tests/image/v2/test_tag.py | 50 ++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 openstack/image/v2/tag.py create mode 100644 openstack/tests/image/v2/test_tag.py diff --git a/openstack/image/v2/tag.py b/openstack/image/v2/tag.py new file mode 100644 index 00000000..a1824ebe --- /dev/null +++ b/openstack/image/v2/tag.py @@ -0,0 +1,35 @@ +# 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.image import image_service +from openstack import resource + + +class Tag(resource.Resource): + id_attribute = 'tag' + resources_key = 'tags' + base_path = '/images/%(image_id)s/tags' + service = image_service.ImageService() + + # capabilities + allow_create = True + allow_delete = True + + # Properties + image_id = resource.prop('image_id') + + def create(self, session): + """Create a remote resource from this instance.""" + # Service expects a naked PUT. Omit properties. + self.create_by_id(session, None, self.id, path_args=self) + self._reset_dirty() + return self \ No newline at end of file diff --git a/openstack/tests/image/v2/test_tag.py b/openstack/tests/image/v2/test_tag.py new file mode 100644 index 00000000..9e335e65 --- /dev/null +++ b/openstack/tests/image/v2/test_tag.py @@ -0,0 +1,50 @@ +# 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. + +import mock +import testtools + +from openstack.image.v2 import tag + +IDENTIFIER = 'IDENTIFIER' +EXAMPLE = { + 'image_id': 'IMAGE_ID', + 'tag': IDENTIFIER, +} + + +class TestTag(testtools.TestCase): + def test_basic(self): + sot = tag.Tag() + self.assertIsNone(sot.resource_key) + self.assertEqual('tags', sot.resources_key) + self.assertEqual('/images/%(image_id)s/tags', sot.base_path) + self.assertEqual('image', sot.service.service_type) + self.assertEqual('tag', sot.id_attribute) + self.assertTrue(sot.allow_create) + self.assertFalse(sot.allow_retrieve) + self.assertFalse(sot.allow_update) + self.assertTrue(sot.allow_delete) + self.assertFalse(sot.allow_list) + + def test_make_it(self): + sot = tag.Tag(EXAMPLE) + self.assertEqual(IDENTIFIER, sot.id) + self.assertEqual(EXAMPLE['image_id'], sot.image_id) + + def test_create(self): + sess = mock.Mock() + resp = mock.Mock() + sess.put = mock.Mock(return_value=resp) + url = 'images/{image_id}/tags/{tag}'.format(**EXAMPLE) + tag.Tag(EXAMPLE).create(sess) + sess.put.assert_called_with(url, service=tag.Tag.service, json=None)