Merge "Add RIS support for power operations"
This commit is contained in:
commit
dab917ddc6
|
@ -32,10 +32,14 @@ SUPPORTED_RIS_METHODS = [
|
|||
'get_product_name',
|
||||
'get_secure_boot_mode',
|
||||
'get_vm_status',
|
||||
'hold_pwr_btn',
|
||||
'insert_virtual_media',
|
||||
'press_pwr_btn',
|
||||
'reset_bios_to_default',
|
||||
'reset_ilo_credential',
|
||||
'reset_secure_boot_keys',
|
||||
'reset_server',
|
||||
'set_host_power',
|
||||
'set_http_boot_url',
|
||||
'set_one_time_boot',
|
||||
'set_pending_boot_mode',
|
||||
|
|
|
@ -43,6 +43,11 @@ DEVICE_COMMON_TO_RIS = {'NETWORK': 'Pxe',
|
|||
DEVICE_RIS_TO_COMMON = dict(
|
||||
(v, k) for (k, v) in DEVICE_COMMON_TO_RIS.items())
|
||||
|
||||
POWER_STATE = {
|
||||
'ON': 'On',
|
||||
'OFF': 'ForceOff',
|
||||
}
|
||||
|
||||
LOG = log.get_logger(__name__)
|
||||
|
||||
|
||||
|
@ -710,6 +715,88 @@ class RISOperations(operations.IloOperations):
|
|||
data = self._get_host_details()
|
||||
return data['Power'].upper()
|
||||
|
||||
def _perform_power_op(self, oper):
|
||||
"""Perform requested power operation.
|
||||
|
||||
:param oper: Type of power button press to simulate.
|
||||
Supported values: 'ON', 'ForceOff' and 'ForceRestart'
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
|
||||
power_settings = {"Action": "Reset",
|
||||
"ResetType": oper}
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
|
||||
status, headers, response = self._rest_post(systems_uri, None,
|
||||
power_settings)
|
||||
if status >= 300:
|
||||
msg = self._get_extended_error(response)
|
||||
raise exception.IloError(msg)
|
||||
|
||||
def reset_server(self):
|
||||
"""Resets the server.
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
|
||||
self._perform_power_op("ForceRestart")
|
||||
|
||||
def _press_pwr_btn(self, pushType="Press"):
|
||||
"""Simulates a physical press of the server power button.
|
||||
|
||||
:param pushType: Type of power button press to simulate
|
||||
Supported values are: 'Press' and 'PressAndHold'
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
power_settings = {"Action": "PowerButton",
|
||||
"Target": "/Oem/Hp",
|
||||
"PushType": pushType}
|
||||
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
|
||||
status, headers, response = self._rest_post(systems_uri, None,
|
||||
power_settings)
|
||||
if status >= 300:
|
||||
msg = self._get_extended_error(response)
|
||||
raise exception.IloError(msg)
|
||||
|
||||
def press_pwr_btn(self):
|
||||
"""Simulates a physical press of the server power button.
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
self._press_pwr_btn()
|
||||
|
||||
def hold_pwr_btn(self):
|
||||
"""Simulate a physical press and hold of the server power button.
|
||||
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
self._press_pwr_btn(pushType="PressAndHold")
|
||||
|
||||
def set_host_power(self, power):
|
||||
"""Toggle the power button of server.
|
||||
|
||||
:param power: 'ON' or 'OFF'
|
||||
:raises: IloError, on an error from iLO.
|
||||
"""
|
||||
power = power.upper()
|
||||
if (power is not None) and (power not in POWER_STATE):
|
||||
msg = ("Invalid input '%(pow)s'. "
|
||||
"The expected input is ON or OFF." %
|
||||
{'pow': power})
|
||||
raise exception.IloInvalidInputError(msg)
|
||||
|
||||
# Check current power status, do not act if it's in requested state.
|
||||
cur_status = self.get_host_power_status()
|
||||
|
||||
if cur_status == power:
|
||||
LOG.debug(self._("Node is already in '%(power)s' power state."),
|
||||
{'power': power})
|
||||
return
|
||||
|
||||
self._perform_power_op(POWER_STATE[power])
|
||||
|
||||
def get_http_boot_url(self):
|
||||
"""Request the http boot url from system in uefi boot mode.
|
||||
|
||||
|
|
|
@ -513,3 +513,51 @@ class IloClientTestCase(testtools.TestCase):
|
|||
_call_method_mock.assert_called_once_with('update_firmware',
|
||||
some_url,
|
||||
some_component_type)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'hold_pwr_btn')
|
||||
def test_hold_pwr_btn_gen9(self, hold_pwr_btn_mock):
|
||||
self.client.model = 'Gen9'
|
||||
self.client.hold_pwr_btn()
|
||||
self.assertTrue(hold_pwr_btn_mock.called)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'hold_pwr_btn')
|
||||
def test_hold_pwr_btn_gen8(self, hold_pwr_btn_mock):
|
||||
self.client.model = 'Gen8'
|
||||
self.client.hold_pwr_btn()
|
||||
self.assertTrue(hold_pwr_btn_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'set_host_power')
|
||||
def test_set_host_power_gen9(self, set_host_power_mock):
|
||||
self.client.model = 'Gen9'
|
||||
self.client.set_host_power('ON')
|
||||
set_host_power_mock.assert_called_once_with('ON')
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'set_host_power')
|
||||
def test_set_host_power_gen8(self, set_host_power_mock):
|
||||
self.client.model = 'Gen8'
|
||||
self.client.set_host_power('ON')
|
||||
set_host_power_mock.assert_called_once_with('ON')
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'press_pwr_btn')
|
||||
def test_press_pwr_btn_gen9(self, press_pwr_btn_mock):
|
||||
self.client.model = 'Gen9'
|
||||
self.client.press_pwr_btn()
|
||||
self.assertTrue(press_pwr_btn_mock.called)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'press_pwr_btn')
|
||||
def test_press_pwr_btn_gen8(self, press_pwr_btn_mock):
|
||||
self.client.model = 'Gen8'
|
||||
self.client.press_pwr_btn()
|
||||
self.assertTrue(press_pwr_btn_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'reset_server')
|
||||
def test_reset_server_gen9(self, reset_server_mock):
|
||||
self.client.model = 'Gen9'
|
||||
self.client.reset_server()
|
||||
self.assertTrue(reset_server_mock.called)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'reset_server')
|
||||
def test_reset_server_gen8(self, reset_server_mock):
|
||||
self.client.model = 'Gen8'
|
||||
self.client.reset_server()
|
||||
self.assertTrue(reset_server_mock.called)
|
||||
|
|
|
@ -948,6 +948,41 @@ class IloRisTestCase(testtools.TestCase):
|
|||
self.assertRaises(exception.IloError,
|
||||
self.client.get_firmware_update_progress)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_host_power_status')
|
||||
def test_set_host_power_no_change(self, host_power_status_mock):
|
||||
host_power_status_mock.return_value = 'ON'
|
||||
self.client.set_host_power('on')
|
||||
self.assertTrue(host_power_status_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_host_power_status')
|
||||
def test_set_host_power_exc(self, host_power_status_mock):
|
||||
self.assertRaises(exception.IloInvalidInputError,
|
||||
self.client.set_host_power, 'invalid')
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_perform_power_op')
|
||||
@mock.patch.object(ris.RISOperations, 'get_host_power_status')
|
||||
def test_set_host_power_change(self, host_power_status_mock,
|
||||
perform_power_op_mock):
|
||||
host_power_status_mock.return_value = 'ON'
|
||||
self.client.set_host_power('off')
|
||||
host_power_status_mock.assert_called_once_with()
|
||||
perform_power_op_mock.assert_called_once_with('ForceOff')
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_perform_power_op')
|
||||
def test_reset_server(self, mock_perform_power):
|
||||
self.client.reset_server()
|
||||
mock_perform_power.assert_called_once_with("ForceRestart")
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_press_pwr_btn')
|
||||
def test_hold_pwr_btn(self, press_pwr_btn_mock):
|
||||
self.client.hold_pwr_btn()
|
||||
press_pwr_btn_mock.assert_called_once_with(pushType="PressAndHold")
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_press_pwr_btn')
|
||||
def test_press_pwr_btn(self, press_pwr_btn_mock):
|
||||
self.client.hold_pwr_btn()
|
||||
press_pwr_btn_mock.assert_called_once_with(pushType="PressAndHold")
|
||||
|
||||
|
||||
class TestRISOperationsPrivateMethods(testtools.TestCase):
|
||||
|
||||
|
@ -1673,3 +1708,49 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
|
|||
# | WHEN | & | THEN |
|
||||
self.assertRaises(exception.IloCommandNotSupportedError,
|
||||
self.client._get_firmware_update_service_resource)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_post')
|
||||
def test_press_pwr_btn(self, rest_post_mock):
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
new_pow_settings = {"Action": "PowerButton",
|
||||
"Target": "/Oem/Hp",
|
||||
"PushType": "Press"}
|
||||
rest_post_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||
ris_outputs.REST_POST_RESPONSE)
|
||||
self.client._press_pwr_btn()
|
||||
rest_post_mock.assert_called_once_with(systems_uri, None,
|
||||
new_pow_settings)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_post')
|
||||
def test_press_pwr_btn_patch_fail(self, rest_post_mock):
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
new_pow_settings = {"Action": "PowerButton",
|
||||
"Target": "/Oem/Hp",
|
||||
"PushType": "Press"}
|
||||
rest_post_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||
ris_outputs.REST_FAILURE_OUTPUT)
|
||||
self.assertRaises(exception.IloError,
|
||||
self.client._press_pwr_btn, 'Press')
|
||||
rest_post_mock.assert_called_once_with(systems_uri, None,
|
||||
new_pow_settings)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_post')
|
||||
def test_perform_power_op(self, rest_post_mock):
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
new_pow_settings = {"Action": "Reset", "ResetType": "ForceRestart"}
|
||||
rest_post_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||
ris_outputs.REST_POST_RESPONSE)
|
||||
self.client.reset_server()
|
||||
rest_post_mock.assert_called_once_with(systems_uri, None,
|
||||
new_pow_settings)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_post')
|
||||
def test_perform_power_op_fail(self, rest_post_mock):
|
||||
systems_uri = "/rest/v1/Systems/1"
|
||||
new_pow_settings = {"Action": "Reset", "ResetType": "ForceRestart"}
|
||||
rest_post_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||
ris_outputs.REST_FAILURE_OUTPUT)
|
||||
self.assertRaises(exception.IloError,
|
||||
self.client.reset_server)
|
||||
rest_post_mock.assert_called_once_with(systems_uri, None,
|
||||
new_pow_settings)
|
||||
|
|
Loading…
Reference in New Issue