Add OEM storage controller extension
Can determine controller's mode and convert to RAID mode for eligible controllers (PERC 9 and PERC 10). Depends-On: https://review.opendev.org/c/openstack/sushy/+/850899 Change-Id: I492c476c6d69b458449eed69644b051b66dfdc65
This commit is contained in:
parent
aac2509f7b
commit
da9a0e4042
@ -28,6 +28,8 @@ packages =
|
||||
[entry_points]
|
||||
sushy.resources.manager.oems =
|
||||
dell = sushy_oem_idrac.resources.manager.manager:get_extension
|
||||
sushy.resources.storage_controller.oems =
|
||||
dell = sushy_oem_idrac.resources.system.storage.controller:get_extension
|
||||
sushy.resources.system.oems =
|
||||
dell = sushy_oem_idrac.resources.system.system:get_extension
|
||||
sushy.resources.task.oems =
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021 Dell Inc. or its subsidiaries.
|
||||
# Copyright (c) 2021-2022 Dell Inc. or its subsidiaries.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
@ -14,4 +14,5 @@
|
||||
|
||||
from sushy_oem_idrac.resources.manager.constants import * # noqa
|
||||
from sushy_oem_idrac.resources.system.constants import * # noqa
|
||||
from sushy_oem_idrac.resources.system.storage.constants import * # noqa
|
||||
from sushy_oem_idrac.resources.taskservice.constants import * # noqa
|
||||
|
28
sushy_oem_idrac/resources/system/storage/constants.py
Normal file
28
sushy_oem_idrac/resources/system/storage/constants.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2022 Dell Inc. or its subsidiaries.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import enum
|
||||
|
||||
|
||||
class ControllerMode(enum.Enum):
|
||||
"""RAID controller modes."""
|
||||
|
||||
RAID = "RAID"
|
||||
"""RAID mode."""
|
||||
|
||||
HBA = "HBA"
|
||||
"""HBA/Passthru mode. Does not support RAID. For PERC 9 controllers."""
|
||||
|
||||
EHBA = "EnhancedHBA"
|
||||
"""Enhanced HBA mode. Limited RAID support. For PERC 10 controllers."""
|
56
sushy_oem_idrac/resources/system/storage/controller.py
Normal file
56
sushy_oem_idrac/resources/system/storage/controller.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright (c) 2022 Dell Inc. or its subsidiaries.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import sushy
|
||||
from sushy.resources import base
|
||||
from sushy.resources.oem import base as oem_base
|
||||
|
||||
from sushy_oem_idrac.resources.system.storage import constants as s_cons
|
||||
|
||||
|
||||
class DellStorageController(base.CompositeField):
|
||||
|
||||
controller_mode = base.MappedField('ControllerMode', s_cons.ControllerMode)
|
||||
"""Mode of RAID controller"""
|
||||
|
||||
|
||||
class DellStorageControllerExtension(oem_base.OEMResourceBase):
|
||||
dell_storage_controller = DellStorageController('DellStorageController')
|
||||
|
||||
def convert_to_raid(self):
|
||||
"""Converts to RAID mode if applicable
|
||||
|
||||
If PERC 9 or PERC 10 controller is in non-RAID mode, then convert
|
||||
to RAID mode. No changes made for PERC 11 and above as they support
|
||||
only RAID mode, and BOSS controller as it does not have controller
|
||||
mode.
|
||||
:returns: TaskMonitor if controller mode changes applied and need to
|
||||
reboot, otherwise None
|
||||
"""
|
||||
controller_mode = self.dell_storage_controller.controller_mode
|
||||
|
||||
# BOSS will have this empty, PERC will have something assigned
|
||||
if controller_mode and controller_mode != s_cons.ControllerMode.RAID:
|
||||
patch = {
|
||||
"Oem": {
|
||||
"Dell": {
|
||||
"DellStorageController": {
|
||||
"ControllerMode":
|
||||
s_cons.ControllerMode.RAID.value}}}}
|
||||
return self._parent_resource.update(
|
||||
patch, apply_time=sushy.ApplyTime.ON_RESET)
|
||||
|
||||
|
||||
def get_extension(*args, **kwargs):
|
||||
return DellStorageControllerExtension
|
@ -0,0 +1,58 @@
|
||||
{
|
||||
"@Redfish.Settings": {
|
||||
"@odata.context": "/redfish/v1/$metadata#Settings.Settings",
|
||||
"@odata.type": "#Settings.v1_3_3.Settings",
|
||||
"SettingsObject": {
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Controllers/1/Settings"
|
||||
},
|
||||
"SupportedApplyTimes": [
|
||||
"Immediate",
|
||||
"OnReset"
|
||||
]
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#StorageController.StorageController",
|
||||
"@odata.id": "/redfish/v1/Systems/437XR1138R2/Storage/1/Controllers/1",
|
||||
"@odata.type": "#StorageController.v1_2_0.StorageController",
|
||||
"Description": "Integrated RAID Controller",
|
||||
"FirmwareVersion": "1.0.0.7",
|
||||
"Id": "1",
|
||||
"Identifiers": [
|
||||
{
|
||||
"@odata.type": "#Resource.v1_1_0.Identifier",
|
||||
"DurableNameFormat": "NAA",
|
||||
"DurableName": "345C59DBD970859C"
|
||||
}
|
||||
],
|
||||
"Identifiers@odata.count": 1,
|
||||
"Manufacturer": "Contoso",
|
||||
"Model": "12Gbs Integrated RAID",
|
||||
"Name": "Contoso Integrated RAID",
|
||||
"Oem": {
|
||||
"Dell": {
|
||||
"@odata.type": "#DellOemStorageController.v1_0_0.DellOemStorageController",
|
||||
"DellStorageController": {
|
||||
"ControllerMode": "EnhancedHBA"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SpeedGbps": 12,
|
||||
"Status": {
|
||||
"Health": "OK",
|
||||
"HealthRollup": "OK",
|
||||
"State": "Enabled"
|
||||
},
|
||||
"SupportedControllerProtocols": [
|
||||
"PCIe"
|
||||
],
|
||||
"SupportedControllerProtocols@odata.count": 1,
|
||||
"SupportedDeviceProtocols": [
|
||||
"SAS",
|
||||
"SATA"
|
||||
],
|
||||
"SupportedDeviceProtocols@odata.count": 2,
|
||||
"SupportedRAIDTypes": [
|
||||
"RAID0",
|
||||
"RAID1"
|
||||
],
|
||||
"SupportedRAIDTypes@odata.count": 2
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
# Copyright (c) 2022 Dell Inc. or its subsidiaries.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
from unittest import mock
|
||||
|
||||
from oslotest.base import BaseTestCase
|
||||
import sushy
|
||||
from sushy.resources.system.storage import controller as sushy_constroller
|
||||
|
||||
from sushy_oem_idrac.resources.system.storage import constants as ctrl_cons
|
||||
from sushy_oem_idrac.resources.system.storage import controller as oem_ctrl
|
||||
|
||||
|
||||
class ControllerTestCase(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ControllerTestCase, self).setUp()
|
||||
self.conn = mock.Mock()
|
||||
|
||||
with open('sushy_oem_idrac/tests/unit/json_samples/'
|
||||
'storage_controller.json') as f:
|
||||
mock_response = self.conn.get.return_value
|
||||
mock_response.json.return_value = json.load(f)
|
||||
mock_response.status_code = 200
|
||||
|
||||
self.controller = sushy_constroller.StorageController(
|
||||
self.conn,
|
||||
'/redfish/v1/Systems/437XR1138R2/Storage/1/Controllers/1')
|
||||
self.oem_controller = oem_ctrl.DellStorageControllerExtension(
|
||||
self.conn,
|
||||
'/redfish/v1/Systems/437XR1138R2/Storage/1/Controllers/1')
|
||||
self.oem_controller = self.oem_controller.set_parent_resource(
|
||||
self.controller, 'Dell')
|
||||
|
||||
def test_parse_attributes(self):
|
||||
self.assertEqual(
|
||||
ctrl_cons.ControllerMode.EHBA,
|
||||
self.oem_controller.dell_storage_controller.controller_mode)
|
||||
|
||||
def test_convert_to_raid(self):
|
||||
mock_controller = mock.Mock()
|
||||
mock_task_monitor = mock.Mock()
|
||||
mock_controller.update.return_value = mock_task_monitor
|
||||
self.oem_controller._parent_resource = mock_controller
|
||||
|
||||
res = self.oem_controller.convert_to_raid()
|
||||
|
||||
self.assertEqual(mock_task_monitor, res)
|
||||
patch = {"Oem": {"Dell": {"DellStorageController": {
|
||||
"ControllerMode": "RAID"}}}}
|
||||
mock_controller.update.assert_called_once_with(
|
||||
patch, apply_time=sushy.ApplyTime.ON_RESET)
|
||||
|
||||
def test_convert_to_raid_already_raid(self):
|
||||
mock_controller = mock.Mock()
|
||||
self.oem_controller._parent_resource = mock_controller
|
||||
json = self.oem_controller.json
|
||||
json['Oem']['Dell']['DellStorageController']['ControllerMode'] = 'RAID'
|
||||
self.oem_controller.refresh()
|
||||
|
||||
res = self.oem_controller.convert_to_raid()
|
||||
|
||||
self.assertIsNone(res)
|
||||
mock_controller.update.assert_not_called()
|
Loading…
Reference in New Issue
Block a user