Added ability to determine if an iDRAC is ready
This patch adds the ability to determine if an iDRAC is ready to accept commands. Change-Id: I929deada3dda7b09a6f29033fff89d9b0382aef8 Partial-Bug: 1691808
This commit is contained in:
parent
f49efaa1bf
commit
39253bb272
|
@ -16,6 +16,7 @@ Wrapper for pywsman.Client
|
|||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from dracclient import exceptions
|
||||
from dracclient.resources import bios
|
||||
|
@ -496,6 +497,53 @@ class DRACClient(object):
|
|||
|
||||
return self._inventory_mgmt.list_nics()
|
||||
|
||||
def is_idrac_ready(self):
|
||||
"""Indicates if the iDRAC is ready to accept commands
|
||||
|
||||
Returns a boolean indicating if the iDRAC is ready to accept
|
||||
commands.
|
||||
|
||||
:returns: Boolean indicating iDRAC readiness
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
|
||||
return self._lifecycle_cfg.is_idrac_ready()
|
||||
|
||||
def wait_until_idrac_is_ready(self, retries=24, retry_delay=10):
|
||||
"""Waits until the iDRAC is in a ready state
|
||||
|
||||
:param retries: The number of times to check if the iDRAC is ready
|
||||
:param retry_delay: The number of seconds to wait between retries
|
||||
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface or timeout
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
|
||||
# Try every 10 seconds over 4 minutes for the iDRAC to become ready
|
||||
while retries > 0:
|
||||
LOG.debug("Checking to see if the iDRAC is ready")
|
||||
|
||||
if self.is_idrac_ready():
|
||||
LOG.debug("The iDRAC is ready")
|
||||
return
|
||||
|
||||
LOG.debug("The iDRAC is not ready")
|
||||
retries -= 1
|
||||
if retries > 0:
|
||||
time.sleep(retry_delay)
|
||||
|
||||
if retries == 0:
|
||||
err_msg = "Timed out waiting for the iDRAC to become ready"
|
||||
LOG.error(err_msg)
|
||||
raise exceptions.DRACOperationFailed(drac_messages=err_msg)
|
||||
|
||||
|
||||
class WSManClient(wsman.Client):
|
||||
"""Wrapper for wsman.Client with return value checking"""
|
||||
|
|
|
@ -15,6 +15,8 @@ from dracclient.resources import uris
|
|||
from dracclient import utils
|
||||
from dracclient import wsman
|
||||
|
||||
IDRAC_IS_READY = "LC061"
|
||||
|
||||
|
||||
class LifecycleControllerManagement(object):
|
||||
|
||||
|
@ -85,6 +87,37 @@ class LCConfiguration(object):
|
|||
|
||||
return result
|
||||
|
||||
def is_idrac_ready(self):
|
||||
"""Indicates if the iDRAC is ready to accept commands
|
||||
|
||||
Returns a boolean indicating if the iDRAC is ready to accept
|
||||
commands.
|
||||
|
||||
:returns: Boolean indicating iDRAC readiness
|
||||
:raises: WSManRequestFailure on request failures
|
||||
:raises: WSManInvalidResponse when receiving invalid response
|
||||
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||
interface
|
||||
:raises: DRACUnexpectedReturnValue on return value mismatch
|
||||
"""
|
||||
|
||||
selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
|
||||
'SystemName': 'DCIM:ComputerSystem',
|
||||
'CreationClassName': 'DCIM_LCService',
|
||||
'Name': 'DCIM:LCService'}
|
||||
|
||||
result = self.client.invoke(uris.DCIM_LCService,
|
||||
'GetRemoteServicesAPIStatus',
|
||||
selectors,
|
||||
{},
|
||||
expected_return_value=utils.RET_SUCCESS)
|
||||
|
||||
message_id = utils.find_xml(result,
|
||||
'MessageID',
|
||||
uris.DCIM_LCService).text
|
||||
|
||||
return message_id == IDRAC_IS_READY
|
||||
|
||||
|
||||
class LCAttribute(object):
|
||||
"""Generic LC attribute class"""
|
||||
|
|
|
@ -11,9 +11,11 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import requests_mock
|
||||
|
||||
import dracclient.client
|
||||
from dracclient import exceptions
|
||||
from dracclient.resources import lifecycle_controller
|
||||
from dracclient.resources import uris
|
||||
from dracclient.tests import base
|
||||
|
@ -84,3 +86,47 @@ class ClientLCConfigurationTestCase(base.BaseTest):
|
|||
lifecycle_settings)
|
||||
self.assertEqual(expected_string_attr,
|
||||
lifecycle_settings['LifecycleController.Embedded.1#LCAttributes.1#SystemID']) # noqa
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_is_idrac_ready_ready(self, mock_requests):
|
||||
expected_text = test_utils.LifecycleControllerInvocations[
|
||||
uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_ready']
|
||||
mock_requests.post('https://1.2.3.4:443/wsman',
|
||||
text=expected_text)
|
||||
|
||||
self.assertTrue(self.drac_client.is_idrac_ready())
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_is_idrac_ready_not_ready(self, mock_requests):
|
||||
expected_text = test_utils.LifecycleControllerInvocations[
|
||||
uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_not_ready']
|
||||
mock_requests.post('https://1.2.3.4:443/wsman',
|
||||
text=expected_text)
|
||||
|
||||
self.assertFalse(self.drac_client.is_idrac_ready())
|
||||
|
||||
@requests_mock.Mocker()
|
||||
def test_wait_until_idrac_is_ready_ready(self, mock_requests):
|
||||
expected_text = test_utils.LifecycleControllerInvocations[
|
||||
uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_ready']
|
||||
mock_requests.post('https://1.2.3.4:443/wsman',
|
||||
text=expected_text)
|
||||
|
||||
try:
|
||||
self.drac_client.wait_until_idrac_is_ready()
|
||||
except exceptions.DRACOperationFailed:
|
||||
self.fail('wait_until_idrac_is_ready() timed out when it should '
|
||||
'not have!')
|
||||
|
||||
@requests_mock.Mocker()
|
||||
@mock.patch('time.sleep', autospec=True)
|
||||
def test_wait_until_idrac_is_ready_timeout(self,
|
||||
mock_requests,
|
||||
mock_ts):
|
||||
expected_text = test_utils.LifecycleControllerInvocations[
|
||||
uris.DCIM_LCService]['GetRemoteServicesAPIStatus']['is_not_ready']
|
||||
mock_requests.post('https://1.2.3.4:443/wsman',
|
||||
text=expected_text)
|
||||
|
||||
self.assertRaises(exceptions.DRACOperationFailed,
|
||||
self.drac_client.wait_until_idrac_is_ready)
|
||||
|
|
|
@ -159,6 +159,16 @@ LifecycleControllerEnumerations = {
|
|||
}
|
||||
}
|
||||
|
||||
LifecycleControllerInvocations = {
|
||||
uris.DCIM_LCService: {
|
||||
'GetRemoteServicesAPIStatus': {
|
||||
'is_ready': load_wsman_xml('lc_getremoteservicesapistatus_ready'),
|
||||
'is_not_ready': load_wsman_xml(
|
||||
'lc_getremoteservicesapistatus_not_ready')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RAIDEnumerations = {
|
||||
uris.DCIM_ControllerView: {
|
||||
'ok': load_wsman_xml('controller_view-enum-ok')
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/GetRemoteServicesAPIStatusResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:3ef0c018-3169-4184-9d81-ee1a73059940</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:9d5ff7cc-4fc0-1fc0-8090-98d61742a844</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:GetRemoteServicesAPIStatus_OUTPUT>
|
||||
<n1:LCStatus>5</n1:LCStatus>
|
||||
<n1:Message>Lifecycle Controller Remote Services is not ready.</n1:Message>
|
||||
<n1:MessageID>LC060</n1:MessageID>
|
||||
<n1:RTStatus>0</n1:RTStatus>
|
||||
<n1:ReturnValue>0</n1:ReturnValue>
|
||||
<n1:ServerStatus>2</n1:ServerStatus>
|
||||
<n1:Status>1</n1:Status>
|
||||
</n1:GetRemoteServicesAPIStatus_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
|
@ -0,0 +1,19 @@
|
|||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService">
|
||||
<s:Header>
|
||||
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
|
||||
<wsa:Action>http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_LCService/GetRemoteServicesAPIStatusResponse</wsa:Action>
|
||||
<wsa:RelatesTo>uuid:18745811-2782-4d30-a288-8f001a895215</wsa:RelatesTo>
|
||||
<wsa:MessageID>uuid:9ec203ba-4fc0-1fc0-8094-98d61742a844</wsa:MessageID>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<n1:GetRemoteServicesAPIStatus_OUTPUT>
|
||||
<n1:LCStatus>0</n1:LCStatus>
|
||||
<n1:Message>Lifecycle Controller Remote Services is ready.</n1:Message>
|
||||
<n1:MessageID>LC061</n1:MessageID>
|
||||
<n1:RTStatus>0</n1:RTStatus>
|
||||
<n1:ReturnValue>0</n1:ReturnValue>
|
||||
<n1:ServerStatus>2</n1:ServerStatus>
|
||||
<n1:Status>0</n1:Status>
|
||||
</n1:GetRemoteServicesAPIStatus_OUTPUT>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
Loading…
Reference in New Issue