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
|
If using noVNC >= 1.0.0, you should use ``vnc_lite.html`` instead of
|
||||||
``vnc_auto.html``.
|
``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:
|
Related options:
|
||||||
|
|
||||||
* novncproxy_host
|
* novncproxy_host
|
||||||
|
@@ -75,9 +75,13 @@ class ConsoleAuthToken(base.NovaTimestampObject, base.NovaObject):
|
|||||||
# top-level 'token' query parameter was removed. The 'path'
|
# top-level 'token' query parameter was removed. The 'path'
|
||||||
# parameter is supported in older noVNC versions, so it is
|
# parameter is supported in older noVNC versions, so it is
|
||||||
# backward compatible.
|
# backward compatible.
|
||||||
qparams = {'path': '?token=%s' % self.token}
|
parsed_base_url = urlparse.urlparse(self.access_url_base)
|
||||||
return '%s?%s' % (self.access_url_base,
|
qparams = urlparse.parse_qs(parsed_base_url.query)
|
||||||
urlparse.urlencode(qparams))
|
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:
|
else:
|
||||||
return '%s?token=%s' % (self.access_url_base, self.token)
|
return '%s?token=%s' % (self.access_url_base, self.token)
|
||||||
|
|
||||||
|
@@ -99,6 +99,41 @@ class _TestConsoleAuthToken(object):
|
|||||||
def test_authorize_novnc(self):
|
def test_authorize_novnc(self):
|
||||||
self._test_authorize('novnc')
|
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')
|
@mock.patch('nova.db.main.api.console_auth_token_create')
|
||||||
def test_authorize_duplicate_token(self, mock_create):
|
def test_authorize_duplicate_token(self, mock_create):
|
||||||
mock_create.side_effect = DBDuplicateEntry()
|
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