Add version to consoleauth rpc API.
Part of blueprint versioned-rpc-apis. Change-Id: I9682bdbd06d744141b94385992b37cd2e55b8f5e
This commit is contained in:
parent
1b6aa2d1af
commit
9ec9fdce62
|
@ -33,6 +33,7 @@ from nova.compute import power_state
|
|||
from nova.compute import task_states
|
||||
from nova.compute import vm_states
|
||||
from nova import crypto
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova.db import base
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
|
@ -162,6 +163,7 @@ class API(BaseAPI):
|
|||
|
||||
self.network_api = network_api or network.API()
|
||||
self.volume_api = volume_api or volume.API()
|
||||
self.consoleauth_rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
super(API, self).__init__(**kwargs)
|
||||
|
||||
def _check_injected_file_quota(self, context, injected_files):
|
||||
|
@ -1630,14 +1632,9 @@ class API(BaseAPI):
|
|||
connect_info = self._call_compute_message('get_vnc_console',
|
||||
context, instance, params={"console_type": console_type})
|
||||
|
||||
rpc.call(context, '%s' % FLAGS.consoleauth_topic,
|
||||
{'method': 'authorize_console',
|
||||
'args': {'token': connect_info['token'],
|
||||
'console_type': console_type,
|
||||
'host': connect_info['host'],
|
||||
'port': connect_info['port'],
|
||||
'internal_access_path':
|
||||
connect_info['internal_access_path']}})
|
||||
self.consoleauth_rpcapi.authorize_console(context,
|
||||
connect_info['token'], console_type, connect_info['host'],
|
||||
connect_info['port'], connect_info['internal_access_path'])
|
||||
|
||||
return {'url': connect_info['access_url']}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ FLAGS.register_opts(consoleauth_opts)
|
|||
class ConsoleAuthManager(manager.Manager):
|
||||
"""Manages token based authentication."""
|
||||
|
||||
RPC_API_VERSION = '1.0'
|
||||
|
||||
def __init__(self, scheduler_driver=None, *args, **kwargs):
|
||||
super(ConsoleAuthManager, self).__init__(*args, **kwargs)
|
||||
self.tokens = {}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012, 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.
|
||||
"""
|
||||
|
||||
from nova import flags
|
||||
import nova.rpc.proxy
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class ConsoleAuthAPI(nova.rpc.proxy.RpcProxy):
|
||||
'''Client side of the consoleauth rpc API.
|
||||
|
||||
API version history:
|
||||
|
||||
1.0 - Initial version.
|
||||
'''
|
||||
|
||||
RPC_API_VERSION = '1.0'
|
||||
|
||||
def __init__(self):
|
||||
super(ConsoleAuthAPI, self).__init__(topic=FLAGS.consoleauth_topic,
|
||||
default_version=self.RPC_API_VERSION)
|
||||
|
||||
def authorize_console(self, ctxt, token, console_type, host, port,
|
||||
internal_access_path):
|
||||
# The remote side doesn't return anything, but we want to block
|
||||
# until it completes.
|
||||
return self.call(ctxt,
|
||||
self.make_msg('authorize_console',
|
||||
token=token, console_type=console_type,
|
||||
host=host, port=port,
|
||||
internal_access_path=internal_access_path))
|
||||
|
||||
def check_token(self, ctxt, token):
|
||||
return self.call(ctxt, self.make_msg('check_token', token=token))
|
|
@ -0,0 +1,19 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2011 OpenStack LLC.
|
||||
# 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.
|
||||
|
||||
# NOTE(vish): this forces the fixtures from tests/__init.py:setup() to work
|
||||
from nova.tests import *
|
|
@ -41,7 +41,7 @@ class ConsoleauthTestCase(test.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(ConsoleauthTestCase, self).setUp()
|
||||
self.manager = importutils.import_object(FLAGS.consoleauth_manager)
|
||||
self.manager = manager.ConsoleAuthManager()
|
||||
self.context = context.get_admin_context()
|
||||
|
||||
def test_tokens_expire(self):
|
|
@ -0,0 +1,74 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012, 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
|
||||
"""
|
||||
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context
|
||||
from nova import flags
|
||||
from nova import rpc
|
||||
from nova import test
|
||||
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class ConsoleAuthRpcAPITestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ConsoleAuthRpcAPITestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(ConsoleAuthRpcAPITestCase, self).tearDown()
|
||||
|
||||
def _test_consoleauth_api(self, method, **kwargs):
|
||||
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||
rpcapi = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
expected_retval = 'foo'
|
||||
expected_msg = rpcapi.make_msg(method, **kwargs)
|
||||
expected_msg['version'] = rpcapi.RPC_API_VERSION
|
||||
|
||||
self.call_ctxt = None
|
||||
self.call_topic = None
|
||||
self.call_msg = None
|
||||
self.call_timeout = None
|
||||
|
||||
def _fake_call(_ctxt, _topic, _msg, _timeout):
|
||||
self.call_ctxt = _ctxt
|
||||
self.call_topic = _topic
|
||||
self.call_msg = _msg
|
||||
self.call_timeout = _timeout
|
||||
return expected_retval
|
||||
|
||||
self.stubs.Set(rpc, 'call', _fake_call)
|
||||
|
||||
retval = getattr(rpcapi, method)(ctxt, **kwargs)
|
||||
|
||||
self.assertEqual(retval, expected_retval)
|
||||
self.assertEqual(self.call_ctxt, ctxt)
|
||||
self.assertEqual(self.call_topic, FLAGS.consoleauth_topic)
|
||||
self.assertEqual(self.call_msg, expected_msg)
|
||||
self.assertEqual(self.call_timeout, None)
|
||||
|
||||
def test_authorize_console(self):
|
||||
self._test_consoleauth_api('authorize_console', token='token',
|
||||
console_type='ctype', host='h', port='p',
|
||||
internal_access_path='iap')
|
||||
|
||||
def test_check_token(self):
|
||||
self._test_consoleauth_api('check_token', token='t')
|
|
@ -3484,26 +3484,23 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
'console_type': fake_console_type,
|
||||
'host': 'fake_console_host',
|
||||
'port': 'fake_console_port',
|
||||
'internal_access_path': 'fake_access_path',
|
||||
'access_url': 'fake_console_url'}
|
||||
'internal_access_path': 'fake_access_path'}
|
||||
fake_connect_info2 = copy.deepcopy(fake_connect_info)
|
||||
fake_connect_info2['access_url'] = 'fake_console_url'
|
||||
|
||||
self.mox.StubOutWithMock(rpc, 'call')
|
||||
|
||||
rpc_msg1 = {'method': 'get_vnc_console',
|
||||
'args': {'instance_uuid': fake_instance['uuid'],
|
||||
'console_type': fake_console_type}}
|
||||
# 2nd rpc.call receives almost everything from fake_connect_info
|
||||
# except 'access_url'
|
||||
rpc_msg2_args = dict([(k, v)
|
||||
for k, v in fake_connect_info.items()
|
||||
if k != 'access_url'])
|
||||
rpc_msg2 = {'method': 'authorize_console',
|
||||
'args': rpc_msg2_args}
|
||||
'args': fake_connect_info,
|
||||
'version': '1.0'}
|
||||
|
||||
rpc.call(self.context, 'compute.%s' % fake_instance['host'],
|
||||
rpc_msg1).AndReturn(fake_connect_info)
|
||||
rpc_msg1).AndReturn(fake_connect_info2)
|
||||
rpc.call(self.context, FLAGS.consoleauth_topic,
|
||||
rpc_msg2).AndReturn(None)
|
||||
rpc_msg2, None).AndReturn(None)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import eventlet.green
|
|||
import eventlet.greenio
|
||||
import eventlet.wsgi
|
||||
|
||||
from nova.consoleauth import rpcapi as consoleauth_rpcapi
|
||||
from nova import context
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
|
@ -49,8 +50,6 @@ xvp_proxy_opts = [
|
|||
FLAGS = flags.FLAGS
|
||||
FLAGS.register_opts(xvp_proxy_opts)
|
||||
|
||||
flags.DECLARE('consoleauth_topic', 'nova.consoleauth')
|
||||
|
||||
|
||||
class XCPVNCProxy(object):
|
||||
"""Class to use the xvp auth protocol to proxy instance vnc consoles."""
|
||||
|
@ -145,9 +144,8 @@ class XCPVNCProxy(object):
|
|||
return "Invalid Request"
|
||||
|
||||
ctxt = context.get_admin_context()
|
||||
connect_info = rpc.call(ctxt, FLAGS.consoleauth_topic,
|
||||
{'method': 'check_token',
|
||||
'args': {'token': token}})
|
||||
api = consoleauth_rpcapi.ConsoleAuthAPI()
|
||||
connect_info = api.check_token(ctxt, token)
|
||||
|
||||
if not connect_info:
|
||||
LOG.audit(_("Request made with invalid token: %s"), req)
|
||||
|
|
Loading…
Reference in New Issue