Respect supplied arguments in novncproxy_base_url
In case an operator want to have NoVNC under a certain subpath instead of the subdomain or custom port, they would need to instruct NoVNC to establish WebSocket connection with a correct URI, which is passed through `path` argument. The implements parsing of novncproxy_base_url and appending token to the request rather then re-writing request completely. Implements: blueprint novnc-base-url-respect-extra-params Change-Id: Ie900f4963a998222942c3d54a757ef1e625f7bf9
This commit is contained in:
@ -75,6 +75,10 @@ instance and, by extension, the VNC sessions.
|
||||
If using noVNC >= 1.0.0, you should use ``vnc_lite.html`` instead of
|
||||
``vnc_auto.html``.
|
||||
|
||||
You can also supply extra request arguments which will be passed to
|
||||
the backend. This might be useful to move console URL to subpath, for example:
|
||||
``http://127.0.0.1/novnc/vnc_auto.html?path=novnc``
|
||||
|
||||
Related options:
|
||||
|
||||
* novncproxy_host
|
||||
|
@ -75,9 +75,13 @@ class ConsoleAuthToken(base.NovaTimestampObject, base.NovaObject):
|
||||
# top-level 'token' query parameter was removed. The 'path'
|
||||
# parameter is supported in older noVNC versions, so it is
|
||||
# backward compatible.
|
||||
qparams = {'path': '?token=%s' % self.token}
|
||||
return '%s?%s' % (self.access_url_base,
|
||||
urlparse.urlencode(qparams))
|
||||
parsed_base_url = urlparse.urlparse(self.access_url_base)
|
||||
qparams = urlparse.parse_qs(parsed_base_url.query)
|
||||
qpath = '%s?token=%s' % (qparams.get('path', [''])[0],
|
||||
self.token)
|
||||
qparams.update({'path': qpath})
|
||||
return parsed_base_url._replace(
|
||||
query=urlparse.urlencode(qparams, doseq=True)).geturl()
|
||||
else:
|
||||
return '%s?token=%s' % (self.access_url_base, self.token)
|
||||
|
||||
|
@ -99,6 +99,41 @@ class _TestConsoleAuthToken(object):
|
||||
def test_authorize_novnc(self):
|
||||
self._test_authorize('novnc')
|
||||
|
||||
@mock.patch('nova.db.main.api.console_auth_token_create')
|
||||
def _test_access_novnc_custom_request(
|
||||
self, url_base, url_expected, mock_create):
|
||||
ttl = 10
|
||||
expires = timeutils.utcnow_ts() + ttl
|
||||
db_dict = copy.deepcopy(fakes.fake_token_dict)
|
||||
db_dict['access_url_base'] = url_base
|
||||
db_dict['expires'] = expires
|
||||
db_dict['console_type'] = 'novnc'
|
||||
mock_create.return_value = db_dict
|
||||
|
||||
obj = token_obj.ConsoleAuthToken(
|
||||
context=self.context,
|
||||
console_type=db_dict['console_type'],
|
||||
host=fakes.fake_token_dict['host'],
|
||||
port=fakes.fake_token_dict['port'],
|
||||
instance_uuid=fakes.fake_token_dict['instance_uuid'],
|
||||
access_url_base=url_base,
|
||||
)
|
||||
|
||||
with mock.patch('uuid.uuid4', return_value=fakes.fake_token):
|
||||
obj.authorize(ttl)
|
||||
token_req = urlparse.quote_plus('token=%s' % fakes.fake_token)
|
||||
expected_url = '%3F'.join([url_expected, token_req])
|
||||
self.assertEqual(expected_url, obj.access_url)
|
||||
|
||||
def test_access_novnc_custom_path(self):
|
||||
base_url = 'http://fake.url.fake/novnc/root.html?path=novnc'
|
||||
self._test_access_novnc_custom_request(base_url, base_url)
|
||||
|
||||
def test_access_novnc_random_req(self):
|
||||
base_url = 'http://fake.url.fake/novnc/root.html?noop=true'
|
||||
expected_url = 'http://fake.url.fake/novnc/root.html?noop=true&path='
|
||||
self._test_access_novnc_custom_request(base_url, expected_url)
|
||||
|
||||
@mock.patch('nova.db.main.api.console_auth_token_create')
|
||||
def test_authorize_duplicate_token(self, mock_create):
|
||||
mock_create.side_effect = DBDuplicateEntry()
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Option ``novncproxy_base_url`` does now respect supplied custom query
|
||||
which might be used to move NoVNC to a subdirectory or pass an extra
|
||||
argument to NoVNC.
|
Reference in New Issue
Block a user