api: Address issues with remote consoles APIs

* Add a note explaining presence of xvpvnc console type
* Make 'url' mandatory in create response
* Remove unnecessary description fields: we will populate these later
* De-deuplcate request body schemas
* Re-add references to the rdp console to the api-ref

Change-Id: I5555b8cf7a83fad689e98522850b5550b49566ed
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2025-06-10 10:46:58 +01:00
parent 485ee768d6
commit c4f81a54d5
5 changed files with 73 additions and 122 deletions

View File

@@ -5986,17 +5986,20 @@ remote_console:
remote_console_protocol:
description: |
The protocol of remote console. The valid values are ``vnc``, ``spice``,
``serial`` and ``mks``. The protocol ``mks`` is added since Microversion
``2.8``.
``rdp``, ``serial`` and ``mks``. The protocol ``mks`` is added since
Microversion ``2.8``. The protocol ``rdp`` requires the Hyper-V driver
which was removed in the 29.0.0 (Caracal) release.
in: body
required: true
type: string
remote_console_type:
description: |
The type of remote console. The valid values are ``novnc``,
``spice-html5``, ``spice-direct``, ``serial``, and ``webmks``. The type
``webmks`` was added in Microversion ``2.8``, and the type
``spice-direct`` was added in Microversion ``2.99``.
``rdp-html5``, ``spice-html5``, ``spice-direct``, ``serial``, and
``webmks``. The type ``webmks`` was added in Microversion ``2.8`` and the
type ``spice-direct`` was added in Microversion ``2.99``. The type
``rdp-html5`` requires the Hyper-V driver which was removed in the 29.0.0
(Caracal) release.
in: body
required: true
type: string

View File

@@ -8,20 +8,22 @@
Enables all users to perform an action on a server. Specify the action
in the request body.
You can associate a fixed or floating IP address with a server,
or disassociate a fixed or floating IP address from a server.
There are many actions available for a server:
You can create an image from a server, create a backup of a server,
and force-delete a server before deferred cleanup.
You can lock, pause, reboot, rebuild, rescue, resize, resume, confirm
the resize of, revert a pending resize for, shelve, shelf-offload,
unshelve, start, stop, unlock, unpause, and unrescue a server. You can
also change the password of the server and add a security group to or
remove a security group from a server. You can also trigger a crash dump
into a server since Mitaka release.
You can get an serial, SPICE, or VNC console for a server.
* You can associate and disassociate a fixed or floating IP address with
or from a server
* You can create an image from a server
* You can create a backup of a server
* You can force-delete a server before deferred cleanup
* You can lock, pause, reboot, rebuild, rescue, resize, resume, confirm
the resize of, revert a pending resize for, shelve, shelf-offload,
unshelve, start, stop, unlock, unpause, and unrescue a server
* You can change the password of the server
* You can add a security group to or remove a security group from a server
* You can trigger a crash dump into a server
* You can get a graphical or serial console for a server
...among others.
Add (Associate) Floating Ip (addFloatingIp Action) (DEPRECATED)
================================================================

View File

@@ -157,13 +157,21 @@ class RemoteConsolesController(wsgi.Controller):
target={'project_id': instance.project_id})
protocol = body['remote_console']['protocol']
console_type = body['remote_console']['type']
# handle removed console types
if protocol in ('rdp',):
raise webob.exc.HTTPBadRequest(
'Unavailable console type %s.' % protocol
)
try:
handler = self.handlers.get(protocol)
# this should never fail in the real world since our schema
# prevents unsupported types getting through
handler = self.handlers[protocol]
output = handler(context, instance, console_type)
return {'remote_console': {'protocol': protocol,
'type': console_type,
'url': output['url']}}
except exception.InstanceNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
except exception.InstanceNotReady as e:
@@ -174,5 +182,5 @@ class RemoteConsolesController(wsgi.Controller):
exception.ImageSerialPortNumberExceedFlavorValue,
exception.SocketPortRangeExhaustedException) as e:
raise webob.exc.HTTPBadRequest(explanation=e.format_message())
except NotImplementedError:
except (NotImplementedError, KeyError):
common.raise_feature_not_supported()

View File

@@ -20,6 +20,11 @@ get_vnc_console = {
'os-getVNCConsole': {
'type': 'object',
'properties': {
# NOTE(stephenfin): While we only support novnc nowadays, we
# previously supported xvpvnc for the XenServer driver. Since
# our generated schemas are unversioned, we need to accept
# these old values here and reject them lower down the stack.
# Ditto for other schemas in this file.
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc'],
@@ -63,8 +68,7 @@ get_serial_console = {
'type': 'object',
'properties': {
'type': {
'type': 'string',
'enum': ['serial'],
'type': 'string', 'enum': ['serial'],
},
},
'required': ['type'],
@@ -83,11 +87,16 @@ create_v26 = {
'properties': {
'protocol': {
'type': 'string',
'enum': ['vnc', 'spice', 'serial'],
# While we no longer support the rdp console type, we still
# list it here for documentation purposes. It is rejected
# at the controller level.
'enum': ['vnc', 'spice', 'serial', 'rdp'],
},
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'serial'],
'enum': [
'novnc', 'xvpvnc', 'spice-html5', 'serial', 'rdp-html5'
],
},
},
'required': ['protocol', 'type'],
@@ -98,53 +107,18 @@ create_v26 = {
'additionalProperties': False,
}
create_v28 = {
'type': 'object',
'properties': {
'remote_console': {
'type': 'object',
'properties': {
'protocol': {
'type': 'string',
'enum': ['vnc', 'spice', 'serial', 'mks'],
},
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'serial',
'webmks'],
},
},
'required': ['protocol', 'type'],
'additionalProperties': False,
},
},
'required': ['remote_console'],
'additionalProperties': False,
}
create_v28 = copy.deepcopy(create_v26)
create_v28['properties']['remote_console']['properties']['protocol'][
'enum'
].append('mks')
create_v28['properties']['remote_console']['properties']['type'][
'enum'
].append('webmks')
create_v299 = {
'type': 'object',
'properties': {
'remote_console': {
'type': 'object',
'properties': {
'protocol': {
'type': 'string',
'enum': ['vnc', 'spice', 'rdp', 'serial', 'mks'],
},
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'spice-direct',
'serial', 'webmks'],
},
},
'required': ['protocol', 'type'],
'additionalProperties': False,
},
},
'required': ['remote_console'],
'additionalProperties': False,
}
create_v299 = copy.deepcopy(create_v28)
create_v299['properties']['remote_console']['properties']['type'][
'enum'
].append('spice-direct')
get_vnc_console_response = {
'type': 'object',
@@ -152,16 +126,8 @@ get_vnc_console_response = {
'console': {
'type': 'object',
'properties': {
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc'],
'description': '',
},
'url': {
'type': 'string',
'format': 'uri',
'description': '',
},
'type': {'type': 'string', 'enum': ['novnc', 'xvpvnc']},
'url': {'type': 'string', 'format': 'uri'},
},
'required': ['type', 'url'],
'additionalProperties': False,
@@ -177,16 +143,8 @@ get_spice_console_response = {
'console': {
'type': 'object',
'properties': {
'type': {
'type': 'string',
'const': 'spice-html5',
'description': '',
},
'url': {
'type': 'string',
'format': 'uri',
'description': '',
},
'type': {'type': 'string', 'const': 'spice-html5'},
'url': {'type': 'string', 'format': 'uri'},
},
'required': ['type', 'url'],
'additionalProperties': False,
@@ -201,16 +159,8 @@ get_rdp_console_response = {
'console': {
'type': 'object',
'properties': {
'type': {
'type': 'string',
'const': 'rdp',
'description': '',
},
'url': {
'type': 'string',
'format': 'uri',
'description': '',
},
'type': {'type': 'string', 'const': 'rdp-html5'},
'url': {'type': 'string', 'format': 'uri'},
},
'required': ['type', 'url'],
'additionalProperties': False,
@@ -226,16 +176,8 @@ get_serial_console_response = {
'console': {
'type': 'object',
'properties': {
'type': {
'type': 'string',
'const': 'serial',
'description': '',
},
'url': {
'type': 'string',
'format': 'uri',
'description': '',
},
'type': {'type': 'string', 'const': 'serial'},
'url': {'type': 'string', 'format': 'uri'},
},
'required': ['type', 'url'],
'additionalProperties': False,
@@ -253,18 +195,17 @@ create_response = {
'properties': {
'protocol': {
'type': 'string',
'enum': ['vnc', 'spice', 'serial'],
'enum': ['vnc', 'spice', 'serial', 'rdp'],
},
'type': {
'type': 'string',
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'serial'],
},
'url': {
'type': 'string',
'format': 'uri',
'enum': [
'novnc', 'xvpvnc', 'spice-html5', 'serial', 'rdp-html5'
],
},
'url': {'type': 'string', 'format': 'uri'},
},
'required': ['protocol', 'type'],
'required': ['protocol', 'type', 'url'],
'additionalProperties': False,
},
},

View File

@@ -16,6 +16,7 @@
from unittest import mock
import webob
import webob.exc
from nova.api.openstack import api_version_request
from nova.api.openstack.compute import remote_consoles \
@@ -352,12 +353,8 @@ class ConsolesExtensionTestV26(test.NoDBTestCase):
'spice-html5')
def test_create_rdp_console_bad_request(self):
mock_handler = mock.MagicMock()
mock_handler.return_value = {'url': "http://fake"}
self.controller.handlers['rdp'] = mock_handler
body = {'remote_console': {'protocol': 'rdp', 'type': 'rdp-html5'}}
self.assertRaises(exception.ValidationError, self.controller.create,
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
self.req, fakes.FAKE_UUID, body=body)
def test_create_serial_console(self):