BIOS Settings: Add DB API
Adds the following methods to DB API: * create_bios_setting_list * update_bios_setting_list * delete_bios_setting * get_bios_setting * get_bios_setting_list Adds two exceptions: * BIOSSettingAlreadyExists * BIOSSettingNotFound This patch also deletes BIOS setting records associated with a node when it's destroyed. Co-Authored-By: Yolanda Robla Mota <yroblamo@redhat.com> Change-Id: Ibbca0a30baaae1e19e015b4dddbbac0189ff80ba Story: #1712032
This commit is contained in:
parent
c7e938cd57
commit
61b04cfd38
@ -775,3 +775,11 @@ class InstanceUnrescueFailure(IronicException):
|
||||
|
||||
class XClarityError(IronicException):
|
||||
_msg_fmt = _("XClarity exception occurred. Error: %(error)s")
|
||||
|
||||
|
||||
class BIOSSettingAlreadyExists(Conflict):
|
||||
_msg_fmt = _('A BIOS setting %(name)s for node %(node)s already exists.')
|
||||
|
||||
|
||||
class BIOSSettingNotFound(NotFound):
|
||||
_msg_fmt = _("Node %(node)s doesn't have a BIOS setting '%(name)s'")
|
||||
|
@ -995,3 +995,86 @@ class Connection(object):
|
||||
:returns: True if the trait exists otherwise False.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_bios_setting_list(self, node_id, settings, version):
|
||||
"""Create a list of BIOSSetting records for a given node.
|
||||
|
||||
:param node_id: The node id.
|
||||
:param settings: A list of BIOS Settings to be created.
|
||||
|
||||
::
|
||||
|
||||
[
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
},
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
},
|
||||
...
|
||||
]
|
||||
:param version: the version of the object.BIOSSetting.
|
||||
:returns: A list of BIOSSetting object.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
:raises: BIOSSettingAlreadyExists if any of the setting records
|
||||
already exists.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_bios_setting_list(self, node_id, settings, version):
|
||||
"""Update a list of BIOSSetting records.
|
||||
|
||||
:param node_id: The node id.
|
||||
:param settings: A list of BIOS Settings to be updated.
|
||||
|
||||
::
|
||||
|
||||
[
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
},
|
||||
{
|
||||
'name': String,
|
||||
'value': String,
|
||||
},
|
||||
...
|
||||
]
|
||||
:param version: the version of the object.BIOSSetting.
|
||||
:returns: A list of BIOSSetting objects.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
:raises: BIOSSettingNotFound if any of the settings is not found.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_bios_setting(self, node_id, name):
|
||||
"""Delete BIOS setting.
|
||||
|
||||
:param node_id: The node id.
|
||||
:param name: String containing name of bios setting to be deleted.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
:raises: BIOSSettingNotFound if the bios setting is not found.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_bios_setting(self, node_id, name):
|
||||
"""Retrieve BIOS setting value.
|
||||
|
||||
:param node_id: The node id.
|
||||
:param name: String containing name of bios setting to be retrieved.
|
||||
:returns: The BIOSSetting object.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
:raises: BIOSSettingNotFound if the bios setting is not found.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_bios_setting_list(self, node_id):
|
||||
"""Retrieve BIOS settings of a given node.
|
||||
|
||||
:param node_id: The node id.
|
||||
:returns: A list of BIOSSetting objects.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
"""
|
||||
|
@ -445,6 +445,11 @@ class Connection(api.Connection):
|
||||
models.VolumeTarget).filter_by(node_id=node_id)
|
||||
volume_target_query.delete()
|
||||
|
||||
# delete all bios attached to the node
|
||||
bios_settings_query = model_query(
|
||||
models.BIOSSetting).filter_by(node_id=node_id)
|
||||
bios_settings_query.delete()
|
||||
|
||||
query.delete()
|
||||
|
||||
def update_node(self, node_id, values):
|
||||
@ -1383,3 +1388,69 @@ class Connection(api.Connection):
|
||||
q = model_query(
|
||||
models.NodeTrait).filter_by(node_id=node_id, trait=trait)
|
||||
return model_query(q.exists()).scalar()
|
||||
|
||||
@oslo_db_api.retry_on_deadlock
|
||||
def create_bios_setting_list(self, node_id, settings, version):
|
||||
self._check_node_exists(node_id)
|
||||
bios_settings = []
|
||||
with _session_for_write() as session:
|
||||
try:
|
||||
for setting in settings:
|
||||
bios_setting = models.BIOSSetting(
|
||||
node_id=node_id,
|
||||
name=setting['name'],
|
||||
value=setting['value'],
|
||||
version=version)
|
||||
bios_settings.append(bios_setting)
|
||||
session.add(bios_setting)
|
||||
session.flush()
|
||||
except db_exc.DBDuplicateEntry:
|
||||
raise exception.BIOSSettingAlreadyExists(
|
||||
node=node_id, name=setting['name'])
|
||||
return bios_settings
|
||||
|
||||
@oslo_db_api.retry_on_deadlock
|
||||
def update_bios_setting_list(self, node_id, settings, version):
|
||||
self._check_node_exists(node_id)
|
||||
bios_settings = []
|
||||
with _session_for_write() as session:
|
||||
try:
|
||||
for setting in settings:
|
||||
query = model_query(models.BIOSSetting).filter_by(
|
||||
node_id=node_id, name=setting['name'])
|
||||
ref = query.one()
|
||||
ref.update({'value': setting['value'],
|
||||
'version': version})
|
||||
bios_settings.append(ref)
|
||||
session.flush()
|
||||
except NoResultFound:
|
||||
raise exception.BIOSSettingNotFound(
|
||||
node=node_id, name=setting['name'])
|
||||
return bios_settings
|
||||
|
||||
@oslo_db_api.retry_on_deadlock
|
||||
def delete_bios_setting(self, node_id, name):
|
||||
self._check_node_exists(node_id)
|
||||
with _session_for_write():
|
||||
count = model_query(models.BIOSSetting).filter_by(
|
||||
node_id=node_id, name=name).delete()
|
||||
if count == 0:
|
||||
raise exception.BIOSSettingNotFound(
|
||||
node=node_id, name=name)
|
||||
|
||||
def get_bios_setting(self, node_id, name):
|
||||
self._check_node_exists(node_id)
|
||||
query = model_query(models.BIOSSetting).filter_by(
|
||||
node_id=node_id, name=name)
|
||||
try:
|
||||
ref = query.one()
|
||||
except NoResultFound:
|
||||
raise exception.BIOSSettingNotFound(node=node_id, name=name)
|
||||
return ref
|
||||
|
||||
def get_bios_setting_list(self, node_id):
|
||||
self._check_node_exists(node_id)
|
||||
result = (model_query(models.BIOSSetting)
|
||||
.filter_by(node_id=node_id)
|
||||
.all())
|
||||
return result
|
||||
|
123
ironic/tests/unit/db/test_bios_settings.py
Normal file
123
ironic/tests/unit/db/test_bios_settings.py
Normal file
@ -0,0 +1,123 @@
|
||||
# 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.
|
||||
|
||||
"""Tests for manipulating BIOSSetting via the DB API"""
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.tests.unit.db import base
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
|
||||
|
||||
class DbBIOSSettingTestCase(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(DbBIOSSettingTestCase, self).setUp()
|
||||
self.node = db_utils.create_test_node()
|
||||
|
||||
def test_get_bios_setting(self):
|
||||
db_utils.create_test_bios_setting(node_id=self.node.id)
|
||||
result = self.dbapi.get_bios_setting(self.node.id, 'virtualization')
|
||||
self.assertEqual(result['node_id'], self.node.id)
|
||||
self.assertEqual(result['name'], 'virtualization')
|
||||
self.assertEqual(result['value'], 'on')
|
||||
self.assertEqual(result['version'], '1.0')
|
||||
|
||||
def test_get_bios_setting_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
self.dbapi.get_bios_setting,
|
||||
'456',
|
||||
'virtualization')
|
||||
|
||||
def test_get_bios_setting_setting_not_exist(self):
|
||||
db_utils.create_test_bios_setting(node_id=self.node.id)
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
self.dbapi.get_bios_setting,
|
||||
self.node.id, 'bios_name')
|
||||
|
||||
def test_get_bios_setting_list(self):
|
||||
db_utils.create_test_bios_setting(node_id=self.node.id)
|
||||
result = self.dbapi.get_bios_setting_list(
|
||||
node_id=self.node.id)
|
||||
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(len(result), 1)
|
||||
|
||||
def test_get_bios_setting_list_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
self.dbapi.get_bios_setting_list,
|
||||
'456')
|
||||
|
||||
def test_delete_bios_setting(self):
|
||||
db_utils.create_test_bios_setting(node_id=self.node.id)
|
||||
self.dbapi.delete_bios_setting(self.node.id, 'virtualization')
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
self.dbapi.get_bios_setting,
|
||||
self.node.id, 'virtualization')
|
||||
|
||||
def test_delete_bios_setting_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
self.dbapi.delete_bios_setting,
|
||||
'456', 'virtualization')
|
||||
|
||||
def test_delete_bios_setting_setting_not_exist(self):
|
||||
db_utils.create_test_bios_setting(node_id=self.node.id)
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
self.dbapi.delete_bios_setting,
|
||||
self.node.id, 'hyperthread')
|
||||
|
||||
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.assertItemsEqual(['virtualization', 'hyperthread', 'numlock'],
|
||||
[setting.name for setting in result])
|
||||
self.assertItemsEqual(['on', 'enabled', 'off'],
|
||||
[setting.value for setting in result])
|
||||
|
||||
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.assertRaises(exception.BIOSSettingAlreadyExists,
|
||||
self.dbapi.create_bios_setting_list,
|
||||
self.node.id, settings, '1.0')
|
||||
|
||||
def test_create_bios_setting_list_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
self.dbapi.create_bios_setting_list,
|
||||
'456', [], '1.0')
|
||||
|
||||
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')
|
||||
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.assertItemsEqual(['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')
|
||||
for setting in settings:
|
||||
setting['name'] = 'bios_name'
|
||||
self.assertRaises(exception.BIOSSettingNotFound,
|
||||
self.dbapi.update_bios_setting_list,
|
||||
self.node.id, settings, '1.0')
|
||||
|
||||
def test_update_bios_setting_list_node_not_exist(self):
|
||||
self.assertRaises(exception.NodeNotFound,
|
||||
self.dbapi.update_bios_setting_list,
|
||||
'456', [], '1.0')
|
@ -544,3 +544,42 @@ def create_test_node_traits(traits, **kw):
|
||||
:returns: a list of test NodeTrait DB objects.
|
||||
"""
|
||||
return [create_test_node_trait(trait=trait, **kw) for trait in traits]
|
||||
|
||||
|
||||
def create_test_bios_setting(**kw):
|
||||
"""Create test bios entry in DB and return BIOSSetting DB object.
|
||||
|
||||
Function to be used to create test BIOSSetting object in the database.
|
||||
|
||||
:param kw: kwargs with overriding values for node bios settings.
|
||||
:returns: Test BIOSSetting DB object.
|
||||
|
||||
"""
|
||||
bios_setting = get_test_bios_setting(**kw)
|
||||
dbapi = db_api.get_instance()
|
||||
node_id = bios_setting['node_id']
|
||||
version = bios_setting['version']
|
||||
settings = [{'name': bios_setting['name'],
|
||||
'value': bios_setting['value']}]
|
||||
return dbapi.create_bios_setting_list(node_id, settings, version)[0]
|
||||
|
||||
|
||||
def get_test_bios_setting(**kw):
|
||||
return {
|
||||
'node_id': kw.get('node_id', '123'),
|
||||
'name': kw.get('name', 'virtualization'),
|
||||
'value': kw.get('value', 'on'),
|
||||
# TODO(zshi) change default version to
|
||||
# bios_setting.BIOSSetting.VERSION
|
||||
'version': kw.get('version', '1.0'),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
}
|
||||
|
||||
|
||||
def get_test_bios_setting_setting_list():
|
||||
return [
|
||||
{'name': 'virtualization', 'value': 'on'},
|
||||
{'name': 'hyperthread', 'value': 'enabled'},
|
||||
{'name': 'numlock', 'value': 'off'}
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user