Merge "Added is_jbod_capable method to raid resource"
This commit is contained in:
commit
589ee04c83
|
@ -782,6 +782,20 @@ class DRACClient(object):
|
||||||
|
|
||||||
return self.client.wait_until_idrac_is_ready(retries, retry_delay)
|
return self.client.wait_until_idrac_is_ready(retries, retry_delay)
|
||||||
|
|
||||||
|
def is_jbod_capable(self, raid_controller_fqdd):
|
||||||
|
"""Find out if raid controller supports jbod
|
||||||
|
|
||||||
|
:param raid_controller_fqdd: The raid controller's fqdd
|
||||||
|
being being checked to see if it is jbod
|
||||||
|
capable.
|
||||||
|
:raises: DRACRequestFailed if unable to find any disks in the Ready
|
||||||
|
or non-RAID states
|
||||||
|
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||||
|
and the exception message does not contain
|
||||||
|
NOT_SUPPORTED_MSG constant
|
||||||
|
"""
|
||||||
|
return self._raid_mgmt.is_jbod_capable(raid_controller_fqdd)
|
||||||
|
|
||||||
|
|
||||||
class WSManClient(wsman.Client):
|
class WSManClient(wsman.Client):
|
||||||
"""Wrapper for wsman.Client that can wait until iDRAC is ready
|
"""Wrapper for wsman.Client that can wait until iDRAC is ready
|
||||||
|
|
|
@ -151,6 +151,8 @@ class VirtualDisk(VirtualDiskTuple):
|
||||||
|
|
||||||
class RAIDManagement(object):
|
class RAIDManagement(object):
|
||||||
|
|
||||||
|
NOT_SUPPORTED_MSG = " operation is not supported on th"
|
||||||
|
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
"""Creates RAIDManagement object
|
"""Creates RAIDManagement object
|
||||||
|
|
||||||
|
@ -517,3 +519,61 @@ class RAIDManagement(object):
|
||||||
return utils.build_return_dict(doc, uris.DCIM_RAIDService,
|
return utils.build_return_dict(doc, uris.DCIM_RAIDService,
|
||||||
include_commit_required=True,
|
include_commit_required=True,
|
||||||
is_commit_required_value=True)
|
is_commit_required_value=True)
|
||||||
|
|
||||||
|
def is_jbod_capable(self, raid_controller_fqdd):
|
||||||
|
"""Find out if raid controller supports jbod
|
||||||
|
|
||||||
|
:param raid_controller_fqdd: The raid controller's fqdd
|
||||||
|
being being checked to see if it is jbod
|
||||||
|
capable.
|
||||||
|
:raises: DRACRequestFailed if unable to find any disks in the Ready
|
||||||
|
or non-RAID states
|
||||||
|
:raises: DRACOperationFailed on error reported back by the DRAC
|
||||||
|
and the exception message does not contain
|
||||||
|
NOT_SUPPORTED_MSG constant
|
||||||
|
"""
|
||||||
|
is_jbod_capable = False
|
||||||
|
|
||||||
|
# Grab all the disks associated with the RAID controller
|
||||||
|
all_physical_disks = self.list_physical_disks()
|
||||||
|
physical_disks = [physical_disk for physical_disk in all_physical_disks
|
||||||
|
if physical_disk.controller == raid_controller_fqdd]
|
||||||
|
|
||||||
|
# If there is a disk in the Non-RAID state, then the controller is JBOD
|
||||||
|
# capable
|
||||||
|
ready_disk = None
|
||||||
|
for physical_disk in physical_disks:
|
||||||
|
if physical_disk.raid_status == 'non-RAID':
|
||||||
|
is_jbod_capable = True
|
||||||
|
break
|
||||||
|
elif not ready_disk and physical_disk.raid_status == 'ready':
|
||||||
|
ready_disk = physical_disk
|
||||||
|
|
||||||
|
if not is_jbod_capable:
|
||||||
|
if not ready_disk:
|
||||||
|
msg = "Unable to find a disk in the Ready state"
|
||||||
|
raise exceptions.DRACRequestFailed(msg)
|
||||||
|
|
||||||
|
# Try moving a disk in the Ready state to JBOD mode
|
||||||
|
try:
|
||||||
|
self.convert_physical_disks(
|
||||||
|
[ready_disk.id],
|
||||||
|
False)
|
||||||
|
is_jbod_capable = True
|
||||||
|
|
||||||
|
# Flip the disk back to the Ready state. This results in the
|
||||||
|
# pending value being reset to nothing, so it effectively
|
||||||
|
# undoes the last command and makes the check non-destructive
|
||||||
|
self.convert_physical_disks(
|
||||||
|
[ready_disk.id],
|
||||||
|
True)
|
||||||
|
except exceptions.DRACOperationFailed as ex:
|
||||||
|
# Fix for python 3, Exception.message no longer
|
||||||
|
# a valid attribute, str(ex) works for both 2.7
|
||||||
|
# and 3.x
|
||||||
|
if self.NOT_SUPPORTED_MSG in str(ex):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return is_jbod_capable
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ClientRAIDManagementTestCase(base.BaseTest):
|
||||||
super(ClientRAIDManagementTestCase, self).setUp()
|
super(ClientRAIDManagementTestCase, self).setUp()
|
||||||
self.drac_client = dracclient.client.DRACClient(
|
self.drac_client = dracclient.client.DRACClient(
|
||||||
**test_utils.FAKE_ENDPOINT)
|
**test_utils.FAKE_ENDPOINT)
|
||||||
|
self.raid_controller_fqdd = "RAID.Integrated.1-1"
|
||||||
|
|
||||||
@mock.patch.object(dracclient.client.WSManClient,
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
'wait_until_idrac_is_ready', spec_set=True,
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
@ -581,3 +582,117 @@ class ClientRAIDManagementTestCase(base.BaseTest):
|
||||||
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
mock.ANY, resource_uri=uris.DCIM_RAIDService,
|
||||||
cim_creation_class_name='DCIM_RAIDService',
|
cim_creation_class_name='DCIM_RAIDService',
|
||||||
cim_name='DCIM:RAIDService', target='controller')
|
cim_name='DCIM:RAIDService', target='controller')
|
||||||
|
|
||||||
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(dracclient.resources.raid.RAIDManagement,
|
||||||
|
'convert_physical_disks',
|
||||||
|
return_value={}, spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
def test_raid_controller_jbod_capable(self, mock_requests,
|
||||||
|
mock_wait_until_idrac_is_ready,
|
||||||
|
mock_convert_physical_disks):
|
||||||
|
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
|
||||||
|
|
||||||
|
is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
|
||||||
|
|
||||||
|
self.assertTrue(is_jbod, msg="is_jbod is true")
|
||||||
|
|
||||||
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(dracclient.resources.raid.RAIDManagement,
|
||||||
|
'convert_physical_disks',
|
||||||
|
return_value={}, spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
def test_raid_controller_jbod_non_raid(self, mock_requests,
|
||||||
|
mock_wait_until_idrac_is_ready,
|
||||||
|
mock_convert_physical_disks):
|
||||||
|
|
||||||
|
pdv = test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok']
|
||||||
|
# change to non-RAID value
|
||||||
|
pdv = pdv.replace("<n1:RaidStatus>1</n1:RaidStatus>",
|
||||||
|
"<n1:RaidStatus>8</n1:RaidStatus>")
|
||||||
|
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=pdv)
|
||||||
|
|
||||||
|
is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
|
||||||
|
|
||||||
|
self.assertTrue(is_jbod, msg="is_jbod is true")
|
||||||
|
|
||||||
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(dracclient.resources.raid.RAIDManagement,
|
||||||
|
'convert_physical_disks',
|
||||||
|
return_value={}, spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
def test_raid_controller_jbod_unknown(self, mock_requests,
|
||||||
|
mock_wait_until_idrac_is_ready,
|
||||||
|
mock_convert_physical_disks):
|
||||||
|
|
||||||
|
is_jbod = False
|
||||||
|
pdv = test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok']
|
||||||
|
# change to non-RAID value
|
||||||
|
pdv = pdv.replace("<n1:RaidStatus>1</n1:RaidStatus>",
|
||||||
|
"<n1:RaidStatus>0</n1:RaidStatus>")
|
||||||
|
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=pdv)
|
||||||
|
self.assertRaises(exceptions.DRACRequestFailed,
|
||||||
|
self.drac_client.is_jbod_capable,
|
||||||
|
self.raid_controller_fqdd)
|
||||||
|
self.assertFalse(is_jbod, msg="is_jbod is false")
|
||||||
|
|
||||||
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(dracclient.resources.raid.RAIDManagement,
|
||||||
|
'convert_physical_disks',
|
||||||
|
spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
def test_raid_controller_jbod_not_supported(self,
|
||||||
|
mock_requests,
|
||||||
|
mock_convert_physical_disks,
|
||||||
|
mock_wait_idrac_is_ready):
|
||||||
|
|
||||||
|
msg = " operation is not supported on th"
|
||||||
|
exc = exceptions.DRACOperationFailed(drac_messages=msg)
|
||||||
|
mock_convert_physical_disks.side_effect = exc
|
||||||
|
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
|
||||||
|
|
||||||
|
is_jbod = self.drac_client.is_jbod_capable(self.raid_controller_fqdd)
|
||||||
|
self.assertFalse(is_jbod, msg="is_jbod is false")
|
||||||
|
|
||||||
|
@mock.patch.object(dracclient.client.WSManClient,
|
||||||
|
'wait_until_idrac_is_ready', spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(dracclient.resources.raid.RAIDManagement,
|
||||||
|
'convert_physical_disks',
|
||||||
|
spec_set=True,
|
||||||
|
autospec=True)
|
||||||
|
def test_raid_controller_jbod_ex_no_match(self,
|
||||||
|
mock_requests,
|
||||||
|
mock_convert_physical_disks,
|
||||||
|
mock_wait_until_idrac_is_ready):
|
||||||
|
|
||||||
|
mock_requests.post(
|
||||||
|
'https://1.2.3.4:443/wsman',
|
||||||
|
text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok'])
|
||||||
|
msg = "NON_MATCHING_MESSAGE"
|
||||||
|
exc = exceptions.DRACOperationFailed(drac_messages=msg)
|
||||||
|
mock_convert_physical_disks.side_effect = exc
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.DRACOperationFailed,
|
||||||
|
self.drac_client.is_jbod_capable, self.raid_controller_fqdd)
|
||||||
|
|
Loading…
Reference in New Issue