From 7491417323a38b2d95dafe49d6883a45faa5455d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 15 Apr 2024 11:17:50 +0100 Subject: [PATCH] api: Migrate to JSON Schema Draft 2020-12 OpenAPI 3.1 is a superset of JSON Schema Draft 2020-12. As a result, we wish to migrate our current schemas to this. There are a couple of issues to address: - 'exclusiveMinimum' is now an integer and allows you to define an minimum for an exclusive range, to complement 'minimum' which is used for an inclusive range. We can drop it and use 'minimum' with a larger number (since draft 6 [1]). - 'integer' types can now accept a fractional part but only if it's zero (i.e. '1.0' is permissible, '1.1' is not) (since draft 6 [1]). - 'items' has been replaced with 'prefixItems' for describing the format of an array item (since draft 2020-12 [2]) [1] https://json-schema.org/draft-06/json-schema-release-notes [2] https://json-schema.org/draft/2020-12/release-notes Change-Id: I1486701786960eef95c5c42674bff1b2d7d686e2 Signed-off-by: Stephen Finucane --- nova/api/openstack/compute/schemas/flavors.py | 2 +- nova/api/openstack/compute/schemas/server_groups.py | 6 ++++-- nova/api/validation/validators.py | 4 ++-- nova/tests/unit/test_api_validation.py | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/nova/api/openstack/compute/schemas/flavors.py b/nova/api/openstack/compute/schemas/flavors.py index f0cecb3dc493..6f4d609e6554 100644 --- a/nova/api/openstack/compute/schemas/flavors.py +++ b/nova/api/openstack/compute/schemas/flavors.py @@ -50,7 +50,7 @@ create = { 'rxtx_factor': { 'type': ['number', 'string'], 'pattern': r'^[0-9]+(\.[0-9]+)?$', - 'minimum': 0, 'exclusiveMinimum': True, + 'minimum': 1, # maximum's value is limited to db constant's # SQL_SP_FLOAT_MAX (in nova/db/constants.py) 'maximum': 3.40282e+38 diff --git a/nova/api/openstack/compute/schemas/server_groups.py b/nova/api/openstack/compute/schemas/server_groups.py index 102c6df869ec..fee2cbd30b98 100644 --- a/nova/api/openstack/compute/schemas/server_groups.py +++ b/nova/api/openstack/compute/schemas/server_groups.py @@ -31,7 +31,7 @@ create = { # enumerated values. It's changed to a single string value # in 2.64. 'type': 'array', - 'items': [ + 'prefixItems': [ { 'type': 'string', 'enum': ['anti-affinity', 'affinity'], @@ -53,7 +53,9 @@ create = { create_v215 = copy.deepcopy(create) policies = create_v215['properties']['server_group']['properties']['policies'] -policies['items'][0]['enum'].extend(['soft-anti-affinity', 'soft-affinity']) +policies['prefixItems'][0]['enum'].extend( + ['soft-anti-affinity', 'soft-affinity'] +) create_v264 = copy.deepcopy(create_v215) del create_v264['properties']['server_group']['properties']['policies'] diff --git a/nova/api/validation/validators.py b/nova/api/validation/validators.py index b0e9478d35e2..e09bdb427bf6 100644 --- a/nova/api/validation/validators.py +++ b/nova/api/validation/validators.py @@ -271,7 +271,7 @@ class FormatChecker(jsonschema.FormatChecker): class _SchemaValidator(object): """A validator class - This class is changed from Draft4Validator to validate minimum/maximum + This class is changed from Draft202012Validator to validate minimum/maximum value of a string number(e.g. '10'). This changes can be removed when we tighten up the API definition and the XML conversion. Also FormatCheckers are added for checking data formats which would be @@ -279,7 +279,7 @@ class _SchemaValidator(object): """ validator = None - validator_org = jsonschema.Draft4Validator + validator_org = jsonschema.Draft202012Validator def __init__(self, schema, relax_additional_properties=False, is_body=True): diff --git a/nova/tests/unit/test_api_validation.py b/nova/tests/unit/test_api_validation.py index 4937722446e8..ea515702ac64 100644 --- a/nova/tests/unit/test_api_validation.py +++ b/nova/tests/unit/test_api_validation.py @@ -548,9 +548,9 @@ class IntegerTestCase(APIValidationTestCase): self.check_validation_error(self.post, body={'foo': '0xffff'}, expected_detail=detail) - detail = ("Invalid input for field/attribute foo. Value: 1.0." - " 1.0 is not of type 'integer', 'string'") - self.check_validation_error(self.post, body={'foo': 1.0}, + detail = ("Invalid input for field/attribute foo. Value: 1.01." + " 1.01 is not of type 'integer', 'string'") + self.check_validation_error(self.post, body={'foo': 1.01}, expected_detail=detail) detail = ("Invalid input for field/attribute foo. Value: 1.0."