Add ImageDetail for extra information
The current Image can only receive the basics returned by a GET /images, which is just name, id, and links. A call to /images/detail gives a number of added details, some of which were already in the Image resource but not set. This change follows with how a few other basic/detail requests were done, and exposes it through the proxy with details coming by default (since they're likely expected, and most useful). Change-Id: Iadc98cd0f679777b1c6e14711ad00787142221e2
This commit is contained in:
parent
ee4c85d243
commit
f92973d7f8
@ -10,3 +10,12 @@ The ``Image`` class inherits from :class:`~openstack.resource.Resource`.
|
||||
|
||||
.. autoclass:: openstack.compute.v2.image.Image
|
||||
:members:
|
||||
|
||||
The ImageDetail Class
|
||||
---------------------
|
||||
|
||||
The ``ImageDetail`` class inherits from
|
||||
:class:`~openstack.compute.v2.image.Image`.
|
||||
|
||||
.. autoclass:: openstack.compute.v2.image.ImageDetail
|
||||
:members:
|
||||
|
@ -59,9 +59,6 @@ class Proxy(object):
|
||||
def update_flavor(self, **data):
|
||||
return flavor.Flavor(data).update(self.session)
|
||||
|
||||
def create_image(self, **data):
|
||||
return image.Image(data).create(self.session)
|
||||
|
||||
def delete_image(self, **data):
|
||||
image.Image(data).delete(self.session)
|
||||
|
||||
@ -71,11 +68,18 @@ class Proxy(object):
|
||||
def get_image(self, **data):
|
||||
return image.Image(data).get(self.session)
|
||||
|
||||
def list_images(self):
|
||||
return image.Image.list(self.session)
|
||||
def list_images(self, details=True):
|
||||
"""Return a generator of images
|
||||
|
||||
def update_image(self, **data):
|
||||
return image.Image(data).update(self.session)
|
||||
:param bool details: When ``True``, returns
|
||||
:class:`~openstack.compute.v2.image.ImageDetail` objects,
|
||||
otherwise :class:`~openstack.compute.v2.image.Image`.
|
||||
*Default: ``True``*
|
||||
|
||||
:returns: A generator of image objects
|
||||
"""
|
||||
img = image.ImageDetail if details else image.Image
|
||||
return img.list(self.session, paginate=False)
|
||||
|
||||
def create_keypair(self, **data):
|
||||
return keypair.Keypair(data).create(self.session)
|
||||
|
@ -21,26 +21,24 @@ class Image(resource.Resource):
|
||||
service = compute_service.ComputeService()
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_retrieve = True
|
||||
allow_update = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
#: Timestamp when the image was created.
|
||||
created = resource.prop('created')
|
||||
#: Links pertaining to this image. This is a list of dictionaries,
|
||||
#: each including keys ``href`` and ``rel``, and optionally ``type``.
|
||||
links = resource.prop('links')
|
||||
#: The name of this image.
|
||||
name = resource.prop('name')
|
||||
#: Timestamp when the image was created.
|
||||
created = resource.prop('created')
|
||||
#: Metadata pertaining to this image. *Type: dict*
|
||||
metadata = resource.prop('metadata', type=dict)
|
||||
#: The mimimum disk size. *Type: int*
|
||||
min_disk = resource.prop('minDisk', type=int)
|
||||
#: The minimum RAM size. *Type: int*
|
||||
min_ram = resource.prop('minRam', type=int)
|
||||
#: The name of this image.
|
||||
name = resource.prop('name')
|
||||
#: If this image is still building, its progress is represented here.
|
||||
#: Once an image is created, progres will be 100. *Type: int*
|
||||
progress = resource.prop('progress', type=int)
|
||||
@ -48,3 +46,13 @@ class Image(resource.Resource):
|
||||
status = resource.prop('status')
|
||||
#: Timestamp when the image was updated.
|
||||
updated = resource.prop('updated')
|
||||
#: Size of the image in bytes. *Type: int*
|
||||
size = resource.prop('OS-EXT-IMG-SIZE:size', type=int)
|
||||
|
||||
|
||||
class ImageDetail(Image):
|
||||
base_path = '/images/detail'
|
||||
|
||||
allow_retrieve = False
|
||||
allow_delete = False
|
||||
allow_list = True
|
||||
|
@ -15,19 +15,26 @@ import testtools
|
||||
from openstack.compute.v2 import image
|
||||
|
||||
IDENTIFIER = 'IDENTIFIER'
|
||||
EXAMPLE = {
|
||||
'created': '1',
|
||||
BASIC_EXAMPLE = {
|
||||
'id': IDENTIFIER,
|
||||
'links': '3',
|
||||
'metadata': {'key': '4'},
|
||||
'minDisk': 5,
|
||||
'minRam': 6,
|
||||
'name': '7',
|
||||
'progress': 8,
|
||||
'status': '9',
|
||||
'updated': '10',
|
||||
'links': '2',
|
||||
'name': '3',
|
||||
}
|
||||
|
||||
DETAILS = {
|
||||
'created': '1',
|
||||
'metadata': {'key': '2'},
|
||||
'minDisk': 3,
|
||||
'minRam': 4,
|
||||
'progress': 5,
|
||||
'status': '6',
|
||||
'updated': '7',
|
||||
'OS-EXT-IMG-SIZE:size': 8
|
||||
}
|
||||
|
||||
DETAIL_EXAMPLE = BASIC_EXAMPLE.copy()
|
||||
DETAIL_EXAMPLE.update(DETAILS)
|
||||
|
||||
|
||||
class TestImage(testtools.TestCase):
|
||||
|
||||
@ -37,21 +44,40 @@ class TestImage(testtools.TestCase):
|
||||
self.assertEqual('images', sot.resources_key)
|
||||
self.assertEqual('/images', sot.base_path)
|
||||
self.assertEqual('compute', sot.service.service_type)
|
||||
self.assertTrue(sot.allow_create)
|
||||
self.assertFalse(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertTrue(sot.allow_update)
|
||||
self.assertFalse(sot.allow_update)
|
||||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = image.Image(EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['created'], sot.created)
|
||||
self.assertEqual(EXAMPLE['id'], sot.id)
|
||||
self.assertEqual(EXAMPLE['links'], sot.links)
|
||||
self.assertEqual(EXAMPLE['metadata'], sot.metadata)
|
||||
self.assertEqual(EXAMPLE['minDisk'], sot.min_disk)
|
||||
self.assertEqual(EXAMPLE['minRam'], sot.min_ram)
|
||||
self.assertEqual(EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(EXAMPLE['progress'], sot.progress)
|
||||
self.assertEqual(EXAMPLE['status'], sot.status)
|
||||
self.assertEqual(EXAMPLE['updated'], sot.updated)
|
||||
def test_make_basic(self):
|
||||
sot = image.Image(BASIC_EXAMPLE)
|
||||
self.assertEqual(BASIC_EXAMPLE['id'], sot.id)
|
||||
self.assertEqual(BASIC_EXAMPLE['links'], sot.links)
|
||||
self.assertEqual(BASIC_EXAMPLE['name'], sot.name)
|
||||
|
||||
def test_detail(self):
|
||||
sot = image.ImageDetail()
|
||||
self.assertEqual('image', sot.resource_key)
|
||||
self.assertEqual('images', sot.resources_key)
|
||||
self.assertEqual('/images/detail', sot.base_path)
|
||||
self.assertEqual('compute', sot.service.service_type)
|
||||
self.assertFalse(sot.allow_create)
|
||||
self.assertFalse(sot.allow_retrieve)
|
||||
self.assertFalse(sot.allow_update)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
def test_make_detail(self):
|
||||
sot = image.ImageDetail(DETAIL_EXAMPLE)
|
||||
self.assertEqual(DETAIL_EXAMPLE['created'], sot.created)
|
||||
self.assertEqual(DETAIL_EXAMPLE['id'], sot.id)
|
||||
self.assertEqual(DETAIL_EXAMPLE['links'], sot.links)
|
||||
self.assertEqual(DETAIL_EXAMPLE['metadata'], sot.metadata)
|
||||
self.assertEqual(DETAIL_EXAMPLE['minDisk'], sot.min_disk)
|
||||
self.assertEqual(DETAIL_EXAMPLE['minRam'], sot.min_ram)
|
||||
self.assertEqual(DETAIL_EXAMPLE['name'], sot.name)
|
||||
self.assertEqual(DETAIL_EXAMPLE['progress'], sot.progress)
|
||||
self.assertEqual(DETAIL_EXAMPLE['status'], sot.status)
|
||||
self.assertEqual(DETAIL_EXAMPLE['updated'], sot.updated)
|
||||
self.assertEqual(DETAIL_EXAMPLE['OS-EXT-IMG-SIZE:size'], sot.size)
|
||||
|
@ -59,10 +59,6 @@ class TestComputeProxy(test_proxy_base.TestProxyBase):
|
||||
self.verify_update('openstack.compute.v2.flavor.Flavor.update',
|
||||
self.proxy.update_flavor)
|
||||
|
||||
def test_image_create(self):
|
||||
self.verify_create('openstack.compute.v2.image.Image.create',
|
||||
self.proxy.create_image)
|
||||
|
||||
def test_image_delete(self):
|
||||
self.verify_delete('openstack.compute.v2.image.Image.delete',
|
||||
self.proxy.delete_image)
|
||||
@ -75,13 +71,17 @@ class TestComputeProxy(test_proxy_base.TestProxyBase):
|
||||
self.verify_get('openstack.compute.v2.image.Image.get',
|
||||
self.proxy.get_image)
|
||||
|
||||
def test_image_list(self):
|
||||
def test_image_list_basic(self):
|
||||
self.verify_list('openstack.compute.v2.image.Image.list',
|
||||
self.proxy.list_images)
|
||||
self.proxy.list_images,
|
||||
method_kwargs={"details": False},
|
||||
expected_kwargs={"paginate": False})
|
||||
|
||||
def test_image_update(self):
|
||||
self.verify_update('openstack.compute.v2.image.Image.update',
|
||||
self.proxy.update_image)
|
||||
def test_image_list_detail(self):
|
||||
self.verify_list('openstack.compute.v2.image.ImageDetail.list',
|
||||
self.proxy.list_images,
|
||||
method_kwargs={"details": True},
|
||||
expected_kwargs={"paginate": False})
|
||||
|
||||
def test_keypair_create(self):
|
||||
self.verify_create('openstack.compute.v2.keypair.Keypair.create',
|
||||
|
Loading…
Reference in New Issue
Block a user