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/?token=123-456-789" 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>')
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' } 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()
def test_new_websocket_client_internal_access_path_rfb( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'internal_access_path': 'vmid', 'console_type': 'novnc', 'access_url_base': 'https://example.net:6080' } validate.return_value = objects.ConsoleAuthToken(**params) tsock = mock.MagicMock() HTTP_RESP = "HTTP/1.1 200 OK\r\n\r\n" RFB_MSG = "RFB 003.003\n" # RFB negotiation message may arrive earlier. tsock.recv.side_effect = [HTTP_RESP + RFB_MSG, HTTP_RESP] self.wh.socket.return_value = tsock self.wh.path = "http://127.0.0.1/?token=123-456-789" self.wh.headers = self.fake_header self.wh.new_websocket_client() validate.assert_called_with(mock.ANY, "123-456-789") self.wh.socket.assert_called_with('node1', 10000, connect=True) tsock.recv.assert_has_calls( [mock.call(4096, socket.MSG_PEEK), mock.call(len(HTTP_RESP))]) self.wh.do_proxy.assert_called_with(tsock)
def test_new_websocket_client_http_forwarded_proto_https( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'console_type': 'serial', 'access_url_base': 'wss://example.net:6080' } validate.return_value = objects.ConsoleAuthToken(**params) header = { 'cookie': 'token="123-456-789"', 'Origin': 'http://example.net:6080', 'Host': 'example.net:6080', 'X-Forwarded-Proto': 'https' } self.wh.socket.return_value = '<socket>' self.wh.path = "https://127.0.0.1/" self.wh.headers = header self.wh.new_websocket_client() 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>')
def test_new_websocket_client_internal_access_path(self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'internal_access_path': 'vmid', 'console_type': 'novnc', 'access_url_base': 'https://example.net:6080' } validate.return_value = objects.ConsoleAuthToken(**params) tsock = mock.MagicMock() tsock.recv.return_value = "HTTP/1.1 200 OK\r\n\r\n" self.wh.socket.return_value = tsock self.wh.path = "http://127.0.0.1/?token=123-456-789" self.wh.headers = self.fake_header self.wh.new_websocket_client() validate.assert_called_with(mock.ANY, "123-456-789") self.wh.socket.assert_called_with('node1', 10000, connect=True) tsock.send.assert_called_with(test.MatchType(bytes)) self.wh.do_proxy.assert_called_with(tsock)
def test_new_websocket_client_internal_access_path_err( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'host': 'node1', 'port': '10000', 'internal_access_path': 'xxx', 'console_type': 'novnc', 'access_url_base': 'https://example.net:6080' } validate.return_value = objects.ConsoleAuthToken(**params) tsock = mock.MagicMock() tsock.recv.return_value = "HTTP/1.1 500 Internal Server Error\r\n\r\n" self.wh.socket.return_value = tsock self.wh.path = "http://127.0.0.1/?token=123-456-789" self.wh.headers = self.fake_header self.assertRaises(exception.InvalidConnectionInfo, self.wh.new_websocket_client) validate.assert_called_with(mock.ANY, "123-456-789")
def _create_service_in_cell(ctxt, cell, binary, is_deleted=False, disabled=False, version=None, create_token_auth=False): with context.target_cell(ctxt, cell) as cctxt: service = objects.Service(context=cctxt, binary=binary, disabled=disabled, host='dontcare') if version: service.version = version service.create() if is_deleted: service.destroy() if create_token_auth: # We have to create an instance in order to create a token # auth. inst = objects.Instance(context=cctxt, uuid=uuidutils.generate_uuid()) inst.create() auth = objects.ConsoleAuthToken(context=cctxt, console_type='novnc', host='hostname', port=6080, instance_uuid=inst.uuid) auth.authorize(CONF.consoleauth.token_ttl) return service
def setUp(self): super(ConsoleAuthTokenTestCase, self).setUp() self.context = context.RequestContext('fake-user', 'fake-project') instance = objects.Instance(context=self.context, project_id=self.context.project_id, uuid=uuidsentinel.fake_instance) instance.create() self.console = objects.ConsoleAuthToken( context=self.context, instance_uuid=uuidsentinel.fake_instance, console_type='fake-type', host='fake-host', port=1000, internal_access_path='fake-internal_access_path', access_url_base='fake-external_access_path') self.token = self.console.authorize(100)
def test_new_websocket_client_novnc_bad_console_type( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'console_type': 'bad-console-type' } validate.return_value = objects.ConsoleAuthToken(**params) self.wh.path = "http://127.0.0.1/" self.wh.headers = self.fake_header self.assertRaises(exception.ValidationError, self.wh.new_websocket_client)
def test_new_websocket_client_novnc_https_origin_proto_ws( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'console_type': 'serial', 'access_url_base': 'ws://example.net:6080' } validate.return_value = objects.ConsoleAuthToken(**params) self.wh.path = "https://127.0.0.1/" self.wh.headers = self.fake_header self.assertRaises(exception.ValidationError, self.wh.new_websocket_client)
class ConsoleAuthTokensExtensionTestV231(ConsoleAuthTokensExtensionTestV21): def setUp(self): super(ConsoleAuthTokensExtensionTestV231, self).setUp() self.req.api_version_request = api_version_request.APIVersionRequest( '2.31') @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) self.assertEqual(self._EXPECTED_OUTPUT_DB, output) mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)
def test_malformed_cookie(self, validate, check_port): 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/" self.wh.headers = self.fake_header_malformed_cookie self.wh.new_websocket_client() 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>')
def test_new_websocket_client_novnc_no_origin_header( self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'console_type': 'novnc' } validate.return_value = objects.ConsoleAuthToken(**params) self.wh.socket.return_value = '<socket>' self.wh.path = "http://127.0.0.1/" self.wh.headers = self.fake_header_no_origin self.wh.new_websocket_client() 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>')
def test_new_websocket_client_ipv6_url(self, validate, check_port): params = { 'id': 1, 'token': '123-456-789', 'instance_uuid': uuids.instance, 'host': 'node1', 'port': '10000', 'console_type': 'novnc', 'access_url_base': 'https://[2001:db8::1]:6080' } validate.return_value = objects.ConsoleAuthToken(**params) self.wh.socket.return_value = '<socket>' self.wh.path = "http://[2001:db8::1]/?%s" % self.path self.wh.headers = self.fake_header_ipv6 self.wh.new_websocket_client() 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>')
def test_new_websocket_client_py273_good_scheme(self, validate, check_port, mock_sys): mock_sys.version_info.return_value = (2, 7, 3) 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() 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>')
def test_new_websocket_client(self, validate, check_port): 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/?token=123-456-789" self.wh.headers = self.fake_header self.wh.new_websocket_client() 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>') # ensure that token is masked when logged connection_info = self.wh.msg.mock_calls[0][1][1] self.assertEqual('***', connection_info.token)
class ConsoleAuthTokensExtensionTestV21(test.NoDBTestCase): controller_class = console_auth_tokens_v21 _EXPECTED_OUTPUT = { 'console': { 'instance_uuid': fakes.FAKE_UUID, 'host': 'fake_host', 'port': '1234', 'internal_access_path': 'fake_access_path' } } # The database backend returns a ConsoleAuthToken.to_dict() and o.vo # StringField are unicode. And the port is an IntegerField. _EXPECTED_OUTPUT_DB = copy.deepcopy(_EXPECTED_OUTPUT) _EXPECTED_OUTPUT_DB['console'].update({ 'host': u'fake_host', 'port': 1234, 'internal_access_path': u'fake_access_path' }) def setUp(self): super(ConsoleAuthTokensExtensionTestV21, self).setUp() self.controller = self.controller_class.ConsoleAuthTokensController() self.req = fakes.HTTPRequest.blank('', use_admin_context=True) self.context = self.req.environ['nova.context'] @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)) def test_get_console_connect_info(self, mock_validate): output = self.controller.show(self.req, fakes.FAKE_UUID) self.assertEqual(self._EXPECTED_OUTPUT_DB, output) mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID) @mock.patch('nova.objects.ConsoleAuthToken.validate', side_effect=exception.InvalidToken(token='***')) 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) mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID) @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)) 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) mock_validate.assert_called_once_with(self.context, fakes.FAKE_UUID)