Reject the cell name include '!', '.' and '@' for Nova API
Nova cells use '!', '.' and '@' for routing the instance in cells. So those special characters can't include in the cell name. This patch adds '@' validation for v2 API, and adds '!', '.' and '@' for v2.1 API. Change-Id: I5cb704a44c2abfb0bfb5b42d4aa8fefe35cc1523 Partial-Bug: #1491511
This commit is contained in:
parent
bc0cc457ba
commit
e5982de3e9
|
@ -187,12 +187,14 @@ class Controller(object):
|
|||
return {}
|
||||
|
||||
def _validate_cell_name(self, cell_name):
|
||||
"""Validate cell name is not empty and doesn't contain '!' or '.'."""
|
||||
"""Validate cell name is not empty and doesn't contain '!',
|
||||
'.' or '@'.
|
||||
"""
|
||||
if not cell_name:
|
||||
msg = _("Cell name cannot be empty")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
if '!' in cell_name or '.' in cell_name:
|
||||
msg = _("Cell name cannot contain '!' or '.'")
|
||||
if '!' in cell_name or '.' in cell_name or '@' in cell_name:
|
||||
msg = _("Cell name cannot contain '!', '.' or '@'")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
def _validate_cell_type(self, cell_type):
|
||||
|
|
|
@ -21,7 +21,7 @@ create = {
|
|||
'cell': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': parameter_types.name,
|
||||
'name': parameter_types.cell_name,
|
||||
'type': {
|
||||
'type': 'string',
|
||||
'enum': ['parent', 'child'],
|
||||
|
@ -61,7 +61,7 @@ update = {
|
|||
'cell': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': parameter_types.name,
|
||||
'name': parameter_types.cell_name,
|
||||
'type': {
|
||||
'type': 'string',
|
||||
'enum': ['parent', 'child'],
|
||||
|
|
|
@ -40,6 +40,7 @@ def _get_all_chars():
|
|||
for i in range(0xFFFF):
|
||||
yield six.unichr(i)
|
||||
|
||||
|
||||
# build a regex that matches all printable characters. This allows
|
||||
# spaces in the middle of the name. Also note that the regexp below
|
||||
# deliberately allows the empty string. This is so only the constraint
|
||||
|
@ -47,13 +48,25 @@ def _get_all_chars():
|
|||
# empty string is tested. Otherwise it is not deterministic which
|
||||
# constraint fails and this causes issues for some unittests when
|
||||
# PYTHONHASHSEED is set randomly.
|
||||
_printable = ''.join(c for c in _get_all_chars() if _is_printable(c))
|
||||
def _get_printable(exclude=None):
|
||||
if exclude is None:
|
||||
exclude = []
|
||||
return ''.join(c for c in _get_all_chars()
|
||||
if _is_printable(c) and c not in exclude)
|
||||
|
||||
|
||||
_printable_ws = ''.join(c for c in _get_all_chars()
|
||||
if unicodedata.category(c) == "Zs")
|
||||
|
||||
valid_name_regex = '^(?![%s])[%s]*(?<![%s])$' % (
|
||||
re.escape(_printable_ws), re.escape(_printable), re.escape(_printable_ws))
|
||||
re.escape(_printable_ws), re.escape(_get_printable()),
|
||||
re.escape(_printable_ws))
|
||||
|
||||
# cell's name disallow '!', '.' and '@'.
|
||||
valid_cell_name_regex = '^(?![%s])[%s]*(?<![%s])$' % (
|
||||
re.escape(_printable_ws),
|
||||
re.escape(_get_printable(exclude=['!', '.', '@'])),
|
||||
re.escape(_printable_ws))
|
||||
|
||||
boolean = {
|
||||
'type': ['boolean', 'string'],
|
||||
|
@ -109,6 +122,12 @@ name = {
|
|||
}
|
||||
|
||||
|
||||
cell_name = {
|
||||
'type': 'string', 'minLength': 1, 'maxLength': 255,
|
||||
'pattern': valid_cell_name_regex,
|
||||
}
|
||||
|
||||
|
||||
tcp_udp_port = {
|
||||
'type': ['integer', 'string'], 'pattern': '^[0-9]*$',
|
||||
'minimum': 0, 'maximum': 65535,
|
||||
|
|
|
@ -286,9 +286,32 @@ class CellsTestV21(BaseCellsTest):
|
|||
|
||||
req = self._get_request("cells")
|
||||
req.environ['nova.context'] = self.context
|
||||
res_dict = self.controller.create(req, body=body)
|
||||
cell = res_dict['cell']
|
||||
self.assertEqual(cell['name'], 'moo.cow')
|
||||
self.assertRaises(self.bad_request, self.controller.create,
|
||||
req, body=body)
|
||||
|
||||
def test_cell_create_name_with_exclamation_point_raises(self):
|
||||
body = {'cell': {'name': 'moo!cow',
|
||||
'username': 'fred',
|
||||
'password': 'secret',
|
||||
'rpc_host': 'r3.example.org',
|
||||
'type': 'parent'}}
|
||||
|
||||
req = self._get_request("cells")
|
||||
req.environ['nova.context'] = self.context
|
||||
self.assertRaises(self.bad_request, self.controller.create,
|
||||
req, body=body)
|
||||
|
||||
def test_cell_create_name_with_at_raises(self):
|
||||
body = {'cell': {'name': 'moo@cow',
|
||||
'username': 'fred',
|
||||
'password': 'secret',
|
||||
'rpc_host': 'r3.example.org',
|
||||
'type': 'parent'}}
|
||||
|
||||
req = self._get_request("cells")
|
||||
req.environ['nova.context'] = self.context
|
||||
self.assertRaises(self.bad_request, self.controller.create,
|
||||
req, body=body)
|
||||
|
||||
def test_cell_create_name_with_invalid_type_raises(self):
|
||||
body = {'cell': {'name': 'moocow',
|
||||
|
@ -681,32 +704,11 @@ class CellsTestV2(CellsTestV21):
|
|||
cell_extension = 'compute_extension:cells'
|
||||
bad_request = exc.HTTPBadRequest
|
||||
|
||||
def test_cell_create_name_with_invalid_character_raises(self):
|
||||
body = {'cell': {'name': 'moo!cow',
|
||||
'username': 'fred',
|
||||
'password': 'secret',
|
||||
'rpc_host': 'r3.example.org',
|
||||
'type': 'parent'}}
|
||||
|
||||
req = self._get_request("cells")
|
||||
req.environ['nova.context'] = self.context
|
||||
self.assertRaises(self.bad_request,
|
||||
self.controller.create, req, body=body)
|
||||
|
||||
def _get_cell_controller(self, ext_mgr):
|
||||
return cells_ext_v2.Controller(ext_mgr)
|
||||
|
||||
def test_cell_create_name_with_dot_raises(self):
|
||||
body = {'cell': {'name': 'moo.cow',
|
||||
'username': 'fred',
|
||||
'password': 'secret',
|
||||
'rpc_host': 'r3.example.org',
|
||||
'type': 'parent'}}
|
||||
|
||||
req = self._get_request("cells")
|
||||
req.environ['nova.context'] = self.context
|
||||
self.assertRaises(exc.HTTPBadRequest,
|
||||
self.controller.create, req, body=body)
|
||||
def test_cell_create_name_with_invalid_character_raises(self):
|
||||
pass
|
||||
|
||||
def test_cell_create_rpc_port_with_null(self):
|
||||
body = {'cell': {'name': 'fake',
|
||||
|
|
Loading…
Reference in New Issue