HyperV: Remove RDP console API
RDP console was only for HyperV driver so removing the API. As API url stay same (because same used for other console types API), RDP console API will return 400. Cleaning up the related config options as well as moving its API ref to obsolete seciton. Keeping RPC method to avoid error when old controller is used with new compute. It can be removed in next RPC version bump. Change-Id: I8f5755009da4af0d12bda096d7a8e85fd41e1a8c
This commit is contained in:
parent
3e47439a68
commit
0c1e1ccf03
@ -90,3 +90,4 @@ Compute API in the past, but no longer exist.
|
|||||||
.. include:: os-consoles.inc
|
.. include:: os-consoles.inc
|
||||||
.. include:: os-security-group-default-rules.inc
|
.. include:: os-security-group-default-rules.inc
|
||||||
.. include:: os-agents.inc
|
.. include:: os-agents.inc
|
||||||
|
.. include:: servers-action-rdp-remote-consoles.inc
|
||||||
|
@ -5956,15 +5956,15 @@ remote_console:
|
|||||||
remote_console_protocol:
|
remote_console_protocol:
|
||||||
description: |
|
description: |
|
||||||
The protocol of remote console. The valid values are ``vnc``, ``spice``,
|
The protocol of remote console. The valid values are ``vnc``, ``spice``,
|
||||||
``rdp``, ``serial`` and ``mks``. The protocol ``mks`` is added since
|
``serial`` and ``mks``. The protocol ``mks`` is added since Microversion
|
||||||
Microversion ``2.8``.
|
``2.8``.
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
remote_console_type:
|
remote_console_type:
|
||||||
description: |
|
description: |
|
||||||
The type of remote console. The valid values are ``novnc``,
|
The type of remote console. The valid values are ``novnc``,
|
||||||
``rdp-html5``, ``spice-html5``, ``serial``, and ``webmks``. The type
|
``spice-html5``, ``serial``, and ``webmks``. The type
|
||||||
``webmks`` is added since Microversion ``2.8``.
|
``webmks`` is added since Microversion ``2.8``.
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
|
53
api-ref/source/servers-action-rdp-remote-consoles.inc
Normal file
53
api-ref/source/servers-action-rdp-remote-consoles.inc
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
.. -*- rst -*-
|
||||||
|
|
||||||
|
Get RDP Console (os-getRDPConsole Action)
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
.. rest_method:: POST /servers/{server_id}/action
|
||||||
|
max_version: 2.5
|
||||||
|
|
||||||
|
Gets an `RDP <https://technet.microsoft.com/en-us/windowsserver/ee236407>`__ console for a server.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Along with HyperV driver, this action was removed in Nova 29.0.0
|
||||||
|
(caracal) release.
|
||||||
|
|
||||||
|
The only supported connect type is ``rdp-html5``. The ``type`` parameter should
|
||||||
|
be set as ``rdp-html5``.
|
||||||
|
|
||||||
|
Specify the ``os-getRDPConsole`` action in the request body.
|
||||||
|
|
||||||
|
Normal response codes: 200
|
||||||
|
|
||||||
|
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404),
|
||||||
|
conflict(409), notImplemented(501)
|
||||||
|
|
||||||
|
Request
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
|
||||||
|
- server_id: server_id_path
|
||||||
|
- os-getRDPConsole: os-getRDPConsole
|
||||||
|
- type: os-getRDPConsole-type
|
||||||
|
|
||||||
|
**Example Get RDP Console (os-getRDPConsole Action)**
|
||||||
|
|
||||||
|
.. literalinclude:: ../../doc/api_samples/os-remote-consoles/get-rdp-console-post-req.json
|
||||||
|
:language: javascript
|
||||||
|
|
||||||
|
Response
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
|
- console: remote_console
|
||||||
|
- type: os-getRDPConsole-type
|
||||||
|
- url: os-getRDPConsole-url
|
||||||
|
|
||||||
|
**Example Get RDP Console (os-getRDPConsole Action)**
|
||||||
|
|
||||||
|
.. literalinclude:: ../../doc/api_samples/os-remote-consoles/get-rdp-console-post-resp.json
|
||||||
|
:language: javascript
|
@ -1,58 +1,5 @@
|
|||||||
.. -*- rst -*-
|
.. -*- rst -*-
|
||||||
|
|
||||||
Get RDP Console (os-getRDPConsole Action) (DEPRECATED)
|
|
||||||
======================================================
|
|
||||||
|
|
||||||
.. rest_method:: POST /servers/{server_id}/action
|
|
||||||
max_version: 2.5
|
|
||||||
|
|
||||||
Gets an `RDP <https://technet.microsoft.com/en-us/windowsserver/ee236407>`__ console for a server.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
This action is deprecated in microversion 2.5 and superseded
|
|
||||||
by the API `Server Consoles`_ in microversion 2.6.
|
|
||||||
The new API offers a unified API for different console types.
|
|
||||||
|
|
||||||
The only supported connect type is ``rdp-html5``. The ``type`` parameter should
|
|
||||||
be set as ``rdp-html5``.
|
|
||||||
|
|
||||||
Specify the ``os-getRDPConsole`` action in the request body.
|
|
||||||
|
|
||||||
Normal response codes: 200
|
|
||||||
|
|
||||||
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404),
|
|
||||||
conflict(409), notImplemented(501)
|
|
||||||
|
|
||||||
Request
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. rest_parameters:: parameters.yaml
|
|
||||||
|
|
||||||
|
|
||||||
- server_id: server_id_path
|
|
||||||
- os-getRDPConsole: os-getRDPConsole
|
|
||||||
- type: os-getRDPConsole-type
|
|
||||||
|
|
||||||
**Example Get RDP Console (os-getRDPConsole Action)**
|
|
||||||
|
|
||||||
.. literalinclude:: ../../doc/api_samples/os-remote-consoles/get-rdp-console-post-req.json
|
|
||||||
:language: javascript
|
|
||||||
|
|
||||||
Response
|
|
||||||
--------
|
|
||||||
|
|
||||||
.. rest_parameters:: parameters.yaml
|
|
||||||
|
|
||||||
- console: remote_console
|
|
||||||
- type: os-getRDPConsole-type
|
|
||||||
- url: os-getRDPConsole-url
|
|
||||||
|
|
||||||
**Example Get RDP Console (os-getRDPConsole Action)**
|
|
||||||
|
|
||||||
.. literalinclude:: ../../doc/api_samples/os-remote-consoles/get-rdp-console-post-resp.json
|
|
||||||
:language: javascript
|
|
||||||
|
|
||||||
Get Serial Console (os-getSerialConsole Action) (DEPRECATED)
|
Get Serial Console (os-getSerialConsole Action) (DEPRECATED)
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ 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
|
remove a security group from a server. You can also trigger a crash dump
|
||||||
into a server since Mitaka release.
|
into a server since Mitaka release.
|
||||||
|
|
||||||
You can get an RDP, serial, SPICE, or VNC console for a server.
|
You can get an serial, SPICE, or VNC console for a server.
|
||||||
|
|
||||||
|
|
||||||
Add (Associate) Floating Ip (addFloatingIp Action) (DEPRECATED)
|
Add (Associate) Floating Ip (addFloatingIp Action) (DEPRECATED)
|
||||||
|
@ -17,7 +17,7 @@ The API provides a unified request for creating a remote console. The user can
|
|||||||
get a URL to connect the console from this API. The URL includes the token
|
get a URL to connect the console from this API. The URL includes the token
|
||||||
which is used to get permission to access the console. Servers may support
|
which is used to get permission to access the console. Servers may support
|
||||||
different console protocols. To return a remote console using a specific
|
different console protocols. To return a remote console using a specific
|
||||||
protocol, such as RDP, set the ``protocol`` parameter to ``rdp``.
|
protocol, such as VNC, set the ``protocol`` parameter to ``vnc``.
|
||||||
|
|
||||||
Normal response codes: 200
|
Normal response codes: 200
|
||||||
|
|
||||||
|
@ -469,49 +469,6 @@ There are some things to keep in mind when configuring these options:
|
|||||||
proxying the console interaction.
|
proxying the console interaction.
|
||||||
|
|
||||||
|
|
||||||
RDP
|
|
||||||
---
|
|
||||||
|
|
||||||
RDP is a graphical console primarily used with Hyper-V. Nova does not provide a
|
|
||||||
console proxy service for RDP - instead, an external proxy service, such as the
|
|
||||||
:program:`wsgate` application provided by `FreeRDP-WebConnect`__, should be
|
|
||||||
used.
|
|
||||||
|
|
||||||
__ https://github.com/FreeRDP/FreeRDP-WebConnect
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To enable the RDP console service, you must configure both a console proxy
|
|
||||||
service like :program:`wsgate` and the :program:`nova-compute` service. All
|
|
||||||
options for the latter service are defined in the :oslo.config:group:`rdp`
|
|
||||||
group.
|
|
||||||
|
|
||||||
Information on configuring an RDP console proxy service, such as
|
|
||||||
:program:`wsgate`, is not provided here. However, more information can be found
|
|
||||||
at `cloudbase.it`__.
|
|
||||||
|
|
||||||
The :program:`nova-compute` service requires the following options to configure
|
|
||||||
RDP console support.
|
|
||||||
|
|
||||||
- :oslo.config:option:`rdp.enabled`
|
|
||||||
- :oslo.config:option:`rdp.html5_proxy_base_url`
|
|
||||||
|
|
||||||
For example, to configure this via a ``nova.conf`` file:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[rdp]
|
|
||||||
enabled = True
|
|
||||||
html5_proxy_base_url = https://IP_ADDRESS:6083/
|
|
||||||
|
|
||||||
Replace ``IP_ADDRESS`` with the IP address from which the proxy is accessible
|
|
||||||
by the outside world. For example, this may be the management interface IP
|
|
||||||
address of the controller or the VIP.
|
|
||||||
|
|
||||||
__ https://cloudbase.it/freerdp-html5-proxy-windows/
|
|
||||||
|
|
||||||
|
|
||||||
MKS
|
MKS
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -625,4 +582,4 @@ References
|
|||||||
|
|
||||||
.. [1] https://qemu.weilnetz.de/doc/4.2/qemu-doc.html#vnc_005fsec_005fcertificate_005fverify
|
.. [1] https://qemu.weilnetz.de/doc/4.2/qemu-doc.html#vnc_005fsec_005fcertificate_005fverify
|
||||||
.. [2] https://tools.ietf.org/html/rfc3280#section-4.2.1.10
|
.. [2] https://tools.ietf.org/html/rfc3280#section-4.2.1.10
|
||||||
.. [3] https://wiki.libvirt.org/page/VNCTLSSetup#Changes_to_be_made_on_the_virtualisation_host_server
|
.. [3] https://wiki.libvirt.org/page/VNCTLSSetup#Changes_to_be_made_on_the_virtualisation_host_server
|
||||||
|
@ -89,8 +89,8 @@ Method titles spelling and case
|
|||||||
|
|
||||||
The spelling and the case of method names in the title have to match
|
The spelling and the case of method names in the title have to match
|
||||||
what is in the code. For instance, the title for the section on method
|
what is in the code. For instance, the title for the section on method
|
||||||
"Get Rdp Console" should be "Get Rdp Console (os-getRDPConsole Action)"
|
"Get VNC Console" should be "Get VNC Console (os-getVNCConsole Action)"
|
||||||
NOT "Get Rdp Console (Os-Getrdpconsole Action)"
|
NOT "Get VNC Console (Os-Getvncconsole Action)"
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
@ -29,7 +29,6 @@ class RemoteConsolesController(wsgi.Controller):
|
|||||||
self.compute_api = compute.API()
|
self.compute_api = compute.API()
|
||||||
self.handlers = {'vnc': self.compute_api.get_vnc_console,
|
self.handlers = {'vnc': self.compute_api.get_vnc_console,
|
||||||
'spice': self.compute_api.get_spice_console,
|
'spice': self.compute_api.get_spice_console,
|
||||||
'rdp': self.compute_api.get_rdp_console,
|
|
||||||
'serial': self.compute_api.get_serial_console,
|
'serial': self.compute_api.get_serial_console,
|
||||||
'mks': self.compute_api.get_mks_console}
|
'mks': self.compute_api.get_mks_console}
|
||||||
|
|
||||||
@ -95,32 +94,11 @@ class RemoteConsolesController(wsgi.Controller):
|
|||||||
@wsgi.Controller.api_version("2.1", "2.5")
|
@wsgi.Controller.api_version("2.1", "2.5")
|
||||||
@wsgi.expected_errors((400, 404, 409, 501))
|
@wsgi.expected_errors((400, 404, 409, 501))
|
||||||
@wsgi.action('os-getRDPConsole')
|
@wsgi.action('os-getRDPConsole')
|
||||||
@validation.schema(remote_consoles.get_rdp_console)
|
|
||||||
def get_rdp_console(self, req, id, body):
|
def get_rdp_console(self, req, id, body):
|
||||||
"""Get text console output."""
|
"""RDP console was available only for HyperV driver which has been
|
||||||
context = req.environ['nova.context']
|
removed from Nova in 29.0.0 (Caracal) release.
|
||||||
context.can(rc_policies.BASE_POLICY_NAME)
|
"""
|
||||||
|
raise webob.exc.HTTPBadRequest()
|
||||||
# If type is not supplied or unknown, get_rdp_console below will cope
|
|
||||||
console_type = body['os-getRDPConsole'].get('type')
|
|
||||||
|
|
||||||
instance = common.get_instance(self.compute_api, context, id)
|
|
||||||
try:
|
|
||||||
# NOTE(mikal): get_rdp_console() can raise InstanceNotFound, so
|
|
||||||
# we still need to catch it here.
|
|
||||||
output = self.compute_api.get_rdp_console(context,
|
|
||||||
instance,
|
|
||||||
console_type)
|
|
||||||
except exception.ConsoleTypeUnavailable as e:
|
|
||||||
raise webob.exc.HTTPBadRequest(explanation=e.format_message())
|
|
||||||
except exception.InstanceNotFound as e:
|
|
||||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
|
||||||
except exception.InstanceNotReady as e:
|
|
||||||
raise webob.exc.HTTPConflict(explanation=e.format_message())
|
|
||||||
except NotImplementedError:
|
|
||||||
common.raise_feature_not_supported()
|
|
||||||
|
|
||||||
return {'console': {'type': console_type, 'url': output['url']}}
|
|
||||||
|
|
||||||
@wsgi.Controller.api_version("2.1", "2.5")
|
@wsgi.Controller.api_version("2.1", "2.5")
|
||||||
@wsgi.expected_errors((400, 404, 409, 501))
|
@wsgi.expected_errors((400, 404, 409, 501))
|
||||||
|
@ -50,25 +50,6 @@ get_spice_console = {
|
|||||||
'additionalProperties': False,
|
'additionalProperties': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
get_rdp_console = {
|
|
||||||
'type': 'object',
|
|
||||||
'properties': {
|
|
||||||
'os-getRDPConsole': {
|
|
||||||
'type': 'object',
|
|
||||||
'properties': {
|
|
||||||
'type': {
|
|
||||||
'type': 'string',
|
|
||||||
'enum': ['rdp-html5'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'required': ['type'],
|
|
||||||
'additionalProperties': False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'required': ['os-getRDPConsole'],
|
|
||||||
'additionalProperties': False,
|
|
||||||
}
|
|
||||||
|
|
||||||
get_serial_console = {
|
get_serial_console = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
@ -96,12 +77,11 @@ create_v26 = {
|
|||||||
'properties': {
|
'properties': {
|
||||||
'protocol': {
|
'protocol': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['vnc', 'spice', 'rdp', 'serial'],
|
'enum': ['vnc', 'spice', 'serial'],
|
||||||
},
|
},
|
||||||
'type': {
|
'type': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['novnc', 'xvpvnc', 'rdp-html5',
|
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'serial'],
|
||||||
'spice-html5', 'serial'],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'required': ['protocol', 'type'],
|
'required': ['protocol', 'type'],
|
||||||
@ -120,12 +100,12 @@ create_v28 = {
|
|||||||
'properties': {
|
'properties': {
|
||||||
'protocol': {
|
'protocol': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['vnc', 'spice', 'rdp', 'serial', 'mks'],
|
'enum': ['vnc', 'spice', 'serial', 'mks'],
|
||||||
},
|
},
|
||||||
'type': {
|
'type': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ['novnc', 'xvpvnc', 'rdp-html5',
|
'enum': ['novnc', 'xvpvnc', 'spice-html5', 'serial',
|
||||||
'spice-html5', 'serial', 'webmks'],
|
'webmks'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'required': ['protocol', 'type'],
|
'required': ['protocol', 'type'],
|
||||||
|
@ -4854,15 +4854,6 @@ class API:
|
|||||||
instance=instance, console_type=console_type)
|
instance=instance, console_type=console_type)
|
||||||
return {'url': connect_info['access_url']}
|
return {'url': connect_info['access_url']}
|
||||||
|
|
||||||
@check_instance_host()
|
|
||||||
@reject_instance_state(
|
|
||||||
task_state=[task_states.DELETING, task_states.MIGRATING])
|
|
||||||
def get_rdp_console(self, context, instance, console_type):
|
|
||||||
"""Get a url to an instance Console."""
|
|
||||||
connect_info = self.compute_rpcapi.get_rdp_console(context,
|
|
||||||
instance=instance, console_type=console_type)
|
|
||||||
return {'url': connect_info['access_url']}
|
|
||||||
|
|
||||||
@check_instance_host()
|
@check_instance_host()
|
||||||
@reject_instance_state(
|
@reject_instance_state(
|
||||||
task_state=[task_states.DELETING, task_states.MIGRATING])
|
task_state=[task_states.DELETING, task_states.MIGRATING])
|
||||||
|
@ -7337,6 +7337,9 @@ class ComputeManager(manager.Manager):
|
|||||||
|
|
||||||
return connect_info
|
return connect_info
|
||||||
|
|
||||||
|
# TODO(gmann): HyperV virt driver has been removed in Nova 29.0.0
|
||||||
|
# but we need to keep this method to avoid RPC error in case of using
|
||||||
|
# old controller with new compute. This can be removed in RPC API 7.0
|
||||||
@messaging.expected_exceptions(exception.ConsoleTypeInvalid,
|
@messaging.expected_exceptions(exception.ConsoleTypeInvalid,
|
||||||
exception.InstanceNotReady,
|
exception.InstanceNotReady,
|
||||||
exception.InstanceNotFound,
|
exception.InstanceNotFound,
|
||||||
@ -7346,38 +7349,10 @@ class ComputeManager(manager.Manager):
|
|||||||
@wrap_instance_fault
|
@wrap_instance_fault
|
||||||
def get_rdp_console(self, context, console_type, instance):
|
def get_rdp_console(self, context, console_type, instance):
|
||||||
"""Return connection information for a RDP console."""
|
"""Return connection information for a RDP console."""
|
||||||
context = context.elevated()
|
|
||||||
LOG.debug("Getting RDP console", instance=instance)
|
|
||||||
|
|
||||||
if not CONF.rdp.enabled:
|
msg = ("RDP console is applicable for HyperV virt driver only which "
|
||||||
raise exception.ConsoleTypeUnavailable(console_type=console_type)
|
"has been removed in Nova 29.0.0")
|
||||||
|
raise NotImplementedError(msg)
|
||||||
if console_type != 'rdp-html5':
|
|
||||||
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Retrieve connect info from driver, and then decorate with our
|
|
||||||
# access info token
|
|
||||||
console = self.driver.get_rdp_console(context, instance)
|
|
||||||
console_auth = objects.ConsoleAuthToken(
|
|
||||||
context=context,
|
|
||||||
console_type=console_type,
|
|
||||||
host=console.host,
|
|
||||||
port=console.port,
|
|
||||||
internal_access_path=console.internal_access_path,
|
|
||||||
instance_uuid=instance.uuid,
|
|
||||||
access_url_base=CONF.rdp.html5_proxy_base_url,
|
|
||||||
)
|
|
||||||
console_auth.authorize(CONF.consoleauth.token_ttl)
|
|
||||||
connect_info = console.get_connection_info(
|
|
||||||
console_auth.token, console_auth.access_url)
|
|
||||||
|
|
||||||
except exception.InstanceNotFound:
|
|
||||||
if instance.vm_state != vm_states.BUILDING:
|
|
||||||
raise
|
|
||||||
raise exception.InstanceNotReady(instance_id=instance.uuid)
|
|
||||||
|
|
||||||
return connect_info
|
|
||||||
|
|
||||||
@messaging.expected_exceptions(exception.ConsoleTypeInvalid,
|
@messaging.expected_exceptions(exception.ConsoleTypeInvalid,
|
||||||
exception.InstanceNotReady,
|
exception.InstanceNotReady,
|
||||||
@ -7474,8 +7449,6 @@ class ComputeManager(manager.Manager):
|
|||||||
def validate_console_port(self, ctxt, instance, port, console_type):
|
def validate_console_port(self, ctxt, instance, port, console_type):
|
||||||
if console_type == "spice-html5":
|
if console_type == "spice-html5":
|
||||||
console_info = self.driver.get_spice_console(ctxt, instance)
|
console_info = self.driver.get_spice_console(ctxt, instance)
|
||||||
elif console_type == "rdp-html5":
|
|
||||||
console_info = self.driver.get_rdp_console(ctxt, instance)
|
|
||||||
elif console_type == "serial":
|
elif console_type == "serial":
|
||||||
console_info = self.driver.get_serial_console(ctxt, instance)
|
console_info = self.driver.get_serial_console(ctxt, instance)
|
||||||
elif console_type == "webmks":
|
elif console_type == "webmks":
|
||||||
@ -9478,7 +9451,7 @@ class ComputeManager(manager.Manager):
|
|||||||
def _consoles_enabled(self):
|
def _consoles_enabled(self):
|
||||||
"""Returns whether a console is enable."""
|
"""Returns whether a console is enable."""
|
||||||
return (CONF.vnc.enabled or CONF.spice.enabled or
|
return (CONF.vnc.enabled or CONF.spice.enabled or
|
||||||
CONF.rdp.enabled or CONF.serial_console.enabled or
|
CONF.serial_console.enabled or
|
||||||
CONF.mks.enabled)
|
CONF.mks.enabled)
|
||||||
|
|
||||||
def _clean_instance_console_tokens(self, ctxt, instance):
|
def _clean_instance_console_tokens(self, ctxt, instance):
|
||||||
|
@ -837,13 +837,6 @@ class ComputeAPI(object):
|
|||||||
return cctxt.call(ctxt, 'get_spice_console',
|
return cctxt.call(ctxt, 'get_spice_console',
|
||||||
instance=instance, console_type=console_type)
|
instance=instance, console_type=console_type)
|
||||||
|
|
||||||
def get_rdp_console(self, ctxt, instance, console_type):
|
|
||||||
version = self._ver(ctxt, '5.0')
|
|
||||||
cctxt = self.router.client(ctxt).prepare(
|
|
||||||
server=_compute_host(None, instance), version=version)
|
|
||||||
return cctxt.call(ctxt, 'get_rdp_console',
|
|
||||||
instance=instance, console_type=console_type)
|
|
||||||
|
|
||||||
def get_mks_console(self, ctxt, instance, console_type):
|
def get_mks_console(self, ctxt, instance, console_type):
|
||||||
version = self._ver(ctxt, '5.0')
|
version = self._ver(ctxt, '5.0')
|
||||||
cctxt = self.router.client(ctxt).prepare(
|
cctxt = self.router.client(ctxt).prepare(
|
||||||
|
@ -49,7 +49,6 @@ from nova.conf import paths
|
|||||||
from nova.conf import pci
|
from nova.conf import pci
|
||||||
from nova.conf import placement
|
from nova.conf import placement
|
||||||
from nova.conf import quota
|
from nova.conf import quota
|
||||||
from nova.conf import rdp
|
|
||||||
from nova.conf import rpc
|
from nova.conf import rpc
|
||||||
from nova.conf import scheduler
|
from nova.conf import scheduler
|
||||||
from nova.conf import serial_console
|
from nova.conf import serial_console
|
||||||
@ -97,7 +96,6 @@ paths.register_opts(CONF)
|
|||||||
pci.register_opts(CONF)
|
pci.register_opts(CONF)
|
||||||
placement.register_opts(CONF)
|
placement.register_opts(CONF)
|
||||||
quota.register_opts(CONF)
|
quota.register_opts(CONF)
|
||||||
rdp.register_opts(CONF)
|
|
||||||
rpc.register_opts(CONF)
|
rpc.register_opts(CONF)
|
||||||
scheduler.register_opts(CONF)
|
scheduler.register_opts(CONF)
|
||||||
serial_console.register_opts(CONF)
|
serial_console.register_opts(CONF)
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
# Copyright 2015 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
|
||||||
|
|
||||||
rdp_group = cfg.OptGroup(
|
|
||||||
'rdp',
|
|
||||||
title='RDP options',
|
|
||||||
help="""
|
|
||||||
Options under this group enable and configure Remote Desktop Protocol (
|
|
||||||
RDP) related features.
|
|
||||||
|
|
||||||
This group is only relevant to Hyper-V users.
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
RDP_OPTS = [
|
|
||||||
cfg.BoolOpt('enabled',
|
|
||||||
default=False,
|
|
||||||
help="""
|
|
||||||
Enable Remote Desktop Protocol (RDP) related features.
|
|
||||||
|
|
||||||
Hyper-V, unlike the majority of the hypervisors employed on Nova compute
|
|
||||||
nodes, uses RDP instead of VNC and SPICE as a desktop sharing protocol to
|
|
||||||
provide instance console access. This option enables RDP for graphical
|
|
||||||
console access for virtual machines created by Hyper-V.
|
|
||||||
|
|
||||||
**Note:** RDP should only be enabled on compute nodes that support the Hyper-V
|
|
||||||
virtualization platform.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* ``compute_driver``: Must be hyperv.
|
|
||||||
|
|
||||||
"""),
|
|
||||||
|
|
||||||
cfg.URIOpt('html5_proxy_base_url',
|
|
||||||
schemes=['http', 'https'],
|
|
||||||
default='http://127.0.0.1:6083/',
|
|
||||||
help="""
|
|
||||||
The URL an end user would use to connect to the RDP HTML5 console proxy.
|
|
||||||
The console proxy service is called with this token-embedded URL and
|
|
||||||
establishes the connection to the proper instance.
|
|
||||||
|
|
||||||
An RDP HTML5 console proxy service will need to be configured to listen on the
|
|
||||||
address configured here. Typically the console proxy service would be run on a
|
|
||||||
controller node. The localhost address used as default would only work in a
|
|
||||||
single node environment i.e. devstack.
|
|
||||||
|
|
||||||
An RDP HTML5 proxy allows a user to access via the web the text or graphical
|
|
||||||
console of any Windows server or workstation using RDP. RDP HTML5 console
|
|
||||||
proxy services include FreeRDP, wsgate.
|
|
||||||
See https://github.com/FreeRDP/FreeRDP-WebConnect
|
|
||||||
|
|
||||||
Possible values:
|
|
||||||
|
|
||||||
* <scheme>://<ip-address>:<port-number>/
|
|
||||||
|
|
||||||
The scheme must be identical to the scheme configured for the RDP HTML5
|
|
||||||
console proxy service. It is ``http`` or ``https``.
|
|
||||||
|
|
||||||
The IP address must be identical to the address on which the RDP HTML5
|
|
||||||
console proxy service is listening.
|
|
||||||
|
|
||||||
The port must be identical to the port on which the RDP HTML5 console proxy
|
|
||||||
service is listening.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* ``rdp.enabled``: Must be set to ``True`` for ``html5_proxy_base_url`` to be
|
|
||||||
effective.
|
|
||||||
"""),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def register_opts(conf):
|
|
||||||
conf.register_group(rdp_group)
|
|
||||||
conf.register_opts(RDP_OPTS, rdp_group)
|
|
||||||
|
|
||||||
|
|
||||||
def list_opts():
|
|
||||||
return {rdp_group: RDP_OPTS}
|
|
@ -32,10 +32,6 @@ class ConsoleVNC(Console):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ConsoleRDP(Console):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleSpice(Console):
|
class ConsoleSpice(Console):
|
||||||
def __init__(self, host, port, tlsPort, internal_access_path=None):
|
def __init__(self, host, port, tlsPort, internal_access_path=None):
|
||||||
super(ConsoleSpice, self).__init__(host, port, internal_access_path)
|
super(ConsoleSpice, self).__init__(host, port, internal_access_path)
|
||||||
|
@ -30,15 +30,10 @@ remote_consoles_policies = [
|
|||||||
This policy is for ``POST /remote-consoles`` API and below Server actions APIs
|
This policy is for ``POST /remote-consoles`` API and below Server actions APIs
|
||||||
are deprecated:
|
are deprecated:
|
||||||
|
|
||||||
- ``os-getRDPConsole``
|
|
||||||
- ``os-getSerialConsole``
|
- ``os-getSerialConsole``
|
||||||
- ``os-getSPICEConsole``
|
- ``os-getSPICEConsole``
|
||||||
- ``os-getVNCConsole``.""",
|
- ``os-getVNCConsole``.""",
|
||||||
operations=[
|
operations=[
|
||||||
{
|
|
||||||
'method': 'POST',
|
|
||||||
'path': '/servers/{server_id}/action (os-getRDPConsole)'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'method': 'POST',
|
'method': 'POST',
|
||||||
'path': '/servers/{server_id}/action (os-getSerialConsole)'
|
'path': '/servers/{server_id}/action (os-getSerialConsole)'
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"console": {
|
|
||||||
"type": "rdp-html5",
|
|
||||||
"url": "http://127.0.0.1:6083/?token=%(uuid)s"
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"remote_console": {
|
||||||
|
"protocol": "rdp",
|
||||||
|
"type": "rdp-html5"
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,6 @@ class ConsolesSampleJsonTests(test_servers.ServersSampleBase):
|
|||||||
self.api.microversion = self.microversion
|
self.api.microversion = self.microversion
|
||||||
self.flags(enabled=True, group='vnc')
|
self.flags(enabled=True, group='vnc')
|
||||||
self.flags(enabled=True, group='spice')
|
self.flags(enabled=True, group='spice')
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
self.flags(enabled=True, group='serial_console')
|
self.flags(enabled=True, group='serial_console')
|
||||||
|
|
||||||
def test_get_vnc_console(self):
|
def test_get_vnc_console(self):
|
||||||
@ -66,13 +65,13 @@ class ConsolesSampleJsonTests(test_servers.ServersSampleBase):
|
|||||||
self._verify_response('get-spice-console-post-resp', {'url': HTTP_RE},
|
self._verify_response('get-spice-console-post-resp', {'url': HTTP_RE},
|
||||||
response, 200)
|
response, 200)
|
||||||
|
|
||||||
def test_get_rdp_console(self):
|
def test_get_rdp_console_bad_request(self):
|
||||||
|
"""Ensure http 400 error is return from RDP console request"""
|
||||||
uuid = self._post_server()
|
uuid = self._post_server()
|
||||||
response = self._do_post('servers/%s/action' % uuid,
|
response = self._do_post('servers/%s/action' % uuid,
|
||||||
'get-rdp-console-post-req',
|
'get-rdp-console-post-req',
|
||||||
{'action': 'os-getRDPConsole'})
|
{'action': 'os-getRDPConsole'})
|
||||||
self._verify_response('get-rdp-console-post-resp', {'url': HTTP_RE},
|
self.assertEqual(400, response.status_code)
|
||||||
response, 200)
|
|
||||||
|
|
||||||
def test_get_serial_console(self):
|
def test_get_serial_console(self):
|
||||||
uuid = self._post_server()
|
uuid = self._post_server()
|
||||||
@ -100,6 +99,14 @@ class ConsolesV26SampleJsonTests(test_servers.ServersSampleBase):
|
|||||||
self._verify_response('create-vnc-console-resp', {'url': HTTP_RE},
|
self._verify_response('create-vnc-console-resp', {'url': HTTP_RE},
|
||||||
response, 200)
|
response, 200)
|
||||||
|
|
||||||
|
def test_create_rdp_console_bad_request(self):
|
||||||
|
"""Ensure http 400 error is return from RDP console request"""
|
||||||
|
uuid = self._post_server()
|
||||||
|
body = {'protocol': 'rdp', 'type': 'rdp-html5'}
|
||||||
|
response = self._do_post('servers/%s/remote-consoles' % uuid,
|
||||||
|
'create-rdp-console-req', body)
|
||||||
|
self.assertEqual(400, response.status_code)
|
||||||
|
|
||||||
|
|
||||||
class ConsolesV28SampleJsonTests(test_servers.ServersSampleBase):
|
class ConsolesV28SampleJsonTests(test_servers.ServersSampleBase):
|
||||||
sample_dir = "os-remote-consoles"
|
sample_dir = "os-remote-consoles"
|
||||||
|
@ -208,65 +208,12 @@ class ConsolesExtensionTestV21(test.NoDBTestCase):
|
|||||||
self.validation_error,
|
self.validation_error,
|
||||||
body)
|
body)
|
||||||
|
|
||||||
@mock.patch.object(compute_api.API, 'get_rdp_console',
|
def test_get_rdp_console_bad_request(self):
|
||||||
return_value={'url': 'http://fake'})
|
|
||||||
def test_get_rdp_console(self, mock_get_rdp_console):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'rdp-html5'}}
|
body = {'os-getRDPConsole': {'type': 'rdp-html5'}}
|
||||||
req = fakes.HTTPRequest.blank('')
|
req = fakes.HTTPRequest.blank('')
|
||||||
output = self.controller.get_rdp_console(req, fakes.FAKE_UUID,
|
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||||
body=body)
|
self.controller.get_rdp_console,
|
||||||
self.assertEqual(output,
|
req, fakes.FAKE_UUID, body=body)
|
||||||
{u'console': {u'url': u'http://fake', u'type': u'rdp-html5'}})
|
|
||||||
mock_get_rdp_console.assert_called_once_with(
|
|
||||||
req.environ['nova.context'], self.instance, 'rdp-html5')
|
|
||||||
|
|
||||||
def test_get_rdp_console_not_ready(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'rdp-html5'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
webob.exc.HTTPConflict,
|
|
||||||
body,
|
|
||||||
'get_rdp_console',
|
|
||||||
exception.InstanceNotReady(instance_id=fakes.FAKE_UUID))
|
|
||||||
|
|
||||||
def test_get_rdp_console_no_type(self):
|
|
||||||
body = {'os-getRDPConsole': {}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
self.validation_error,
|
|
||||||
body)
|
|
||||||
|
|
||||||
def test_get_rdp_console_no_instance(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'rdp-html5'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
webob.exc.HTTPNotFound,
|
|
||||||
body,
|
|
||||||
'get',
|
|
||||||
exception.InstanceNotFound(instance_id=fakes.FAKE_UUID))
|
|
||||||
|
|
||||||
def test_get_rdp_console_no_instance_on_console_get(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'rdp-html5'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
webob.exc.HTTPNotFound,
|
|
||||||
body,
|
|
||||||
'get_rdp_console',
|
|
||||||
exception.InstanceNotFound(instance_id=fakes.FAKE_UUID))
|
|
||||||
|
|
||||||
def test_get_rdp_console_invalid_type(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'invalid'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
self.validation_error,
|
|
||||||
body)
|
|
||||||
|
|
||||||
def test_get_rdp_console_type_unavailable(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'unavailable'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
self.validation_error,
|
|
||||||
body)
|
|
||||||
|
|
||||||
def test_get_vnc_console_with_undefined_param(self):
|
def test_get_vnc_console_with_undefined_param(self):
|
||||||
body = {'os-getVNCConsole': {'type': 'novnc', 'undefined': 'foo'}}
|
body = {'os-getVNCConsole': {'type': 'novnc', 'undefined': 'foo'}}
|
||||||
@ -283,13 +230,6 @@ class ConsolesExtensionTestV21(test.NoDBTestCase):
|
|||||||
self.validation_error,
|
self.validation_error,
|
||||||
body)
|
body)
|
||||||
|
|
||||||
def test_get_rdp_console_with_undefined_param(self):
|
|
||||||
body = {'os-getRDPConsole': {'type': 'rdp-html5', 'undefined': 'foo'}}
|
|
||||||
self._check_console_failure(
|
|
||||||
self.controller.get_rdp_console,
|
|
||||||
self.validation_error,
|
|
||||||
body)
|
|
||||||
|
|
||||||
@mock.patch.object(compute_api.API, 'get_serial_console',
|
@mock.patch.object(compute_api.API, 'get_serial_console',
|
||||||
return_value={'url': 'ws://fake'})
|
return_value={'url': 'ws://fake'})
|
||||||
def test_get_serial_console(self, mock_get_serial_console):
|
def test_get_serial_console(self, mock_get_serial_console):
|
||||||
@ -412,18 +352,14 @@ class ConsolesExtensionTestV26(test.NoDBTestCase):
|
|||||||
mock_handler.assert_called_once_with(self.context, self.instance,
|
mock_handler.assert_called_once_with(self.context, self.instance,
|
||||||
'spice-html5')
|
'spice-html5')
|
||||||
|
|
||||||
def test_create_rdp_console(self):
|
def test_create_rdp_console_bad_request(self):
|
||||||
mock_handler = mock.MagicMock()
|
mock_handler = mock.MagicMock()
|
||||||
mock_handler.return_value = {'url': "http://fake"}
|
mock_handler.return_value = {'url': "http://fake"}
|
||||||
self.controller.handlers['rdp'] = mock_handler
|
self.controller.handlers['rdp'] = mock_handler
|
||||||
|
|
||||||
body = {'remote_console': {'protocol': 'rdp', 'type': 'rdp-html5'}}
|
body = {'remote_console': {'protocol': 'rdp', 'type': 'rdp-html5'}}
|
||||||
output = self.controller.create(self.req, fakes.FAKE_UUID, body=body)
|
self.assertRaises(exception.ValidationError, self.controller.create,
|
||||||
self.assertEqual({'remote_console': {'protocol': 'rdp',
|
self.req, fakes.FAKE_UUID, body=body)
|
||||||
'type': 'rdp-html5',
|
|
||||||
'url': 'http://fake'}}, output)
|
|
||||||
mock_handler.assert_called_once_with(self.context, self.instance,
|
|
||||||
'rdp-html5')
|
|
||||||
|
|
||||||
def test_create_serial_console(self):
|
def test_create_serial_console(self):
|
||||||
mock_handler = mock.MagicMock()
|
mock_handler = mock.MagicMock()
|
||||||
|
@ -3996,20 +3996,6 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
context=self.context, instance=instance, port="5900",
|
context=self.context, instance=instance, port="5900",
|
||||||
console_type="spice-html5"))
|
console_type="spice-html5"))
|
||||||
|
|
||||||
def test_validate_console_port_rdp(self):
|
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
instance = self._create_fake_instance_obj()
|
|
||||||
|
|
||||||
def fake_driver_get_console(*args, **kwargs):
|
|
||||||
return ctype.ConsoleRDP(host="fake_host", port=5900)
|
|
||||||
|
|
||||||
self.stub_out("nova.virt.fake.FakeDriver.get_rdp_console",
|
|
||||||
fake_driver_get_console)
|
|
||||||
|
|
||||||
self.assertTrue(self.compute.validate_console_port(
|
|
||||||
context=self.context, instance=instance, port="5900",
|
|
||||||
console_type="rdp-html5"))
|
|
||||||
|
|
||||||
def test_validate_console_port_serial(self):
|
def test_validate_console_port_serial(self):
|
||||||
self.flags(enabled=True, group='serial_console')
|
self.flags(enabled=True, group='serial_console')
|
||||||
instance = self._create_fake_instance_obj()
|
instance = self._create_fake_instance_obj()
|
||||||
@ -4197,70 +4183,6 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
|
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
def test_rdphtml5_rdp_console(self):
|
|
||||||
# Make sure we can a rdp console for an instance.
|
|
||||||
self.flags(enabled=False, group='vnc')
|
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
|
|
||||||
instance = self._create_fake_instance_obj()
|
|
||||||
self.compute.build_and_run_instance(self.context,
|
|
||||||
instance, {}, {}, {}, [], block_device_mapping=[])
|
|
||||||
|
|
||||||
# Try with the full instance
|
|
||||||
console = self.compute.get_rdp_console(self.context, 'rdp-html5',
|
|
||||||
instance=instance)
|
|
||||||
self.assertTrue(console)
|
|
||||||
|
|
||||||
# Verify that the console auth has also been stored in the
|
|
||||||
# database backend.
|
|
||||||
auth = objects.ConsoleAuthToken.validate(self.context,
|
|
||||||
console['token'])
|
|
||||||
self.assertIsNotNone(auth)
|
|
||||||
|
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
|
||||||
|
|
||||||
def test_invalid_rdp_console_type(self):
|
|
||||||
# Raise useful error if console type is an unrecognised string
|
|
||||||
self.flags(enabled=False, group='vnc')
|
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
|
|
||||||
instance = self._create_fake_instance_obj()
|
|
||||||
self.compute.build_and_run_instance(self.context,
|
|
||||||
instance, {}, {}, {}, [], block_device_mapping=[])
|
|
||||||
|
|
||||||
self.assertRaises(messaging.ExpectedException,
|
|
||||||
self.compute.get_rdp_console,
|
|
||||||
self.context, 'invalid', instance=instance)
|
|
||||||
|
|
||||||
self.compute = utils.ExceptionHelper(self.compute)
|
|
||||||
|
|
||||||
self.assertRaises(exception.ConsoleTypeInvalid,
|
|
||||||
self.compute.get_rdp_console,
|
|
||||||
self.context, 'invalid', instance=instance)
|
|
||||||
|
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
|
||||||
|
|
||||||
def test_missing_rdp_console_type(self):
|
|
||||||
# Raise useful error is console type is None
|
|
||||||
self.flags(enabled=False, group='vnc')
|
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
|
|
||||||
instance = self._create_fake_instance_obj()
|
|
||||||
self.compute.build_and_run_instance(self.context,
|
|
||||||
instance, {}, {}, {}, [], block_device_mapping=[])
|
|
||||||
|
|
||||||
self.assertRaises(messaging.ExpectedException,
|
|
||||||
self.compute.get_rdp_console,
|
|
||||||
self.context, None, instance=instance)
|
|
||||||
|
|
||||||
self.compute = utils.ExceptionHelper(self.compute)
|
|
||||||
|
|
||||||
self.assertRaises(exception.ConsoleTypeInvalid,
|
|
||||||
self.compute.get_rdp_console,
|
|
||||||
self.context, None, instance=instance)
|
|
||||||
|
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
|
||||||
|
|
||||||
def test_vnc_console_instance_not_ready(self):
|
def test_vnc_console_instance_not_ready(self):
|
||||||
self.flags(enabled=True, group='vnc')
|
self.flags(enabled=True, group='vnc')
|
||||||
self.flags(enabled=False, group='spice')
|
self.flags(enabled=False, group='spice')
|
||||||
@ -4297,24 +4219,6 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
self.compute.get_spice_console, self.context, 'spice-html5',
|
self.compute.get_spice_console, self.context, 'spice-html5',
|
||||||
instance=instance)
|
instance=instance)
|
||||||
|
|
||||||
def test_rdp_console_instance_not_ready(self):
|
|
||||||
self.flags(enabled=False, group='vnc')
|
|
||||||
self.flags(enabled=True, group='rdp')
|
|
||||||
instance = self._create_fake_instance_obj(
|
|
||||||
params={'vm_state': vm_states.BUILDING})
|
|
||||||
|
|
||||||
def fake_driver_get_console(*args, **kwargs):
|
|
||||||
raise exception.InstanceNotFound(instance_id=instance['uuid'])
|
|
||||||
|
|
||||||
self.stub_out("nova.virt.fake.FakeDriver.get_rdp_console",
|
|
||||||
fake_driver_get_console)
|
|
||||||
|
|
||||||
self.compute = utils.ExceptionHelper(self.compute)
|
|
||||||
|
|
||||||
self.assertRaises(exception.InstanceNotReady,
|
|
||||||
self.compute.get_rdp_console, self.context, 'rdp-html5',
|
|
||||||
instance=instance)
|
|
||||||
|
|
||||||
def test_vnc_console_disabled(self):
|
def test_vnc_console_disabled(self):
|
||||||
self.flags(enabled=False, group='vnc')
|
self.flags(enabled=False, group='vnc')
|
||||||
instance = self._create_fake_instance_obj(
|
instance = self._create_fake_instance_obj(
|
||||||
@ -4337,17 +4241,6 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
self.compute.get_spice_console, self.context, 'spice-html5',
|
self.compute.get_spice_console, self.context, 'spice-html5',
|
||||||
instance=instance)
|
instance=instance)
|
||||||
|
|
||||||
def test_rdp_console_disabled(self):
|
|
||||||
self.flags(enabled=False, group='rdp')
|
|
||||||
instance = self._create_fake_instance_obj(
|
|
||||||
params={'vm_state': vm_states.BUILDING})
|
|
||||||
|
|
||||||
self.compute = utils.ExceptionHelper(self.compute)
|
|
||||||
|
|
||||||
self.assertRaises(exception.ConsoleTypeUnavailable,
|
|
||||||
self.compute.get_rdp_console, self.context, 'rdp-html5',
|
|
||||||
instance=instance)
|
|
||||||
|
|
||||||
def test_diagnostics(self):
|
def test_diagnostics(self):
|
||||||
# Make sure we can get diagnostics for an instance.
|
# Make sure we can get diagnostics for an instance.
|
||||||
expected_diagnostic = {'cpu0_time': 17300000000,
|
expected_diagnostic = {'cpu0_time': 17300000000,
|
||||||
@ -10282,8 +10175,6 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
|
|
||||||
@ddt.data(('spice', task_states.DELETING),
|
@ddt.data(('spice', task_states.DELETING),
|
||||||
('spice', task_states.MIGRATING),
|
('spice', task_states.MIGRATING),
|
||||||
('rdp', task_states.DELETING),
|
|
||||||
('rdp', task_states.MIGRATING),
|
|
||||||
('vnc', task_states.DELETING),
|
('vnc', task_states.DELETING),
|
||||||
('vnc', task_states.MIGRATING),
|
('vnc', task_states.MIGRATING),
|
||||||
('mks', task_states.DELETING),
|
('mks', task_states.DELETING),
|
||||||
@ -10299,36 +10190,6 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
getattr(self.compute_api, 'get_%s_console' % console_type),
|
getattr(self.compute_api, 'get_%s_console' % console_type),
|
||||||
self.context, instance, console_type)
|
self.context, instance, console_type)
|
||||||
|
|
||||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_rdp_console')
|
|
||||||
def test_rdp_console(self, mock_rdp):
|
|
||||||
# Make sure we can a rdp console for an instance.
|
|
||||||
fake_instance = self._fake_instance({
|
|
||||||
'uuid': 'f3000000-0000-0000-0000-000000000000',
|
|
||||||
'host': 'fake_compute_host'})
|
|
||||||
fake_console_type = "rdp-html5"
|
|
||||||
fake_connect_info = {'token': 'fake_token',
|
|
||||||
'console_type': fake_console_type,
|
|
||||||
'host': 'fake_console_host',
|
|
||||||
'port': 'fake_console_port',
|
|
||||||
'internal_access_path': 'fake_access_path',
|
|
||||||
'instance_uuid': fake_instance.uuid,
|
|
||||||
'access_url': 'fake_console_url'}
|
|
||||||
mock_rdp.return_value = fake_connect_info
|
|
||||||
|
|
||||||
console = self.compute_api.get_rdp_console(self.context,
|
|
||||||
fake_instance, fake_console_type)
|
|
||||||
|
|
||||||
self.assertEqual(console, {'url': 'fake_console_url'})
|
|
||||||
mock_rdp.assert_called_once_with(self.context, instance=fake_instance,
|
|
||||||
console_type=fake_console_type)
|
|
||||||
|
|
||||||
def test_get_rdp_console_no_host(self):
|
|
||||||
instance = self._create_fake_instance_obj(params={'host': ''})
|
|
||||||
|
|
||||||
self.assertRaises(exception.InstanceNotReady,
|
|
||||||
self.compute_api.get_rdp_console,
|
|
||||||
self.context, instance, 'rdp')
|
|
||||||
|
|
||||||
def test_serial_console(self):
|
def test_serial_console(self):
|
||||||
# Make sure we can get a serial proxy url for an instance.
|
# Make sure we can get a serial proxy url for an instance.
|
||||||
|
|
||||||
|
@ -6034,19 +6034,18 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
self.assertEqual(args[1], self.compute.host)
|
self.assertEqual(args[1], self.compute.host)
|
||||||
self.assertEqual(args[2], mock.sentinel.inst_uuid)
|
self.assertEqual(args[2], mock.sentinel.inst_uuid)
|
||||||
|
|
||||||
@ddt.data(('vnc', 'spice', 'rdp', 'serial_console', 'mks'),
|
@ddt.data(('vnc', 'spice', 'serial_console', 'mks'),
|
||||||
('spice', 'vnc', 'rdp', 'serial_console', 'mks'),
|
('spice', 'vnc', 'serial_console', 'mks'),
|
||||||
('rdp', 'vnc', 'spice', 'serial_console', 'mks'),
|
('serial_console', 'vnc', 'spice', 'mks'),
|
||||||
('serial_console', 'vnc', 'spice', 'rdp', 'mks'),
|
('mks', 'vnc', 'spice', 'serial_console'))
|
||||||
('mks', 'vnc', 'spice', 'rdp', 'serial_console'))
|
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
@mock.patch('nova.objects.ConsoleAuthToken.'
|
@mock.patch('nova.objects.ConsoleAuthToken.'
|
||||||
'clean_console_auths_for_instance')
|
'clean_console_auths_for_instance')
|
||||||
def test_clean_instance_console_tokens(self, g1, g2, g3, g4, g5,
|
def test_clean_instance_console_tokens(self, g1, g2, g3, g4,
|
||||||
mock_clean):
|
mock_clean):
|
||||||
# Enable one of each of the console types and disable the rest
|
# Enable one of each of the console types and disable the rest
|
||||||
self.flags(enabled=True, group=g1)
|
self.flags(enabled=True, group=g1)
|
||||||
for g in [g2, g3, g4, g5]:
|
for g in [g2, g3, g4]:
|
||||||
self.flags(enabled=False, group=g)
|
self.flags(enabled=False, group=g)
|
||||||
instance = objects.Instance(uuid=uuids.instance)
|
instance = objects.Instance(uuid=uuids.instance)
|
||||||
self.compute._clean_instance_console_tokens(self.context, instance)
|
self.compute._clean_instance_console_tokens(self.context, instance)
|
||||||
@ -6056,7 +6055,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
'clean_console_auths_for_instance')
|
'clean_console_auths_for_instance')
|
||||||
def test_clean_instance_console_tokens_no_consoles_enabled(self,
|
def test_clean_instance_console_tokens_no_consoles_enabled(self,
|
||||||
mock_clean):
|
mock_clean):
|
||||||
for g in ['vnc', 'spice', 'rdp', 'serial_console', 'mks']:
|
for g in ['vnc', 'spice', 'serial_console', 'mks']:
|
||||||
self.flags(enabled=False, group=g)
|
self.flags(enabled=False, group=g)
|
||||||
instance = objects.Instance(uuid=uuids.instance)
|
instance = objects.Instance(uuid=uuids.instance)
|
||||||
self.compute._clean_instance_console_tokens(self.context, instance)
|
self.compute._clean_instance_console_tokens(self.context, instance)
|
||||||
@ -9843,7 +9842,6 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
|
|||||||
def test_consoles_enabled(self):
|
def test_consoles_enabled(self):
|
||||||
self.flags(enabled=False, group='vnc')
|
self.flags(enabled=False, group='vnc')
|
||||||
self.flags(enabled=False, group='spice')
|
self.flags(enabled=False, group='spice')
|
||||||
self.flags(enabled=False, group='rdp')
|
|
||||||
self.flags(enabled=False, group='serial_console')
|
self.flags(enabled=False, group='serial_console')
|
||||||
self.assertFalse(self.compute._consoles_enabled())
|
self.assertFalse(self.compute._consoles_enabled())
|
||||||
|
|
||||||
@ -9851,7 +9849,7 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase,
|
|||||||
self.assertTrue(self.compute._consoles_enabled())
|
self.assertTrue(self.compute._consoles_enabled())
|
||||||
self.flags(enabled=False, group='vnc')
|
self.flags(enabled=False, group='vnc')
|
||||||
|
|
||||||
for console in ['spice', 'rdp', 'serial_console']:
|
for console in ['spice', 'serial_console']:
|
||||||
self.flags(enabled=True, group=console)
|
self.flags(enabled=True, group=console)
|
||||||
self.assertTrue(self.compute._consoles_enabled())
|
self.assertTrue(self.compute._consoles_enabled())
|
||||||
self.flags(enabled=False, group=console)
|
self.flags(enabled=False, group=console)
|
||||||
|
@ -355,11 +355,6 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
instance=self.fake_instance_obj, console_type='type',
|
instance=self.fake_instance_obj, console_type='type',
|
||||||
version='6.0')
|
version='6.0')
|
||||||
|
|
||||||
def test_get_rdp_console(self):
|
|
||||||
self._test_compute_api('get_rdp_console', 'call',
|
|
||||||
instance=self.fake_instance_obj, console_type='type',
|
|
||||||
version='6.0')
|
|
||||||
|
|
||||||
def test_get_serial_console(self):
|
def test_get_serial_console(self):
|
||||||
self._test_compute_api('get_serial_console', 'call',
|
self._test_compute_api('get_serial_console', 'call',
|
||||||
instance=self.fake_instance_obj, console_type='serial',
|
instance=self.fake_instance_obj, console_type='serial',
|
||||||
|
@ -42,11 +42,6 @@ class TypeTestCase(test.NoDBTestCase):
|
|||||||
|
|
||||||
self.assertIsInstance(c, ctype.Console)
|
self.assertIsInstance(c, ctype.Console)
|
||||||
|
|
||||||
def test_console_rdp(self):
|
|
||||||
c = ctype.ConsoleRDP(host='127.0.0.1', port=8945)
|
|
||||||
|
|
||||||
self.assertIsInstance(c, ctype.Console)
|
|
||||||
|
|
||||||
def test_console_spice(self):
|
def test_console_spice(self):
|
||||||
c = ctype.ConsoleSpice(host='127.0.0.1', port=8945, tlsPort=6547)
|
c = ctype.ConsoleSpice(host='127.0.0.1', port=8945, tlsPort=6547)
|
||||||
|
|
||||||
|
@ -541,12 +541,6 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
|
|||||||
instance_ref)
|
instance_ref)
|
||||||
self.assertIsInstance(spice_console, ctype.ConsoleSpice)
|
self.assertIsInstance(spice_console, ctype.ConsoleSpice)
|
||||||
|
|
||||||
@catch_notimplementederror
|
|
||||||
def test_get_rdp_console(self):
|
|
||||||
instance_ref, network_info = self._get_running_instance()
|
|
||||||
rdp_console = self.connection.get_rdp_console(self.ctxt, instance_ref)
|
|
||||||
self.assertIsInstance(rdp_console, ctype.ConsoleRDP)
|
|
||||||
|
|
||||||
@catch_notimplementederror
|
@catch_notimplementederror
|
||||||
def test_get_serial_console(self):
|
def test_get_serial_console(self):
|
||||||
self.flags(enabled=True, group='serial_console')
|
self.flags(enabled=True, group='serial_console')
|
||||||
|
@ -547,16 +547,6 @@ class ComputeDriver(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_rdp_console(self, context, instance):
|
|
||||||
"""Get connection info for a rdp console.
|
|
||||||
|
|
||||||
:param context: security context
|
|
||||||
:param instance: nova.objects.instance.Instance
|
|
||||||
|
|
||||||
:returns: an instance of console.type.ConsoleRDP
|
|
||||||
"""
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def get_serial_console(self, context, instance):
|
def get_serial_console(self, context, instance):
|
||||||
"""Get connection info for a serial console.
|
"""Get connection info for a serial console.
|
||||||
|
|
||||||
|
@ -467,11 +467,6 @@ class FakeDriver(driver.ComputeDriver):
|
|||||||
port=6969,
|
port=6969,
|
||||||
tlsPort=6970)
|
tlsPort=6970)
|
||||||
|
|
||||||
def get_rdp_console(self, context, instance):
|
|
||||||
return ctype.ConsoleRDP(internal_access_path='FAKE',
|
|
||||||
host='fakerdpconsole.com',
|
|
||||||
port=6969)
|
|
||||||
|
|
||||||
def get_serial_console(self, context, instance):
|
def get_serial_console(self, context, instance):
|
||||||
return ctype.ConsoleSerial(internal_access_path='FAKE',
|
return ctype.ConsoleSerial(internal_access_path='FAKE',
|
||||||
host='fakerdpconsole.com',
|
host='fakerdpconsole.com',
|
||||||
|
@ -6,15 +6,24 @@ upgrade:
|
|||||||
maintainers. In addition, it has a dependency on the OpenStack Winstacker
|
maintainers. In addition, it has a dependency on the OpenStack Winstacker
|
||||||
project that also has been retired.
|
project that also has been retired.
|
||||||
|
|
||||||
The RDP console was only available for the HyperV driver, therefore its
|
The RDP console was only available for the HyperV driver, therefore the
|
||||||
connection information via below API ``os-console-auth-tokens`` will now
|
RDP console related APIs below will return HTTP ``400 (BadRequest)`` error:
|
||||||
return HTTP ``400 (BadRequest)`` error:
|
|
||||||
|
|
||||||
* Show Console Connection Information:
|
* GET RDP console:
|
||||||
GET /os-console-auth-tokens/{console_token}
|
|
||||||
|
* Server Action Get RDP Console:
|
||||||
|
POST /servers/{server_id}/action (os-getRDPConsole Action)
|
||||||
|
|
||||||
|
* RDP protocol support from remote console API:
|
||||||
|
POST /servers/{server_id}/remote-consoles
|
||||||
|
|
||||||
|
* GET RDP console connection information:
|
||||||
|
|
||||||
|
* Show Console Connection Information:
|
||||||
|
GET /os-console-auth-tokens/{console_token}
|
||||||
|
|
||||||
The following config options which only apply for the ``HyperV`` virt
|
The following config options which only apply for the ``HyperV`` virt
|
||||||
driver also been removed:
|
driver or RDP console APIs also have been removed:
|
||||||
|
|
||||||
* ``[hyperv] dynamic_memory_ratio``
|
* ``[hyperv] dynamic_memory_ratio``
|
||||||
* ``[hyperv] enable_instance_metrics_collection``
|
* ``[hyperv] enable_instance_metrics_collection``
|
||||||
@ -34,3 +43,5 @@ upgrade:
|
|||||||
* ``[hyperv] enable_remotefx``
|
* ``[hyperv] enable_remotefx``
|
||||||
* ``[hyperv] use_multipath_io``
|
* ``[hyperv] use_multipath_io``
|
||||||
* ``[hyperv] iscsi_initiator_list``
|
* ``[hyperv] iscsi_initiator_list``
|
||||||
|
* ``[rdp] enabled``
|
||||||
|
* ``[rdp] html5_proxy_base_url``
|
||||||
|
Loading…
Reference in New Issue
Block a user