Include bios registry fields in bios API
Provide the fields in the BIOS setting API - ``/v1/nodes/{node}/bios/{setting}``, and in the BIOS setting list API when details are requested - ``/v1/nodes/<node>/bios?detail=True``. Story: #2008571 Task: #42483 Change-Id: Ie86ec57e428e2bb2efd099a839105e51a94824ab
This commit is contained in:
parent
caa4c8fd29
commit
e15440370c
@ -19,6 +19,53 @@ List all Bios settings by Node
|
||||
|
||||
Return a list of Bios settings associated with ``node_ident``.
|
||||
|
||||
.. versionadded:: 1.74
|
||||
Added additional fields from bios registry which can be retrieved using
|
||||
``?detail=True`` (see detailed response below).
|
||||
Added ``fields`` selector to query for particular fields.
|
||||
|
||||
Normal response code: 200
|
||||
|
||||
Error codes: 404
|
||||
|
||||
Request
|
||||
-------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- node_ident: node_ident
|
||||
- fields: fields
|
||||
- detail: detail
|
||||
|
||||
Response
|
||||
--------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- bios: bios_settings
|
||||
- created_at: created_at
|
||||
- updated_at: updated_at
|
||||
- links: links
|
||||
- name: bios_setting_name
|
||||
- value: bios_setting_value
|
||||
|
||||
**Example list of a Node's Bios settings:**
|
||||
|
||||
.. literalinclude:: samples/node-bios-list-response.json
|
||||
|
||||
List detailed Bios settings by Node
|
||||
===================================
|
||||
|
||||
.. rest_method:: GET /v1/nodes/{node_ident}/bios/?detail=True
|
||||
|
||||
Return a list of detailed Bios settings associated with ``node_ident``.
|
||||
The detailed list includes the BIOS Attribute Registry information
|
||||
retrieved via Redfish.
|
||||
|
||||
.. versionadded:: 1.74
|
||||
Introduced
|
||||
|
||||
|
||||
Normal response code: 200
|
||||
|
||||
Error codes: 404
|
||||
@ -41,10 +88,19 @@ Response
|
||||
- links: links
|
||||
- name: bios_setting_name
|
||||
- value: bios_setting_value
|
||||
- attribute_type: bios_setting_attribute_type
|
||||
- allowable_values: bios_setting_allowable_values
|
||||
- lower_bound: bios_setting_lower_bound
|
||||
- max_length: bios_setting_max_length
|
||||
- min_length: bios_setting_min_length
|
||||
- read_only: bios_setting_read_only
|
||||
- reset_required: bios_setting_reset_required
|
||||
- unique: bios_setting_unique
|
||||
- upper_bound: bios_setting_upper_bound
|
||||
|
||||
**Example list of a Node's Bios settings:**
|
||||
|
||||
.. literalinclude:: samples/node-bios-list-response.json
|
||||
.. literalinclude:: samples/node-bios-list-details-response.json
|
||||
|
||||
|
||||
Show single Bios setting of a Node
|
||||
@ -55,6 +111,9 @@ Show single Bios setting of a Node
|
||||
Return the content of the specific bios ``bios_setting`` associated with
|
||||
``node_ident``.
|
||||
|
||||
. versionadded:: 1.74
|
||||
Introduced fields from the BIOS registry.
|
||||
|
||||
Normal response code: 200
|
||||
|
||||
Error codes: 404
|
||||
@ -78,6 +137,15 @@ Response
|
||||
- links: links
|
||||
- name: bios_setting_name
|
||||
- value: bios_setting_value
|
||||
- attribute_type: bios_setting_attribute_type
|
||||
- allowable_values: bios_setting_allowable_values
|
||||
- lower_bound: bios_setting_lower_bound
|
||||
- max_length: bios_setting_max_length
|
||||
- min_length: bios_setting_min_length
|
||||
- read_only: bios_setting_read_only
|
||||
- reset_required: bios_setting_reset_required
|
||||
- unique: bios_setting_unique
|
||||
- upper_bound: bios_setting_upper_bound
|
||||
|
||||
**Example details of a Node's Bios setting details:**
|
||||
|
||||
|
@ -505,12 +505,75 @@ bios_interface:
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
bios_setting_allowable_values:
|
||||
description: |
|
||||
A list of allowable values when the attribute_type is "Enumeration",
|
||||
otherwise None.
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
bios_setting_attribute_type:
|
||||
description: |
|
||||
A string describing the type of the Bios setting - "Enumeration",
|
||||
"Integer", "String", "Boolean", or "Password". May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
bios_setting_lower_bound:
|
||||
description: |
|
||||
The lowest allowed value when attribute_type is "Integer".
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: integer
|
||||
bios_setting_max_length:
|
||||
description: |
|
||||
The maximum length when attribute_type is "String".
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: integer
|
||||
bios_setting_min_length:
|
||||
description: |
|
||||
The minimum length when attribute_type is "String".
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: integer
|
||||
bios_setting_name:
|
||||
description: |
|
||||
The name of a Bios setting for a Node, eg. "virtualization".
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
bios_setting_read_only:
|
||||
description: |
|
||||
This Bios seting is read only and can't be changed.
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
bios_setting_reset_required:
|
||||
description: |
|
||||
After setting this Bios setting a node reboot is required.
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
bios_setting_unique:
|
||||
description: |
|
||||
This Bios setting is unique to this node.
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: boolean
|
||||
bios_setting_upper_bound:
|
||||
description: |
|
||||
The lowest allowed value when attribute_type is "Integer".
|
||||
May be None.
|
||||
in: body
|
||||
required: true
|
||||
type: integer
|
||||
bios_setting_value:
|
||||
description: |
|
||||
The value of a Bios setting for a Node, eg. "on".
|
||||
@ -520,7 +583,9 @@ bios_setting_value:
|
||||
bios_settings:
|
||||
description: |
|
||||
Optional list of one or more Bios settings. It includes following fields
|
||||
"created_at", "updated_at", "links", "name", "value".
|
||||
"created_at", "updated_at", "links", "name", "value", "attribute_type",
|
||||
"allowable_values", "lower_bound", "max_length", "min_length", "read_only",
|
||||
"reset_required", "unique", "upper_bound"
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
|
@ -12,7 +12,16 @@
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"name": "virtualization",
|
||||
"value": "on"
|
||||
"name": "Virtualization",
|
||||
"value": "Enabled",
|
||||
"attribute_type": "Enumeration",
|
||||
"allowable_values": ["Enabled", "Disabled"],
|
||||
"lower_bound": None,
|
||||
"max_length": None,
|
||||
"min_length": None,
|
||||
"read_only": false,
|
||||
"reset_required": None,
|
||||
"unique": None,
|
||||
"upper_bound": None
|
||||
}
|
||||
}
|
||||
|
30
api-ref/source/samples/node-bios-list-details-response.json
Normal file
30
api-ref/source/samples/node-bios-list-details-response.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"bios": [
|
||||
{
|
||||
"created_at": "2016-08-18T22:28:49.653974+00:00",
|
||||
"updated_at": "2016-08-18T22:28:49.653974+00:00",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://127.0.0.1:6385/v1/nodes/6d85703a-565d-469a-96ce-30b6de53079d/bios/virtualization",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://127.0.0.1:6385/v1/nodes/6d85703a-565d-469a-96ce-30b6de53079d/bios/virtualization",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"name": "Virtualization",
|
||||
"value": "Enabled",
|
||||
"attribute_type": "Enumeration",
|
||||
"allowable_values": ["Enabled", "Disabled"],
|
||||
"lower_bound": None,
|
||||
"max_length": None,
|
||||
"min_length": None,
|
||||
"read_only": false,
|
||||
"reset_required": None,
|
||||
"unique": None,
|
||||
"upper_bound": None
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"name": "virtualization",
|
||||
"value": "on"
|
||||
"name": "Virtualization",
|
||||
"value": "Enabled"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -2,8 +2,19 @@
|
||||
REST API Version History
|
||||
========================
|
||||
|
||||
1.74 (Xena)
|
||||
----------------------
|
||||
|
||||
Add support for BIOS registry fields which include details about the BIOS
|
||||
setting. Included in the ``/v1/nodes/{node_ident}/bios/{setting}`` response.
|
||||
Add a new selector to include the fields in the BIOS settings list:
|
||||
* ``/v1/nodes/{node_ident}/bios/?detail=``
|
||||
Also add a fields selector to the the BIOS settings list:
|
||||
* ``/v1/nodes/{node_ident}/bios/?fields=``
|
||||
|
||||
1.73 (Xena)
|
||||
----------------------
|
||||
|
||||
Add a new ``deploy`` verb as an alias to ``active`` and
|
||||
``undeploy`` verb as an alias to ``deleted``.
|
||||
|
||||
|
@ -25,23 +25,34 @@ from ironic import objects
|
||||
|
||||
METRICS = metrics_utils.get_metrics_logger(__name__)
|
||||
|
||||
_DEFAULT_RETURN_FIELDS = ('name', 'value')
|
||||
_DEFAULT_FIELDS_WITH_REGISTRY = ('name', 'value', 'attribute_type',
|
||||
'allowable_values', 'lower_bound',
|
||||
'max_length', 'min_length', 'read_only',
|
||||
'reset_required', 'unique', 'upper_bound')
|
||||
|
||||
def convert_with_links(rpc_bios, node_uuid):
|
||||
|
||||
def convert_with_links(rpc_bios, node_uuid, detail=None, fields=None):
|
||||
"""Build a dict containing a bios setting value."""
|
||||
|
||||
if detail:
|
||||
fields = _DEFAULT_FIELDS_WITH_REGISTRY
|
||||
|
||||
bios = api_utils.object_to_dict(
|
||||
rpc_bios,
|
||||
include_uuid=False,
|
||||
fields=('name', 'value'),
|
||||
fields=fields,
|
||||
link_resource='nodes',
|
||||
link_resource_args="%s/bios/%s" % (node_uuid, rpc_bios.name),
|
||||
)
|
||||
return bios
|
||||
|
||||
|
||||
def collection_from_list(node_ident, bios_settings):
|
||||
def collection_from_list(node_ident, bios_settings, detail=None, fields=None):
|
||||
bios_list = []
|
||||
for bios_setting in bios_settings:
|
||||
bios_list.append(convert_with_links(bios_setting, node_ident))
|
||||
bios_list.append(convert_with_links(bios_setting, node_ident,
|
||||
detail, fields))
|
||||
return {'bios': bios_list}
|
||||
|
||||
|
||||
@ -54,14 +65,23 @@ class NodeBiosController(rest.RestController):
|
||||
|
||||
@METRICS.timer('NodeBiosController.get_all')
|
||||
@method.expose()
|
||||
def get_all(self):
|
||||
@args.validate(fields=args.string_list, detail=args.boolean)
|
||||
def get_all(self, detail=None, fields=None):
|
||||
"""List node bios settings."""
|
||||
node = api_utils.check_node_policy_and_retrieve(
|
||||
'baremetal:node:bios:get', self.node_ident)
|
||||
|
||||
# The BIOS detail and fields query were added in a later
|
||||
# version, check if they are valid based on version
|
||||
allow_query = api_utils.allow_query_bios
|
||||
fields = api_utils.get_request_return_fields(fields, detail,
|
||||
_DEFAULT_RETURN_FIELDS,
|
||||
allow_query, allow_query)
|
||||
|
||||
settings = objects.BIOSSettingList.get_by_node_id(
|
||||
api.request.context, node.id)
|
||||
return collection_from_list(self.node_ident, settings)
|
||||
return collection_from_list(self.node_ident, settings,
|
||||
detail, fields)
|
||||
|
||||
@METRICS.timer('NodeBiosController.get_one')
|
||||
@method.expose()
|
||||
@ -81,4 +101,11 @@ class NodeBiosController(rest.RestController):
|
||||
raise exception.BIOSSettingNotFound(node=node.uuid,
|
||||
name=setting_name)
|
||||
|
||||
return {setting_name: convert_with_links(setting, node.uuid)}
|
||||
# Return fields based on version
|
||||
if api_utils.allow_query_bios():
|
||||
fields = _DEFAULT_FIELDS_WITH_REGISTRY
|
||||
else:
|
||||
fields = _DEFAULT_RETURN_FIELDS
|
||||
|
||||
return {setting_name: convert_with_links(setting, node.uuid,
|
||||
fields=fields)}
|
||||
|
@ -1321,18 +1321,27 @@ def allow_detail_query():
|
||||
return api.request.version.minor >= versions.MINOR_43_ENABLE_DETAIL_QUERY
|
||||
|
||||
|
||||
def allow_query_bios():
|
||||
"""Check if BIOS queries should be allowed based on version"""
|
||||
|
||||
return api.request.version.minor >= versions.MINOR_74_BIOS_REGISTRY
|
||||
|
||||
|
||||
def allow_reset_interfaces():
|
||||
"""Check if passing a reset_interfaces query string is allowed."""
|
||||
return api.request.version.minor >= versions.MINOR_45_RESET_INTERFACES
|
||||
|
||||
|
||||
def get_request_return_fields(fields, detail, default_fields):
|
||||
def get_request_return_fields(fields, detail, default_fields,
|
||||
check_detail_version=allow_detail_query,
|
||||
check_fields_version=None):
|
||||
"""Calculate fields to return from an API request
|
||||
|
||||
The fields query and detail=True query can not be passed into a request at
|
||||
the same time. To use the detail query we need to be on a version of the
|
||||
API greater than 1.43. This function raises an InvalidParameterValue
|
||||
exception if either of these conditions are not met.
|
||||
API greater than expected, likewise some APIs require a certain version for
|
||||
the fields query. This function raises an InvalidParameterValue exception
|
||||
if any of these conditions are not met.
|
||||
|
||||
If these checks pass then this function will return either the fields
|
||||
passed in or the default fields provided.
|
||||
@ -1341,15 +1350,24 @@ def get_request_return_fields(fields, detail, default_fields):
|
||||
:param detail: The detail query passed into the API request.
|
||||
:param default_fields: The default fields to return if fields=None and
|
||||
detail=None.
|
||||
:param check_detail_version: Function to check if detail query is allowed
|
||||
based on the version.
|
||||
:param check_fields_version: Function to check if fields query is allowed
|
||||
based on the version.
|
||||
:raises: InvalidParameterValue if there is an invalid combination of query
|
||||
strings or API version.
|
||||
:returns: 'fields' passed in value or 'default_fields'
|
||||
"""
|
||||
|
||||
if detail is not None and not allow_detail_query():
|
||||
if detail is not None and not check_detail_version():
|
||||
raise exception.InvalidParameterValue(
|
||||
"Invalid query parameter ?detail=%s received." % detail)
|
||||
|
||||
if (fields is not None and callable(check_fields_version)
|
||||
and not check_fields_version()):
|
||||
raise exception.InvalidParameterValue(
|
||||
"Invalid query parameter ?fields=%s received." % fields)
|
||||
|
||||
if fields is not None and detail:
|
||||
raise exception.InvalidParameterValue(
|
||||
"Can not specify ?detail=True and fields in the same request.")
|
||||
|
@ -111,6 +111,7 @@ BASE_VERSION = 1
|
||||
# v1.71: Add signifier for Scope based roles.
|
||||
# v1.72: Add agent_status and agent_status_message to /v1/heartbeat
|
||||
# v1.73: Add support for deploy and undeploy verbs
|
||||
# v1.74: Add bios registry to /v1/nodes/{node}/bios/{setting}
|
||||
|
||||
MINOR_0_JUNO = 0
|
||||
MINOR_1_INITIAL_VERSION = 1
|
||||
@ -186,6 +187,7 @@ MINOR_70_CLEAN_DISABLE_RAMDISK = 70
|
||||
MINOR_71_RBAC_SCOPES = 71
|
||||
MINOR_72_HEARTBEAT_STATUS = 72
|
||||
MINOR_73_DEPLOY_UNDEPLOY_VERBS = 73
|
||||
MINOR_74_BIOS_REGISTRY = 74
|
||||
|
||||
# When adding another version, update:
|
||||
# - MINOR_MAX_VERSION
|
||||
@ -193,7 +195,7 @@ MINOR_73_DEPLOY_UNDEPLOY_VERBS = 73
|
||||
# explanation of what changed in the new version
|
||||
# - common/release_mappings.py, RELEASE_MAPPING['master']['api']
|
||||
|
||||
MINOR_MAX_VERSION = MINOR_73_DEPLOY_UNDEPLOY_VERBS
|
||||
MINOR_MAX_VERSION = MINOR_74_BIOS_REGISTRY
|
||||
|
||||
# String representations of the minor and maximum versions
|
||||
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)
|
||||
|
@ -320,10 +320,11 @@ RELEASE_MAPPING = {
|
||||
}
|
||||
},
|
||||
'master': {
|
||||
'api': '1.73',
|
||||
'api': '1.74',
|
||||
'rpc': '1.54',
|
||||
'objects': {
|
||||
'Allocation': ['1.1'],
|
||||
'BIOSSetting': ['1.1'],
|
||||
'Node': ['1.35'],
|
||||
'Conductor': ['1.3'],
|
||||
'Chassis': ['1.3'],
|
||||
|
@ -1385,8 +1385,7 @@ def store_agent_certificate(node, agent_verify_ca):
|
||||
def node_cache_bios_settings(task, node):
|
||||
"""Do caching of bios settings if supported by driver"""
|
||||
try:
|
||||
LOG.debug('BF getting BIOS info for node %s',
|
||||
node.uuid)
|
||||
LOG.debug('Getting BIOS info for node %s', node.uuid)
|
||||
task.driver.bios.cache_bios_settings(task)
|
||||
except exception.UnsupportedDriverExtension:
|
||||
LOG.warning('BIOS settings are not supported for node %s, '
|
||||
|
@ -1054,10 +1054,12 @@ class Connection(object, metaclass=abc.ABCMeta):
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
additional settings from BIOS registry
|
||||
},
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
additional settings from BIOS registry
|
||||
},
|
||||
...
|
||||
]
|
||||
@ -1081,10 +1083,12 @@ class Connection(object, metaclass=abc.ABCMeta):
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
additional settings from BIOS registry
|
||||
},
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
additional settings from BIOS registry
|
||||
},
|
||||
...
|
||||
]
|
||||
|
@ -0,0 +1,46 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Add fields from BIOS registry
|
||||
|
||||
Revision ID: 2bbd96b6ccb9
|
||||
Revises: ac00b586ab95
|
||||
Create Date: 2021-04-29 08:52:23.938863
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '2bbd96b6ccb9'
|
||||
down_revision = 'ac00b586ab95'
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('bios_settings', sa.Column('attribute_type',
|
||||
sa.String(length=255), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('allowable_values',
|
||||
sa.Text(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('lower_bound',
|
||||
sa.Integer(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('max_length',
|
||||
sa.Integer(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('min_length',
|
||||
sa.Integer(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('read_only',
|
||||
sa.Boolean(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('reset_required',
|
||||
sa.Boolean(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('unique',
|
||||
sa.Boolean(), nullable=True))
|
||||
op.add_column('bios_settings', sa.Column('upper_bound',
|
||||
sa.Integer(), nullable=True))
|
@ -1675,6 +1675,15 @@ class Connection(api.Connection):
|
||||
node_id=node_id,
|
||||
name=setting['name'],
|
||||
value=setting['value'],
|
||||
attribute_type=setting.get('attribute_type'),
|
||||
allowable_values=setting.get('allowable_values'),
|
||||
lower_bound=setting.get('lower_bound'),
|
||||
max_length=setting.get('max_length'),
|
||||
min_length=setting.get('min_length'),
|
||||
read_only=setting.get('read_only'),
|
||||
reset_required=setting.get('reset_required'),
|
||||
unique=setting.get('unique'),
|
||||
upper_bound=setting.get('upper_bound'),
|
||||
version=version)
|
||||
bios_settings.append(bios_setting)
|
||||
session.add(bios_setting)
|
||||
@ -1695,6 +1704,18 @@ class Connection(api.Connection):
|
||||
node_id=node_id, name=setting['name'])
|
||||
ref = query.one()
|
||||
ref.update({'value': setting['value'],
|
||||
'attribute_type':
|
||||
setting.get('attribute_type'),
|
||||
'allowable_values':
|
||||
setting.get('allowable_values'),
|
||||
'lower_bound': setting.get('lower_bound'),
|
||||
'max_length': setting.get('max_length'),
|
||||
'min_length': setting.get('min_length'),
|
||||
'read_only': setting.get('read_only'),
|
||||
'reset_required':
|
||||
setting.get('reset_required'),
|
||||
'unique': setting.get('unique'),
|
||||
'upper_bound': setting.get('upper_bound'),
|
||||
'version': version})
|
||||
bios_settings.append(ref)
|
||||
session.flush()
|
||||
|
@ -339,6 +339,15 @@ class BIOSSetting(Base):
|
||||
primary_key=True, nullable=False)
|
||||
name = Column(String(255), primary_key=True, nullable=False)
|
||||
value = Column(Text, nullable=True)
|
||||
attribute_type = Column(String(255), nullable=True)
|
||||
allowable_values = Column(db_types.JsonEncodedList, nullable=True)
|
||||
lower_bound = Column(Integer, nullable=True)
|
||||
max_length = Column(Integer, nullable=True)
|
||||
min_length = Column(Integer, nullable=True)
|
||||
read_only = Column(Boolean, nullable=True)
|
||||
reset_required = Column(Boolean, nullable=True)
|
||||
unique = Column(Boolean, nullable=True)
|
||||
upper_bound = Column(Integer, nullable=True)
|
||||
|
||||
|
||||
class Allocation(Base):
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_utils import versionutils
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
from ironic.db import api as dbapi
|
||||
@ -23,14 +24,29 @@ from ironic.objects import fields as object_fields
|
||||
@base.IronicObjectRegistry.register
|
||||
class BIOSSetting(base.IronicObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
# Version 1.1: Added registry
|
||||
VERSION = '1.1'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
registry_fields = ('attribute_type', 'allowable_values', 'lower_bound',
|
||||
'max_length', 'min_length', 'read_only',
|
||||
'reset_required', 'unique', 'upper_bound')
|
||||
|
||||
fields = {
|
||||
'node_id': object_fields.StringField(nullable=False),
|
||||
'name': object_fields.StringField(nullable=False),
|
||||
'value': object_fields.StringField(nullable=True),
|
||||
'attribute_type': object_fields.StringField(nullable=True),
|
||||
'allowable_values': object_fields.ListOfStringsField(
|
||||
nullable=True),
|
||||
'lower_bound': object_fields.IntegerField(nullable=True),
|
||||
'max_length': object_fields.IntegerField(nullable=True),
|
||||
'min_length': object_fields.IntegerField(nullable=True),
|
||||
'read_only': object_fields.BooleanField(nullable=True),
|
||||
'reset_required': object_fields.BooleanField(nullable=True),
|
||||
'unique': object_fields.BooleanField(nullable=True),
|
||||
'upper_bound': object_fields.IntegerField(nullable=True)
|
||||
}
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
@ -50,9 +66,12 @@ class BIOSSetting(base.IronicObject):
|
||||
:raises: BIOSSettingAlreadyExists if the setting record already exists.
|
||||
"""
|
||||
values = self.do_version_changes_for_db()
|
||||
setting = [{'name': values['name'], 'value': values['value']}]
|
||||
settings = {'name': values['name'], 'value': values['value']}
|
||||
for r in self.registry_fields:
|
||||
settings[r] = values.get(r)
|
||||
|
||||
db_bios_setting = self.dbapi.create_bios_setting_list(
|
||||
values['node_id'], setting, values['version'])
|
||||
values['node_id'], [settings], values['version'])
|
||||
self._from_db_object(self._context, self, db_bios_setting[0])
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
@ -72,9 +91,13 @@ class BIOSSetting(base.IronicObject):
|
||||
:raises: BIOSSettingNotFound if the bios setting name is not found.
|
||||
"""
|
||||
values = self.do_version_changes_for_db()
|
||||
setting = [{'name': values['name'], 'value': values['value']}]
|
||||
|
||||
settings = {'name': values['name'], 'value': values['value']}
|
||||
for r in self.registry_fields:
|
||||
settings[r] = values.get(r)
|
||||
|
||||
updated_bios_setting = self.dbapi.update_bios_setting_list(
|
||||
values['node_id'], setting, values['version'])
|
||||
values['node_id'], [settings], values['version'])
|
||||
self._from_db_object(self._context, self, updated_bios_setting[0])
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
@ -111,6 +134,40 @@ class BIOSSetting(base.IronicObject):
|
||||
"""
|
||||
cls.dbapi.delete_bios_setting_list(node_id, [name])
|
||||
|
||||
def _convert_to_version(self, target_version,
|
||||
remove_unavailable_fields=True):
|
||||
"""Convert to the target version.
|
||||
|
||||
Convert the object to the target version. The target version may be
|
||||
the same, older, or newer than the version of the object. This is
|
||||
used for DB interactions as well as for serialization/deserialization.
|
||||
|
||||
Version 1.74: remove registry field for unsupported versions if
|
||||
remove_unavailable_fields is True.
|
||||
|
||||
:param target_version: the desired version of the object
|
||||
:param remove_unavailable_fields: True to remove fields that are
|
||||
unavailable in the target version; set this to True when
|
||||
(de)serializing. False to set the unavailable fields to appropriate
|
||||
values; set this to False for DB interactions.
|
||||
"""
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
|
||||
for field in self.get_registry_fields():
|
||||
field_is_set = self.obj_attr_is_set(field)
|
||||
if target_version >= (1, 74):
|
||||
# target version supports the major/minor specified
|
||||
if not field_is_set:
|
||||
# set it to its default value if it is not set
|
||||
setattr(self, field, None)
|
||||
elif field_is_set:
|
||||
# target version does not support the field, and it is set
|
||||
if remove_unavailable_fields:
|
||||
# (De)serialising: remove unavailable fields
|
||||
delattr(self, field)
|
||||
elif self.registry:
|
||||
setattr(self, field, None)
|
||||
|
||||
|
||||
@base.IronicObjectRegistry.register
|
||||
class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
|
||||
|
@ -6685,7 +6685,7 @@ class TestBIOS(test_api_base.BaseApiTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBIOS, self).setUp()
|
||||
self.version = "1.40"
|
||||
self.version = "1.74"
|
||||
self.node = obj_utils.create_test_node(
|
||||
self.context, id=1)
|
||||
self.bios = obj_utils.create_test_bios_setting(self.context,
|
||||
@ -6718,13 +6718,40 @@ class TestBIOS(test_api_base.BaseApiTest):
|
||||
|
||||
expected_json = {
|
||||
'virtualization': {
|
||||
'allowable_values': ['on', 'off'],
|
||||
'attribute_type': 'Enumeration',
|
||||
'created_at': ret['virtualization']['created_at'],
|
||||
'updated_at': ret['virtualization']['updated_at'],
|
||||
'links': [
|
||||
{'href': 'http://localhost/v1/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, u'rel': u'self'},
|
||||
{'href': 'http://localhost/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, u'rel': u'bookmark'}],
|
||||
'lower_bound': None,
|
||||
'min_length': None,
|
||||
'max_length': None,
|
||||
'name': 'virtualization',
|
||||
'read_only': False,
|
||||
'reset_required': True,
|
||||
'unique': False,
|
||||
'updated_at': None,
|
||||
'upper_bound': None,
|
||||
'value': 'on'}}
|
||||
|
||||
self.assertEqual(expected_json, ret)
|
||||
|
||||
def test_get_one_bios_no_registry(self):
|
||||
ret = self.get_json('/nodes/%s/bios/virtualization' % self.node.uuid,
|
||||
headers={api_base.Version.string: "1.73"})
|
||||
|
||||
expected_json = {
|
||||
'virtualization': {
|
||||
'created_at': ret['virtualization']['created_at'],
|
||||
'updated_at': ret['virtualization']['updated_at'],
|
||||
'links': [
|
||||
{'href': 'http://localhost/v1/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'self'},
|
||||
{'href': 'http://localhost/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'bookmark'}],
|
||||
'name': 'virtualization', 'value': 'on'}}
|
||||
self.assertEqual(expected_json, ret)
|
||||
|
||||
@ -6742,6 +6769,88 @@ class TestBIOS(test_api_base.BaseApiTest):
|
||||
self.assertIn("fake_setting", ret.json['error_message'])
|
||||
self.assertNotIn(self.node.id, ret.json['error_message'])
|
||||
|
||||
def test_get_all_bios_with_detail(self):
|
||||
ret = self.get_json('/nodes/%s/bios?detail=True' % self.node.uuid,
|
||||
headers={api_base.Version.string: self.version})
|
||||
|
||||
expected_json = [
|
||||
{'allowable_values': ['on', 'off'],
|
||||
'attribute_type': 'Enumeration',
|
||||
'created_at': ret['bios'][0]['created_at'],
|
||||
'links': [
|
||||
{'href': 'http://localhost/v1/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'self'},
|
||||
{'href': 'http://localhost/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'bookmark'}],
|
||||
'lower_bound': None,
|
||||
'max_length': None,
|
||||
'min_length': None,
|
||||
'name': 'virtualization',
|
||||
'read_only': False,
|
||||
'reset_required': True,
|
||||
'unique': False,
|
||||
'updated_at': None,
|
||||
'upper_bound': None,
|
||||
'value': 'on'}]
|
||||
|
||||
self.assertEqual({'bios': expected_json}, ret)
|
||||
|
||||
def test_get_all_bios_detail_false(self):
|
||||
ret = self.get_json('/nodes/%s/bios?detail=False' % self.node.uuid,
|
||||
headers={api_base.Version.string: self.version})
|
||||
|
||||
expected_json = [
|
||||
{'created_at': ret['bios'][0]['created_at'],
|
||||
'updated_at': ret['bios'][0]['updated_at'],
|
||||
'links': [
|
||||
{'href': 'http://localhost/v1/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'self'},
|
||||
{'href': 'http://localhost/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'bookmark'}],
|
||||
'name': 'virtualization', 'value': 'on'}]
|
||||
self.assertEqual({'bios': expected_json}, ret)
|
||||
|
||||
def test_get_all_bios_detail_old_version(self):
|
||||
ret = self.get_json('/nodes/%s/bios?detail=True' % self.node.uuid,
|
||||
headers={api_base.Version.string: "1.73"},
|
||||
expect_errors=True)
|
||||
|
||||
self.assertEqual(http_client.BAD_REQUEST, ret.status_int)
|
||||
|
||||
def test_get_bios_fields_old_version(self):
|
||||
ret = self.get_json('/nodes/%s/bios?fields=name,read_only'
|
||||
% self.node.uuid,
|
||||
headers={api_base.Version.string: "1.73"},
|
||||
expect_errors=True)
|
||||
|
||||
self.assertEqual(http_client.BAD_REQUEST, ret.status_int)
|
||||
|
||||
def test_get_bios_detail_and_fields(self):
|
||||
ret = self.get_json('/nodes/%s/bios?detail=True?fields=name,read_only'
|
||||
% self.node.uuid,
|
||||
headers={api_base.Version.string: "1.74"},
|
||||
expect_errors=True)
|
||||
|
||||
self.assertEqual(http_client.BAD_REQUEST, ret.status_int)
|
||||
|
||||
def test_get_bios_fields(self):
|
||||
ret = self.get_json('/nodes/%s/bios?fields=name,read_only'
|
||||
% self.node.uuid,
|
||||
headers={api_base.Version.string: self.version})
|
||||
|
||||
expected_json = [
|
||||
{'created_at': ret['bios'][0]['created_at'],
|
||||
'links': [
|
||||
{'href': 'http://localhost/v1/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'self'},
|
||||
{'href': 'http://localhost/nodes/%s/bios/virtualization'
|
||||
% self.node.uuid, 'rel': 'bookmark'}],
|
||||
'name': 'virtualization',
|
||||
'read_only': False,
|
||||
'updated_at': None}]
|
||||
|
||||
self.assertEqual({'bios': expected_json}, ret)
|
||||
|
||||
|
||||
class TestTraits(test_api_base.BaseApiTest):
|
||||
|
||||
|
@ -85,7 +85,7 @@ class ReleaseMappingsTestCase(base.TestCase):
|
||||
self.assertIn('master', release_mappings.RELEASE_MAPPING)
|
||||
model_names = set((s.__name__ for s in models.Base.__subclasses__()))
|
||||
exceptions = set(['NodeTag', 'ConductorHardwareInterfaces',
|
||||
'NodeTrait', 'BIOSSetting', 'DeployTemplateStep'])
|
||||
'NodeTrait', 'DeployTemplateStep'])
|
||||
# NOTE(xek): As a rule, all models which can be changed between
|
||||
# releases or are sent through RPC should have their counterpart
|
||||
# versioned objects.
|
||||
|
@ -705,6 +705,40 @@ class MigrationCheckersMixin(object):
|
||||
bios_settings.c.name == setting['name'])).execute().first()
|
||||
self.assertEqual('on', setting['value'])
|
||||
|
||||
def _check_2bbd96b6ccb9(self, engine, data):
|
||||
bios_settings = db_utils.get_table(engine, 'bios_settings')
|
||||
col_names = [column.name for column in bios_settings.c]
|
||||
self.assertIn('attribute_type', col_names)
|
||||
self.assertIn('allowable_values', col_names)
|
||||
self.assertIn('lower_bound', col_names)
|
||||
self.assertIn('max_length', col_names)
|
||||
self.assertIn('min_length', col_names)
|
||||
self.assertIn('read_only', col_names)
|
||||
self.assertIn('reset_required', col_names)
|
||||
self.assertIn('unique', col_names)
|
||||
self.assertIn('upper_bound', col_names)
|
||||
self.assertIsInstance(bios_settings.c.attribute_type.type,
|
||||
sqlalchemy.types.String)
|
||||
self.assertIsInstance(bios_settings.c.allowable_values.type,
|
||||
sqlalchemy.types.TEXT)
|
||||
self.assertIsInstance(bios_settings.c.lower_bound.type,
|
||||
sqlalchemy.types.Integer)
|
||||
self.assertIsInstance(bios_settings.c.max_length.type,
|
||||
sqlalchemy.types.Integer)
|
||||
self.assertIsInstance(bios_settings.c.min_length.type,
|
||||
sqlalchemy.types.Integer)
|
||||
self.assertIsInstance(bios_settings.c.read_only.type,
|
||||
(sqlalchemy.types.Boolean,
|
||||
sqlalchemy.types.Integer))
|
||||
self.assertIsInstance(bios_settings.c.reset_required.type,
|
||||
(sqlalchemy.types.Boolean,
|
||||
sqlalchemy.types.Integer))
|
||||
self.assertIsInstance(bios_settings.c.unique.type,
|
||||
(sqlalchemy.types.Boolean,
|
||||
sqlalchemy.types.Integer))
|
||||
self.assertIsInstance(bios_settings.c.upper_bound.type,
|
||||
sqlalchemy.types.Integer)
|
||||
|
||||
def _check_2d13bc3d6bba(self, engine, data):
|
||||
nodes = db_utils.get_table(engine, 'nodes')
|
||||
col_names = [column.name for column in nodes.c]
|
||||
|
@ -29,7 +29,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
self.assertEqual(result['node_id'], self.node.id)
|
||||
self.assertEqual(result['name'], 'virtualization')
|
||||
self.assertEqual(result['value'], 'on')
|
||||
self.assertEqual(result['version'], '1.0')
|
||||
self.assertEqual(result['version'], '1.1')
|
||||
|
||||
def test_get_bios_setting_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
@ -50,7 +50,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
self.assertEqual(result[0]['node_id'], self.node.id)
|
||||
self.assertEqual(result[0]['name'], 'virtualization')
|
||||
self.assertEqual(result[0]['value'], 'on')
|
||||
self.assertEqual(result[0]['version'], '1.0')
|
||||
self.assertEqual(result[0]['version'], '1.1')
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
def test_get_bios_setting_list_node_not_exist(self):
|
||||
@ -61,7 +61,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
def test_create_bios_setting_list(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
result = self.dbapi.create_bios_setting_list(
|
||||
self.node.id, settings, '1.0')
|
||||
self.node.id, settings, '1.1')
|
||||
self.assertCountEqual(['virtualization', 'hyperthread', 'numlock'],
|
||||
[setting.name for setting in result])
|
||||
self.assertCountEqual(['on', 'enabled', 'off'],
|
||||
@ -69,7 +69,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
|
||||
def test_create_bios_setting_list_duplicate(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.0')
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.1')
|
||||
self.assertRaises(exception.BIOSSettingAlreadyExists,
|
||||
self.dbapi.create_bios_setting_list,
|
||||
self.node.id, settings, '1.0')
|
||||
@ -81,18 +81,18 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
|
||||
def test_update_bios_setting_list(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.0')
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.1')
|
||||
settings = [{'name': 'virtualization', 'value': 'off'},
|
||||
{'name': 'hyperthread', 'value': 'disabled'},
|
||||
{'name': 'numlock', 'value': 'on'}]
|
||||
result = self.dbapi.update_bios_setting_list(
|
||||
self.node.id, settings, '1.0')
|
||||
self.node.id, settings, '1.1')
|
||||
self.assertCountEqual(['off', 'disabled', 'on'],
|
||||
[setting.value for setting in result])
|
||||
|
||||
def test_update_bios_setting_list_setting_not_exist(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.0')
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.1')
|
||||
for setting in settings:
|
||||
setting['name'] = 'bios_name'
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
@ -106,7 +106,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
|
||||
def test_delete_bios_setting_list(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.0')
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.1')
|
||||
name_list = [setting['name'] for setting in settings]
|
||||
self.dbapi.delete_bios_setting_list(self.node.id, name_list)
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
@ -126,7 +126,7 @@ class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
|
||||
def test_delete_bios_setting_list_setting_not_exist(self):
|
||||
settings = db_utils.get_test_bios_setting_setting_list()
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.0')
|
||||
self.dbapi.create_bios_setting_list(self.node.id, settings, '1.1')
|
||||
self.assertRaises(exception.BIOSSettingListNotFound,
|
||||
self.dbapi.delete_bios_setting_list,
|
||||
self.node.id, ['fake-bios-option'])
|
||||
|
@ -566,7 +566,12 @@ def create_test_bios_setting(**kw):
|
||||
node_id = bios_setting['node_id']
|
||||
version = bios_setting['version']
|
||||
settings = [{'name': bios_setting['name'],
|
||||
'value': bios_setting['value']}]
|
||||
'value': bios_setting['value'],
|
||||
'attribute_type': bios_setting['attribute_type'],
|
||||
'allowable_values': bios_setting['allowable_values'],
|
||||
'read_only': bios_setting['read_only'],
|
||||
'reset_required': bios_setting['reset_required'],
|
||||
'unique': bios_setting['unique']}]
|
||||
return dbapi.create_bios_setting_list(node_id, settings, version)[0]
|
||||
|
||||
|
||||
@ -575,6 +580,15 @@ def get_test_bios_setting(**kw):
|
||||
'node_id': kw.get('node_id', '123'),
|
||||
'name': kw.get('name', 'virtualization'),
|
||||
'value': kw.get('value', 'on'),
|
||||
'attribute_type': kw.get('attribute_type', 'Enumeration'),
|
||||
'allowable_values': kw.get('allowable_values', ['on', 'off']),
|
||||
'lower_bound': kw.get('lower_bound', None),
|
||||
'max_length': kw.get('max_length', None),
|
||||
'min_length': kw.get('max_length', None),
|
||||
'read_only': kw.get('read_only', False),
|
||||
'reset_required': kw.get('reset_required', True),
|
||||
'unique': kw.get('unique', False),
|
||||
'upper_bound': kw.get('upper_bound', None),
|
||||
'version': kw.get('version', bios.BIOSSetting.VERSION),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
|
@ -42,6 +42,15 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
self.assertEqual(self.bios_setting['node_id'], bios_obj.node_id)
|
||||
self.assertEqual(self.bios_setting['name'], bios_obj.name)
|
||||
self.assertEqual(self.bios_setting['value'], bios_obj.value)
|
||||
self.assertEqual(self.bios_setting['attribute_type'],
|
||||
bios_obj.attribute_type)
|
||||
self.assertEqual(self.bios_setting['allowable_values'],
|
||||
bios_obj.allowable_values)
|
||||
self.assertEqual(self.bios_setting['reset_required'],
|
||||
bios_obj.reset_required)
|
||||
self.assertEqual(self.bios_setting['read_only'],
|
||||
bios_obj.read_only)
|
||||
self.assertEqual(self.bios_setting['unique'], bios_obj.unique)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'get_bios_setting_list', autospec=True)
|
||||
def test_get_by_node_id(self, mock_get_setting_list):
|
||||
@ -67,9 +76,22 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
fake_call_args = {'node_id': self.bios_setting['node_id'],
|
||||
'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value'],
|
||||
'attribute_type':
|
||||
self.bios_setting['attribute_type'],
|
||||
'allowable_values':
|
||||
self.bios_setting['allowable_values'],
|
||||
'read_only': self.bios_setting['read_only'],
|
||||
'reset_required':
|
||||
self.bios_setting['reset_required'],
|
||||
'unique': self.bios_setting['unique'],
|
||||
'version': self.bios_setting['version']}
|
||||
setting = [{'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value']}]
|
||||
setting = [{'name': 'virtualization', 'value': 'on', 'attribute_type':
|
||||
'Enumeration', 'allowable_values': ['on', 'off'],
|
||||
'lower_bound': None, 'max_length': None,
|
||||
'min_length': None, 'read_only': False,
|
||||
'reset_required': True, 'unique': False,
|
||||
'upper_bound': None}]
|
||||
|
||||
bios_obj = objects.BIOSSetting(context=self.context,
|
||||
**fake_call_args)
|
||||
mock_create_list.return_value = [self.bios_setting]
|
||||
@ -81,6 +103,15 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
self.assertEqual(self.bios_setting['node_id'], bios_obj.node_id)
|
||||
self.assertEqual(self.bios_setting['name'], bios_obj.name)
|
||||
self.assertEqual(self.bios_setting['value'], bios_obj.value)
|
||||
self.assertEqual(self.bios_setting['attribute_type'],
|
||||
bios_obj.attribute_type)
|
||||
self.assertEqual(self.bios_setting['allowable_values'],
|
||||
bios_obj.allowable_values)
|
||||
self.assertEqual(self.bios_setting['read_only'],
|
||||
bios_obj.read_only)
|
||||
self.assertEqual(self.bios_setting['reset_required'],
|
||||
bios_obj.reset_required)
|
||||
self.assertEqual(self.bios_setting['unique'], bios_obj.unique)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'update_bios_setting_list', autospec=True)
|
||||
def test_save(self, mock_update_list):
|
||||
@ -89,7 +120,12 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
'value': self.bios_setting['value'],
|
||||
'version': self.bios_setting['version']}
|
||||
setting = [{'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value']}]
|
||||
'value': self.bios_setting['value'],
|
||||
'attribute_type': None, 'allowable_values': None,
|
||||
'lower_bound': None, 'max_length': None,
|
||||
'min_length': None, 'read_only': None,
|
||||
'reset_required': None, 'unique': None,
|
||||
'upper_bound': None}]
|
||||
bios_obj = objects.BIOSSetting(context=self.context,
|
||||
**fake_call_args)
|
||||
mock_update_list.return_value = [self.bios_setting]
|
||||
@ -111,7 +147,7 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
bios_obj_list = objects.BIOSSettingList.create(
|
||||
self.context, self.node_id, settings)
|
||||
|
||||
mock_create_list.assert_called_once_with(self.node_id, settings, '1.0')
|
||||
mock_create_list.assert_called_once_with(self.node_id, settings, '1.1')
|
||||
self.assertEqual(self.context, bios_obj_list._context)
|
||||
self.assertEqual(2, len(bios_obj_list))
|
||||
self.assertEqual(self.bios_setting['node_id'],
|
||||
@ -120,7 +156,6 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
self.assertEqual(self.bios_setting['value'], bios_obj_list[0].value)
|
||||
self.assertEqual(bios_setting2['node_id'], bios_obj_list[1].node_id)
|
||||
self.assertEqual(bios_setting2['name'], bios_obj_list[1].name)
|
||||
self.assertEqual(bios_setting2['value'], bios_obj_list[1].value)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'update_bios_setting_list', autospec=True)
|
||||
def test_list_save(self, mock_update_list):
|
||||
@ -131,7 +166,7 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
bios_obj_list = objects.BIOSSettingList.save(
|
||||
self.context, self.node_id, settings)
|
||||
|
||||
mock_update_list.assert_called_once_with(self.node_id, settings, '1.0')
|
||||
mock_update_list.assert_called_once_with(self.node_id, settings, '1.1')
|
||||
self.assertEqual(self.context, bios_obj_list._context)
|
||||
self.assertEqual(2, len(bios_obj_list))
|
||||
self.assertEqual(self.bios_setting['node_id'],
|
||||
@ -189,8 +224,7 @@ class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
objects.BIOSSettingList.sync_node_setting(self.ctxt, node.id,
|
||||
settings))
|
||||
|
||||
expected_delete = [{'name': bios_obj_1.name,
|
||||
'value': bios_obj_1.value}]
|
||||
expected_delete = [{'name': 'virtualization', 'value': 'on'}]
|
||||
self.assertEqual(create, settings[:2])
|
||||
self.assertEqual(update, [])
|
||||
self.assertEqual(delete, expected_delete)
|
||||
|
@ -711,7 +711,7 @@ expected_object_fingerprints = {
|
||||
'VolumeTargetCRUDPayload': '1.0-30dcc4735512c104a3a36a2ae1e2aeb2',
|
||||
'Trait': '1.0-3f26cb70c8a10a3807d64c219453e347',
|
||||
'TraitList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
|
||||
'BIOSSetting': '1.0-fd4a791dc2139a7cc21cefbbaedfd9e7',
|
||||
'BIOSSetting': '1.1-1137db88675a4e2d7f7bcc3a0d52345a',
|
||||
'BIOSSettingList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
|
||||
'Allocation': '1.1-38937f2854722f1057ec667b12878708',
|
||||
'AllocationCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Provide the registry fields in the BIOS setting API and in the BIOS setting
|
||||
list when detail is requested. Also added fields selector to query API.
|
||||
See `story
|
||||
2008571 <https://storyboard.openstack.org/#!/story/2008571>`_.
|
||||
|
Loading…
Reference in New Issue
Block a user