summaryrefslogtreecommitdiff
path: root/nova/api
diff options
context:
space:
mode:
authorSylvain Bauza <sbauza@redhat.com>2022-07-08 17:23:01 +0200
committerSylvain Bauza <sbauza@redhat.com>2022-07-28 11:05:50 +0200
commita755e5d9f25c7bb06533a3799d9c39b74f334873 (patch)
treed5ff4cba5b9c734940b6b229340336583d58f32b /nova/api
parent09239fc2eadcf266b42c640e386c7cebad715eea (diff)
downloadnova-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.py5
-rw-r--r--nova/api/openstack/compute/keypairs.py10
-rw-r--r--nova/api/openstack/compute/rest_api_version_history.rst8
-rw-r--r--nova/api/openstack/compute/schemas/keypairs.py11
-rw-r--r--nova/api/validation/parameter_types.py14
-rw-r--r--nova/api/validation/validators.py23
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,