Merge "Use Resource layer for the compute Hypervsors and Images"

This commit is contained in:
Zuul 2019-06-21 15:35:51 +00:00 committed by Gerrit Code Review
commit d488e44cb4
7 changed files with 56 additions and 93 deletions

View File

@ -1590,16 +1590,16 @@ class ComputeCloudMixin(_normalize.Normalizer):
return _utils.normalize_flavor_accesses( return _utils.normalize_flavor_accesses(
self._get_and_munchify('flavor_access', data)) self._get_and_munchify('flavor_access', data))
def list_hypervisors(self): def list_hypervisors(self, filters={}):
"""List all hypervisors """List all hypervisors
:returns: A list of hypervisor ``munch.Munch``. :returns: A list of hypervisor ``munch.Munch``.
""" """
data = proxy._json_response( return list(self.compute.hypervisors(
self.compute.get('/os-hypervisors/detail'), details=True,
error_message="Error fetching hypervisor list") allow_unknown_params=True,
return self._get_and_munchify('hypervisors', data) **filters))
def search_aggregates(self, name_or_id=None, filters=None): def search_aggregates(self, name_or_id=None, filters=None):
"""Seach host aggregates. """Seach host aggregates.

View File

@ -9,6 +9,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import warnings
from openstack.compute.v2 import aggregate as _aggregate from openstack.compute.v2 import aggregate as _aggregate
from openstack.compute.v2 import availability_zone from openstack.compute.v2 import availability_zone
@ -275,16 +276,18 @@ class Proxy(proxy.Proxy):
"""Return a generator of images """Return a generator of images
:param bool details: When ``True``, returns :param bool details: When ``True``, returns
:class:`~openstack.compute.v2.image.ImageDetail` objects, :class:`~openstack.compute.v2.image.Image` objects with all
otherwise :class:`~openstack.compute.v2.image.Image`. available properties, otherwise only basic properties are returned.
*Default: ``True``* *Default: ``True``*
:param kwargs query: Optional query parameters to be sent to limit :param kwargs query: Optional query parameters to be sent to limit
the resources being returned. the resources being returned.
:returns: A generator of image objects :returns: A generator of image objects
""" """
img = _image.ImageDetail if details else _image.Image warnings.warn('This API is deprecated and may disappear shortly',
return self._list(img, **query) DeprecationWarning)
base_path = '/images/detail' if details else None
return self._list(_image.Image, base_path=base_path, **query)
def _get_base_resource(self, res, base): def _get_base_resource(self, res, base):
# Metadata calls for Image and Server can work for both those # Metadata calls for Image and Server can work for both those
@ -299,9 +302,7 @@ class Proxy(proxy.Proxy):
"""Return a dictionary of metadata for an image """Return a dictionary of metadata for an image
:param image: Either the ID of an image or a :param image: Either the ID of an image or a
:class:`~openstack.compute.v2.image.Image` or :class:`~openstack.compute.v2.image.Image` instance.
:class:`~openstack.compute.v2.image.ImageDetail`
instance.
:returns: A :class:`~openstack.compute.v2.image.Image` with only the :returns: A :class:`~openstack.compute.v2.image.Image` with only the
image's metadata. All keys and values are Unicode text. image's metadata. All keys and values are Unicode text.
@ -316,9 +317,7 @@ class Proxy(proxy.Proxy):
"""Update metadata for an image """Update metadata for an image
:param image: Either the ID of an image or a :param image: Either the ID of an image or a
:class:`~openstack.compute.v2.image.Image` or :class:`~openstack.compute.v2.image.Image` instance.
:class:`~openstack.compute.v2.image.ImageDetail`
instance.
:param kwargs metadata: Key/value pairs to be updated in the image's :param kwargs metadata: Key/value pairs to be updated in the image's
metadata. No other metadata is modified metadata. No other metadata is modified
by this call. All keys and values are stored by this call. All keys and values are stored
@ -339,9 +338,7 @@ class Proxy(proxy.Proxy):
Note: This method will do a HTTP DELETE request for every key in keys. Note: This method will do a HTTP DELETE request for every key in keys.
:param image: Either the ID of an image or a :param image: Either the ID of an image or a
:class:`~openstack.compute.v2.image.Image` or :class:`~openstack.compute.v2.image.Image` instance.
:class:`~openstack.compute.v2.image.ImageDetail`
instance.
:param keys: The keys to delete. :param keys: The keys to delete.
:rtype: ``None`` :rtype: ``None``
@ -1068,9 +1065,7 @@ class Proxy(proxy.Proxy):
"""Update metadata for a server """Update metadata for a server
:param server: Either the ID of a server or a :param server: Either the ID of a server or a
:class:`~openstack.compute.v2.server.Server` or :class:`~openstack.compute.v2.server.Server` instance.
:class:`~openstack.compute.v2.server.ServerDetail`
instance.
:param kwargs metadata: Key/value pairs to be updated in the server's :param kwargs metadata: Key/value pairs to be updated in the server's
metadata. No other metadata is modified metadata. No other metadata is modified
by this call. All keys and values are stored by this call. All keys and values are stored
@ -1091,9 +1086,7 @@ class Proxy(proxy.Proxy):
Note: This method will do a HTTP DELETE request for every key in keys. Note: This method will do a HTTP DELETE request for every key in keys.
:param server: Either the ID of a server or a :param server: Either the ID of a server or a
:class:`~openstack.compute.v2.server.Server` or :class:`~openstack.compute.v2.server.Server` instance.
:class:`~openstack.compute.v2.server.ServerDetail`
instance.
:param keys: The keys to delete :param keys: The keys to delete
:rtype: ``None`` :rtype: ``None``
@ -1171,23 +1164,19 @@ class Proxy(proxy.Proxy):
""" """
return self._list(_server_group.ServerGroup, **query) return self._list(_server_group.ServerGroup, **query)
def hypervisors(self, details=False): def hypervisors(self, details=False, **query):
"""Return a generator of hypervisor """Return a generator of hypervisor
:param bool details: When set to the default, ``False``, :param bool details: When set to the default, ``False``,
:class:`~openstack.compute.v2.hypervisor.Hypervisor` :class:`~openstack.compute.v2.hypervisor.Hypervisor`
instances will be returned. ``True`` will cause instances will be returned with only basic information populated.
:class:`~openstack.compute.v2.hypervisor.HypervisorDetail` :param kwargs query: Optional query parameters to be sent to limit
instances to be returned. the resources being returned.
:returns: A generator of hypervisor :returns: A generator of hypervisor
:rtype: class: `~openstack.compute.v2.hypervisor.Hypervisor` :rtype: class: `~openstack.compute.v2.hypervisor.Hypervisor`
""" """
if details: base_path = '/os-hypervisors/detail' if details else None
hypervisor = _hypervisor.HypervisorDetail return self._list(_hypervisor.Hypervisor, base_path=base_path, **query)
else:
hypervisor = _hypervisor.Hypervisor
return self._list(hypervisor)
def find_hypervisor(self, name_or_id, ignore_missing=True): def find_hypervisor(self, name_or_id, ignore_missing=True):
"""Find a hypervisor from name or id to get the corresponding info """Find a hypervisor from name or id to get the corresponding info

View File

@ -23,6 +23,10 @@ class Hypervisor(resource.Resource):
allow_fetch = True allow_fetch = True
allow_list = True allow_list = True
_query_mapping = resource.QueryParameters(
'hypervisor_hostname_pattern', 'with_servers'
)
# Properties # Properties
#: Status of hypervisor #: Status of hypervisor
status = resource.Body('status') status = resource.Body('status')
@ -64,9 +68,4 @@ class Hypervisor(resource.Resource):
disk_available = resource.Body("disk_available_least") disk_available = resource.Body("disk_available_least")
class HypervisorDetail(Hypervisor): HypervisorDetail = Hypervisor
base_path = '/os-hypervisors/detail'
# capabilities
allow_fetch = False
allow_list = True

View File

@ -55,9 +55,4 @@ class Image(resource.Resource, metadata.MetadataMixin):
size = resource.Body('OS-EXT-IMG-SIZE:size', type=int) size = resource.Body('OS-EXT-IMG-SIZE:size', type=int)
class ImageDetail(Image): ImageDetail = Image
base_path = '/images/detail'
allow_fetch = False
allow_delete = False
allow_list = True

View File

@ -130,7 +130,7 @@ class TestOperatorCloud(base.TestCase):
r = self.cloud.list_hypervisors() r = self.cloud.list_hypervisors()
self.assertEqual(2, len(r)) self.assertEqual(2, len(r))
self.assertEqual('testserver1', r[0]['hypervisor_hostname']) self.assertEqual('testserver1', r[0]['name'])
self.assertEqual('testserver2', r[1]['hypervisor_hostname']) self.assertEqual('testserver2', r[1]['name'])
self.assert_calls() self.assert_calls()

View File

@ -52,6 +52,13 @@ class TestHypervisor(base.TestCase):
self.assertTrue(sot.allow_fetch) self.assertTrue(sot.allow_fetch)
self.assertTrue(sot.allow_list) self.assertTrue(sot.allow_list)
self.assertDictEqual({'hypervisor_hostname_pattern':
'hypervisor_hostname_pattern',
'limit': 'limit',
'marker': 'marker',
'with_servers': 'with_servers'},
sot._query_mapping._mapping)
def test_make_it(self): def test_make_it(self):
sot = hypervisor.Hypervisor(**EXAMPLE) sot = hypervisor.Hypervisor(**EXAMPLE)
self.assertEqual(EXAMPLE['id'], sot.id) self.assertEqual(EXAMPLE['id'], sot.id)
@ -75,11 +82,3 @@ class TestHypervisor(base.TestCase):
self.assertEqual(EXAMPLE['disk_available_least'], sot.disk_available) self.assertEqual(EXAMPLE['disk_available_least'], sot.disk_available)
self.assertEqual(EXAMPLE['local_gb'], sot.local_disk_size) self.assertEqual(EXAMPLE['local_gb'], sot.local_disk_size)
self.assertEqual(EXAMPLE['free_ram_mb'], sot.memory_free) self.assertEqual(EXAMPLE['free_ram_mb'], sot.memory_free)
def test_detail(self):
sot = hypervisor.HypervisorDetail()
self.assertEqual('hypervisor', sot.resource_key)
self.assertEqual('hypervisors', sot.resources_key)
self.assertEqual('/os-hypervisors/detail', sot.base_path)
self.assertFalse(sot.allow_fetch)
self.assertTrue(sot.allow_list)

View File

@ -15,13 +15,11 @@ from openstack.tests.unit import base
from openstack.compute.v2 import image from openstack.compute.v2 import image
IDENTIFIER = 'IDENTIFIER' IDENTIFIER = 'IDENTIFIER'
BASIC_EXAMPLE = {
EXAMPLE = {
'id': IDENTIFIER, 'id': IDENTIFIER,
'links': '2', 'links': '2',
'name': '3', 'name': '3',
}
DETAILS = {
'created': '2015-03-09T12:14:57.233772', 'created': '2015-03-09T12:14:57.233772',
'metadata': {'key': '2'}, 'metadata': {'key': '2'},
'minDisk': 3, 'minDisk': 3,
@ -32,9 +30,6 @@ DETAILS = {
'OS-EXT-IMG-SIZE:size': 8 'OS-EXT-IMG-SIZE:size': 8
} }
DETAIL_EXAMPLE = BASIC_EXAMPLE.copy()
DETAIL_EXAMPLE.update(DETAILS)
class TestImage(base.TestCase): class TestImage(base.TestCase):
@ -61,32 +56,18 @@ class TestImage(base.TestCase):
sot._query_mapping._mapping) sot._query_mapping._mapping)
def test_make_basic(self): def test_make_basic(self):
sot = image.Image(**BASIC_EXAMPLE) sot = image.Image(**EXAMPLE)
self.assertEqual(BASIC_EXAMPLE['id'], sot.id) self.assertEqual(EXAMPLE['id'], sot.id)
self.assertEqual(BASIC_EXAMPLE['links'], sot.links) self.assertEqual(EXAMPLE['links'], sot.links)
self.assertEqual(BASIC_EXAMPLE['name'], sot.name) self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['created'], sot.created_at)
def test_detail(self): self.assertEqual(EXAMPLE['id'], sot.id)
sot = image.ImageDetail() self.assertEqual(EXAMPLE['links'], sot.links)
self.assertEqual('image', sot.resource_key) self.assertEqual(EXAMPLE['metadata'], sot.metadata)
self.assertEqual('images', sot.resources_key) self.assertEqual(EXAMPLE['minDisk'], sot.min_disk)
self.assertEqual('/images/detail', sot.base_path) self.assertEqual(EXAMPLE['minRam'], sot.min_ram)
self.assertFalse(sot.allow_create) self.assertEqual(EXAMPLE['name'], sot.name)
self.assertFalse(sot.allow_fetch) self.assertEqual(EXAMPLE['progress'], sot.progress)
self.assertFalse(sot.allow_commit) self.assertEqual(EXAMPLE['status'], sot.status)
self.assertFalse(sot.allow_delete) self.assertEqual(EXAMPLE['updated'], sot.updated_at)
self.assertTrue(sot.allow_list) self.assertEqual(EXAMPLE['OS-EXT-IMG-SIZE:size'], sot.size)
def test_make_detail(self):
sot = image.ImageDetail(**DETAIL_EXAMPLE)
self.assertEqual(DETAIL_EXAMPLE['created'], sot.created_at)
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_at)
self.assertEqual(DETAIL_EXAMPLE['OS-EXT-IMG-SIZE:size'], sot.size)