Moved hypervisor to the SDK

Change-Id: Ie955fb4d27c30e044626732a1f3e0f141cb85aa5
This commit is contained in:
Violet Kurtz 2022-08-15 23:52:55 +00:00
parent 27b2496e03
commit 006e35509d
4 changed files with 304 additions and 202 deletions

View File

@ -18,8 +18,8 @@
import json import json
import re import re
from novaclient import api_versions
from novaclient import exceptions as nova_exceptions from novaclient import exceptions as nova_exceptions
from openstack import utils as sdk_utils
from osc_lib.cli import format_columns from osc_lib.cli import format_columns
from osc_lib.command import command from osc_lib.command import command
from osc_lib import exceptions from osc_lib import exceptions
@ -28,11 +28,44 @@ from osc_lib import utils
from openstackclient.i18n import _ from openstackclient.i18n import _
def _get_hypervisor_columns(item, client):
column_map = {'name': 'hypervisor_hostname'}
hidden_columns = ['location', 'servers']
if sdk_utils.supports_microversion(client, '2.88'):
hidden_columns.extend([
'current_workload',
'disk_available',
'local_disk_free',
'local_disk_size',
'local_disk_used',
'memory_free',
'memory_size',
'memory_used',
'running_vms',
'vcpus_used',
'vcpus',
])
else:
column_map.update({
'disk_available': 'disk_available_least',
'local_disk_free': 'free_disk_gb',
'local_disk_size': 'local_gb',
'local_disk_used': 'local_gb_used',
'memory_free': 'free_ram_mb',
'memory_used': 'memory_mb_used',
'memory_size': 'memory_mb',
})
return utils.get_osc_show_columns_for_sdk_resource(
item, column_map, hidden_columns)
class ListHypervisor(command.Lister): class ListHypervisor(command.Lister):
_description = _("List hypervisors") _description = _("List hypervisors")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(ListHypervisor, self).get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
'--matching', '--matching',
metavar='<hostname>', metavar='<hostname>',
@ -67,7 +100,7 @@ class ListHypervisor(command.Lister):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.sdk_connection.compute
list_opts = {} list_opts = {}
@ -78,7 +111,7 @@ class ListHypervisor(command.Lister):
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
if parsed_args.marker: if parsed_args.marker:
if compute_client.api_version < api_versions.APIVersion('2.33'): if not sdk_utils.supports_microversion(compute_client, '2.33'):
msg = _( msg = _(
'--os-compute-api-version 2.33 or greater is required to ' '--os-compute-api-version 2.33 or greater is required to '
'support the --marker option' 'support the --marker option'
@ -87,7 +120,7 @@ class ListHypervisor(command.Lister):
list_opts['marker'] = parsed_args.marker list_opts['marker'] = parsed_args.marker
if parsed_args.limit: if parsed_args.limit:
if compute_client.api_version < api_versions.APIVersion('2.33'): if not sdk_utils.supports_microversion(compute_client, '2.33'):
msg = _( msg = _(
'--os-compute-api-version 2.33 or greater is required to ' '--os-compute-api-version 2.33 or greater is required to '
'support the --limit option' 'support the --limit option'
@ -95,23 +128,43 @@ class ListHypervisor(command.Lister):
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
list_opts['limit'] = parsed_args.limit list_opts['limit'] = parsed_args.limit
columns = ( column_headers = (
"ID", "ID",
"Hypervisor Hostname", "Hypervisor Hostname",
"Hypervisor Type", "Hypervisor Type",
"Host IP", "Host IP",
"State" "State"
) )
columns = (
'id',
'name',
'hypervisor_type',
'host_ip',
'state'
)
if parsed_args.long: if parsed_args.long:
columns += ("vCPUs Used", "vCPUs", "Memory MB Used", "Memory MB") if not sdk_utils.supports_microversion(compute_client, '2.88'):
column_headers += (
'vCPUs Used',
'vCPUs',
'Memory MB Used',
'Memory MB'
)
columns += (
'vcpus_used',
'vcpus',
'memory_used',
'memory_size'
)
if parsed_args.matching: if parsed_args.matching:
data = compute_client.hypervisors.search(parsed_args.matching) data = compute_client.find_hypervisor(
parsed_args.matching, ignore_missing=False)
else: else:
data = compute_client.hypervisors.list(**list_opts) data = compute_client.hypervisors(**list_opts, details=True)
return ( return (
columns, column_headers,
(utils.get_item_properties(s, columns) for s in data), (utils.get_item_properties(s, columns) for s in data),
) )
@ -120,7 +173,7 @@ class ShowHypervisor(command.ShowOne):
_description = _("Display hypervisor details") _description = _("Display hypervisor details")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(ShowHypervisor, self).get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
"hypervisor", "hypervisor",
metavar="<hypervisor>", metavar="<hypervisor>",
@ -129,20 +182,25 @@ class ShowHypervisor(command.ShowOne):
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.sdk_connection.compute
hypervisor = utils.find_resource(compute_client.hypervisors, hypervisor = compute_client.find_hypervisor(
parsed_args.hypervisor)._info.copy() parsed_args.hypervisor, ignore_missing=False).copy()
# Some of the properties in the hypervisor object need to be processed
# before they get reported to the user. We spend this section
# extracting the relevant details to be reported by modifying our
# copy of the hypervisor object.
aggregates = compute_client.aggregates()
hypervisor['aggregates'] = list()
service_details = hypervisor['service_details']
aggregates = compute_client.aggregates.list()
hypervisor["aggregates"] = list()
if aggregates: if aggregates:
# Hypervisors in nova cells are prefixed by "<cell>@" # Hypervisors in nova cells are prefixed by "<cell>@"
if "@" in hypervisor['service']['host']: if "@" in service_details['host']:
cell, service_host = hypervisor['service']['host'].split( cell, service_host = service_details['host'].split('@', 1)
'@', 1)
else: else:
cell = None cell = None
service_host = hypervisor['service']['host'] service_host = service_details['host']
if cell: if cell:
# The host aggregates are also prefixed by "<cell>@" # The host aggregates are also prefixed by "<cell>@"
@ -154,42 +212,45 @@ class ShowHypervisor(command.ShowOne):
member_of = [aggregate.name member_of = [aggregate.name
for aggregate in aggregates for aggregate in aggregates
if service_host in aggregate.hosts] if service_host in aggregate.hosts]
hypervisor["aggregates"] = member_of hypervisor['aggregates'] = member_of
try: try:
uptime = compute_client.hypervisors.uptime(hypervisor['id'])._info if sdk_utils.supports_microversion(compute_client, '2.88'):
uptime = hypervisor['uptime'] or ''
del hypervisor['uptime']
else:
del hypervisor['uptime']
uptime = compute_client.get_hypervisor_uptime(
hypervisor['id'])['uptime']
# Extract data from uptime value # Extract data from uptime value
# format: 0 up 0, 0 users, load average: 0, 0, 0 # format: 0 up 0, 0 users, load average: 0, 0, 0
# example: 17:37:14 up 2:33, 3 users, # example: 17:37:14 up 2:33, 3 users,
# load average: 0.33, 0.36, 0.34 # load average: 0.33, 0.36, 0.34
m = re.match( m = re.match(
r"\s*(.+)\sup\s+(.+),\s+(.+)\susers?,\s+load average:\s(.+)", r"\s*(.+)\sup\s+(.+),\s+(.+)\susers?,\s+load average:\s(.+)",
uptime['uptime']) uptime)
if m: if m:
hypervisor["host_time"] = m.group(1) hypervisor['host_time'] = m.group(1)
hypervisor["uptime"] = m.group(2) hypervisor['uptime'] = m.group(2)
hypervisor["users"] = m.group(3) hypervisor['users'] = m.group(3)
hypervisor["load_average"] = m.group(4) hypervisor['load_average'] = m.group(4)
except nova_exceptions.HTTPNotImplemented: except nova_exceptions.HTTPNotImplemented:
pass pass
hypervisor["service_id"] = hypervisor["service"]["id"] hypervisor['service_id'] = service_details['id']
hypervisor["service_host"] = hypervisor["service"]["host"] hypervisor['service_host'] = service_details['host']
del hypervisor["service"] del hypervisor['service_details']
if compute_client.api_version < api_versions.APIVersion('2.28'): if not sdk_utils.supports_microversion(compute_client, '2.28'):
# microversion 2.28 transformed this to a JSON blob rather than a # microversion 2.28 transformed this to a JSON blob rather than a
# string; on earlier fields, do this manually # string; on earlier fields, do this manually
if hypervisor['cpu_info']: hypervisor['cpu_info'] = json.loads(hypervisor['cpu_info'] or '{}')
hypervisor['cpu_info'] = json.loads(hypervisor['cpu_info']) display_columns, columns = _get_hypervisor_columns(
else: hypervisor, compute_client)
hypervisor['cpu_info'] = {}
columns = tuple(sorted(hypervisor))
data = utils.get_dict_properties( data = utils.get_dict_properties(
hypervisor, columns, hypervisor, columns,
formatters={ formatters={
'cpu_info': format_columns.DictColumn, 'cpu_info': format_columns.DictColumn,
}) })
return (columns, data) return display_columns, data

View File

@ -20,6 +20,7 @@ import uuid
from novaclient import api_versions from novaclient import api_versions
from openstack.compute.v2 import flavor as _flavor from openstack.compute.v2 import flavor as _flavor
from openstack.compute.v2 import hypervisor as _hypervisor
from openstack.compute.v2 import server from openstack.compute.v2 import server
from openstack.compute.v2 import server_group as _server_group from openstack.compute.v2 import server_group as _server_group
from openstack.compute.v2 import server_interface as _server_interface from openstack.compute.v2 import server_interface as _server_interface
@ -340,75 +341,6 @@ class FakeExtension(object):
return extension return extension
class FakeHypervisor(object):
"""Fake one or more hypervisor."""
@staticmethod
def create_one_hypervisor(attrs=None):
"""Create a fake hypervisor.
:param dict attrs:
A dictionary with all attributes
:return:
A FakeResource object, with id, hypervisor_hostname, and so on
"""
attrs = attrs or {}
# Set default attributes.
hypervisor_info = {
'id': 'hypervisor-id-' + uuid.uuid4().hex,
'hypervisor_hostname': 'hypervisor-hostname-' + uuid.uuid4().hex,
'status': 'enabled',
'host_ip': '192.168.0.10',
'cpu_info': {
'aaa': 'aaa',
},
'free_disk_gb': 50,
'hypervisor_version': 2004001,
'disk_available_least': 50,
'local_gb': 50,
'free_ram_mb': 1024,
'service': {
'host': 'aaa',
'disabled_reason': None,
'id': 1,
},
'vcpus_used': 0,
'hypervisor_type': 'QEMU',
'local_gb_used': 0,
'vcpus': 4,
'memory_mb_used': 512,
'memory_mb': 1024,
'current_workload': 0,
'state': 'up',
'running_vms': 0,
}
# Overwrite default attributes.
hypervisor_info.update(attrs)
hypervisor = fakes.FakeResource(info=copy.deepcopy(hypervisor_info),
loaded=True)
return hypervisor
@staticmethod
def create_hypervisors(attrs=None, count=2):
"""Create multiple fake hypervisors.
:param dict attrs:
A dictionary with all attributes
:param int count:
The number of hypervisors to fake
:return:
A list of FakeResource objects faking the hypervisors
"""
hypervisors = []
for i in range(0, count):
hypervisors.append(FakeHypervisor.create_one_hypervisor(attrs))
return hypervisors
class FakeHypervisorStats(object): class FakeHypervisorStats(object):
"""Fake one or more hypervisor stats.""" """Fake one or more hypervisor stats."""
@ -1795,6 +1727,70 @@ class FakeVolumeAttachment(object):
return volume_attachments return volume_attachments
def create_one_hypervisor(attrs=None):
"""Create a fake hypervisor.
:param dict attrs:
A dictionary with all attributes
:return:
A FakeResource object, with id, hypervisor_hostname, and so on
"""
attrs = attrs or {}
# Set default attributes.
hypervisor_info = {
'id': 'hypervisor-id-' + uuid.uuid4().hex,
'hypervisor_hostname': 'hypervisor-hostname-' + uuid.uuid4().hex,
'status': 'enabled',
'host_ip': '192.168.0.10',
'cpu_info': {
'aaa': 'aaa',
},
'free_disk_gb': 50,
'hypervisor_version': 2004001,
'disk_available_least': 50,
'local_gb': 50,
'free_ram_mb': 1024,
'service': {
'host': 'aaa',
'disabled_reason': None,
'id': 1,
},
'vcpus_used': 0,
'hypervisor_type': 'QEMU',
'local_gb_used': 0,
'vcpus': 4,
'memory_mb_used': 512,
'memory_mb': 1024,
'current_workload': 0,
'state': 'up',
'running_vms': 0,
}
# Overwrite default attributes.
hypervisor_info.update(attrs)
hypervisor = _hypervisor.Hypervisor(**hypervisor_info, loaded=True)
return hypervisor
def create_hypervisors(attrs=None, count=2):
"""Create multiple fake hypervisors.
:param dict attrs:
A dictionary with all attributes
:param int count:
The number of hypervisors to fake
:return:
A list of FakeResource objects faking the hypervisors
"""
hypervisors = []
for i in range(0, count):
hypervisors.append(create_one_hypervisor(attrs))
return hypervisors
def create_one_server_group(attrs=None): def create_one_server_group(attrs=None):
"""Create a fake server group """Create a fake server group

View File

@ -13,41 +13,37 @@
# under the License. # under the License.
# #
import copy
import json import json
from unittest import mock
from novaclient import api_versions
from novaclient import exceptions as nova_exceptions from novaclient import exceptions as nova_exceptions
from openstack import utils as sdk_utils
from osc_lib.cli import format_columns from osc_lib.cli import format_columns
from osc_lib import exceptions from osc_lib import exceptions
from openstackclient.compute.v2 import hypervisor from openstackclient.compute.v2 import hypervisor
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit import fakes
class TestHypervisor(compute_fakes.TestComputev2): class TestHypervisor(compute_fakes.TestComputev2):
def setUp(self): def setUp(self):
super(TestHypervisor, self).setUp() super().setUp()
# Get a shortcut to the compute client hypervisors mock # Create and get a shortcut to the compute client mock
self.hypervisors_mock = self.app.client_manager.compute.hypervisors self.app.client_manager.sdk_connection = mock.Mock()
self.hypervisors_mock.reset_mock() self.sdk_client = self.app.client_manager.sdk_connection.compute
self.sdk_client.reset_mock()
# Get a shortcut to the compute client aggregates mock
self.aggregates_mock = self.app.client_manager.compute.aggregates
self.aggregates_mock.reset_mock()
class TestHypervisorList(TestHypervisor): class TestHypervisorList(TestHypervisor):
def setUp(self): def setUp(self):
super(TestHypervisorList, self).setUp() super().setUp()
# Fake hypervisors to be listed up # Fake hypervisors to be listed up
self.hypervisors = compute_fakes.FakeHypervisor.create_hypervisors() self.hypervisors = compute_fakes.create_hypervisors()
self.hypervisors_mock.list.return_value = self.hypervisors self.sdk_client.hypervisors.return_value = self.hypervisors
self.columns = ( self.columns = (
"ID", "ID",
@ -70,14 +66,14 @@ class TestHypervisorList(TestHypervisor):
self.data = ( self.data = (
( (
self.hypervisors[0].id, self.hypervisors[0].id,
self.hypervisors[0].hypervisor_hostname, self.hypervisors[0].name,
self.hypervisors[0].hypervisor_type, self.hypervisors[0].hypervisor_type,
self.hypervisors[0].host_ip, self.hypervisors[0].host_ip,
self.hypervisors[0].state self.hypervisors[0].state
), ),
( (
self.hypervisors[1].id, self.hypervisors[1].id,
self.hypervisors[1].hypervisor_hostname, self.hypervisors[1].name,
self.hypervisors[1].hypervisor_type, self.hypervisors[1].hypervisor_type,
self.hypervisors[1].host_ip, self.hypervisors[1].host_ip,
self.hypervisors[1].state self.hypervisors[1].state
@ -87,25 +83,25 @@ class TestHypervisorList(TestHypervisor):
self.data_long = ( self.data_long = (
( (
self.hypervisors[0].id, self.hypervisors[0].id,
self.hypervisors[0].hypervisor_hostname, self.hypervisors[0].name,
self.hypervisors[0].hypervisor_type, self.hypervisors[0].hypervisor_type,
self.hypervisors[0].host_ip, self.hypervisors[0].host_ip,
self.hypervisors[0].state, self.hypervisors[0].state,
self.hypervisors[0].vcpus_used, self.hypervisors[0].vcpus_used,
self.hypervisors[0].vcpus, self.hypervisors[0].vcpus,
self.hypervisors[0].memory_mb_used, self.hypervisors[0].memory_used,
self.hypervisors[0].memory_mb self.hypervisors[0].memory_size
), ),
( (
self.hypervisors[1].id, self.hypervisors[1].id,
self.hypervisors[1].hypervisor_hostname, self.hypervisors[1].name,
self.hypervisors[1].hypervisor_type, self.hypervisors[1].hypervisor_type,
self.hypervisors[1].host_ip, self.hypervisors[1].host_ip,
self.hypervisors[1].state, self.hypervisors[1].state,
self.hypervisors[1].vcpus_used, self.hypervisors[1].vcpus_used,
self.hypervisors[1].vcpus, self.hypervisors[1].vcpus,
self.hypervisors[1].memory_mb_used, self.hypervisors[1].memory_used,
self.hypervisors[1].memory_mb self.hypervisors[1].memory_size
), ),
) )
# Get the command object to test # Get the command object to test
@ -121,25 +117,25 @@ class TestHypervisorList(TestHypervisor):
# containing the data to be listed. # containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.hypervisors_mock.list.assert_called_with() self.sdk_client.hypervisors.assert_called_with(details=True)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, tuple(data)) self.assertEqual(self.data, tuple(data))
def test_hypervisor_list_matching_option_found(self): def test_hypervisor_list_matching_option_found(self):
arglist = [ arglist = [
'--matching', self.hypervisors[0].hypervisor_hostname, '--matching', self.hypervisors[0].name,
] ]
verifylist = [ verifylist = [
('matching', self.hypervisors[0].hypervisor_hostname), ('matching', self.hypervisors[0].name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# Fake the return value of search() # Fake the return value of search()
self.hypervisors_mock.search.return_value = [self.hypervisors[0]] self.sdk_client.find_hypervisor.return_value = [self.hypervisors[0]]
self.data = ( self.data = (
( (
self.hypervisors[0].id, self.hypervisors[0].id,
self.hypervisors[0].hypervisor_hostname, self.hypervisors[0].name,
self.hypervisors[1].hypervisor_type, self.hypervisors[1].hypervisor_type,
self.hypervisors[1].host_ip, self.hypervisors[1].host_ip,
self.hypervisors[1].state, self.hypervisors[1].state,
@ -151,8 +147,9 @@ class TestHypervisorList(TestHypervisor):
# containing the data to be listed. # containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.hypervisors_mock.search.assert_called_with( self.sdk_client.find_hypervisor.assert_called_with(
self.hypervisors[0].hypervisor_hostname self.hypervisors[0].name,
ignore_missing=False
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, tuple(data)) self.assertEqual(self.data, tuple(data))
@ -167,25 +164,25 @@ class TestHypervisorList(TestHypervisor):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# Fake exception raised from search() # Fake exception raised from search()
self.hypervisors_mock.search.side_effect = exceptions.NotFound(None) self.sdk_client.find_hypervisor.side_effect = \
exceptions.NotFound(None)
self.assertRaises(exceptions.NotFound, self.assertRaises(exceptions.NotFound,
self.cmd.take_action, self.cmd.take_action,
parsed_args) parsed_args)
def test_hypervisor_list_with_matching_and_pagination_options(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=False)
self.app.client_manager.compute.api_version = \ def test_hypervisor_list_with_matching_and_pagination_options(
api_versions.APIVersion('2.32') self, sm_mock):
arglist = [ arglist = [
'--matching', self.hypervisors[0].hypervisor_hostname, '--matching', self.hypervisors[0].name,
'--limit', '1', '--limit', '1',
'--marker', self.hypervisors[0].hypervisor_hostname, '--marker', self.hypervisors[0].name,
] ]
verifylist = [ verifylist = [
('matching', self.hypervisors[0].hypervisor_hostname), ('matching', self.hypervisors[0].name),
('limit', 1), ('limit', 1),
('marker', self.hypervisors[0].hypervisor_hostname), ('marker', self.hypervisors[0].name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -197,7 +194,8 @@ class TestHypervisorList(TestHypervisor):
self.assertIn( self.assertIn(
'--matching is not compatible with --marker or --limit', str(ex)) '--matching is not compatible with --marker or --limit', str(ex))
def test_hypervisor_list_long_option(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=False)
def test_hypervisor_list_long_option(self, sm_mock):
arglist = [ arglist = [
'--long', '--long',
] ]
@ -211,14 +209,12 @@ class TestHypervisorList(TestHypervisor):
# containing the data to be listed. # containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.hypervisors_mock.list.assert_called_with() self.sdk_client.hypervisors.assert_called_with(details=True)
self.assertEqual(self.columns_long, columns) self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, tuple(data)) self.assertEqual(self.data_long, tuple(data))
def test_hypervisor_list_with_limit(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=True)
self.app.client_manager.compute.api_version = \ def test_hypervisor_list_with_limit(self, sm_mock):
api_versions.APIVersion('2.33')
arglist = [ arglist = [
'--limit', '1', '--limit', '1',
] ]
@ -229,12 +225,10 @@ class TestHypervisorList(TestHypervisor):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.hypervisors_mock.list.assert_called_with(limit=1) self.sdk_client.hypervisors.assert_called_with(limit=1, details=True)
def test_hypervisor_list_with_limit_pre_v233(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.32')
@mock.patch.object(sdk_utils, 'supports_microversion', return_value=False)
def test_hypervisor_list_with_limit_pre_v233(self, sm_mock):
arglist = [ arglist = [
'--limit', '1', '--limit', '1',
] ]
@ -251,10 +245,8 @@ class TestHypervisorList(TestHypervisor):
self.assertIn( self.assertIn(
'--os-compute-api-version 2.33 or greater is required', str(ex)) '--os-compute-api-version 2.33 or greater is required', str(ex))
def test_hypervisor_list_with_marker(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=True)
self.app.client_manager.compute.api_version = \ def test_hypervisor_list_with_marker(self, sm_mock):
api_versions.APIVersion('2.33')
arglist = [ arglist = [
'--marker', 'test_hyp', '--marker', 'test_hyp',
] ]
@ -265,12 +257,11 @@ class TestHypervisorList(TestHypervisor):
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.hypervisors_mock.list.assert_called_with(marker='test_hyp') self.sdk_client.hypervisors.assert_called_with(
marker='test_hyp', details=True)
def test_hypervisor_list_with_marker_pre_v233(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.32')
@mock.patch.object(sdk_utils, 'supports_microversion', return_value=False)
def test_hypervisor_list_with_marker_pre_v233(self, sm_mock):
arglist = [ arglist = [
'--marker', 'test_hyp', '--marker', 'test_hyp',
] ]
@ -291,29 +282,66 @@ class TestHypervisorList(TestHypervisor):
class TestHypervisorShow(TestHypervisor): class TestHypervisorShow(TestHypervisor):
def setUp(self): def setUp(self):
super(TestHypervisorShow, self).setUp() super().setUp()
uptime_string = (' 01:28:24 up 3 days, 11:15, 1 user, '
' load average: 0.94, 0.62, 0.50\n')
# Fake hypervisors to be listed up # Fake hypervisors to be listed up
self.hypervisor = compute_fakes.FakeHypervisor.create_one_hypervisor() self.hypervisor = compute_fakes.create_one_hypervisor(attrs={
'uptime': uptime_string,
})
# Return value of utils.find_resource() # Return value of compute_client.find_hypervisor
self.hypervisors_mock.get.return_value = self.hypervisor self.sdk_client.find_hypervisor.return_value = self.hypervisor
# Return value of compute_client.aggregates.list() # Return value of compute_client.aggregates()
self.aggregates_mock.list.return_value = [] self.sdk_client.aggregates.return_value = []
# Return value of compute_client.hypervisors.uptime() # Return value of compute_client.get_hypervisor_uptime()
uptime_info = { uptime_info = {
'status': self.hypervisor.status, 'status': self.hypervisor.status,
'state': self.hypervisor.state, 'state': self.hypervisor.state,
'id': self.hypervisor.id, 'id': self.hypervisor.id,
'hypervisor_hostname': self.hypervisor.hypervisor_hostname, 'hypervisor_hostname': self.hypervisor.name,
'uptime': ' 01:28:24 up 3 days, 11:15, 1 user, ' 'uptime': uptime_string,
' load average: 0.94, 0.62, 0.50\n',
} }
self.hypervisors_mock.uptime.return_value = fakes.FakeResource( self.sdk_client.get_hypervisor_uptime.return_value = uptime_info
info=copy.deepcopy(uptime_info),
loaded=True self.columns_v288 = (
'aggregates',
'cpu_info',
'host_ip',
'host_time',
'hypervisor_hostname',
'hypervisor_type',
'hypervisor_version',
'id',
'load_average',
'service_host',
'service_id',
'state',
'status',
'uptime',
'users',
)
self.data_v288 = (
[],
format_columns.DictColumn({'aaa': 'aaa'}),
'192.168.0.10',
'01:28:24',
self.hypervisor.name,
'QEMU',
2004001,
self.hypervisor.id,
'0.94, 0.62, 0.50',
'aaa',
1,
'up',
'enabled',
'3 days, 11:15',
'1',
) )
self.columns = ( self.columns = (
@ -353,7 +381,7 @@ class TestHypervisorShow(TestHypervisor):
1024, 1024,
'192.168.0.10', '192.168.0.10',
'01:28:24', '01:28:24',
self.hypervisor.hypervisor_hostname, self.hypervisor.name,
'QEMU', 'QEMU',
2004001, 2004001,
self.hypervisor.id, self.hypervisor.id,
@ -376,15 +404,32 @@ class TestHypervisorShow(TestHypervisor):
# Get the command object to test # Get the command object to test
self.cmd = hypervisor.ShowHypervisor(self.app, None) self.cmd = hypervisor.ShowHypervisor(self.app, None)
def test_hypervisor_show(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=True)
self.app.client_manager.compute.api_version = \ def test_hypervisor_show(self, sm_mock):
api_versions.APIVersion('2.28')
arglist = [ arglist = [
self.hypervisor.hypervisor_hostname, self.hypervisor.name,
] ]
verifylist = [ verifylist = [
('hypervisor', self.hypervisor.hypervisor_hostname), ('hypervisor', self.hypervisor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns_v288, columns)
self.assertCountEqual(self.data_v288, data)
@mock.patch.object(sdk_utils, 'supports_microversion',
side_effect=[False, True, False])
def test_hypervisor_show_pre_v288(self, sm_mock):
arglist = [
self.hypervisor.name,
]
verifylist = [
('hypervisor', self.hypervisor.name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -396,21 +441,19 @@ class TestHypervisorShow(TestHypervisor):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_hypervisor_show_pre_v228(self): @mock.patch.object(sdk_utils, 'supports_microversion', return_value=False)
self.app.client_manager.compute.api_version = \ def test_hypervisor_show_pre_v228(self, sm_mock):
api_versions.APIVersion('2.27')
# before microversion 2.28, nova returned a stringified version of this # before microversion 2.28, nova returned a stringified version of this
# field # field
self.hypervisor._info['cpu_info'] = json.dumps( self.hypervisor.cpu_info = json.dumps(
self.hypervisor._info['cpu_info']) self.hypervisor.cpu_info)
self.hypervisors_mock.get.return_value = self.hypervisor self.sdk_client.find_hypervisor.return_value = self.hypervisor
arglist = [ arglist = [
self.hypervisor.hypervisor_hostname, self.hypervisor.name,
] ]
verifylist = [ verifylist = [
('hypervisor', self.hypervisor.hypervisor_hostname), ('hypervisor', self.hypervisor.name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -422,19 +465,18 @@ class TestHypervisorShow(TestHypervisor):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data) self.assertCountEqual(self.data, data)
def test_hypervisor_show_uptime_not_implemented(self): @mock.patch.object(sdk_utils, 'supports_microversion',
self.app.client_manager.compute.api_version = \ side_effect=[False, True, False])
api_versions.APIVersion('2.28') def test_hypervisor_show_uptime_not_implemented(self, sm_mock):
arglist = [ arglist = [
self.hypervisor.hypervisor_hostname, self.hypervisor.name,
] ]
verifylist = [ verifylist = [
('hypervisor', self.hypervisor.hypervisor_hostname), ('hypervisor', self.hypervisor.name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.hypervisors_mock.uptime.side_effect = ( self.sdk_client.get_hypervisor_uptime.side_effect = (
nova_exceptions.HTTPNotImplemented(501)) nova_exceptions.HTTPNotImplemented(501))
# In base command class ShowOne in cliff, abstract method take_action() # In base command class ShowOne in cliff, abstract method take_action()
@ -474,7 +516,7 @@ class TestHypervisorShow(TestHypervisor):
50, 50,
1024, 1024,
'192.168.0.10', '192.168.0.10',
self.hypervisor.hypervisor_hostname, self.hypervisor.name,
'QEMU', 'QEMU',
2004001, 2004001,
self.hypervisor.id, self.hypervisor.id,

View File

@ -0,0 +1,3 @@
---
features:
- Switch hypervisor to the OpenStackSDK