From ebc262e2d0a1e3f2a06dda2d93465170170e3b4c Mon Sep 17 00:00:00 2001 From: Ramakrishnan G Date: Mon, 3 Nov 2014 04:34:08 +0000 Subject: [PATCH] HPSSA: create and get should return physical disks info This commit adds support in create and get calls to return the physical disks information. Implements: blueprint hpssa-support Change-Id: I3b2ea42109d60893ae6c89687b803090c5181dd2 --- proliantutils/hpssa/manager.py | 11 ++++++ proliantutils/hpssa/objects.py | 39 +++++++++++++++++++ proliantutils/tests/hpssa/test_manager.py | 22 +++++++++++ proliantutils/tests/hpssa/test_objects.py | 47 +++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/proliantutils/hpssa/manager.py b/proliantutils/hpssa/manager.py index 660dc9dd..7ee2b646 100644 --- a/proliantutils/hpssa/manager.py +++ b/proliantutils/hpssa/manager.py @@ -27,6 +27,15 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) RAID_CONFIG_SCHEMA = os.path.join(CURRENT_DIR, "raid_config_schema.json") +def _update_physical_disk_details(raid_config, server): + """Adds the physical disk details to the RAID configuration passed.""" + raid_config['physical_disks'] = [] + physical_drives = server.get_physical_drives() + for physical_drive in physical_drives: + physical_drive_dict = physical_drive.get_physical_drive_dict() + raid_config['physical_disks'].append(physical_drive_dict) + + def validate(raid_config): """Validates the RAID configuration provided. @@ -149,6 +158,7 @@ def create_configuration(raid_config): wwns_before_create = wwns_after_create.copy() + _update_physical_disk_details(raid_config, server) return raid_config @@ -190,4 +200,5 @@ def get_configuration(): logical_drive_dict = logical_drive.get_logical_drive_dict() raid_config['logical_disks'].append(logical_drive_dict) + _update_physical_disk_details(raid_config, server) return raid_config diff --git a/proliantutils/hpssa/objects.py b/proliantutils/hpssa/objects.py index 41cbb608..9973e412 100644 --- a/proliantutils/hpssa/objects.py +++ b/proliantutils/hpssa/objects.py @@ -242,6 +242,26 @@ class Server(object): logical_drives.append(logical_drive) return logical_drives + def get_physical_drives(self): + """Get all the RAID physical drives on the Server. + + This method returns all the physical drives on the server + by examining all the controllers. + + :returns: a list of PhysicalDrive objects. + """ + physical_drives = [] + for controller in self.controllers: + # First add unassigned physical drives. + for physical_drive in controller.unassigned_physical_drives: + physical_drives.append(physical_drive) + # Now add physical drives part of RAID arrays. + for array in controller.raid_arrays: + for physical_drive in array.physical_drives: + physical_drives.append(physical_drive) + + return physical_drives + def get_logical_drive_by_wwn(self, wwn): """Get the logical drive object given the wwn. @@ -466,3 +486,22 @@ class PhysicalDrive: self.disk_type = constants.get_disk_type(ssa_interface) self.model = self.properties.get('Model') self.firmware = self.properties.get('Firmware Revision') + + def get_physical_drive_dict(self): + """Returns a dictionary of with the details of the physical drive.""" + + if isinstance(self.parent, RaidArray): + controller = self.parent.parent.id + status = 'active' + else: + controller = self.parent.id + status = 'ready' + + return {'size_gb': self.size_gb, + 'controller': controller, + 'id': self.id, + 'disk_type': self.disk_type, + 'interface_type': self.interface_type, + 'model': self.model, + 'firmware': self.firmware, + 'status': status} diff --git a/proliantutils/tests/hpssa/test_manager.py b/proliantutils/tests/hpssa/test_manager.py index 03aa331c..3177e3d0 100644 --- a/proliantutils/tests/hpssa/test_manager.py +++ b/proliantutils/tests/hpssa/test_manager.py @@ -67,6 +67,17 @@ class ManagerTestCases(testtools.TestCase): self.assertIsNotNone(ld1_ret['volume_name']) self.assertIsNotNone(ld2_ret['volume_name']) + # Assert physical disk info + pds_active = [x['id'] for x in current_config['physical_disks'] + if x['status'] == 'active'] + pds_ready = [x['id'] for x in current_config['physical_disks'] + if x['status'] == 'ready'] + pds_active_expected = ['5I:1:3', '5I:1:4', '6I:1:5', + '5I:1:1', '5I:1:2'] + pds_ready_expected = ['6I:1:6', '6I:1:7'] + self.assertEqual(sorted(pds_active_expected), sorted(pds_active)) + self.assertEqual(sorted(pds_ready_expected), sorted(pds_ready)) + @mock.patch.object(objects.Controller, 'execute_cmd') def test_create_configuration_with_disk_input_create_succeeds( self, controller_exec_cmd_mock, get_all_details_mock): @@ -205,6 +216,17 @@ class ManagerTestCases(testtools.TestCase): self.assertEqual(sorted(ld1_expected['physical_disks']), sorted(ld1_returned['physical_disks'])) + # Assert physical disk info + pds_active = [x['id'] for x in raid_info_returned['physical_disks'] + if x['status'] == 'active'] + pds_ready = [x['id'] for x in raid_info_returned['physical_disks'] + if x['status'] == 'ready'] + pds_active_expected = ['5I:1:1', '5I:1:2'] + pds_ready_expected = ['6I:1:6', '6I:1:7', '5I:1:3', + '5I:1:4', '6I:1:5'] + self.assertEqual(sorted(pds_active_expected), sorted(pds_active)) + self.assertEqual(sorted(pds_ready_expected), sorted(pds_ready)) + class RaidConfigValidationTestCases(testtools.TestCase): diff --git a/proliantutils/tests/hpssa/test_objects.py b/proliantutils/tests/hpssa/test_objects.py index 7b209b55..a39375dd 100644 --- a/proliantutils/tests/hpssa/test_objects.py +++ b/proliantutils/tests/hpssa/test_objects.py @@ -118,6 +118,19 @@ class ServerTest(testtools.TestCase): server.get_controller_by_id(id)) self.assertIsNone(server.get_controller_by_id('foo')) + def test_get_physical_drives(self, get_all_details_mock): + + get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE + server = objects.Server() + exp_pds = [server.controllers[0].unassigned_physical_drives[0], + server.controllers[0].unassigned_physical_drives[1], + server.controllers[0].unassigned_physical_drives[2], + server.controllers[0].unassigned_physical_drives[3], + server.controllers[0].unassigned_physical_drives[4], + server.controllers[0].raid_arrays[0].physical_drives[0], + server.controllers[0].raid_arrays[0].physical_drives[1]] + self.assertEqual(exp_pds, server.get_physical_drives()) + def test_get_logical_drives(self, get_all_details_mock): get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE @@ -336,3 +349,37 @@ class PhysicalDriveTest(testtools.TestCase): server = objects.Server() self.assertEqual( 2, server.controllers[0].unassigned_physical_drives[0].size_gb) + + def test_get_physical_drive_dict_part_of_array(self, get_all_details_mock): + + get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE + server = objects.Server() + d = server.controllers[0].raid_arrays[0].physical_drives[0] + d = [x for x in server.controllers[0].raid_arrays[0].physical_drives + if x.id == '5I:1:1'] + ret = d[0].get_physical_drive_dict() + self.assertEqual(500, ret['size_gb']) + self.assertEqual('Smart Array P822 in Slot 2', ret['controller']) + self.assertEqual('5I:1:1', ret['id']) + self.assertEqual('hdd', ret['disk_type']) + self.assertEqual('sas', ret['interface_type']) + self.assertEqual('HP EF0600FARNA', ret['model']) + self.assertEqual('HPD6', ret['firmware']) + self.assertEqual('active', ret['status']) + + def test_get_physical_drive_dict_unassigned(self, get_all_details_mock): + + get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE + server = objects.Server() + d = server.controllers[0].unassigned_physical_drives[0] + d = [x for x in server.controllers[0].unassigned_physical_drives + if x.id == '5I:1:3'] + ret = d[0].get_physical_drive_dict() + self.assertEqual('Smart Array P822 in Slot 2', ret['controller']) + self.assertEqual(400, ret['size_gb']) + self.assertEqual('5I:1:3', ret['id']) + self.assertEqual('hdd', ret['disk_type']) + self.assertEqual('sas', ret['interface_type']) + self.assertEqual('HP EF0600FARNA', ret['model']) + self.assertEqual('HPD6', ret['firmware']) + self.assertEqual('ready', ret['status'])