Remove nova-consoleauth
Obliterate all references to the aforementioned service. This mostly consists of removing the core service and any references to the now removed '[workarounds] enable_consoleauth' configuration option. Part of blueprint remove-consoleauth Change-Id: I0498599fd636aa9e30df932f0d893db5efa23260 Signed-off-by: Stephen Finucane <sfinucan@redhat.com> Depends-On: Icfc175c49a1fc650d1c9ad06b77209a70c6386db
This commit is contained in:
parent
bedaeab074
commit
2398b78df5
@ -17,7 +17,6 @@ import webob
|
||||
|
||||
from nova.api.openstack import wsgi
|
||||
import nova.conf
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context as nova_context
|
||||
from nova.i18n import _
|
||||
from nova import objects
|
||||
@ -27,9 +26,6 @@ CONF = nova.conf.CONF
|
||||
|
||||
|
||||
class ConsoleAuthTokensController(wsgi.Controller):
|
||||
def __init__(self):
|
||||
super(ConsoleAuthTokensController, self).__init__()
|
||||
self._consoleauth_rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
|
||||
def _show(self, req, id, rdp_only):
|
||||
"""Checks a console auth token and returns the related connect info."""
|
||||
@ -42,21 +38,19 @@ class ConsoleAuthTokensController(wsgi.Controller):
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
connect_info = None
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
connect_info = self._consoleauth_rpcapi.check_token(context, token)
|
||||
else:
|
||||
results = nova_context.scatter_gather_skip_cell0(
|
||||
context, objects.ConsoleAuthToken.validate, token)
|
||||
# NOTE(melwitt): Console token auths are stored in cell databases,
|
||||
# but with only the token as a request param, we can't know which
|
||||
# cell database contains the token's corresponding connection info.
|
||||
# So, we must query all cells for the info and we can break the
|
||||
# loop as soon as we find a result because the token is associated
|
||||
# with one instance, which can only be in one cell.
|
||||
for result in results.values():
|
||||
if not nova_context.is_cell_failure_sentinel(result):
|
||||
connect_info = result.to_dict()
|
||||
break
|
||||
|
||||
results = nova_context.scatter_gather_skip_cell0(
|
||||
context, objects.ConsoleAuthToken.validate, token)
|
||||
# NOTE(melwitt): Console token auths are stored in cell databases,
|
||||
# but with only the token as a request param, we can't know which
|
||||
# cell database contains the token's corresponding connection info.
|
||||
# So, we must query all cells for the info and we can break the
|
||||
# loop as soon as we find a result because the token is associated
|
||||
# with one instance, which can only be in one cell.
|
||||
for result in results.values():
|
||||
if not nova_context.is_cell_failure_sentinel(result):
|
||||
connect_info = result.to_dict()
|
||||
break
|
||||
|
||||
if not connect_info:
|
||||
raise webob.exc.HTTPNotFound(explanation=_("Token not found"))
|
||||
|
@ -53,9 +53,6 @@ class HostController(wsgi.Controller):
|
||||
| {'host_name': 'some.celly.host.name',
|
||||
| 'service': 'cells',
|
||||
| 'zone': 'internal'},
|
||||
| {'host_name': 'console1.host.com',
|
||||
| 'service': 'consoleauth',
|
||||
| 'zone': 'internal'},
|
||||
| {'host_name': 'network1.host.com',
|
||||
| 'service': 'network',
|
||||
| 'zone': 'internal'},
|
||||
|
@ -1,50 +0,0 @@
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
"""VNC Console Proxy Server."""
|
||||
|
||||
import sys
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_reports import guru_meditation_report as gmr
|
||||
from oslo_reports import opts as gmr_opts
|
||||
|
||||
import nova.conf
|
||||
from nova import config
|
||||
from nova.consoleauth import rpcapi
|
||||
from nova import objects
|
||||
from nova import service
|
||||
from nova import version
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
LOG = logging.getLogger('nova.consoleauth')
|
||||
|
||||
|
||||
def main():
|
||||
config.parse_args(sys.argv)
|
||||
logging.setup(CONF, "nova")
|
||||
objects.register_all()
|
||||
gmr_opts.set_defaults(CONF)
|
||||
|
||||
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
|
||||
|
||||
LOG.warning('The nova-consoleauth service is deprecated as console token '
|
||||
'authorization storage has moved from the nova-consoleauth '
|
||||
'service backend to the database backend.')
|
||||
|
||||
server = service.Service.create(binary='nova-consoleauth',
|
||||
topic=rpcapi.RPC_TOPIC)
|
||||
service.serve(server)
|
||||
service.wait()
|
@ -51,7 +51,6 @@ from nova.compute.utils import wrap_instance_event
|
||||
from nova.compute import vm_states
|
||||
from nova import conductor
|
||||
import nova.conf
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context as nova_context
|
||||
from nova import crypto
|
||||
from nova.db import base
|
||||
@ -259,7 +258,6 @@ class API(base.Base):
|
||||
self._placementclient = None # Lazy-load on first access.
|
||||
self.security_group_api = (security_group_api or
|
||||
openstack_driver.get_openstack_security_group_driver())
|
||||
self.consoleauth_rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self.compute_task_api = conductor.ComputeTaskAPI()
|
||||
self.servicegroup_api = servicegroup.API()
|
||||
@ -2066,13 +2064,6 @@ class API(base.Base):
|
||||
instance.progress = 0
|
||||
instance.save()
|
||||
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
# TODO(melwitt): Remove the conditions for running this line
|
||||
# with cells v2, when consoleauth is no longer being used by
|
||||
# cells v2, in Stein.
|
||||
self.consoleauth_rpcapi.delete_tokens_for_instance(
|
||||
context, instance.uuid)
|
||||
|
||||
if not instance.host and not may_have_ports_or_volumes:
|
||||
try:
|
||||
with compute_utils.notify_about_instance_delete(
|
||||
@ -3803,18 +3794,6 @@ class API(base.Base):
|
||||
"""Get a url to an instance Console."""
|
||||
connect_info = self.compute_rpcapi.get_vnc_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
|
||||
# TODO(melwitt): In Rocky, the compute manager puts the
|
||||
# console authorization in the database in the above method.
|
||||
# The following will be removed when everything has been
|
||||
# converted to use the database, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type,
|
||||
connect_info['host'], connect_info['port'],
|
||||
connect_info['internal_access_path'], instance.uuid,
|
||||
access_url=connect_info['access_url'])
|
||||
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@check_instance_host
|
||||
@ -3824,17 +3803,6 @@ class API(base.Base):
|
||||
"""Get a url to an instance Console."""
|
||||
connect_info = self.compute_rpcapi.get_spice_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
# TODO(melwitt): In Rocky, the compute manager puts the
|
||||
# console authorization in the database in the above method.
|
||||
# The following will be removed when everything has been
|
||||
# converted to use the database, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type,
|
||||
connect_info['host'], connect_info['port'],
|
||||
connect_info['internal_access_path'], instance.uuid,
|
||||
access_url=connect_info['access_url'])
|
||||
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@check_instance_host
|
||||
@ -3844,17 +3812,6 @@ class API(base.Base):
|
||||
"""Get a url to an instance Console."""
|
||||
connect_info = self.compute_rpcapi.get_rdp_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
# TODO(melwitt): In Rocky, the compute manager puts the
|
||||
# console authorization in the database in the above method.
|
||||
# The following will be removed when everything has been
|
||||
# converted to use the database, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type,
|
||||
connect_info['host'], connect_info['port'],
|
||||
connect_info['internal_access_path'], instance.uuid,
|
||||
access_url=connect_info['access_url'])
|
||||
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@check_instance_host
|
||||
@ -3864,17 +3821,6 @@ class API(base.Base):
|
||||
"""Get a url to a serial console."""
|
||||
connect_info = self.compute_rpcapi.get_serial_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
|
||||
# TODO(melwitt): In Rocky, the compute manager puts the
|
||||
# console authorization in the database in the above method.
|
||||
# The following will be removed when everything has been
|
||||
# converted to use the database, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type,
|
||||
connect_info['host'], connect_info['port'],
|
||||
connect_info['internal_access_path'], instance.uuid,
|
||||
access_url=connect_info['access_url'])
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@check_instance_host
|
||||
@ -3884,16 +3830,6 @@ class API(base.Base):
|
||||
"""Get a url to a MKS console."""
|
||||
connect_info = self.compute_rpcapi.get_mks_console(context,
|
||||
instance=instance, console_type=console_type)
|
||||
# TODO(melwitt): In Rocky, the compute manager puts the
|
||||
# console authorization in the database in the above method.
|
||||
# The following will be removed when everything has been
|
||||
# converted to use the database, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type,
|
||||
connect_info['host'], connect_info['port'],
|
||||
connect_info['internal_access_path'], instance.uuid,
|
||||
access_url=connect_info['access_url'])
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
@check_instance_host
|
||||
@ -4493,15 +4429,6 @@ class API(base.Base):
|
||||
self._record_action_start(context, instance,
|
||||
instance_actions.LIVE_MIGRATION)
|
||||
|
||||
# TODO(melwitt): In Rocky, we optionally store console authorizations
|
||||
# in both the consoleauth service and the database while
|
||||
# we convert to using the database. Remove the condition for running
|
||||
# this line with cells v2, when consoleauth is no longer being used by
|
||||
# cells v2, in Stein.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
self.consoleauth_rpcapi.delete_tokens_for_instance(
|
||||
context, instance.uuid)
|
||||
|
||||
# NOTE(sbauza): Force is a boolean by the new related API version
|
||||
if force is False and host_name:
|
||||
# Unset the host to make sure we call the scheduler
|
||||
|
@ -1289,7 +1289,7 @@ registered in the database as an enabled service. Sometimes it can be useful
|
||||
to register new compute services in disabled state and then enabled them at a
|
||||
later point in time. This option only sets this behavior for nova-compute
|
||||
services, it does not auto-disable other services like nova-conductor,
|
||||
nova-scheduler, nova-consoleauth, or nova-osapi_compute.
|
||||
nova-scheduler, or nova-osapi_compute.
|
||||
|
||||
Possible values:
|
||||
|
||||
|
@ -32,10 +32,6 @@ The lifetime of a console auth token (in seconds).
|
||||
A console auth token is used in authorizing console access for a user.
|
||||
Once the auth token time to live count has elapsed, the token is
|
||||
considered expired. Expired tokens are then deleted.
|
||||
|
||||
Related options:
|
||||
|
||||
* ``[workarounds]/enable_consoleauth``
|
||||
""")
|
||||
]
|
||||
|
||||
|
@ -108,24 +108,6 @@ Console RPC API version cap.
|
||||
|
||||
Possible values:
|
||||
|
||||
* By default send the latest version the client knows about
|
||||
* A string representing a version number in the format 'N.N';
|
||||
for example, possible values might be '1.12' or '2.0'.
|
||||
* An OpenStack release name, in lower case, such as 'mitaka' or
|
||||
'liberty'.
|
||||
"""),
|
||||
cfg.StrOpt('consoleauth',
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since='18.0.0',
|
||||
deprecated_reason="""
|
||||
The nova-consoleauth service was deprecated in 18.0.0 (Rocky) and will be
|
||||
removed in an upcoming release.
|
||||
""",
|
||||
help="""
|
||||
Consoleauth RPC API version cap.
|
||||
|
||||
Possible values:
|
||||
|
||||
* By default send the latest version the client knows about
|
||||
* A string representing a version number in the format 'N.N';
|
||||
for example, possible values might be '1.12' or '2.0'.
|
||||
|
@ -154,38 +154,6 @@ Related options:
|
||||
compute service to the scheduler service.
|
||||
"""),
|
||||
|
||||
cfg.BoolOpt(
|
||||
'enable_consoleauth',
|
||||
default=False,
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since="18.0.0",
|
||||
deprecated_reason="""
|
||||
This option has been added as deprecated originally because it is used
|
||||
for avoiding a upgrade issue and it will not be used in the future.
|
||||
See the help text for more details.
|
||||
""",
|
||||
help="""
|
||||
Enable the consoleauth service to avoid resetting unexpired consoles.
|
||||
|
||||
Console token authorizations have moved from the ``nova-consoleauth`` service
|
||||
to the database, so all new consoles will be supported by the database backend.
|
||||
With this, consoles that existed before database backend support will be reset.
|
||||
For most operators, this should be a minimal disruption as the default TTL of a
|
||||
console token is 10 minutes.
|
||||
|
||||
Operators that have much longer token TTL configured or otherwise wish to avoid
|
||||
immediately resetting all existing consoles can enable this flag to continue
|
||||
using the ``nova-consoleauth`` service in addition to the database backend.
|
||||
Once all of the old ``nova-consoleauth`` supported console tokens have expired,
|
||||
this flag should be disabled. For example, if a deployment has configured a
|
||||
token TTL of one hour, the operator may disable the flag, one hour after
|
||||
deploying the new code during an upgrade.
|
||||
|
||||
Related options:
|
||||
|
||||
* ``[consoleauth]/token_ttl``
|
||||
"""),
|
||||
|
||||
cfg.BoolOpt(
|
||||
'enable_numa_live_migration',
|
||||
default=False,
|
||||
|
@ -30,7 +30,6 @@ import websockify
|
||||
|
||||
from nova.compute import rpcapi as compute_rpcapi
|
||||
import nova.conf
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
@ -125,14 +124,8 @@ class NovaProxyRequestHandlerBase(object):
|
||||
str(port),
|
||||
console_type)
|
||||
|
||||
def _get_connect_info_consoleauth(self, ctxt, token):
|
||||
# NOTE(PaulMurray) consoleauth check_token() validates the token
|
||||
# and does an rpc to compute manager to check the console port
|
||||
# is correct.
|
||||
rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
return rpcapi.check_token(ctxt, token=token)
|
||||
|
||||
def _get_connect_info_database(self, ctxt, token):
|
||||
def _get_connect_info(self, ctxt, token):
|
||||
"""Validate the token and get the connect info."""
|
||||
# NOTE(PaulMurray) ConsoleAuthToken.validate validates the token.
|
||||
# We call the compute manager directly to check the console port
|
||||
# is correct.
|
||||
@ -147,25 +140,6 @@ class NovaProxyRequestHandlerBase(object):
|
||||
|
||||
return connect_info
|
||||
|
||||
def _get_connect_info(self, ctxt, token):
|
||||
"""Validate the token and get the connect info."""
|
||||
connect_info = None
|
||||
|
||||
# NOTE(melwitt): If consoleauth is enabled to aid in transitioning
|
||||
# to the database backend, check it first before falling back to
|
||||
# the database. Tokens that existed pre-database-backend will
|
||||
# reside in the consoleauth service storage.
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
connect_info = self._get_connect_info_consoleauth(ctxt, token)
|
||||
# If consoleauth is enabled to aid in transitioning to the database
|
||||
# backend and we didn't find a token in the consoleauth service
|
||||
# storage, check the database for a token because it's probably a
|
||||
# post-database-backend token, which are stored in the database.
|
||||
if not connect_info:
|
||||
connect_info = self._get_connect_info_database(ctxt, token)
|
||||
|
||||
return connect_info
|
||||
|
||||
def new_websocket_client(self):
|
||||
"""Called after a new WebSocket connection has been established."""
|
||||
# Reopen the eventlet hub to make sure we don't share an epoll
|
||||
|
@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
"""Module to authenticate Consoles."""
|
@ -1,136 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
"""Auth Components for Consoles."""
|
||||
|
||||
import time
|
||||
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging as messaging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from nova import cache_utils
|
||||
from nova.compute import rpcapi as compute_rpcapi
|
||||
import nova.conf
|
||||
from nova import context as nova_context
|
||||
from nova import manager
|
||||
from nova import objects
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
|
||||
class ConsoleAuthManager(manager.Manager):
|
||||
"""Manages token based authentication."""
|
||||
|
||||
target = messaging.Target(version='2.1')
|
||||
|
||||
def __init__(self, scheduler_driver=None, *args, **kwargs):
|
||||
super(ConsoleAuthManager, self).__init__(service_name='consoleauth',
|
||||
*args, **kwargs)
|
||||
self._mc = None
|
||||
self._mc_instance = None
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
||||
@property
|
||||
def mc(self):
|
||||
if self._mc is None:
|
||||
self._mc = cache_utils.get_client(CONF.consoleauth.token_ttl)
|
||||
return self._mc
|
||||
|
||||
@property
|
||||
def mc_instance(self):
|
||||
if self._mc_instance is None:
|
||||
self._mc_instance = cache_utils.get_client()
|
||||
return self._mc_instance
|
||||
|
||||
def reset(self):
|
||||
LOG.info('Reloading compute RPC API')
|
||||
compute_rpcapi.LAST_VERSION = None
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
||||
def _get_tokens_for_instance(self, instance_uuid):
|
||||
tokens_str = self.mc_instance.get(instance_uuid.encode('UTF-8'))
|
||||
if not tokens_str:
|
||||
tokens = []
|
||||
else:
|
||||
tokens = jsonutils.loads(tokens_str)
|
||||
return tokens
|
||||
|
||||
def authorize_console(self, context, token, console_type, host, port,
|
||||
internal_access_path, instance_uuid,
|
||||
access_url=None):
|
||||
|
||||
token_dict = {'token': token,
|
||||
'instance_uuid': instance_uuid,
|
||||
'console_type': console_type,
|
||||
'host': host,
|
||||
'port': port,
|
||||
'internal_access_path': internal_access_path,
|
||||
'access_url': access_url,
|
||||
'last_activity_at': time.time()}
|
||||
data = jsonutils.dumps(token_dict)
|
||||
|
||||
self.mc.set(token.encode('UTF-8'), data)
|
||||
tokens = self._get_tokens_for_instance(instance_uuid)
|
||||
|
||||
# Remove the expired tokens from cache.
|
||||
token_values = self.mc.get_multi(
|
||||
[tok.encode('UTF-8') for tok in tokens])
|
||||
tokens = [name for name, value in zip(tokens, token_values)
|
||||
if value is not None]
|
||||
tokens.append(token)
|
||||
|
||||
self.mc_instance.set(instance_uuid.encode('UTF-8'),
|
||||
jsonutils.dumps(tokens))
|
||||
|
||||
LOG.info("Received Token: %(token)s, %(token_dict)s",
|
||||
{'token': token, 'token_dict': token_dict})
|
||||
|
||||
def _validate_token(self, context, token):
|
||||
instance_uuid = token['instance_uuid']
|
||||
if instance_uuid is None:
|
||||
return False
|
||||
|
||||
mapping = objects.InstanceMapping.get_by_instance_uuid(context,
|
||||
instance_uuid)
|
||||
with nova_context.target_cell(context, mapping.cell_mapping) as cctxt:
|
||||
instance = objects.Instance.get_by_uuid(cctxt, instance_uuid)
|
||||
|
||||
return self.compute_rpcapi.validate_console_port(
|
||||
cctxt,
|
||||
instance,
|
||||
token['port'],
|
||||
token['console_type'])
|
||||
|
||||
def check_token(self, context, token):
|
||||
token_str = self.mc.get(token.encode('UTF-8'))
|
||||
token_valid = (token_str is not None)
|
||||
LOG.info("Checking Token: %(token)s, %(token_valid)s",
|
||||
{'token': token, 'token_valid': token_valid})
|
||||
if token_valid:
|
||||
token = jsonutils.loads(token_str)
|
||||
if self._validate_token(context, token):
|
||||
return token
|
||||
|
||||
def delete_tokens_for_instance(self, context, instance_uuid):
|
||||
tokens = self._get_tokens_for_instance(instance_uuid)
|
||||
if tokens:
|
||||
self.mc.delete_multi(
|
||||
[tok.encode('UTF-8') for tok in tokens])
|
||||
self.mc_instance.delete(instance_uuid.encode('UTF-8'))
|
@ -1,103 +0,0 @@
|
||||
# Copyright 2013 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Client side of the consoleauth RPC API.
|
||||
"""
|
||||
|
||||
import oslo_messaging as messaging
|
||||
|
||||
import nova.conf
|
||||
from nova import profiler
|
||||
from nova import rpc
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
RPC_TOPIC = 'consoleauth'
|
||||
|
||||
|
||||
@profiler.trace_cls("rpc")
|
||||
class ConsoleAuthAPI(object):
|
||||
'''Client side of the consoleauth rpc API.
|
||||
|
||||
API version history:
|
||||
|
||||
* 1.0 - Initial version.
|
||||
* 1.1 - Added get_backdoor_port()
|
||||
* 1.2 - Added instance_uuid to authorize_console, and
|
||||
delete_tokens_for_instance
|
||||
|
||||
... Grizzly and Havana support message version 1.2. So, any changes
|
||||
to existing methods in 2.x after that point should be done such that
|
||||
they can handle the version_cap being set to 1.2.
|
||||
|
||||
* 2.0 - Major API rev for Icehouse
|
||||
|
||||
... Icehouse and Juno support message version 2.0. So, any changes to
|
||||
existing methods in 2.x after that point should be done such that they
|
||||
can handle the version_cap being set to 2.0.
|
||||
|
||||
* 2.1 - Added access_url to authorize_console
|
||||
|
||||
... Kilo, Liberty, Mitaka, Newton, and Ocata support message version
|
||||
2.1. So, any changes to existing methods in 2.x after that point should
|
||||
be done such that they can handle the version_cap being set to 2.1.
|
||||
|
||||
'''
|
||||
|
||||
VERSION_ALIASES = {
|
||||
'grizzly': '1.2',
|
||||
'havana': '1.2',
|
||||
'icehouse': '2.0',
|
||||
'juno': '2.0',
|
||||
'kilo': '2.1',
|
||||
'liberty': '2.1',
|
||||
'mitaka': '2.1',
|
||||
'newton': '2.1',
|
||||
'ocata': '2.1',
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super(ConsoleAuthAPI, self).__init__()
|
||||
target = messaging.Target(topic=RPC_TOPIC, version='2.1')
|
||||
version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.consoleauth,
|
||||
CONF.upgrade_levels.consoleauth)
|
||||
self.client = rpc.get_client(target, version_cap=version_cap)
|
||||
|
||||
def authorize_console(self, ctxt, token, console_type, host, port,
|
||||
internal_access_path, instance_uuid,
|
||||
access_url):
|
||||
# The remote side doesn't return anything, but we want to block
|
||||
# until it completes.'
|
||||
msg_args = dict(token=token, console_type=console_type,
|
||||
host=host, port=port,
|
||||
internal_access_path=internal_access_path,
|
||||
instance_uuid=instance_uuid,
|
||||
access_url=access_url)
|
||||
version = '2.1'
|
||||
if not self.client.can_send_version('2.1'):
|
||||
version = '2.0'
|
||||
del msg_args['access_url']
|
||||
|
||||
cctxt = self.client.prepare(version=version)
|
||||
return cctxt.call(ctxt, 'authorize_console', **msg_args)
|
||||
|
||||
def check_token(self, ctxt, token):
|
||||
cctxt = self.client.prepare()
|
||||
return cctxt.call(ctxt, 'check_token', token=token)
|
||||
|
||||
def delete_tokens_for_instance(self, ctxt, instance_uuid):
|
||||
cctxt = self.client.prepare()
|
||||
return cctxt.cast(ctxt,
|
||||
'delete_tokens_for_instance',
|
||||
instance_uuid=instance_uuid)
|
@ -765,6 +765,8 @@ class NotificationSource(BaseNovaEnum):
|
||||
CONDUCTOR = 'nova-conductor'
|
||||
SCHEDULER = 'nova-scheduler'
|
||||
NETWORK = 'nova-network'
|
||||
# TODO(stephenfin): Remove 'CONSOLEAUTH' when 'NotificationPublisher' is
|
||||
# updated to version 3.0
|
||||
CONSOLEAUTH = 'nova-consoleauth'
|
||||
# TODO(stephenfin): Remove when 'NotificationPublisher' object version is
|
||||
# bumped to 3.0
|
||||
|
@ -55,7 +55,6 @@ CONF = nova.conf.CONF
|
||||
SERVICE_MANAGERS = {
|
||||
'nova-compute': 'nova.compute.manager.ComputeManager',
|
||||
'nova-console': 'nova.console.manager.ConsoleProxyManager',
|
||||
'nova-consoleauth': 'nova.consoleauth.manager.ConsoleAuthManager',
|
||||
'nova-conductor': 'nova.conductor.manager.ConductorManager',
|
||||
'nova-metadata': 'nova.api.manager.MetadataManager',
|
||||
'nova-scheduler': 'nova.scheduler.manager.SchedulerManager',
|
||||
|
@ -15,21 +15,18 @@
|
||||
|
||||
import copy
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
import webob
|
||||
|
||||
from nova.api.openstack import api_version_request
|
||||
from nova.api.openstack.compute import console_auth_tokens \
|
||||
as console_auth_tokens_v21
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests.unit.api.openstack import fakes
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ConsoleAuthTokensExtensionTestV21(test.NoDBTestCase):
|
||||
controller_class = console_auth_tokens_v21
|
||||
|
||||
@ -52,86 +49,35 @@ class ConsoleAuthTokensExtensionTestV21(test.NoDBTestCase):
|
||||
self.req = fakes.HTTPRequest.blank('', use_admin_context=True)
|
||||
self.context = self.req.environ['nova.context']
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate',
|
||||
return_value=objects.ConsoleAuthToken(
|
||||
instance_uuid=fakes.FAKE_UUID, host='fake_host',
|
||||
port='1234', internal_access_path='fake_access_path',
|
||||
console_type='rdp-html5', token=fakes.FAKE_UUID))
|
||||
@mock.patch.object(consoleauth_rpcapi.ConsoleAuthAPI, 'check_token',
|
||||
return_value={
|
||||
'instance_uuid': fakes.FAKE_UUID,
|
||||
'host': 'fake_host',
|
||||
'port': '1234',
|
||||
'internal_access_path': 'fake_access_path',
|
||||
'console_type': 'rdp-html5'})
|
||||
def test_get_console_connect_info(self, enable_consoleauth,
|
||||
mock_check_token, mock_validate):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_get_console_connect_info(self, mock_validate):
|
||||
output = self.controller.show(self.req, fakes.FAKE_UUID)
|
||||
if enable_consoleauth:
|
||||
self.assertEqual(self._EXPECTED_OUTPUT, output)
|
||||
mock_check_token.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_validate.assert_not_called()
|
||||
else:
|
||||
self.assertEqual(self._EXPECTED_OUTPUT_DB, output)
|
||||
mock_validate.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_check_token.assert_not_called()
|
||||
self.assertEqual(self._EXPECTED_OUTPUT_DB, output)
|
||||
mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate',
|
||||
side_effect=exception.InvalidToken(token='***'))
|
||||
@mock.patch.object(consoleauth_rpcapi.ConsoleAuthAPI, 'check_token',
|
||||
return_value=None)
|
||||
def test_get_console_connect_info_token_not_found(self, enable_consoleauth,
|
||||
mock_check_token,
|
||||
mock_validate):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_get_console_connect_info_token_not_found(self, mock_validate):
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show, self.req, fakes.FAKE_UUID)
|
||||
if enable_consoleauth:
|
||||
mock_check_token.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_validate.assert_not_called()
|
||||
else:
|
||||
mock_validate.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_check_token.assert_not_called()
|
||||
mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate',
|
||||
return_value=objects.ConsoleAuthToken(
|
||||
instance_uuid=fakes.FAKE_UUID, host='fake_host',
|
||||
port='1234', internal_access_path='fake_access_path',
|
||||
console_type='unauthorized_console_type',
|
||||
token=fakes.FAKE_UUID))
|
||||
@mock.patch.object(consoleauth_rpcapi.ConsoleAuthAPI, 'check_token',
|
||||
return_value={
|
||||
'instance_uuid': fakes.FAKE_UUID,
|
||||
'host': 'fake_host',
|
||||
'port': '1234',
|
||||
'internal_access_path': 'fake_access_path',
|
||||
'console_type': 'unauthorized_console_type'})
|
||||
def test_get_console_connect_info_nonrdp_console_type(self,
|
||||
enable_consoleauth,
|
||||
mock_check_token,
|
||||
mock_validate):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_get_console_connect_info_nonrdp_console_type(self, mock_validate):
|
||||
self.assertRaises(webob.exc.HTTPUnauthorized,
|
||||
self.controller.show, self.req, fakes.FAKE_UUID)
|
||||
if enable_consoleauth:
|
||||
mock_check_token.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_validate.assert_not_called()
|
||||
else:
|
||||
mock_validate.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_check_token.assert_not_called()
|
||||
mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ConsoleAuthTokensExtensionTestV231(ConsoleAuthTokensExtensionTestV21):
|
||||
|
||||
def setUp(self):
|
||||
@ -139,30 +85,13 @@ class ConsoleAuthTokensExtensionTestV231(ConsoleAuthTokensExtensionTestV21):
|
||||
self.req.api_version_request = api_version_request.APIVersionRequest(
|
||||
'2.31')
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate')
|
||||
@mock.patch.object(consoleauth_rpcapi.ConsoleAuthAPI, 'check_token')
|
||||
def test_get_console_connect_info_nonrdp_console_type(self,
|
||||
enable_consoleauth,
|
||||
mock_check,
|
||||
mock_validate):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
mock_validate.return_value = objects.ConsoleAuthToken(
|
||||
instance_uuid=fakes.FAKE_UUID, host='fake_host', port='1234',
|
||||
internal_access_path='fake_access_path', console_type='webmks',
|
||||
token=fakes.FAKE_UUID)
|
||||
mock_check.return_value = {'instance_uuid': fakes.FAKE_UUID,
|
||||
'host': 'fake_host',
|
||||
'port': '1234',
|
||||
'internal_access_path': 'fake_access_path',
|
||||
'console_type': 'webmks'}
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate',
|
||||
return_value = objects.ConsoleAuthToken(
|
||||
instance_uuid=fakes.FAKE_UUID, host='fake_host',
|
||||
port='1234', internal_access_path='fake_access_path',
|
||||
console_type='webmks',
|
||||
token=fakes.FAKE_UUID))
|
||||
def test_get_console_connect_info_nonrdp_console_type(self, mock_validate):
|
||||
output = self.controller.show(self.req, fakes.FAKE_UUID)
|
||||
if enable_consoleauth:
|
||||
self.assertEqual(self._EXPECTED_OUTPUT, output)
|
||||
mock_check.assert_called_once_with(self.context, fakes.FAKE_UUID)
|
||||
mock_validate.assert_not_called()
|
||||
else:
|
||||
self.assertEqual(self._EXPECTED_OUTPUT_DB, output)
|
||||
mock_validate.assert_called_once_with(self.context,
|
||||
fakes.FAKE_UUID)
|
||||
mock_check.assert_not_called()
|
||||
self.assertEqual(self._EXPECTED_OUTPUT_DB, output)
|
||||
mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)
|
||||
|
@ -10157,12 +10157,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.assertRaises(exception.InvalidVolume,
|
||||
self.compute_api.rescue, self.context, instance)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_vnc_console')
|
||||
@mock.patch.object(compute.consoleauth_rpcapi.ConsoleAuthAPI,
|
||||
'authorize_console')
|
||||
def test_vnc_console(self, enable_consoleauth, mock_auth, mock_get):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_vnc_console(self, mock_get):
|
||||
# Make sure we can a vnc console for an instance.
|
||||
|
||||
fake_instance = self._fake_instance(
|
||||
@ -10185,14 +10181,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
mock_get.assert_called_once_with(
|
||||
self.context, instance=fake_instance,
|
||||
console_type=fake_console_type)
|
||||
if enable_consoleauth:
|
||||
mock_auth.assert_called_once_with(
|
||||
self.context, 'fake_token', fake_console_type,
|
||||
'fake_console_host', 'fake_console_port', 'fake_access_path',
|
||||
'f3000000-0000-0000-0000-000000000000',
|
||||
access_url='fake_console_url')
|
||||
else:
|
||||
mock_auth.assert_not_called()
|
||||
|
||||
def test_get_vnc_console_no_host(self):
|
||||
instance = self._create_fake_instance_obj(params={'host': ''})
|
||||
@ -10201,12 +10189,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.compute_api.get_vnc_console,
|
||||
self.context, instance, 'novnc')
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch.object(compute.consoleauth_rpcapi.ConsoleAuthAPI,
|
||||
'authorize_console')
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_spice_console')
|
||||
def test_spice_console(self, enable_consoleauth, mock_spice, mock_auth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_spice_console(self, mock_spice):
|
||||
# Make sure we can a spice console for an instance.
|
||||
|
||||
fake_instance = self._fake_instance(
|
||||
@ -10229,14 +10213,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
mock_spice.assert_called_once_with(self.context,
|
||||
instance=fake_instance,
|
||||
console_type=fake_console_type)
|
||||
if enable_consoleauth:
|
||||
mock_auth.assert_called_once_with(
|
||||
self.context, 'fake_token', fake_console_type,
|
||||
'fake_console_host', 'fake_console_port', 'fake_access_path',
|
||||
'f3000000-0000-0000-0000-000000000000',
|
||||
access_url='fake_console_url')
|
||||
else:
|
||||
mock_auth.assert_not_called()
|
||||
|
||||
def test_get_spice_console_no_host(self):
|
||||
instance = self._create_fake_instance_obj(params={'host': ''})
|
||||
@ -10264,12 +10240,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
getattr(self.compute_api, 'get_%s_console' % console_type),
|
||||
self.context, instance, console_type)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@mock.patch.object(compute.consoleauth_rpcapi.ConsoleAuthAPI,
|
||||
'authorize_console')
|
||||
@mock.patch.object(compute_rpcapi.ComputeAPI, 'get_rdp_console')
|
||||
def test_rdp_console(self, enable_consoleauth, mock_rdp, mock_auth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
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',
|
||||
@ -10290,14 +10262,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.assertEqual(console, {'url': 'fake_console_url'})
|
||||
mock_rdp.assert_called_once_with(self.context, instance=fake_instance,
|
||||
console_type=fake_console_type)
|
||||
if enable_consoleauth:
|
||||
mock_auth.assert_called_once_with(
|
||||
self.context, 'fake_token', fake_console_type,
|
||||
'fake_console_host', 'fake_console_port', 'fake_access_path',
|
||||
'f3000000-0000-0000-0000-000000000000',
|
||||
access_url='fake_console_url')
|
||||
else:
|
||||
mock_auth.assert_not_called()
|
||||
|
||||
def test_get_rdp_console_no_host(self):
|
||||
instance = self._create_fake_instance_obj(params={'host': ''})
|
||||
@ -10321,21 +10285,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
'instance_uuid': fake_instance.uuid,
|
||||
'access_url': 'fake_access_url'}
|
||||
|
||||
rpcapi = compute_rpcapi.ComputeAPI
|
||||
|
||||
with test.nested(
|
||||
mock.patch.object(rpcapi, 'get_serial_console',
|
||||
return_value=fake_connect_info),
|
||||
mock.patch.object(self.compute_api.consoleauth_rpcapi,
|
||||
'authorize_console')
|
||||
) as (mock_get_serial_console, mock_authorize_console):
|
||||
self.compute_api.consoleauth_rpcapi.authorize_console(
|
||||
self.context, 'fake_token', fake_console_type,
|
||||
'fake_serial_host', 'fake_tcp_port',
|
||||
'fake_access_path',
|
||||
'f3000000-0000-0000-0000-000000000000',
|
||||
access_url='fake_access_url')
|
||||
|
||||
with mock.patch.object(self.compute_api.compute_rpcapi,
|
||||
'get_serial_console', return_value=fake_connect_info):
|
||||
console = self.compute_api.get_serial_console(self.context,
|
||||
fake_instance,
|
||||
fake_console_type)
|
||||
@ -10362,13 +10313,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
'instance_uuid': fake_instance.uuid,
|
||||
'access_url': 'fake_access_url'}
|
||||
|
||||
with test.nested(
|
||||
mock.patch.object(self.compute_api.compute_rpcapi,
|
||||
'get_mks_console',
|
||||
return_value=fake_connect_info),
|
||||
mock.patch.object(self.compute_api.consoleauth_rpcapi,
|
||||
'authorize_console')
|
||||
) as (mock_get_mks_console, mock_authorize_console):
|
||||
with mock.patch.object(self.compute_api.compute_rpcapi,
|
||||
'get_mks_console', return_value=fake_connect_info):
|
||||
console = self.compute_api.get_mks_console(self.context,
|
||||
fake_instance,
|
||||
fake_console_type)
|
||||
@ -11433,17 +11379,14 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
instance, instance_uuid = self._run_instance()
|
||||
|
||||
rpcapi = self.compute_api.compute_task_api
|
||||
consoleauth_rpcapi = self.compute_api.consoleauth_rpcapi
|
||||
fake_spec = objects.RequestSpec()
|
||||
|
||||
@mock.patch.object(consoleauth_rpcapi, 'delete_tokens_for_instance')
|
||||
@mock.patch.object(rpcapi, 'live_migrate_instance')
|
||||
@mock.patch.object(objects.ComputeNodeList, 'get_all_by_host')
|
||||
@mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid')
|
||||
@mock.patch.object(self.compute_api, '_record_action_start')
|
||||
def do_test(record_action_start, get_by_instance_uuid,
|
||||
get_all_by_host, live_migrate_instance,
|
||||
delete_tokens_for_instance):
|
||||
get_all_by_host, live_migrate_instance):
|
||||
get_by_instance_uuid.return_value = fake_spec
|
||||
get_all_by_host.return_value = objects.ComputeNodeList(
|
||||
objects=[objects.ComputeNode(
|
||||
@ -11468,12 +11411,6 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
disk_over_commit=True,
|
||||
request_spec=fake_spec, async_=False)
|
||||
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
delete_tokens_for_instance.assert_called_once_with(
|
||||
self.context, instance.uuid)
|
||||
else:
|
||||
delete_tokens_for_instance.assert_not_called()
|
||||
|
||||
do_test()
|
||||
instance.refresh()
|
||||
self.assertEqual(instance['task_state'], task_states.MIGRATING)
|
||||
@ -11484,19 +11421,13 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.assertEqual('fake_dest_host', req_dest.host)
|
||||
self.assertEqual('fake_dest_node', req_dest.node)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_live_migrate(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_live_migrate(self):
|
||||
self._test_live_migrate()
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_live_migrate_with_not_forced_host(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_live_migrate_with_not_forced_host(self):
|
||||
self._test_live_migrate(force=False)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_live_migrate_with_forced_host(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_live_migrate_with_forced_host(self):
|
||||
self._test_live_migrate(force=True)
|
||||
|
||||
def test_fail_live_migrate_with_non_existing_destination(self):
|
||||
|
@ -37,7 +37,6 @@ from nova.compute import utils as compute_utils
|
||||
from nova.compute import vm_states
|
||||
from nova import conductor
|
||||
import nova.conf
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context
|
||||
from nova.db import api as db
|
||||
from nova import exception
|
||||
@ -992,8 +991,6 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
@mock.patch.object(image_api.API, 'delete')
|
||||
@mock.patch.object(objects.InstanceMapping, 'save')
|
||||
@mock.patch.object(objects.InstanceMapping, 'get_by_instance_uuid')
|
||||
@mock.patch.object(consoleauth_rpcapi.ConsoleAuthAPI,
|
||||
'delete_tokens_for_instance')
|
||||
@mock.patch.object(compute_utils,
|
||||
'notify_about_instance_usage')
|
||||
@mock.patch.object(db, 'instance_destroy')
|
||||
@ -1010,7 +1007,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
def _test_delete(self, delete_type, mock_save, mock_bdm_get, mock_elevated,
|
||||
mock_get_cn, mock_up, mock_record, mock_inst_update,
|
||||
mock_deallocate, mock_inst_meta, mock_inst_destroy,
|
||||
mock_notify_legacy, mock_del_token, mock_get_inst,
|
||||
mock_notify_legacy, mock_get_inst,
|
||||
mock_save_im, mock_image_delete, mock_mig_get,
|
||||
mock_notify, **attrs):
|
||||
expected_save_calls = [mock.call()]
|
||||
@ -1175,11 +1172,6 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
mock_terminate.assert_called_once_with(
|
||||
self.context, inst, [])
|
||||
|
||||
if CONF.workarounds.enable_consoleauth:
|
||||
mock_del_token.assert_called_once_with(self.context, instance_uuid)
|
||||
else:
|
||||
mock_del_token.assert_not_called()
|
||||
|
||||
if is_shelved:
|
||||
mock_image_delete.assert_called_once_with(self.context,
|
||||
snapshot_id)
|
||||
@ -1204,9 +1196,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
task_state=task_states.RESIZE_FINISH,
|
||||
old_flavor=old_flavor)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete_in_resized(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_delete_in_resized(self):
|
||||
self._test_delete('delete', vm_state=vm_states.RESIZED)
|
||||
|
||||
def test_delete_shelved(self):
|
||||
@ -1215,9 +1205,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
vm_state=vm_states.SHELVED,
|
||||
system_metadata=fake_sys_meta)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete_shelved_offloaded(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_delete_shelved_offloaded(self):
|
||||
fake_sys_meta = {'shelved_image_id': SHELVED_IMAGE}
|
||||
self._test_delete('delete',
|
||||
vm_state=vm_states.SHELVED_OFFLOADED,
|
||||
@ -1235,9 +1223,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
vm_state=vm_states.SHELVED_OFFLOADED,
|
||||
system_metadata=fake_sys_meta)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete_shelved_exception(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_delete_shelved_exception(self):
|
||||
fake_sys_meta = {'shelved_image_id': SHELVED_IMAGE_EXCEPTION}
|
||||
self._test_delete('delete',
|
||||
vm_state=vm_states.SHELVED,
|
||||
@ -1252,9 +1238,7 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
def test_delete_soft_in_resized(self):
|
||||
self._test_delete('soft_delete', vm_state=vm_states.RESIZED)
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_delete_soft(self, enable_consoleauth):
|
||||
self.flags(enable_consoleauth=enable_consoleauth, group='workarounds')
|
||||
def test_delete_soft(self):
|
||||
self._test_delete('soft_delete')
|
||||
|
||||
def test_delete_forced(self):
|
||||
|
@ -66,10 +66,9 @@ class NovaProxyRequestHandlerDBTestCase(test.TestCase):
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate')
|
||||
@mock.patch('nova.objects.Instance.get_by_uuid')
|
||||
@mock.patch('nova.compute.rpcapi.ComputeAPI.validate_console_port')
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
|
||||
def test_new_websocket_client_db(
|
||||
self, mock_ca_check, mock_validate_port, mock_inst_get,
|
||||
mock_validate, internal_access_path=None,
|
||||
self, mock_validate_port, mock_inst_get, mock_validate,
|
||||
internal_access_path=None,
|
||||
instance_not_found=False):
|
||||
|
||||
db_obj = self._fake_console_db(
|
||||
@ -113,7 +112,6 @@ class NovaProxyRequestHandlerDBTestCase(test.TestCase):
|
||||
mock_validate_port.assert_called_once_with(
|
||||
ctxt, mock_inst_get.return_value, str(db_obj['port']),
|
||||
db_obj['console_type'])
|
||||
mock_ca_check.assert_not_called()
|
||||
|
||||
self.wh.socket.assert_called_with('node1', 10000, connect=True)
|
||||
|
||||
@ -201,60 +199,6 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase):
|
||||
'Host': 'example.net:6080',
|
||||
}
|
||||
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
|
||||
def test_new_websocket_client_enable_consoleauth(self, check_token):
|
||||
self.flags(enable_consoleauth=True, group='workarounds')
|
||||
|
||||
check_token.return_value = {
|
||||
'host': 'node1',
|
||||
'port': '10000',
|
||||
'console_type': 'novnc',
|
||||
'access_url': 'https://example.net:6080'
|
||||
}
|
||||
self.wh.socket.return_value = '<socket>'
|
||||
self.wh.path = "http://127.0.0.1/?%s" % self.path
|
||||
self.wh.headers = self.fake_header
|
||||
|
||||
self.wh.new_websocket_client()
|
||||
|
||||
check_token.assert_called_with(mock.ANY, token="123-456-789")
|
||||
self.wh.socket.assert_called_with('node1', 10000, connect=True)
|
||||
self.wh.do_proxy.assert_called_with('<socket>')
|
||||
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token',
|
||||
return_value=None)
|
||||
@mock.patch('nova.console.websocketproxy.NovaProxyRequestHandlerBase.'
|
||||
'_check_console_port')
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate')
|
||||
def test_new_websocket_client_enable_consoleauth_fallback(self, validate,
|
||||
check_port,
|
||||
check_token):
|
||||
# Since consoleauth is enabled, it should be called first before
|
||||
# falling back to the database.
|
||||
self.flags(enable_consoleauth=True, group='workarounds')
|
||||
|
||||
params = {
|
||||
'id': 1,
|
||||
'token': '123-456-789',
|
||||
'instance_uuid': uuids.instance,
|
||||
'host': 'node1',
|
||||
'port': '10000',
|
||||
'console_type': 'novnc',
|
||||
'access_url_base': 'https://example.net:6080'
|
||||
}
|
||||
validate.return_value = objects.ConsoleAuthToken(**params)
|
||||
|
||||
self.wh.socket.return_value = '<socket>'
|
||||
self.wh.path = "http://127.0.0.1/?%s" % self.path
|
||||
self.wh.headers = self.fake_header
|
||||
|
||||
self.wh.new_websocket_client()
|
||||
|
||||
check_token.assert_called_with(mock.ANY, token="123-456-789")
|
||||
validate.assert_called_with(mock.ANY, "123-456-789")
|
||||
self.wh.socket.assert_called_with('node1', 10000, connect=True)
|
||||
self.wh.do_proxy.assert_called_with('<socket>')
|
||||
|
||||
@mock.patch('nova.console.websocketproxy.NovaProxyRequestHandlerBase.'
|
||||
'_check_console_port')
|
||||
@mock.patch('nova.objects.ConsoleAuthToken.validate')
|
||||
@ -441,23 +385,6 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase):
|
||||
self.wh.socket.assert_called_with('node1', 10000, connect=True)
|
||||
self.wh.do_proxy.assert_called_with('<socket>')
|
||||
|
||||
@mock.patch.object(websocketproxy, 'sys')
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
|
||||
def test_new_websocket_client_py273_special_scheme(
|
||||
self, check_token, mock_sys):
|
||||
mock_sys.version_info = (2, 7, 3)
|
||||
check_token.return_value = {
|
||||
'host': 'node1',
|
||||
'port': '10000',
|
||||
'console_type': 'novnc'
|
||||
}
|
||||
self.wh.socket.return_value = '<socket>'
|
||||
self.wh.path = "ws://127.0.0.1/?%s" % self.path
|
||||
self.wh.headers = self.fake_header
|
||||
|
||||
self.assertRaises(exception.NovaException,
|
||||
self.wh.new_websocket_client)
|
||||
|
||||
@mock.patch('socket.getfqdn')
|
||||
def test_address_string_doesnt_do_reverse_dns_lookup(self, getfqdn):
|
||||
request_mock = mock.MagicMock()
|
||||
|
@ -1,240 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# 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.
|
||||
"""
|
||||
Tests for Consoleauth Code.
|
||||
|
||||
"""
|
||||
|
||||
import mock
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
from oslo_utils import timeutils
|
||||
import six
|
||||
|
||||
from nova.consoleauth import manager
|
||||
from nova import context
|
||||
from nova import objects
|
||||
from nova import test
|
||||
|
||||
|
||||
class ConsoleauthTestCase(test.NoDBTestCase):
|
||||
"""Test Case for consoleauth."""
|
||||
|
||||
rpcapi = 'nova.compute.rpcapi.ComputeAPI.'
|
||||
|
||||
def setUp(self):
|
||||
super(ConsoleauthTestCase, self).setUp()
|
||||
self.manager_api = self.manager = manager.ConsoleAuthManager()
|
||||
self.context = context.get_admin_context()
|
||||
self.instance_uuid = '00000000-0000-0000-0000-000000000000'
|
||||
self.is_cells = False
|
||||
|
||||
def test_reset(self):
|
||||
with mock.patch('nova.compute.rpcapi.ComputeAPI') as mock_rpc:
|
||||
old_rpcapi = self.manager_api.compute_rpcapi
|
||||
self.manager_api.reset()
|
||||
mock_rpc.assert_called_once_with()
|
||||
self.assertNotEqual(old_rpcapi,
|
||||
self.manager_api.compute_rpcapi)
|
||||
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_uuid')
|
||||
def test_tokens_expire(self, mock_get):
|
||||
mock_get.return_value = None
|
||||
# NOTE(danms): Get the faked InstanceMapping from the SingleCellSimple
|
||||
# fixture so we can return it from our own mock to verify
|
||||
# that it was called
|
||||
fake_im = objects.InstanceMapping.get_by_instance_uuid(self.context,
|
||||
uuids.instance)
|
||||
|
||||
# Test that tokens expire correctly.
|
||||
self.useFixture(test.TimeOverride())
|
||||
token = u'mytok'
|
||||
self.flags(token_ttl=1, group='consoleauth')
|
||||
|
||||
self._stub_validate_console_port(True)
|
||||
|
||||
self.manager_api.authorize_console(self.context, token, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
self.instance_uuid)
|
||||
with mock.patch('nova.objects.InstanceMapping.'
|
||||
'get_by_instance_uuid') as mock_get:
|
||||
mock_get.return_value = fake_im
|
||||
self.assertIsNotNone(self.manager_api.check_token(self.context,
|
||||
token))
|
||||
timeutils.advance_time_seconds(1)
|
||||
self.assertIsNone(self.manager_api.check_token(self.context,
|
||||
token))
|
||||
if not self.is_cells:
|
||||
mock_get.assert_called_once_with(self.context,
|
||||
self.instance_uuid)
|
||||
|
||||
def _stub_validate_console_port(self, result):
|
||||
def fake_validate_console_port(self, ctxt, instance,
|
||||
port, console_type):
|
||||
return result
|
||||
|
||||
self.stub_out(self.rpcapi + 'validate_console_port',
|
||||
fake_validate_console_port)
|
||||
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_uuid')
|
||||
def test_multiple_tokens_for_instance(self, mock_get):
|
||||
mock_get.return_value = None
|
||||
|
||||
tokens = [u"token" + str(i) for i in range(10)]
|
||||
|
||||
self._stub_validate_console_port(True)
|
||||
|
||||
for token in tokens:
|
||||
self.manager_api.authorize_console(self.context, token, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
self.instance_uuid)
|
||||
|
||||
for token in tokens:
|
||||
self.assertIsNotNone(
|
||||
self.manager_api.check_token(self.context, token))
|
||||
|
||||
def test_delete_tokens_for_instance(self):
|
||||
tokens = [u"token" + str(i) for i in range(10)]
|
||||
for token in tokens:
|
||||
self.manager_api.authorize_console(self.context, token, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
self.instance_uuid)
|
||||
self.manager_api.delete_tokens_for_instance(self.context,
|
||||
self.instance_uuid)
|
||||
stored_tokens = self.manager._get_tokens_for_instance(
|
||||
self.instance_uuid)
|
||||
|
||||
self.assertEqual(len(stored_tokens), 0)
|
||||
|
||||
for token in tokens:
|
||||
self.assertIsNone(
|
||||
self.manager_api.check_token(self.context, token))
|
||||
|
||||
def test_delete_tokens_for_instance_no_tokens(self):
|
||||
with test.nested(
|
||||
mock.patch.object(self.manager, '_get_tokens_for_instance',
|
||||
return_value=[]),
|
||||
mock.patch.object(self.manager.mc, 'delete_multi'),
|
||||
mock.patch.object(self.manager.mc_instance, 'delete')
|
||||
) as (
|
||||
mock_get_tokens, mock_delete_multi, mock_delete
|
||||
):
|
||||
self.manager.delete_tokens_for_instance(
|
||||
self.context, self.instance_uuid)
|
||||
# Since here were no tokens, we didn't try to clear anything
|
||||
# from the cache.
|
||||
mock_delete_multi.assert_not_called()
|
||||
mock_delete.assert_called_once_with(
|
||||
self.instance_uuid.encode('UTF-8'))
|
||||
|
||||
@mock.patch('nova.objects.instance.Instance.get_by_uuid')
|
||||
def test_wrong_token_has_port(self, mock_get):
|
||||
mock_get.return_value = None
|
||||
|
||||
token = u'mytok'
|
||||
|
||||
self._stub_validate_console_port(False)
|
||||
|
||||
self.manager_api.authorize_console(self.context, token, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
instance_uuid=self.instance_uuid)
|
||||
self.assertIsNone(self.manager_api.check_token(self.context, token))
|
||||
|
||||
def test_delete_expired_tokens(self):
|
||||
self.useFixture(test.TimeOverride())
|
||||
token = u'mytok'
|
||||
self.flags(token_ttl=1, group='consoleauth')
|
||||
|
||||
self._stub_validate_console_port(True)
|
||||
|
||||
self.manager_api.authorize_console(self.context, token, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
self.instance_uuid)
|
||||
timeutils.advance_time_seconds(1)
|
||||
self.assertIsNone(self.manager_api.check_token(self.context, token))
|
||||
|
||||
token1 = u'mytok2'
|
||||
self.manager_api.authorize_console(self.context, token1, 'novnc',
|
||||
'127.0.0.1', '8080', 'host',
|
||||
self.instance_uuid)
|
||||
stored_tokens = self.manager._get_tokens_for_instance(
|
||||
self.instance_uuid)
|
||||
# when trying to store token1, expired token is removed fist.
|
||||
self.assertEqual(len(stored_tokens), 1)
|
||||
self.assertEqual(stored_tokens[0], token1)
|
||||
|
||||
|
||||
class ControlauthMemcacheEncodingTestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(ControlauthMemcacheEncodingTestCase, self).setUp()
|
||||
self.manager = manager.ConsoleAuthManager()
|
||||
self.context = context.get_admin_context()
|
||||
self.u_token = u"token"
|
||||
self.u_instance = u"instance"
|
||||
|
||||
def test_authorize_console_encoding(self):
|
||||
with test.nested(
|
||||
mock.patch.object(self.manager.mc_instance,
|
||||
'set', return_value=None),
|
||||
mock.patch.object(self.manager.mc_instance,
|
||||
'get', return_value='["token"]'),
|
||||
mock.patch.object(self.manager.mc,
|
||||
'set', return_value=None),
|
||||
mock.patch.object(self.manager.mc,
|
||||
'get', return_value=None),
|
||||
mock.patch.object(self.manager.mc,
|
||||
'get_multi', return_value=["token1"]),
|
||||
) as (
|
||||
mock_instance_set,
|
||||
mock_instance_get,
|
||||
mock_set,
|
||||
mock_get,
|
||||
mock_get_multi):
|
||||
self.manager.authorize_console(self.context, self.u_token,
|
||||
'novnc', '127.0.0.1', '8080',
|
||||
'host', self.u_instance)
|
||||
mock_set.assert_has_calls([mock.call(b'token', mock.ANY)])
|
||||
mock_instance_get.assert_has_calls([mock.call(b'instance')])
|
||||
mock_get_multi.assert_has_calls([mock.call([b'token'])])
|
||||
mock_instance_set.assert_has_calls(
|
||||
[mock.call(b'instance', mock.ANY)])
|
||||
|
||||
def test_check_token_encoding(self):
|
||||
with mock.patch.object(self.manager.mc,
|
||||
"get",
|
||||
return_value=None) as mock_get:
|
||||
self.manager.check_token(self.context, self.u_token)
|
||||
mock_get.assert_called_once_with(test.MatchType(six.binary_type))
|
||||
|
||||
def test_delete_tokens_for_instance_encoding(self):
|
||||
with test.nested(
|
||||
mock.patch.object(self.manager.mc_instance,
|
||||
'get', return_value='["token"]'),
|
||||
mock.patch.object(self.manager.mc_instance,
|
||||
'delete', return_value=True),
|
||||
mock.patch.object(self.manager.mc,
|
||||
'get'),
|
||||
mock.patch.object(self.manager.mc,
|
||||
'delete_multi', return_value=True),
|
||||
) as (
|
||||
mock_instance_get,
|
||||
mock_instance_delete,
|
||||
mock_get,
|
||||
mock_delete_multi):
|
||||
self.manager.delete_tokens_for_instance(self.context,
|
||||
self.u_instance)
|
||||
mock_instance_get.assert_has_calls([mock.call(b'instance')])
|
||||
mock_instance_delete.assert_has_calls([mock.call(b'instance')])
|
||||
mock_delete_multi.assert_has_calls([mock.call([b'token'])])
|
@ -1,90 +0,0 @@
|
||||
# Copyright 2013 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Unit Tests for nova.consoleauth.rpcapi
|
||||
"""
|
||||
|
||||
import mock
|
||||
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context
|
||||
from nova import test
|
||||
|
||||
|
||||
class ConsoleAuthRpcAPITestCase(test.NoDBTestCase):
|
||||
DROPPED_ARG = object()
|
||||
|
||||
def _test_consoleauth_api(self, method, **kwargs):
|
||||
do_cast = kwargs.pop('_do_cast', False)
|
||||
|
||||
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||
|
||||
rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
self.assertIsNotNone(rpcapi.client)
|
||||
self.assertEqual(rpcapi.client.target.topic,
|
||||
consoleauth_rpcapi.RPC_TOPIC)
|
||||
|
||||
orig_prepare = rpcapi.client.prepare
|
||||
|
||||
version = kwargs.pop('version', None)
|
||||
rpc_kwargs = {k: v for k, v in kwargs.items()
|
||||
if v is not self.DROPPED_ARG}
|
||||
|
||||
with test.nested(
|
||||
mock.patch.object(rpcapi.client, 'cast' if do_cast else 'call'),
|
||||
mock.patch.object(rpcapi.client, 'prepare'),
|
||||
mock.patch.object(rpcapi.client, 'can_send_version'),
|
||||
) as (
|
||||
rpc_mock, prepare_mock, csv_mock
|
||||
):
|
||||
prepare_mock.return_value = rpcapi.client
|
||||
rpc_mock.return_value = None if do_cast else 'foo'
|
||||
|
||||
def fake_csv(v):
|
||||
if version:
|
||||
return orig_prepare(
|
||||
version_cap=version).can_send_version(version=v)
|
||||
else:
|
||||
return orig_prepare().can_send_version()
|
||||
csv_mock.side_effect = fake_csv
|
||||
|
||||
retval = getattr(rpcapi, method)(ctxt, **kwargs)
|
||||
self.assertEqual(retval, rpc_mock.return_value)
|
||||
|
||||
if version:
|
||||
prepare_mock.assert_called_once_with(version=version)
|
||||
else:
|
||||
prepare_mock.assert_called_once_with()
|
||||
rpc_mock.assert_called_once_with(ctxt, method, **rpc_kwargs)
|
||||
|
||||
def test_authorize_console(self):
|
||||
self._test_consoleauth_api('authorize_console', token='token',
|
||||
console_type='ctype', host='h', port='p',
|
||||
internal_access_path='iap', instance_uuid="instance",
|
||||
access_url=self.DROPPED_ARG, version='2.0')
|
||||
|
||||
def test_authorize_console_access_url(self):
|
||||
self._test_consoleauth_api('authorize_console', token='token',
|
||||
console_type='ctype', host='h', port='p',
|
||||
internal_access_path='iap', instance_uuid="instance",
|
||||
access_url="fake_access_url", version='2.1')
|
||||
|
||||
def test_check_token(self):
|
||||
self._test_consoleauth_api('check_token', token='t')
|
||||
|
||||
def test_delete_tokens_for_instnace(self):
|
||||
self._test_consoleauth_api('delete_tokens_for_instance',
|
||||
_do_cast=True,
|
||||
instance_uuid="instance")
|
@ -57,8 +57,6 @@ class TestProfiler(test.NoDBTestCase):
|
||||
'nova.conductor.rpcapi.ConductorAPI',
|
||||
'nova.console.manager.ConsoleProxyManager',
|
||||
'nova.console.rpcapi.ConsoleAPI',
|
||||
'nova.consoleauth.manager.ConsoleAuthManager',
|
||||
'nova.consoleauth.rpcapi.ConsoleAuthAPI',
|
||||
'nova.image.api.API',
|
||||
'nova.network.api.API',
|
||||
'nova.network.manager.FlatDHCPManager',
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The ``nova-consoleauth`` service has been deprecated since the 18.0.0
|
||||
Rocky release and has now been removed. The following configuration
|
||||
options have been removed:
|
||||
|
||||
* ``[upgrade_levels] consoleauth``
|
||||
* ``[workarounds] enable_consoleauth``
|
@ -59,7 +59,6 @@ console_scripts =
|
||||
nova-compute = nova.cmd.compute:main
|
||||
nova-conductor = nova.cmd.conductor:main
|
||||
nova-console = nova.cmd.console:main
|
||||
nova-consoleauth = nova.cmd.consoleauth:main
|
||||
nova-dhcpbridge = nova.cmd.dhcpbridge:main
|
||||
nova-manage = nova.cmd.manage:main
|
||||
nova-network = nova.cmd.network:main
|
||||
|
Loading…
Reference in New Issue
Block a user