BIOS Settings: Add RPC object
Add BIOS Objects to expose DB operations to API: * BIOSSetting + create + save + get + delete * BIOSSettingList + create + save + get_by_node_id This patch also adds BIOSSetting and BIOSSettingList in expected_object_fingerprints. Co-Authored-By: Yolanda Robla Mota <yroblamo@redhat.com> Change-Id: I4901dd4ce018b84c92f4f58ef29a7fbc79851a25 Story: #1712032
This commit is contained in:
parent
91251d19ad
commit
9eaff34b5b
@ -24,6 +24,7 @@ def register_all():
|
||||
# NOTE(danms): You must make sure your object gets imported in this
|
||||
# function in order for it to be registered by services that may
|
||||
# need to receive it via RPC.
|
||||
__import__('ironic.objects.bios')
|
||||
__import__('ironic.objects.chassis')
|
||||
__import__('ironic.objects.conductor')
|
||||
__import__('ironic.objects.node')
|
||||
|
195
ironic/objects/bios.py
Normal file
195
ironic/objects/bios.py
Normal file
@ -0,0 +1,195 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
from ironic.db import api as dbapi
|
||||
from ironic.objects import base
|
||||
from ironic.objects import fields as object_fields
|
||||
|
||||
|
||||
@base.IronicObjectRegistry.register
|
||||
class BIOSSetting(base.IronicObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'node_id': object_fields.StringField(nullable=False),
|
||||
'name': object_fields.StringField(nullable=False),
|
||||
'value': object_fields.StringField(nullable=True),
|
||||
}
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable
|
||||
def create(self, context=None):
|
||||
"""Create a BIOS Setting record in DB.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: BIOSSetting(context)
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingAlreadyExists if the setting record already exists.
|
||||
"""
|
||||
values = self.do_version_changes_for_db()
|
||||
setting = [{'name': values['name'], 'value': values['value']}]
|
||||
db_bios_setting = self.dbapi.create_bios_setting_list(
|
||||
values['node_id'], setting, 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
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable
|
||||
def save(self, context=None):
|
||||
"""Save BIOS Setting update in DB.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: BIOSSetting(context)
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingNotFound if the bios setting name is not found.
|
||||
"""
|
||||
values = self.do_version_changes_for_db()
|
||||
setting = [{'name': values['name'], 'value': values['value']}]
|
||||
updated_bios_setting = self.dbapi.update_bios_setting_list(
|
||||
values['node_id'], setting, 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
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable_classmethod
|
||||
@classmethod
|
||||
def get(cls, context, node_id, name):
|
||||
"""Get a BIOS Setting based on its node_id and name.
|
||||
|
||||
:param context: Security context.
|
||||
:param node_id: The node id.
|
||||
:param name: Bios setting name to be retrieved.
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingNotFound if the bios setting name is not found.
|
||||
:returns: A :class:'BIOSSetting' object.
|
||||
"""
|
||||
db_bios_setting = cls.dbapi.get_bios_setting(node_id, name)
|
||||
return cls._from_db_object(context, cls(), db_bios_setting)
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable_classmethod
|
||||
@classmethod
|
||||
def delete(cls, context, node_id, name):
|
||||
"""Delete a BIOS Setting based on its node_id and name.
|
||||
|
||||
:param context: Security context.
|
||||
:param node_id: The node id.
|
||||
:param name: Bios setting name to be deleted.
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingNotFound if the bios setting name is not found.
|
||||
"""
|
||||
cls.dbapi.delete_bios_setting(node_id, name)
|
||||
|
||||
|
||||
@base.IronicObjectRegistry.register
|
||||
class BIOSSettingList(base.IronicObjectListBase, base.IronicObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
dbapi = dbapi.get_instance()
|
||||
|
||||
fields = {
|
||||
'objects': object_fields.ListOfObjectsField('BIOSSetting'),
|
||||
}
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable_classmethod
|
||||
@classmethod
|
||||
def create(cls, context, node_id, settings):
|
||||
"""Create a list of BIOS Setting records in DB.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: BIOSSetting(context)
|
||||
:param node_id: The node id.
|
||||
:param settings: A list of bios settings.
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingAlreadyExists if any of the setting records
|
||||
already exists.
|
||||
:return: A list of BIOSSetting objects.
|
||||
"""
|
||||
version = BIOSSetting.get_target_version()
|
||||
db_setting_list = cls.dbapi.create_bios_setting_list(
|
||||
node_id, settings, version)
|
||||
return object_base.obj_make_list(
|
||||
context, cls(), BIOSSetting, db_setting_list)
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable_classmethod
|
||||
@classmethod
|
||||
def save(cls, context, node_id, settings):
|
||||
"""Save a list of BIOS Setting updates in DB.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: BIOSSetting(context)
|
||||
:param node_id: The node id.
|
||||
:param settings: A list of bios settings.
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:raises: BIOSSettingNotFound if any of the bios setting names
|
||||
is not found.
|
||||
:return: A list of BIOSSetting objects.
|
||||
"""
|
||||
version = BIOSSetting.get_target_version()
|
||||
updated_setting_list = cls.dbapi.update_bios_setting_list(
|
||||
node_id, settings, version)
|
||||
return object_base.obj_make_list(
|
||||
context, cls(), BIOSSetting, updated_setting_list)
|
||||
|
||||
# NOTE(xek): We don't want to enable RPC on this call just yet. Remotable
|
||||
# methods can be used in the future to replace current explicit RPC calls.
|
||||
# Implications of calling new remote procedures should be thought through.
|
||||
# @object_base.remotable_classmethod
|
||||
@classmethod
|
||||
def get_by_node_id(cls, context, node_id):
|
||||
"""Get BIOS Setting based on node_id.
|
||||
|
||||
:param context: Security context.
|
||||
:param node_id: The node id.
|
||||
:raises: NodeNotFound if the node id is not found.
|
||||
:return: A list of BIOSSetting objects.
|
||||
"""
|
||||
node_bios_setting = cls.dbapi.get_bios_setting_list(node_id)
|
||||
return object_base.obj_make_list(
|
||||
context, cls(), BIOSSetting, node_bios_setting)
|
149
ironic/tests/unit/objects/test_bios.py
Normal file
149
ironic/tests/unit/objects/test_bios.py
Normal file
@ -0,0 +1,149 @@
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from ironic.common import context
|
||||
from ironic.db import api as dbapi
|
||||
from ironic import objects
|
||||
from ironic.tests.unit.db import base as db_base
|
||||
from ironic.tests.unit.db import utils as db_utils
|
||||
from ironic.tests.unit.objects import utils as obj_utils
|
||||
|
||||
|
||||
class TestBIOSSettingObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBIOSSettingObject, self).setUp()
|
||||
self.ctxt = context.get_admin_context()
|
||||
self.bios_setting = db_utils.get_test_bios_setting()
|
||||
self.node_id = self.bios_setting['node_id']
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'get_bios_setting', autospec=True)
|
||||
def test_get(self, mock_get_setting):
|
||||
mock_get_setting.return_value = self.bios_setting
|
||||
|
||||
bios_obj = objects.BIOSSetting.get(self.context, self.node_id,
|
||||
self.bios_setting['name'])
|
||||
|
||||
mock_get_setting.assert_called_once_with(self.node_id,
|
||||
self.bios_setting['name'])
|
||||
self.assertEqual(self.context, bios_obj._context)
|
||||
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)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'get_bios_setting_list', autospec=True)
|
||||
def test_get_by_node_id(self, mock_get_setting_list):
|
||||
bios_setting2 = db_utils.get_test_bios_setting(name='hyperthread',
|
||||
value='enabled')
|
||||
mock_get_setting_list.return_value = [self.bios_setting, bios_setting2]
|
||||
bios_obj_list = objects.BIOSSettingList.get_by_node_id(
|
||||
self.context, self.node_id)
|
||||
|
||||
mock_get_setting_list.assert_called_once_with(self.node_id)
|
||||
self.assertEqual(self.context, bios_obj_list._context)
|
||||
self.assertEqual(2, len(bios_obj_list))
|
||||
self.assertEqual(self.bios_setting['node_id'],
|
||||
bios_obj_list[0].node_id)
|
||||
self.assertEqual(self.bios_setting['name'], bios_obj_list[0].name)
|
||||
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, 'create_bios_setting_list', autospec=True)
|
||||
def test_create(self, mock_create_list):
|
||||
fake_call_args = {'node_id': self.bios_setting['node_id'],
|
||||
'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value'],
|
||||
'version': self.bios_setting['version']}
|
||||
setting = [{'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value']}]
|
||||
bios_obj = objects.BIOSSetting(context=self.context,
|
||||
**fake_call_args)
|
||||
mock_create_list.return_value = [self.bios_setting]
|
||||
mock_create_list.call_args
|
||||
bios_obj.create()
|
||||
mock_create_list.assert_called_once_with(self.bios_setting['node_id'],
|
||||
setting,
|
||||
self.bios_setting['version'])
|
||||
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)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'update_bios_setting_list', autospec=True)
|
||||
def test_save(self, mock_update_list):
|
||||
fake_call_args = {'node_id': self.bios_setting['node_id'],
|
||||
'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value'],
|
||||
'version': self.bios_setting['version']}
|
||||
setting = [{'name': self.bios_setting['name'],
|
||||
'value': self.bios_setting['value']}]
|
||||
bios_obj = objects.BIOSSetting(context=self.context,
|
||||
**fake_call_args)
|
||||
mock_update_list.return_value = [self.bios_setting]
|
||||
mock_update_list.call_args
|
||||
bios_obj.save()
|
||||
mock_update_list.assert_called_once_with(self.bios_setting['node_id'],
|
||||
setting,
|
||||
self.bios_setting['version'])
|
||||
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)
|
||||
|
||||
@mock.patch.object(dbapi.IMPL, 'create_bios_setting_list', autospec=True)
|
||||
def test_list_create(self, mock_create_list):
|
||||
bios_setting2 = db_utils.get_test_bios_setting(name='hyperthread',
|
||||
value='enabled')
|
||||
settings = db_utils.get_test_bios_setting_setting_list()[:-1]
|
||||
mock_create_list.return_value = [self.bios_setting, bios_setting2]
|
||||
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')
|
||||
self.assertEqual(self.context, bios_obj_list._context)
|
||||
self.assertEqual(2, len(bios_obj_list))
|
||||
self.assertEqual(self.bios_setting['node_id'],
|
||||
bios_obj_list[0].node_id)
|
||||
self.assertEqual(self.bios_setting['name'], bios_obj_list[0].name)
|
||||
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):
|
||||
bios_setting2 = db_utils.get_test_bios_setting(name='hyperthread',
|
||||
value='enabled')
|
||||
settings = db_utils.get_test_bios_setting_setting_list()[:-1]
|
||||
mock_update_list.return_value = [self.bios_setting, bios_setting2]
|
||||
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')
|
||||
self.assertEqual(self.context, bios_obj_list._context)
|
||||
self.assertEqual(2, len(bios_obj_list))
|
||||
self.assertEqual(self.bios_setting['node_id'],
|
||||
bios_obj_list[0].node_id)
|
||||
self.assertEqual(self.bios_setting['name'], bios_obj_list[0].name)
|
||||
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, 'delete_bios_setting', autospec=True)
|
||||
def test_delete(self, mock_delete):
|
||||
objects.BIOSSetting.delete(self.context, self.node_id,
|
||||
self.bios_setting['name'])
|
||||
mock_delete.assert_called_once_with(self.node_id,
|
||||
self.bios_setting['name'])
|
@ -698,6 +698,8 @@ expected_object_fingerprints = {
|
||||
'VolumeTargetCRUDPayload': '1.0-30dcc4735512c104a3a36a2ae1e2aeb2',
|
||||
'Trait': '1.0-3f26cb70c8a10a3807d64c219453e347',
|
||||
'TraitList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
|
||||
'BIOSSetting': '1.0-fd4a791dc2139a7cc21cefbbaedfd9e7',
|
||||
'BIOSSettingList': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user