diff --git a/dracclient/client.py b/dracclient/client.py
index ef32f74..580a529 100644
--- a/dracclient/client.py
+++ b/dracclient/client.py
@@ -326,6 +326,25 @@ class DRACClient(object):
"""
return self._raid_mgmt.list_physical_disks()
+ def convert_physical_disks(self, raid_controller, physical_disks,
+ raid_enable=True):
+ """Changes the operational mode of a physical disk.
+
+ Disks can be enabled or disabled for RAID mode.
+
+ :param raid_controller: the FQDD ID of the RAID controller
+ :param physical_disks: list of FQDD ID strings of the physical disks
+ to update
+ :param raid_enable: boolean flag, set to True if the disk is to
+ become part of the RAID. The same flag is applied to all
+ listed disks
+ :returns: a dictionary containing the commit_required key with a
+ boolean value indicating whether a config job must be
+ created for the values to be applied.
+ """
+ return self._raid_mgmt.convert_physical_disks(
+ physical_disks, raid_enable)
+
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
size_mb, disk_name=None, span_length=None,
span_depth=None):
diff --git a/dracclient/resources/raid.py b/dracclient/resources/raid.py
index 16ce455..f30bff3 100644
--- a/dracclient/resources/raid.py
+++ b/dracclient/resources/raid.py
@@ -234,6 +234,36 @@ class RAIDManagement(object):
return utils.get_wsman_resource_attr(
drac_disk, uris.DCIM_PhysicalDiskView, attr_name)
+ def convert_physical_disks(self, physical_disks, raid_enable):
+ """Converts a list of physical disks into or out of RAID mode.
+
+ Disks can be enabled or disabled for RAID mode.
+
+ :param physical_disks: list of FQDD ID strings of the physical disks
+ to update
+ :param raid_enable: boolean flag, set to True if the disk is to
+ become part of the RAID. The same flag is applied to all
+ listed disks
+ :returns: a dictionary containing the commit_needed key with a boolean
+ value indicating whether a config job must be created for the
+ values to be applied.
+ """
+ invocation = 'ConvertToRAID' if raid_enable else 'ConvertToNonRAID'
+
+ selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+
+ properties = {'PDArray': physical_disks}
+
+ doc = self.client.invoke(uris.DCIM_RAIDService, invocation,
+ selectors, properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ return {'commit_required':
+ utils.is_reboot_required(doc, uris.DCIM_RAIDService)}
+
def create_virtual_disk(self, raid_controller, physical_disks, raid_level,
size_mb, disk_name=None, span_length=None,
span_depth=None):
diff --git a/dracclient/tests/test_client.py b/dracclient/tests/test_client.py
index 347be2f..05e204e 100644
--- a/dracclient/tests/test_client.py
+++ b/dracclient/tests/test_client.py
@@ -15,6 +15,7 @@ import re
import lxml.etree
import mock
+import random
import requests_mock
import dracclient.client
@@ -702,6 +703,162 @@ class ClientRAIDManagementTestCase(base.BaseTest):
self.assertIn(expected_physical_disk,
self.drac_client.list_physical_disks())
+ # Verify that various client convert_physical_disks calls to dracclient
+ # result in a WSMan.invoke with appropriate parameters
+ def _random_term(self):
+ return "".join(random.sample('ABCDEFGHabcdefgh0123456',
+ random.randint(4, 12)))
+
+ def _random_fqdd(self):
+ result = self._random_term()
+ for i in range(0, random.randint(6, 10)):
+ result += random.sample('.:-', 1)[0] + self._random_term()
+ return result
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_convert_physical_disks_1(self, mock_requests, mock_invoke):
+ '''Convert a single disk to RAID mode'''
+ device_fqdd = self._random_fqdd()
+ expected_invocation = 'ConvertToRAID'
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'PDArray': [device_fqdd]}
+
+ result = self.drac_client.convert_physical_disks(
+ raid_controller='controller',
+ physical_disks=[device_fqdd],
+ raid_enable=True)
+
+ self.assertEqual({'commit_required': False}, result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, expected_invocation,
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_convert_physical_disks_n(self, mock_requests, mock_invoke):
+ '''Convert a number of disks to RAID mode'''
+ device_list = []
+ for i in range(0, random.randint(2, 10)):
+ device_list += self._random_fqdd()
+
+ expected_invocation = 'ConvertToRAID'
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'PDArray': device_list}
+
+ result = self.drac_client.convert_physical_disks(
+ raid_controller='controller',
+ physical_disks=device_list,
+ raid_enable=True)
+
+ self.assertEqual({'commit_required': False}, result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, expected_invocation,
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_convert_physical_disks_nonraid_1(self, mock_requests,
+ mock_invoke):
+ '''Convert a single disk to non-RAID mode'''
+ device_fqdd = self._random_fqdd()
+ expected_invocation = 'ConvertToNonRAID'
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'PDArray': [device_fqdd]}
+
+ result = self.drac_client.convert_physical_disks(
+ raid_controller='controller',
+ physical_disks=[device_fqdd],
+ raid_enable=False)
+
+ self.assertEqual({'commit_required': False}, result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, expected_invocation,
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_convert_physical_disks_nonraid_n(self, mock_requests,
+ mock_invoke):
+ '''Convert a number of disks to non-RAID mode'''
+ device_list = []
+ for i in range(0, random.randint(2, 10)):
+ device_list += self._random_fqdd()
+
+ expected_invocation = 'ConvertToNonRAID'
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'PDArray': device_list}
+
+ result = self.drac_client.convert_physical_disks(
+ raid_controller='controller',
+ physical_disks=device_list,
+ raid_enable=False)
+
+ self.assertEqual({'commit_required': False}, result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, expected_invocation,
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ @mock.patch.object(dracclient.client.WSManClient, 'invoke',
+ spec_set=True, autospec=True)
+ def test_convert_physical_disks_ok(self, mock_requests, mock_invoke):
+ '''Convert a number of disks to RAID mode and check the return value'''
+ device_list = []
+ for i in range(0, random.randint(2, 10)):
+ device_list += self._random_fqdd()
+
+ expected_invocation = 'ConvertToRAID'
+ expected_selectors = {'SystemCreationClassName': 'DCIM_ComputerSystem',
+ 'CreationClassName': 'DCIM_RAIDService',
+ 'SystemName': 'DCIM:ComputerSystem',
+ 'Name': 'DCIM:RAIDService'}
+ expected_properties = {'PDArray': device_list}
+
+ mock_invoke.return_value = lxml.etree.fromstring(
+ test_utils.RAIDInvocations[uris.DCIM_RAIDService][
+ expected_invocation]['ok'])
+
+ result = self.drac_client.convert_physical_disks(
+ raid_controller='controller',
+ physical_disks=device_list,
+ raid_enable=True)
+
+ self.assertEqual({'commit_required': True}, result)
+ mock_invoke.assert_called_once_with(
+ mock.ANY, uris.DCIM_RAIDService, expected_invocation,
+ expected_selectors, expected_properties,
+ expected_return_value=utils.RET_SUCCESS)
+
+ def test_convert_physical_disks_fail(self, mock_requests):
+ mock_requests.post(
+ 'https://1.2.3.4:443/wsman',
+ text=test_utils.RAIDInvocations[
+ uris.DCIM_RAIDService]['ConvertToRAID']['error'])
+
+ self.assertRaises(
+ exceptions.DRACOperationFailed,
+ self.drac_client.convert_physical_disks,
+ raid_controller='controller',
+ physical_disks=['Disk0:Enclosure-1:RAID-1',
+ 'Disk1:Enclosure-1:RAID-1'],
+ raid_enable=True)
+
@mock.patch.object(dracclient.client.WSManClient, 'invoke',
spec_set=True, autospec=True)
def test_create_virtual_disk(self, mock_requests, mock_invoke):
diff --git a/dracclient/tests/utils.py b/dracclient/tests/utils.py
index 6b14081..47d590a 100644
--- a/dracclient/tests/utils.py
+++ b/dracclient/tests/utils.py
@@ -164,6 +164,12 @@ RAIDInvocations = {
'raid_service-invoke-delete_virtual_disk-ok'),
'error': load_wsman_xml(
'raid_service-invoke-delete_virtual_disk-error'),
+ },
+ 'ConvertToRAID': {
+ 'ok': load_wsman_xml(
+ 'raid_service-invoke-convert_physical_disks-ok'),
+ 'error': load_wsman_xml(
+ 'raid_service-invoke-convert_physical_disks-error'),
}
}
}
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-error.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-error.xml
new file mode 100644
index 0000000..d5fa89c
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-error.xml
@@ -0,0 +1,16 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ConvertToRAIDResponse
+ uuid:6364e38d-4e3c-4769-8c67-ff4332ea603a
+ uuid:ad08919a-34b2-14b2-a4b0-ea19c46a0064
+
+
+
+ Invalid parameter value
+ NULL
+ STOR004
+ 2
+
+
+
diff --git a/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-ok.xml b/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-ok.xml
new file mode 100644
index 0000000..5ad5c1e
--- /dev/null
+++ b/dracclient/tests/wsman_mocks/raid_service-invoke-convert_physical_disks-ok.xml
@@ -0,0 +1,14 @@
+
+
+ http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
+ http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_RAIDService/ConvertToRAIDResponse
+ uuid:c6c4bcf6-c340-4f0b-9aef-3c7be94f0d61
+ uuid:3223ac5b-3439-1439-9855-ea19c46a0064
+
+
+
+ YES
+ 0
+
+
+