From 9a1580517c23c611a2171a75556c98f90c4bf5a1 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 9 Jun 2025 16:02:27 +0100 Subject: [PATCH] api: Add schema for bios API (responses) We also harmonise the api-ref docs. Change-Id: Ife3e6ae660f85d1e6a6e2fb835d08e4d45d1827e Signed-off-by: Stephen Finucane --- api-ref/source/parameters.yaml | 10 ++--- ironic/api/controllers/v1/bios.py | 4 ++ ironic/api/schemas/v1/bios.py | 71 +++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index 02fabf9215..602fb0ab28 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -568,7 +568,7 @@ bios_interface: type: string bios_setting_allowable_values: description: | - A list of allowable values, otherwise ``null``. + A list of allowable values. May be ``null``. in: body required: true type: array @@ -598,21 +598,19 @@ bios_setting_min_length: type: integer bios_setting_name: description: | - The name of a Bios setting for a Node, eg. "virtualization". + The name of a Bios setting for a Node, eg. ``virtualization``. in: body required: true type: string bios_setting_read_only: description: | - This Bios setting is read only and can't be changed. - May be None. + This Bios setting is read only and can't be changed. May be ``null``. in: body required: true type: boolean bios_setting_reset_required: description: | - After setting this Bios setting a node reboot is required. - May be None. + After setting this Bios setting a node reboot is required. May be ``null``. in: body required: true type: boolean diff --git a/ironic/api/controllers/v1/bios.py b/ironic/api/controllers/v1/bios.py index dc2cb5c31a..ce2c97b8ea 100644 --- a/ironic/api/controllers/v1/bios.py +++ b/ironic/api/controllers/v1/bios.py @@ -75,6 +75,8 @@ class NodeBiosController(rest.RestController): @args.validate(fields=args.string_list, detail=args.boolean) @validation.request_query_schema(schema.index_request_query, None, 73) @validation.request_query_schema(schema.index_request_query_v74, 74) + @validation.response_body_schema(schema.index_response_body, None, 73) + @validation.response_body_schema(schema.index_response_body_v74, 74) def get_all(self, detail=None, fields=None): """List node bios settings.""" node = api_utils.check_node_policy_and_retrieve( @@ -97,6 +99,8 @@ class NodeBiosController(rest.RestController): @validation.api_version(min_version=versions.MINOR_40_BIOS_INTERFACE) @validation.request_parameter_schema(schema.show_request_parameter) @validation.request_query_schema(schema.show_request_query) + @validation.response_body_schema(schema.show_response_body, None, 73) + @validation.response_body_schema(schema.show_response_body_v74, 74) def get_one(self, setting_name): """Retrieve information about the given bios setting. diff --git a/ironic/api/schemas/v1/bios.py b/ironic/api/schemas/v1/bios.py index f030d89953..01290854ac 100644 --- a/ironic/api/schemas/v1/bios.py +++ b/ironic/api/schemas/v1/bios.py @@ -13,6 +13,7 @@ import copy from ironic.api.schemas.common import request_types +from ironic.api.schemas.common import response_types # request parameter schemas @@ -71,3 +72,73 @@ show_request_query = { 'required': [], 'additionalProperties': False, } + +# response body schemas + +_bios_response_body = { + 'type': 'object', + 'properties': { + 'created_at': {'type': 'string', 'format': 'date-time'}, + 'links': response_types.links, + 'name': {'type': 'string'}, + 'updated_at': {'type': ['string', 'null'], 'format': 'date-time'}, + 'value': {'type': 'string'}, + }, + 'required': ['created_at', 'links', 'name', 'value', 'updated_at'], + 'additionalProperties': False, +} + +_bios_response_body_v74 = { + 'type': 'object', + 'properties': { + 'allowable_values': { + 'type': ['null', 'array'], 'items': {'type': 'string'} + }, + 'attribute_type': {'type': ['null', 'string']}, + 'created_at': {'type': 'string', 'format': 'date-time'}, + 'links': response_types.links, + 'lower_bound': {'type': ['null', 'integer'], 'minimum': 0}, + 'max_length': {'type': ['null', 'integer'], 'minimum': 0}, + 'min_length': {'type': ['null', 'integer'], 'minimum': 0}, + 'name': {'type': 'string'}, + 'read_only': {'type': ['null', 'boolean']}, + 'reset_required': {'type': ['null', 'boolean']}, + 'unique': {'type': ['null', 'boolean']}, + 'updated_at': {'type': ['string', 'null'], 'format': 'date-time'}, + 'upper_bound': {'type': ['null', 'integer'], 'minimum': 0}, + 'value': {'type': 'string'}, + }, + # NOTE(stephenfin): The 'fields' parameter means only a minimal set of + # fields are required + 'required': ['created_at', 'links', 'updated_at'], + 'additionalProperties': False, +} + +index_response_body = { + 'type': 'object', + 'properties': { + 'bios': { + 'type': 'array', + 'items': copy.deepcopy(_bios_response_body), + }, + }, + 'required': ['bios'], + 'additionalProperties': False, +} +index_response_body_v74 = copy.deepcopy(index_response_body) +index_response_body_v74['properties']['bios']['items'] = copy.deepcopy( + _bios_response_body_v74 +) + +show_response_body = { + 'type': 'object', + 'patternProperties': { + r'(?i)^[A-Z0-9-._~]+$': copy.deepcopy(_bios_response_body), + }, + 'minProperties': 1, + 'maxProperties': 1, +} +show_response_body_v74 = copy.deepcopy(show_response_body) +show_response_body_v74['patternProperties'][ + r'(?i)^[A-Z0-9-._~]+$' +] = copy.deepcopy(_bios_response_body_v74)