diff options
author | Sylvain Bauza <sbauza@redhat.com> | 2022-07-08 17:23:01 +0200 |
---|---|---|
committer | Sylvain Bauza <sbauza@redhat.com> | 2022-07-28 11:05:50 +0200 |
commit | a755e5d9f25c7bb06533a3799d9c39b74f334873 (patch) | |
tree | d5ff4cba5b9c734940b6b229340336583d58f32b /nova/api | |
parent | 09239fc2eadcf266b42c640e386c7cebad715eea (diff) | |
download | nova-a755e5d9f25c7bb06533a3799d9c39b74f334873.tar.gz |
api: Drop generating a keypair and add special chars to naming
As agreed in the spec, we will both drop the generation support for a keypair
but we'll also accept @ (at) and . (dot) chars in the keyname, all of them in
the same API microversion.
Rebased the work from I5de15935e83823afa545a250cf84f6a7a37036b4
APIImpact
Implements: blueprint keypair-generation-removal
Co-Authored-By: Nicolas Parquet <nicolas.parquet@gandi.net>
Change-Id: I6a7c71fb4385348c87067543d0454f302907395e
Diffstat (limited to 'nova/api')
-rw-r--r-- | nova/api/openstack/api_version_request.py | 5 | ||||
-rw-r--r-- | nova/api/openstack/compute/keypairs.py | 10 | ||||
-rw-r--r-- | nova/api/openstack/compute/rest_api_version_history.rst | 8 | ||||
-rw-r--r-- | nova/api/openstack/compute/schemas/keypairs.py | 11 | ||||
-rw-r--r-- | nova/api/validation/parameter_types.py | 14 | ||||
-rw-r--r-- | nova/api/validation/validators.py | 23 |
6 files changed, 64 insertions, 7 deletions
diff --git a/nova/api/openstack/api_version_request.py b/nova/api/openstack/api_version_request.py index 4345e2c914..a3a8b1f41e 100644 --- a/nova/api/openstack/api_version_request.py +++ b/nova/api/openstack/api_version_request.py @@ -249,6 +249,9 @@ REST_API_VERSION_HISTORY = """REST API Version History: server responses regardless of policy configuration. * 2.91 - Add support to unshelve instance to a specific host and to pin/unpin AZ. + * 2.92 - Drop generation of keypair, add keypair name validation on + ``POST /os-keypairs`` and allow including @ and dot (.) characters + in keypair name. """ # The minimum and maximum versions of the API supported @@ -257,7 +260,7 @@ REST_API_VERSION_HISTORY = """REST API Version History: # Note(cyeoh): This only applies for the v2.1 API once microversions # support is fully merged. It does not affect the V2 API. _MIN_API_VERSION = '2.1' -_MAX_API_VERSION = '2.91' +_MAX_API_VERSION = '2.92' DEFAULT_API_VERSION = _MIN_API_VERSION # Almost all proxy APIs which are related to network, images and baremetal diff --git a/nova/api/openstack/compute/keypairs.py b/nova/api/openstack/compute/keypairs.py index 65dacfa638..40b702bdb5 100644 --- a/nova/api/openstack/compute/keypairs.py +++ b/nova/api/openstack/compute/keypairs.py @@ -43,15 +43,19 @@ class KeypairController(wsgi.Controller): @wsgi.Controller.api_version("2.10") @wsgi.response(201) @wsgi.expected_errors((400, 403, 409)) - @validation.schema(keypairs.create_v210) + @validation.schema(keypairs.create_v210, "2.10", "2.91") + @validation.schema(keypairs.create_v292, "2.92") def create(self, req, body): """Create or import keypair. + Keypair generations are allowed until version 2.91. + Afterwards, only imports are allowed. + A policy check restricts users from creating keys for other users params: keypair object with: name (required) - string - public_key (optional) - string + public_key (optional or required if >=2.92) - string type (optional) - string user_id (optional) - string """ @@ -114,6 +118,8 @@ class KeypairController(wsgi.Controller): context, user_id, name, params['public_key'], key_type_value) else: + # public_key is a required field starting with 2.92 so this + # generation should only happen with older versions. keypair, private_key = self.api.create_key_pair( context, user_id, name, key_type_value) keypair['private_key'] = private_key diff --git a/nova/api/openstack/compute/rest_api_version_history.rst b/nova/api/openstack/compute/rest_api_version_history.rst index b1dfadf3fb..b65e50c62f 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -1211,3 +1211,11 @@ responses is now visible to all users. Previously this was an admin-only field. Add support to unshelve instance to a specific host. Add support to pin a server to an availability zone or unpin a server from any availability zone. + +.. _microversion 2.92: + +2.92 +---- + +The ``POST /os-keypairs`` API now forbids to generate a keypair and allows new +safe characters, specifically '@' and '.' (dot character). diff --git a/nova/api/openstack/compute/schemas/keypairs.py b/nova/api/openstack/compute/schemas/keypairs.py index 7ebd3c7433..74b992c3e3 100644 --- a/nova/api/openstack/compute/schemas/keypairs.py +++ b/nova/api/openstack/compute/schemas/keypairs.py @@ -23,7 +23,7 @@ create = { 'keypair': { 'type': 'object', 'properties': { - 'name': parameter_types.name, + 'name': parameter_types.keypair_name_special_chars, 'public_key': {'type': 'string'}, }, 'required': ['name'], @@ -46,7 +46,7 @@ create_v22 = { 'keypair': { 'type': 'object', 'properties': { - 'name': parameter_types.name, + 'name': parameter_types.keypair_name_special_chars, 'type': { 'type': 'string', 'enum': ['ssh', 'x509'] @@ -67,7 +67,7 @@ create_v210 = { 'keypair': { 'type': 'object', 'properties': { - 'name': parameter_types.name, + 'name': parameter_types.keypair_name_special_chars, 'type': { 'type': 'string', 'enum': ['ssh', 'x509'] @@ -83,6 +83,11 @@ create_v210 = { 'additionalProperties': False, } +create_v292 = copy.deepcopy(create_v210) +create_v292['properties']['keypair']['properties']['name'] = (parameter_types. + keypair_name_special_chars_292) +create_v292['properties']['keypair']['required'] = ['name', 'public_key'] + index_query_schema_v20 = { 'type': 'object', 'properties': {}, diff --git a/nova/api/validation/parameter_types.py b/nova/api/validation/parameter_types.py index 79badb7d14..bdb3ad3c83 100644 --- a/nova/api/validation/parameter_types.py +++ b/nova/api/validation/parameter_types.py @@ -290,7 +290,7 @@ fqdn = { name = { # NOTE: Nova v2.1 API contains some 'name' parameters such - # as keypair, server, flavor, aggregate and so on. They are + # as server, flavor, aggregate and so on. They are # stored in the DB and Nova specific parameters. # This definition is used for all their parameters. 'type': 'string', 'minLength': 1, 'maxLength': 255, @@ -304,6 +304,18 @@ az_name = { } +keypair_name_special_chars = {'allOf': [name, { + 'type': 'string', 'minLength': 1, 'maxLength': 255, + 'format': 'keypair_name_20' +}]} + + +keypair_name_special_chars_292 = {'allOf': [name, { + 'type': 'string', 'minLength': 1, 'maxLength': 255, + 'format': 'keypair_name_292' +}]} + + az_name_with_leading_trailing_spaces = { 'type': 'string', 'minLength': 1, 'maxLength': 255, 'format': 'az_name_with_leading_trailing_spaces' diff --git a/nova/api/validation/validators.py b/nova/api/validation/validators.py index ed2f211eee..b0e9478d35 100644 --- a/nova/api/validation/validators.py +++ b/nova/api/validation/validators.py @@ -17,6 +17,7 @@ Internal implementation of request Body validating middleware. """ import re +import string import jsonschema from jsonschema import exceptions as jsonschema_exc @@ -153,6 +154,28 @@ def _validate_az_name(instance): raise exception.InvalidName(reason=regex.reason) +@jsonschema.FormatChecker.cls_checks('keypair_name_20', + exception.InvalidName) +def _validate_keypair_name_20(keypair_name): + safe_chars = "_- " + string.digits + string.ascii_letters + return _validate_keypair_name(keypair_name, safe_chars) + + +@jsonschema.FormatChecker.cls_checks('keypair_name_292', + exception.InvalidName) +def _validate_keypair_name_292(keypair_name): + safe_chars = "@._- " + string.digits + string.ascii_letters + return _validate_keypair_name(keypair_name, safe_chars) + + +def _validate_keypair_name(keypair_name, safe_chars): + clean_value = "".join(x for x in keypair_name if x in safe_chars) + if clean_value != keypair_name: + reason = _("Only expected characters: [%s]") % safe_chars + raise exception.InvalidName(reason=reason) + return True + + def _soft_validate_additional_properties(validator, additional_properties_value, instance, |