diff --git a/nova/api/openstack/compute/legacy_v2/contrib/cells.py b/nova/api/openstack/compute/legacy_v2/contrib/cells.py index 90cf227d43cd..8e2c5e969235 100644 --- a/nova/api/openstack/compute/legacy_v2/contrib/cells.py +++ b/nova/api/openstack/compute/legacy_v2/contrib/cells.py @@ -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): diff --git a/nova/api/openstack/compute/schemas/cells.py b/nova/api/openstack/compute/schemas/cells.py index 37a9ed5cc0de..2ee79e32b4c5 100644 --- a/nova/api/openstack/compute/schemas/cells.py +++ b/nova/api/openstack/compute/schemas/cells.py @@ -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'], diff --git a/nova/api/validation/parameter_types.py b/nova/api/validation/parameter_types.py index a0126e7270f8..4fbf6477a3d4 100644 --- a/nova/api/validation/parameter_types.py +++ b/nova/api/validation/parameter_types.py @@ -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]*(?