Validates the BIOS settings before applying

If 'only_allowed_settings' filter is applied, this change validates if
each of the settings provided is supported. If any setting is provided which
is not supported by the user, 'IloError' exception is thrown.

Change-Id: I966db94634b7e3021f07dc45dcca5cc4f5120329
Closes-Bug: 1785782
This commit is contained in:
vmud213 2018-08-06 21:57:54 +05:30
parent 8bda342451
commit 0e9f3d1b46
4 changed files with 138 additions and 86 deletions

View File

@ -1924,14 +1924,22 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
"""
if only_allowed_settings and data:
refined_data = utils.apply_bios_properties_filter(
data, constants.SUPPORTED_BIOS_PROPERTIES)
self._change_bios_setting(refined_data)
return
if not data:
raise exception.IloError("Could not apply settings with"
" empty data")
if data:
self._change_bios_setting(data)
if only_allowed_settings:
unsupported_settings = [key for key in data if key not in (
constants.SUPPORTED_BIOS_PROPERTIES)]
if unsupported_settings:
msg = ("Could not apply settings as one or more settings are"
" not supported. Unsupported settings are %s."
"Supported settings are %s." % (
unsupported_settings,
constants.SUPPORTED_BIOS_PROPERTIES))
raise exception.IloError(msg)
self._change_bios_setting(data)
def get_default_bios_settings(self, only_allowed_settings=True):
"""Get default BIOS settings.

View File

@ -1127,21 +1127,30 @@ class RedfishOperations(operations.IloOperations):
:raises: IloCommandNotSupportedError, if the command is not supported
on the server.
"""
if not data:
raise exception.IloError("Could not apply settings with"
" empty data")
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
filtered_data = data
if only_allowed_settings and data:
filtered_data = common_utils.apply_bios_properties_filter(
data, ilo_cons.SUPPORTED_REDFISH_BIOS_PROPERTIES)
if filtered_data:
try:
settings_required = sushy_system.bios_settings.pending_settings
settings_required.update_bios_data_by_patch(filtered_data)
except sushy.exceptions.SushyError as e:
msg = (self._('The pending BIOS Settings resource not found.'
' Error %(error)s') %
{'error': str(e)})
LOG.debug(msg)
if only_allowed_settings:
unsupported_settings = [key for key in data if key not in (
ilo_cons.SUPPORTED_REDFISH_BIOS_PROPERTIES)]
if unsupported_settings:
msg = ("Could not apply settings as one or more settings are"
" not supported. Unsupported settings are %s."
"Supported settings are %s." % (
unsupported_settings,
ilo_cons.SUPPORTED_REDFISH_BIOS_PROPERTIES))
raise exception.IloError(msg)
try:
settings_required = sushy_system.bios_settings.pending_settings
settings_required.update_bios_data_by_patch(data)
except sushy.exceptions.SushyError as e:
msg = (self._('The pending BIOS Settings resource not found.'
' Error %(error)s') %
{'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)
def get_default_bios_settings(self, only_allowed_settings=True):
"""Get default BIOS settings.

View File

@ -1490,59 +1490,66 @@ class IloRisTestCase(testtools.TestCase):
ext_err_mock.assert_not_called()
filter_mock.assert_not_called()
@mock.patch.object(utils, 'apply_bios_properties_filter')
@mock.patch.object(ris.RISOperations, '_change_bios_setting')
def test_set_bios_settings_no_data_apply_filter(self, change_bios_mock,
filter_mock):
def test_set_bios_settings_no_data(self, change_bios_mock):
apply_filter = True
data = None
self.client.set_bios_settings(data, apply_filter)
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings with empty data",
self.client.set_bios_settings,
data, apply_filter)
change_bios_mock.assert_not_called()
filter_mock.assert_not_called()
@mock.patch.object(utils, 'apply_bios_properties_filter')
@mock.patch.object(ris.RISOperations, '_change_bios_setting')
def test_set_bios_settings_no_data_no_filter(self, change_bios_mock,
filter_mock):
def test_set_bios_settings_no_data_no_filter(self, change_bios_mock):
apply_filter = False
data = None
self.client.set_bios_settings(data, apply_filter)
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings with empty data",
self.client.set_bios_settings,
data, apply_filter)
change_bios_mock.assert_not_called()
filter_mock.assert_not_called()
@mock.patch.object(utils, 'apply_bios_properties_filter')
@mock.patch.object(ris.RISOperations, '_change_bios_setting')
def test_set_bios_settings_filter_true(self, change_bios_mock,
filter_mock):
def test_set_bios_settings_filter_true_valid_data(self, change_bios_mock):
data = {
"AdminName": "Administrator",
"BootMode": "LEGACY",
"ServerName": "Gen9 server",
"TimeFormat": "Ist",
"BootOrderPolicy": "RetryIndefinitely",
"ChannelInterleaving": "Enabled",
"CollabPowerControl": "Enabled",
"ConsistentDevNaming": "LomsOnly",
"CustomPostMessage": ""
"BootOrderPolicy": "AttemptOnce",
"IntelPerfMonitoring": "Enabled",
"IntelProcVtd": "Disabled",
"UefiOptimizedBoot": "Disabled",
"PowerProfile": "MaxPerf",
}
expected = {
"AdminName": "Administrator",
"BootMode": "LEGACY",
"ServerName": "Gen9 server",
"TimeFormat": "Ist",
"BootOrderPolicy": "RetryIndefinitely",
}
filter_mock.return_value = expected
apply_filter = True
self.client.set_bios_settings(data, apply_filter)
change_bios_mock.assert_called_once_with(expected)
filter_mock.assert_called_once_with(
data, constants.SUPPORTED_BIOS_PROPERTIES)
change_bios_mock.assert_called_once_with(data)
@mock.patch.object(utils, 'apply_bios_properties_filter')
@mock.patch.object(ris.RISOperations, '_change_bios_setting')
def test_set_bios_settings_filter_false(self, change_bios_mock,
filter_mock):
def test_set_bios_settings_filter_true_invalid_data(self,
change_bios_mock):
data = {
"AdminName": "Administrator",
"BootOrderPolicy": "AttemptOnce",
"IntelPerfMonitoring": "Enabled",
"IntelProcVtd": "Disabled",
"UefiOptimizedBoot": "Disabled",
"PowerProfile": "MaxPerf",
"TimeZone": "Utc1"
}
apply_filter = True
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings as one or more settings"
" are not supported",
self.client.set_bios_settings,
data, apply_filter)
change_bios_mock.assert_not_called()
@mock.patch.object(ris.RISOperations, '_change_bios_setting')
def test_set_bios_settings_filter_false(self, change_bios_mock):
data = {
"AdminName": "Administrator",
"BootMode": "LEGACY",
@ -1557,7 +1564,6 @@ class IloRisTestCase(testtools.TestCase):
apply_filter = False
self.client.set_bios_settings(data, apply_filter)
change_bios_mock.assert_called_once_with(data)
filter_mock.assert_not_called()
class TestRISOperationsPrivateMethods(testtools.TestCase):

View File

@ -41,7 +41,6 @@ from proliantutils.redfish.resources.system.storage import array_controller
from proliantutils.redfish.resources.system.storage \
import common as common_storage
from proliantutils.redfish.resources.system import system as pro_sys
from proliantutils import utils
@ddt.ddt
@ -1584,49 +1583,76 @@ class RedfishOperationsTestCase(testtools.TestCase):
only_allowed_settings)
@mock.patch.object(bios.BIOSPendingSettings, 'update_bios_data_by_patch')
@mock.patch.object(utils, 'apply_bios_properties_filter')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_set_bios_settings_no_data(self, system_mock, bios_filter_mock,
update_data_mock):
def test_set_bios_settings_no_data(self, system_mock, update_data_mock):
data = None
apply_filter = True
pending_settings_mock = mock.PropertyMock()
type(system_mock.return_value.bios_settings).pending_settings = (
pending_settings_mock)
self.rf_client.set_bios_settings(data, apply_filter)
bios_filter_mock.assert_not_called()
pending_settings_mock.assert_not_called()
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings with empty data",
self.rf_client.set_bios_settings,
data, apply_filter)
update_data_mock.assert_not_called()
system_mock.assert_not_called()
@mock.patch.object(bios.BIOSPendingSettings, 'update_bios_data_by_patch')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_set_bios_settings_no_data_no_filter(self, system_mock,
update_data_mock):
data = None
apply_filter = False
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings with empty data",
self.rf_client.set_bios_settings,
data, apply_filter)
update_data_mock.assert_not_called()
system_mock.assert_not_called()
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_set_bios_settings_filter_true(self, system_mock):
def test_set_bios_settings_filter_true_valid_data(self, system_mock):
apply_filter = True
data = {
"AdminName": "Administrator",
"BootMode": "LEGACY",
"ServerName": "Gen9 server",
"TimeFormat": "Ist",
"BootOrderPolicy": "RetryIndefinitely",
"ChannelInterleaving": "Enabled",
"CollabPowerControl": "Enabled",
"ConsistentDevNaming": "LomsOnly",
"CustomPostMessage": ""
"BootOrderPolicy": "AttemptOnce",
"IntelPerfMonitoring": "Enabled",
"IntelProcVtd": "Disabled",
"UefiOptimizedBoot": "Disabled",
"PowerProfile": "MaxPerf",
}
expected = {k: data[k] for k in data if k in (
ilo_cons.SUPPORTED_REDFISH_BIOS_PROPERTIES)}
bios_ps_mock = mock.MagicMock(spec=bios.BIOSPendingSettings)
pending_settings_mock = mock.PropertyMock(return_value=bios_ps_mock)
type(system_mock.return_value.bios_settings).pending_settings = (
pending_settings_mock)
self.rf_client.set_bios_settings(data, apply_filter)
bios_ps_mock.update_bios_data_by_patch.assert_called_once_with(
expected)
bios_ps_mock.update_bios_data_by_patch.assert_called_once_with(data)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_set_bios_settings_filter_true_invalid_data(self, system_mock):
apply_filter = True
data = {
"AdminName": "Administrator",
"BootOrderPolicy": "AttemptOnce",
"IntelPerfMonitoring": "Enabled",
"IntelProcVtd": "Disabled",
"UefiOptimizedBoot": "Disabled",
"PowerProfile": "MaxPerf",
"TimeZone": "Utc1"
}
self.assertRaisesRegex(
exception.IloError,
"Could not apply settings as one or more settings"
" are not supported",
self.rf_client.set_bios_settings,
data, apply_filter)
system_mock.assert_called_once_with(redfish.PROLIANT_SYSTEM_ID)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_system')
def test_set_bios_settings_filter_false(self, system_mock):
apply_filter = False
data = {
"AdminName": "Administrator",
"BootMode": "LEGACY",
"ServerName": "Gen9 server",
"TimeFormat": "Ist",
@ -1636,6 +1662,7 @@ class RedfishOperationsTestCase(testtools.TestCase):
"ConsistentDevNaming": "LomsOnly",
"CustomPostMessage": ""
}
bios_ps_mock = mock.MagicMock(spec=bios.BIOSPendingSettings)
pending_settings_mock = mock.PropertyMock(return_value=bios_ps_mock)
type(system_mock.return_value.bios_settings).pending_settings = (
@ -1648,11 +1675,13 @@ class RedfishOperationsTestCase(testtools.TestCase):
def test_set_bios_settings_raises_exception(self, system_mock):
apply_filter = True
data = {
"BootMode": "LEGACY",
"TimeFormat": "Ist",
"BootOrderPolicy": "RetryIndefinitely",
"CollabPowerControl": "Enabled",
"BootOrderPolicy": "AttemptOnce",
"IntelPerfMonitoring": "Enabled",
"IntelProcVtd": "Disabled",
"UefiOptimizedBoot": "Disabled",
"PowerProfile": "MaxPerf"
}
pending_settings_mock = mock.PropertyMock(
side_effect=sushy.exceptions.SushyError)
type(system_mock.return_value.bios_settings).pending_settings = (