Merge "api: Add response body schemas for server diagnostics API"

This commit is contained in:
Zuul
2025-06-27 15:15:54 +00:00
committed by Gerrit Code Review
4 changed files with 165 additions and 6 deletions

View File

@@ -16,3 +16,140 @@ index_query = {
'properties': {},
'additionalProperties': True,
}
# NOTE(stephenfin): We could define all available response types for the
# various virt drivers, but we'd need to be able to do this (accurately) for
# every virt driver including those we once supported but no longer do. Seems
# like a lot of work with very little in return.
index_response = {
'type': 'object',
'properties': {},
'required': [],
'additionalProperties': True,
}
index_response_v248 = {
'type': 'object',
'properties': {
'config_drive': {'type': 'boolean'},
'cpu_details': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'id': {
'type': ['integer', 'null'],
},
'time': {
'type': ['integer', 'null'],
},
'utilisation': {
'type': ['integer', 'null'],
},
},
'required': ['id', 'time', 'utilisation'],
},
},
'disk_details': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'errors_count': {'type': ['integer', 'null']},
'read_bytes': {'type': ['integer', 'null']},
'read_requests': {'type': ['integer', 'null']},
'write_bytes': {'type': ['integer', 'null']},
'write_requests': {'type': ['integer', 'null']},
},
'required': [
'errors_count',
'read_bytes',
'read_requests',
'write_bytes',
'write_requests',
],
},
},
'driver': {
'type': 'string',
'enum': [
'ironic',
'libvirt',
'vmwareapi',
'xenapi',
],
},
'hypervisor': {'type': ['string', 'null']},
'hypervisor_os': {'type': ['string', 'null']},
'memory_details': {
'type': 'object',
'properties': {
'maximum': {'type': ['integer', 'null']},
'used': {'type': ['integer', 'null']},
},
'required': ['maximum', 'used'],
},
'nic_details': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'mac_address': {'type': ['string', 'null']},
'rx_drop': {'type': ['integer', 'null']},
'rx_errors': {'type': ['integer', 'null']},
'rx_octets': {'type': ['integer', 'null']},
'rx_packets': {'type': ['integer', 'null']},
'rx_rate': {'type': ['integer', 'null']},
'tx_drop': {'type': ['integer', 'null']},
'tx_errors': {'type': ['integer', 'null']},
'tx_octets': {'type': ['integer', 'null']},
'tx_packets': {'type': ['integer', 'null']},
'tx_rate': {'type': ['integer', 'null']},
},
'required': [
'mac_address',
'rx_drop',
'rx_errors',
'rx_octets',
'rx_packets',
'rx_rate',
'tx_drop',
'tx_errors',
'tx_octets',
'tx_packets',
'tx_rate',
],
},
},
'num_cpus': {'type': ['integer', 'null']},
'num_disks': {'type': ['integer', 'null']},
'num_nics': {'type': ['integer', 'null']},
'state': {
'type': 'string',
'enum': [
'pending',
'running',
'paused',
'shutdown',
'crashed',
'suspended',
],
},
'uptime': {'type': ['integer', 'null']},
},
'required': [
'config_drive',
'cpu_details',
'disk_details',
'driver',
'hypervisor',
'hypervisor_os',
'memory_details',
'nic_details',
'num_cpus',
'num_disks',
'num_nics',
'state',
'uptime',
],
}

View File

@@ -26,6 +26,7 @@ from nova import exception
from nova.policies import server_diagnostics as sd_policies
@validation.validated
class ServerDiagnosticsController(wsgi.Controller):
_view_builder_class = server_diagnostics.ViewBuilder
@@ -35,6 +36,8 @@ class ServerDiagnosticsController(wsgi.Controller):
@wsgi.expected_errors((400, 404, 409, 501))
@validation.query_schema(schema.index_query)
@validation.response_body_schema(schema.index_response, '2.1', '2.47')
@validation.response_body_schema(schema.index_response_v248, '2.48')
def index(self, req, server_id):
context = req.environ["nova.context"]
instance = common.get_instance(self.compute_api, context, server_id)

View File

@@ -10,14 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
from unittest import mock
import fixtures
from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import timeutils
from nova.api.openstack.compute import server_diagnostics
from nova.compute import vm_states
from nova import objects
from nova.policies import base as base_policy
from nova.policies import server_diagnostics as policies
from nova.tests.unit.api.openstack import fakes
@@ -38,14 +37,34 @@ class ServerDiagnosticsPolicyTest(base.BasePolicyTest):
super(ServerDiagnosticsPolicyTest, self).setUp()
self.controller = server_diagnostics.ServerDiagnosticsController()
self.req = fakes.HTTPRequest.blank('', version='2.48')
self.controller.compute_api.get_instance_diagnostics = mock.MagicMock()
self.mock_get = self.useFixture(
self.mock_get_instance = self.useFixture(
fixtures.MockPatch('nova.api.openstack.common.get_instance')).mock
self.instance = fake_instance.fake_instance_obj(
self.project_member_context, project_id=self.project_id,
id=1, uuid=uuids.fake_id, vm_state=vm_states.ACTIVE,
task_state=None, launched_at=timeutils.utcnow())
self.mock_get.return_value = self.instance
self.mock_get_instance.return_value = self.instance
self.mock_get_diagnostics = self.useFixture(
fixtures.MockPatch('nova.compute.api.API.get_instance_diagnostics')
).mock
self.diagnostics = objects.Diagnostics(
config_drive=False,
state='running',
driver='libvirt',
uptime=5,
hypervisor='hypervisor',
# hypervisor_os is unset
cpu_details=[],
nic_details=[],
disk_details=[],
num_cpus=4,
num_disks=1,
num_nics=1,
memory_details=objects.MemoryDiagnostics(maximum=8192, used=3072),
)
self.mock_get_diagnostics.return_value = self.diagnostics
# With legacy rule, any admin is able get server diagnostics.
self.project_admin_authorized_contexts = [

View File

@@ -701,7 +701,7 @@ class ComputeDriver(object):
:return: Has a big overlap to the return value of the older interface
:func:`get_diagnostics`
:rtype: nova.virt.diagnostics.Diagnostics
:rtype: nova.objects.diagnostics.Diagnostics
"""
raise NotImplementedError()