Redfish: Add system power operations

This patch adds system power operations in proliantutils via
redfish way. These 2 methods are introduced on redfish ops:

    1) reset_server
    2) set_host_power

Partial-Bug: 1691955
Change-Id: Ib8217cfe68c5ae5b647d5ece055251153054454d
This commit is contained in:
Debayan Ray 2017-06-02 12:42:26 -04:00
parent 100c058a09
commit 7e3a0e4559
3 changed files with 102 additions and 0 deletions

View File

@ -60,6 +60,8 @@ SUPPORTED_RIS_METHODS = [
SUPPORTED_REDFISH_METHODS = [
'get_product_name',
'get_host_power_status',
'set_host_power',
'reset_server',
]
LOG = log.get_logger(__name__)

View File

@ -33,6 +33,11 @@ GET_POWER_STATE_MAP = {
sushy.SYSTEM_POWER_STATE_POWERING_OFF: 'OFF'
}
POWER_RESET_MAP = {
'ON': sushy.RESET_ON,
'OFF': sushy.RESET_FORCE_OFF,
}
PROLIANT_SYSTEM_ID = '1'
LOG = log.get_logger(__name__)
@ -138,3 +143,55 @@ class RedfishOperations(operations.IloOperations):
# as we are dealing with iLO's here.
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
return GET_POWER_STATE_MAP.get(sushy_system.power_state)
def reset_server(self):
"""Resets the server.
:raises: IloError, on an error from iLO.
"""
# Assuming only one sushy_system present as part of collection,
# as we are dealing with iLO's here.
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
try:
sushy_system.reset_system(sushy.RESET_FORCE_RESTART)
except sushy.exceptions.SushyError as e:
msg = (self._('The Redfish controller failed to reset server. '
'Error %(error)s') %
{'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)
def set_host_power(self, target_value):
"""Sets the power state of the system.
:param target_value: The target value to be set. Value can be:
'ON' or 'OFF'.
:raises: IloError, on an error from iLO.
:raises: InvalidInputError, if the target value is not
allowed.
"""
if target_value not in POWER_RESET_MAP:
msg = ('The parameter "%(parameter)s" value "%(target_value)s" is '
'invalid. Valid values are: %(valid_power_values)s' %
{'parameter': 'target_value', 'target_value': target_value,
'valid_power_values': POWER_RESET_MAP.keys()})
raise exception.InvalidInputError(msg)
# Check current power status, do not act if it's in requested state.
current_power_status = self.get_host_power_status()
if current_power_status == target_value:
LOG.debug(self._("Node is already in '%(target_value)s' power "
"state."), {'target_value': target_value})
return
# Assuming only one system present as part of collection,
# as we are dealing with iLO's here.
sushy_system = self._get_sushy_system(PROLIANT_SYSTEM_ID)
try:
sushy_system.reset_system(POWER_RESET_MAP[target_value])
except sushy.exceptions.SushyError as e:
msg = (self._('The Redfish controller failed to set power state '
'of server to %(target_value)s. Error %(error)s') %
{'target_value': target_value, 'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)

View File

@ -78,3 +78,46 @@ class RedfishOperationsTestCase(testtools.TestCase):
self.sushy.get_system().power_state = sushy.SYSTEM_POWER_STATE_ON
power_state = self.rf_client.get_host_power_status()
self.assertEqual('ON', power_state)
def test_reset_server(self):
self.rf_client.reset_server()
self.sushy.get_system().reset_system.assert_called_once_with(
sushy.RESET_FORCE_RESTART)
def test_reset_server_invalid_value(self):
self.sushy.get_system().reset_system.side_effect = (
sushy.exceptions.SushyError)
self.assertRaisesRegex(
exception.IloError,
'The Redfish controller failed to reset server.',
self.rf_client.reset_server)
@mock.patch.object(redfish.RedfishOperations, 'get_host_power_status')
def test_set_host_power_no_change(self, get_host_power_status_mock):
get_host_power_status_mock.return_value = 'ON'
self.rf_client.set_host_power('ON')
self.assertTrue(get_host_power_status_mock.called)
self.assertFalse(self.sushy.get_system().reset_system.called)
@mock.patch.object(redfish.RedfishOperations, 'get_host_power_status')
def test_set_host_power_failure(self, get_host_power_status_mock):
get_host_power_status_mock.return_value = 'OFF'
self.sushy.get_system().reset_system.side_effect = (
sushy.exceptions.SushyError)
self.assertRaisesRegex(
exception.IloError,
'The Redfish controller failed to set power state of server to ON',
self.rf_client.set_host_power, 'ON')
def test_set_host_power_invalid_input(self):
self.assertRaisesRegex(
exception.InvalidInputError,
'The parameter "target_value" value "Off" is invalid.',
self.rf_client.set_host_power, 'Off')
@mock.patch.object(redfish.RedfishOperations, 'get_host_power_status')
def test_set_host_power_change(self, get_host_power_status_mock):
get_host_power_status_mock.return_value = 'OFF'
self.rf_client.set_host_power('ON')
self.sushy.get_system().reset_system.assert_called_once_with(
sushy.RESET_ON)