Merge "Discover Storage details"
This commit is contained in:
commit
f885f47e2d
@ -274,6 +274,175 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
|
|||||||
gpu_list.append(item)
|
gpu_list.append(item)
|
||||||
return gpu_list
|
return gpu_list
|
||||||
|
|
||||||
|
def _get_storage_resource(self):
|
||||||
|
"""Gets the SmartStorage resource if exists.
|
||||||
|
|
||||||
|
:raises: IloCommandNotSupportedError if the resource SmartStorage
|
||||||
|
doesn't exist.
|
||||||
|
:returns the tuple of SmartStorage URI, Headers and settings.
|
||||||
|
"""
|
||||||
|
system = self._get_host_details()
|
||||||
|
if ('links' in system['Oem']['Hp'] and
|
||||||
|
'SmartStorage' in system['Oem']['Hp']['links']):
|
||||||
|
# Get the SmartStorage URI and Settings
|
||||||
|
storage_uri = system['Oem']['Hp']['links']['SmartStorage']['href']
|
||||||
|
status, headers, storage_settings = self._rest_get(storage_uri)
|
||||||
|
|
||||||
|
if status >= 300:
|
||||||
|
msg = self._get_extended_error(storage_settings)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
|
return headers, storage_uri, storage_settings
|
||||||
|
else:
|
||||||
|
msg = ('"links/SmartStorage" section in ComputerSystem/Oem/Hp'
|
||||||
|
' does not exist')
|
||||||
|
raise exception.IloCommandNotSupportedError(msg)
|
||||||
|
|
||||||
|
def _get_array_controller_resource(self):
|
||||||
|
"""Gets the ArrayController resource if exists.
|
||||||
|
|
||||||
|
:raises: IloCommandNotSupportedError if the resource ArrayController
|
||||||
|
doesn't exist.
|
||||||
|
:returns the tuple of SmartStorage URI, Headers and settings.
|
||||||
|
"""
|
||||||
|
headers, storage_uri, storage_settings = self._get_storage_resource()
|
||||||
|
if ('links' in storage_settings and
|
||||||
|
'ArrayControllers' in storage_settings['links']):
|
||||||
|
# Get the ArrayCOntrollers URI and Settings
|
||||||
|
array_uri = storage_settings['links']['ArrayControllers']['href']
|
||||||
|
status, headers, array_settings = self._rest_get(array_uri)
|
||||||
|
|
||||||
|
if status >= 300:
|
||||||
|
msg = self._get_extended_error(array_settings)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
|
return headers, array_uri, array_settings
|
||||||
|
else:
|
||||||
|
msg = ('"links/ArrayControllers" section in SmartStorage'
|
||||||
|
' does not exist')
|
||||||
|
raise exception.IloCommandNotSupportedError(msg)
|
||||||
|
|
||||||
|
def _create_list_of_array_controllers(self):
|
||||||
|
"""Creates the list of Array Controller URIs.
|
||||||
|
|
||||||
|
:raises: IloCommandNotSupportedError if the ArrayControllers
|
||||||
|
doesnt have member "Member".
|
||||||
|
:returns list of ArrayControllers.
|
||||||
|
"""
|
||||||
|
headers, array_uri, array_settings = (
|
||||||
|
self._get_array_controller_resource())
|
||||||
|
array_uri_links = []
|
||||||
|
if ('links' in array_settings and
|
||||||
|
'Member' in array_settings['links']):
|
||||||
|
array_uri_links = array_settings['links']['Member']
|
||||||
|
else:
|
||||||
|
msg = ('"links/Member" section in ArrayControllers'
|
||||||
|
' does not exist')
|
||||||
|
raise exception.IloCommandNotSupportedError(msg)
|
||||||
|
return array_uri_links
|
||||||
|
|
||||||
|
def _get_drive_type_and_speed(self):
|
||||||
|
"""Gets the disk drive type.
|
||||||
|
|
||||||
|
:returns: A dictionary with the following keys:
|
||||||
|
- has_rotational: True/False. It is True if atleast one
|
||||||
|
rotational disk is attached.
|
||||||
|
- has_ssd: True/False. It is True if at least one SSD disk is
|
||||||
|
attached.
|
||||||
|
- drive_rotational_<speed>_rpm: These are set to true as
|
||||||
|
per the speed of the rotational disks.
|
||||||
|
:raises: IloCommandNotSupportedError if the PhysicalDrives resource
|
||||||
|
doesn't exist.
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
"""
|
||||||
|
disk_details = self._get_physical_drive_resource()
|
||||||
|
drive_hdd = False
|
||||||
|
drive_ssd = False
|
||||||
|
drive_details = {}
|
||||||
|
speed_const_list = [4800, 5400, 7200, 10000, 15000]
|
||||||
|
if disk_details:
|
||||||
|
for item in disk_details:
|
||||||
|
value = item['MediaType']
|
||||||
|
if value == "HDD":
|
||||||
|
drive_hdd = True
|
||||||
|
speed = item['RotationalSpeedRpm']
|
||||||
|
if speed in speed_const_list:
|
||||||
|
var = 'rotational_drive_' + str(speed) + '_rpm'
|
||||||
|
drive_details.update({var: 'true'})
|
||||||
|
# Note: RIS returns value as 'SDD' for SSD drives.
|
||||||
|
else:
|
||||||
|
drive_ssd = True
|
||||||
|
if drive_hdd:
|
||||||
|
drive_details.update({'has_rotational': 'true'})
|
||||||
|
if drive_ssd:
|
||||||
|
drive_details.update({'has_ssd': 'true'})
|
||||||
|
return drive_details if len(drive_details.keys()) > 0 else None
|
||||||
|
|
||||||
|
def _get_drive_resource(self, drive_name):
|
||||||
|
"""Gets the DiskDrive resource if exists.
|
||||||
|
|
||||||
|
:param drive_name: can be either "PhysicalDrives" or
|
||||||
|
"LogicalDrives".
|
||||||
|
:returns the list of drives.
|
||||||
|
:raises: IloCommandNotSupportedError if the given drive resource
|
||||||
|
doesn't exist.
|
||||||
|
:raises: IloError, on an error from iLO.
|
||||||
|
"""
|
||||||
|
disk_details_list = []
|
||||||
|
array_uri_links = self._create_list_of_array_controllers()
|
||||||
|
for array_link in array_uri_links:
|
||||||
|
_, _, member_settings = (
|
||||||
|
self._rest_get(array_link['href']))
|
||||||
|
|
||||||
|
if ('links' in member_settings and
|
||||||
|
drive_name in member_settings['links']):
|
||||||
|
disk_uri = member_settings['links'][drive_name]['href']
|
||||||
|
headers, disk_member_uri, disk_mem = (
|
||||||
|
self._rest_get(disk_uri))
|
||||||
|
if ('links' in disk_mem and
|
||||||
|
'Member' in disk_mem['links']):
|
||||||
|
for disk_link in disk_mem['links']['Member']:
|
||||||
|
diskdrive_uri = disk_link['href']
|
||||||
|
_, _, disk_details = (
|
||||||
|
self._rest_get(diskdrive_uri))
|
||||||
|
disk_details_list.append(disk_details)
|
||||||
|
else:
|
||||||
|
msg = ('"links/Member" section in %s'
|
||||||
|
' does not exist', drive_name)
|
||||||
|
raise exception.IloCommandNotSupportedError(msg)
|
||||||
|
else:
|
||||||
|
msg = ('"links/%s" section in '
|
||||||
|
' ArrayController/links/Member does not exist',
|
||||||
|
drive_name)
|
||||||
|
raise exception.IloCommandNotSupportedError(msg)
|
||||||
|
if disk_details_list:
|
||||||
|
return disk_details_list
|
||||||
|
|
||||||
|
def _get_logical_drive_resource(self):
|
||||||
|
"""Returns the LogicalDrives data."""
|
||||||
|
return self._get_drive_resource('LogicalDrives')
|
||||||
|
|
||||||
|
def _get_physical_drive_resource(self):
|
||||||
|
"""Returns the PhysicalDrives data."""
|
||||||
|
return self._get_drive_resource('PhysicalDrives')
|
||||||
|
|
||||||
|
def _get_logical_raid_levels(self):
|
||||||
|
"""Gets the different raid levels configured on a server.
|
||||||
|
|
||||||
|
:returns a dictionary of logical_raid_levels set to true.
|
||||||
|
Example if raid level 1+0 and 6 are configured, it returns
|
||||||
|
{'logical_raid_level_10': 'true',
|
||||||
|
'logical_raid_level_6': 'true'}
|
||||||
|
"""
|
||||||
|
logical_drive_details = self._get_logical_drive_resource()
|
||||||
|
raid_level = {}
|
||||||
|
if logical_drive_details:
|
||||||
|
for item in logical_drive_details:
|
||||||
|
if 'Raid' in item:
|
||||||
|
raid_level_var = "logical_raid_level_" + item['Raid']
|
||||||
|
raid_level.update({raid_level_var: 'true'})
|
||||||
|
return raid_level if len(raid_level.keys()) > 0 else None
|
||||||
|
|
||||||
def _get_bios_settings_resource(self, data):
|
def _get_bios_settings_resource(self, data):
|
||||||
"""Get the BIOS settings resource."""
|
"""Get the BIOS settings resource."""
|
||||||
try:
|
try:
|
||||||
@ -1002,6 +1171,12 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
|
|||||||
capabilities['rom_firmware_version'] = rom_firmware_version
|
capabilities['rom_firmware_version'] = rom_firmware_version
|
||||||
capabilities.update(self._get_ilo_firmware_version())
|
capabilities.update(self._get_ilo_firmware_version())
|
||||||
capabilities.update(self._get_number_of_gpu_devices_connected())
|
capabilities.update(self._get_number_of_gpu_devices_connected())
|
||||||
|
drive_details = self._get_drive_type_and_speed()
|
||||||
|
if drive_details is not None:
|
||||||
|
capabilities.update(drive_details)
|
||||||
|
raid_details = self._get_logical_raid_levels()
|
||||||
|
if raid_details is not None:
|
||||||
|
capabilities.update(raid_details)
|
||||||
boot_modes = common.get_supported_boot_modes(
|
boot_modes = common.get_supported_boot_modes(
|
||||||
self.get_supported_boot_mode())
|
self.get_supported_boot_mode())
|
||||||
capabilities.update({
|
capabilities.update({
|
||||||
@ -1016,7 +1191,7 @@ class RISOperations(rest.RestConnectorBase, operations.IloOperations):
|
|||||||
try:
|
try:
|
||||||
self._check_iscsi_rest_patch_allowed()
|
self._check_iscsi_rest_patch_allowed()
|
||||||
capabilities['iscsi_boot'] = 'true'
|
capabilities['iscsi_boot'] = 'true'
|
||||||
except exception.IloCommandNotSupportedError:
|
except exception.IloError:
|
||||||
# If an error is raised dont populate the capability
|
# If an error is raised dont populate the capability
|
||||||
# iscsi_boot
|
# iscsi_boot
|
||||||
pass
|
pass
|
||||||
|
@ -287,6 +287,24 @@ GET_HEADERS = {
|
|||||||
'x_hp-chrp-service-version': '1.0.3'
|
'x_hp-chrp-service-version': '1.0.3'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REST_GET_SMART_STORAGE = """
|
||||||
|
{
|
||||||
|
"Model": "ProLiant BL460c Gen9",
|
||||||
|
"Name": "Computer System",
|
||||||
|
"Oem": {
|
||||||
|
"Hp": {
|
||||||
|
"links":
|
||||||
|
{
|
||||||
|
"SmartStorage":
|
||||||
|
{
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
REST_GET_SECURE_BOOT = {
|
REST_GET_SECURE_BOOT = {
|
||||||
"Name": "SecureBoot",
|
"Name": "SecureBoot",
|
||||||
"ResetAllKeys": True,
|
"ResetAllKeys": True,
|
||||||
@ -3892,3 +3910,272 @@ Pci(0x8,0x0)/Pci(0x0,0x0)",
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
STORAGE_SETTINGS = """
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1\
|
||||||
|
/SmartStorage$entity",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/",
|
||||||
|
"@odata.type": "#HpSmartStorage.HpSmartStorage",
|
||||||
|
"Description": "HP Smart Storage",
|
||||||
|
"Id": "1",
|
||||||
|
"Links": {
|
||||||
|
"ArrayControllers": {
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1\
|
||||||
|
/SmartStorage/ArrayControllers/"
|
||||||
|
},
|
||||||
|
"HostBusAdapters": {
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage\
|
||||||
|
/HostBusAdapters/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Name": "HpSmartStorage",
|
||||||
|
"Status": {
|
||||||
|
"Health": "OK"
|
||||||
|
},
|
||||||
|
"Type": "HpSmartStorage.1.0.0",
|
||||||
|
"links": {
|
||||||
|
"ArrayControllers": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage\
|
||||||
|
/ArrayControllers"
|
||||||
|
},
|
||||||
|
"HostBusAdapters": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage\
|
||||||
|
/HostBusAdapters"
|
||||||
|
},
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
ARRAY_SETTINGS = """
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1\
|
||||||
|
/SmartStorage/ArrayControllers",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/",
|
||||||
|
"@odata.type": "#HpSmartStorageArrayControllerCollection.\
|
||||||
|
1.0.0.HpSmartStorageArrayControllerCollection",
|
||||||
|
"Description": "HP Smart Storage Array Controllers View",
|
||||||
|
"MemberType": "HpSmartStorageArrayController.1",
|
||||||
|
"Members": [{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage\
|
||||||
|
/ArrayControllers/0/"
|
||||||
|
}],
|
||||||
|
"Members@odata.count": 1,
|
||||||
|
"Name": "HpSmartStorageArrayControllers",
|
||||||
|
"Total": 1,
|
||||||
|
"Type": "Collection.0.9.5",
|
||||||
|
"links": {
|
||||||
|
"Member": [{
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/0"
|
||||||
|
}],
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
ARRAY_MEM_SETTINGS = """
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1\
|
||||||
|
/SmartStorage/ArrayControllers/Members/$entity",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/",
|
||||||
|
"@odata.type": "#HpSmartStorageArrayController.\
|
||||||
|
HpSmartStorageArrayController",
|
||||||
|
"AdapterType": "SmartArray",
|
||||||
|
"BackupPowerSourceStatus": "Present",
|
||||||
|
"CacheMemorySizeMiB": 1024,
|
||||||
|
"CurrentOperatingMode": "RAID",
|
||||||
|
"Description": "HP Smart Storage Array Controller View",
|
||||||
|
"FirmwareVersion": {
|
||||||
|
"Current": {
|
||||||
|
"VersionString": "2.49"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"HardwareRevision": "B",
|
||||||
|
"Id": "0",
|
||||||
|
"Links": {
|
||||||
|
"LogicalDrives": {
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/LogicalDrives/"
|
||||||
|
},
|
||||||
|
"PhysicalDrives": {
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/DiskDrives/"
|
||||||
|
},
|
||||||
|
"StorageEnclosures": {
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/StorageEnclosures/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Location": "Slot 0",
|
||||||
|
"LocationFormat": "PCISlot",
|
||||||
|
"Model": "HP Smart Array P244br Controller",
|
||||||
|
"Name": "HpSmartStorageArrayController",
|
||||||
|
"SerialNumber": "PDZVU0FLM7I03I",
|
||||||
|
"Status": {
|
||||||
|
"Health": "OK",
|
||||||
|
"State": "Enabled"
|
||||||
|
},
|
||||||
|
"Type": "HpSmartStorageArrayController.1.0.0",
|
||||||
|
"links": {
|
||||||
|
"LogicalDrives": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers\
|
||||||
|
/0/LogicalDrives"
|
||||||
|
},
|
||||||
|
"PhysicalDrives": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/\
|
||||||
|
0/DiskDrives"
|
||||||
|
},
|
||||||
|
"StorageEnclosures": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/\
|
||||||
|
0/StorageEnclosures"
|
||||||
|
},
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
DISK_COLLECTION = """
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1\
|
||||||
|
/SmartStorage/ArrayControllers/Members/2/DiskDrives",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers\
|
||||||
|
/2/DiskDrives/",
|
||||||
|
"@odata.type": "\
|
||||||
|
#HpSmartStorageDiskDriveCollection.HpSmartStorageDiskDriveCollection",
|
||||||
|
"Description": "HP Smart Storage Disk Drives View",
|
||||||
|
"MemberType": "HpSmartStorageDiskDrive.1",
|
||||||
|
"Members": [{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/DiskDrives/0/"
|
||||||
|
}],
|
||||||
|
"Members@odata.count": 1,
|
||||||
|
"Name": "HpSmartStorageDiskDrives",
|
||||||
|
"Total": 1,
|
||||||
|
"Type": "Collection.1.0.0",
|
||||||
|
"links": {
|
||||||
|
"Member": [{
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/DiskDrives/0"
|
||||||
|
}],
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/\
|
||||||
|
ArrayControllers/0/DiskDrives"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
DISK_DETAILS_LIST = """
|
||||||
|
[{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1\
|
||||||
|
/SmartStorage/ArrayControllers/Members/0/DiskDrives/Members/$entity",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers\
|
||||||
|
/0/DiskDrives/0/",
|
||||||
|
"@odata.type": "#HpSmartStorageDiskDrive.HpSmartStorageDiskDrive",
|
||||||
|
"CapacityMiB": 572325,
|
||||||
|
"CurrentTemperatureCelsius": 25,
|
||||||
|
"Description": "HP Smart Storage Disk Drive View",
|
||||||
|
"EncryptedDrive": "False",
|
||||||
|
"FirmwareVersion": {
|
||||||
|
"Current": {
|
||||||
|
"VersionString": "HPDC"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Id": "0",
|
||||||
|
"InterfaceType": "SAS",
|
||||||
|
"Location": "1I:1:1",
|
||||||
|
"LocationFormat": "ControllerPort:Box:Bay",
|
||||||
|
"MaximumTemperatureCelsius": 34,
|
||||||
|
"MediaType": "HDD",
|
||||||
|
"Model": "EG0600FBVFP",
|
||||||
|
"Name": "HpSmartStorageDiskDrive",
|
||||||
|
"RotationalSpeedRpm": 10000,
|
||||||
|
"SerialNumber": "KWK1JS2X",
|
||||||
|
"Status": {
|
||||||
|
"Health": "OK",
|
||||||
|
"State": "Enabled"
|
||||||
|
},
|
||||||
|
"Type": "HpSmartStorageDiskDrive.1.0.0",
|
||||||
|
"links": {
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers\
|
||||||
|
/0/DiskDrives/0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
"""
|
||||||
|
|
||||||
|
LOGICAL_COLLECTION = """
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/\
|
||||||
|
ArrayControllers/Members/0/LogicalDrives",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/\
|
||||||
|
0/LogicalDrives/",
|
||||||
|
"@odata.type": "\
|
||||||
|
#HpSmartStorageLogicalDriveCollection.HpSmartStorageLogicalDriveCollection",
|
||||||
|
"Description": "HP Smart Storage Logical Drives View",
|
||||||
|
"MemberType": "HpSmartStorageLogicalDrive.1",
|
||||||
|
"Members": [{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers\
|
||||||
|
/0/LogicalDrives/0/"
|
||||||
|
}],
|
||||||
|
"Members@odata.count": 1,
|
||||||
|
"Name": "HpSmartStorageLogicalDrives",
|
||||||
|
"Total": 1,
|
||||||
|
"Type": "Collection.1.0.0",
|
||||||
|
"links": {
|
||||||
|
"Member": [{
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/\
|
||||||
|
0/LogicalDrives/1"
|
||||||
|
}],
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/0\
|
||||||
|
/LogicalDrives"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
LOGICAL_DETAILS = """
|
||||||
|
[{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1/SmartStorage/\
|
||||||
|
ArrayControllers/Members/0/LogicalDrives/Members/$entity",
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/0/\
|
||||||
|
LogicalDrives/1/",
|
||||||
|
"@odata.type": "\
|
||||||
|
#HpSmartStorageLogicalDrive.1.1.0.HpSmartStorageLogicalDrive",
|
||||||
|
"CapacityMiB": 286070,
|
||||||
|
"Description": "HP Smart Storage Logical Drive View",
|
||||||
|
"Id": "1",
|
||||||
|
"LogicalDriveEncryption": false,
|
||||||
|
"LogicalDriveName": "01908CF2PDNMF0ARH6X0FN6FE9",
|
||||||
|
"LogicalDriveNumber": 1,
|
||||||
|
"LogicalDriveType": "Data",
|
||||||
|
"Name": "HpSmartStorageLogicalDrive",
|
||||||
|
"Raid": "0",
|
||||||
|
"Status": {
|
||||||
|
"Health": "OK",
|
||||||
|
"State": "Enabled"
|
||||||
|
},
|
||||||
|
"StripeSizeBytes": 262144,
|
||||||
|
"Type": "HpSmartStorageLogicalDrive.1.1.0",
|
||||||
|
"VolumeUniqueIdentifier": "600508B1001CC8A5FF549462C7B8412A",
|
||||||
|
"links": {
|
||||||
|
"DataDrives": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/0/\
|
||||||
|
LogicalDrives/1/DataDrives"
|
||||||
|
},
|
||||||
|
"self": {
|
||||||
|
"href": "/rest/v1/Systems/1/SmartStorage/ArrayControllers/0/\
|
||||||
|
LogicalDrives/1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
"""
|
||||||
|
@ -437,6 +437,8 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
validate_mock.assert_called_once_with(ris_outputs.GET_HEADERS,
|
validate_mock.assert_called_once_with(ris_outputs.GET_HEADERS,
|
||||||
settings_uri)
|
settings_uri)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_logical_raid_levels')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_drive_type_and_speed')
|
||||||
@mock.patch.object(ris.RISOperations, '_check_iscsi_rest_patch_allowed')
|
@mock.patch.object(ris.RISOperations, '_check_iscsi_rest_patch_allowed')
|
||||||
@mock.patch.object(ris.RISOperations, '_get_bios_setting')
|
@mock.patch.object(ris.RISOperations, '_get_bios_setting')
|
||||||
@mock.patch.object(ris.RISOperations, '_get_nvdimm_n_status')
|
@mock.patch.object(ris.RISOperations, '_get_nvdimm_n_status')
|
||||||
@ -452,7 +454,8 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
def test_get_server_capabilities(self, get_details_mock, ilo_firm_mock,
|
def test_get_server_capabilities(self, get_details_mock, ilo_firm_mock,
|
||||||
secure_mock, boot_mode_mock, gpu_mock,
|
secure_mock, boot_mode_mock, gpu_mock,
|
||||||
tpm_mock, cpu_vt_mock, nvdimm_n_mock,
|
tpm_mock, cpu_vt_mock, nvdimm_n_mock,
|
||||||
bios_sriov_mock, iscsi_boot_mock):
|
bios_sriov_mock, iscsi_boot_mock,
|
||||||
|
drive_mock, raid_mock):
|
||||||
host_details = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
host_details = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
||||||
get_details_mock.return_value = host_details
|
get_details_mock.return_value = host_details
|
||||||
ilo_firm_mock.return_value = {'ilo_firmware_version': 'iLO 4 v2.20'}
|
ilo_firm_mock.return_value = {'ilo_firmware_version': 'iLO 4 v2.20'}
|
||||||
@ -465,6 +468,9 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
tpm_mock.return_value = True
|
tpm_mock.return_value = True
|
||||||
bios_sriov_mock.return_value = 'Disabled'
|
bios_sriov_mock.return_value = 'Disabled'
|
||||||
iscsi_boot_mock.return_value = '/rest/v1/systems/1/bios/iScsi'
|
iscsi_boot_mock.return_value = '/rest/v1/systems/1/bios/iScsi'
|
||||||
|
drive_mock.return_value = {'has_rotational': True,
|
||||||
|
'rotational_drive_4800_rpm': True}
|
||||||
|
raid_mock.return_value = {'logical_raid_volume_0': 'true'}
|
||||||
expected_caps = {'secure_boot': 'true',
|
expected_caps = {'secure_boot': 'true',
|
||||||
'ilo_firmware_version': 'iLO 4 v2.20',
|
'ilo_firmware_version': 'iLO 4 v2.20',
|
||||||
'rom_firmware_version': u'I36 v1.40 (01/28/2015)',
|
'rom_firmware_version': u'I36 v1.40 (01/28/2015)',
|
||||||
@ -475,10 +481,15 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
'nvdimm_n': 'true',
|
'nvdimm_n': 'true',
|
||||||
'boot_mode_bios': 'false',
|
'boot_mode_bios': 'false',
|
||||||
'boot_mode_uefi': 'true',
|
'boot_mode_uefi': 'true',
|
||||||
'iscsi_boot': 'true'}
|
'iscsi_boot': 'true',
|
||||||
|
'has_rotational': True,
|
||||||
|
'rotational_drive_4800_rpm': True,
|
||||||
|
'logical_raid_volume_0': 'true'}
|
||||||
capabilities = self.client.get_server_capabilities()
|
capabilities = self.client.get_server_capabilities()
|
||||||
self.assertEqual(expected_caps, capabilities)
|
self.assertEqual(expected_caps, capabilities)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_logical_raid_levels')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_drive_type_and_speed')
|
||||||
@mock.patch.object(ris.RISOperations, '_check_iscsi_rest_patch_allowed')
|
@mock.patch.object(ris.RISOperations, '_check_iscsi_rest_patch_allowed')
|
||||||
@mock.patch.object(ris.RISOperations, '_get_bios_setting')
|
@mock.patch.object(ris.RISOperations, '_get_bios_setting')
|
||||||
@mock.patch.object(ris.RISOperations, '_get_nvdimm_n_status')
|
@mock.patch.object(ris.RISOperations, '_get_nvdimm_n_status')
|
||||||
@ -494,7 +505,7 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
def test_get_server_capabilities_tp_absent(
|
def test_get_server_capabilities_tp_absent(
|
||||||
self, get_details_mock, ilo_firm_mock, secure_mock, boot_mode_mock,
|
self, get_details_mock, ilo_firm_mock, secure_mock, boot_mode_mock,
|
||||||
gpu_mock, tpm_mock, cpu_vt_mock, nvdimm_n_mock, bios_sriov_mock,
|
gpu_mock, tpm_mock, cpu_vt_mock, nvdimm_n_mock, bios_sriov_mock,
|
||||||
iscsi_mock):
|
iscsi_mock, drive_mock, raid_mock):
|
||||||
host_details = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
host_details = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
||||||
get_details_mock.return_value = host_details
|
get_details_mock.return_value = host_details
|
||||||
ilo_firm_mock.return_value = {'ilo_firmware_version': 'iLO 4 v2.20'}
|
ilo_firm_mock.return_value = {'ilo_firmware_version': 'iLO 4 v2.20'}
|
||||||
@ -507,6 +518,9 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
cpu_vt_mock.return_value = True
|
cpu_vt_mock.return_value = True
|
||||||
bios_sriov_mock.return_value = 'Enabled'
|
bios_sriov_mock.return_value = 'Enabled'
|
||||||
iscsi_mock.side_effect = exception.IloCommandNotSupportedError('error')
|
iscsi_mock.side_effect = exception.IloCommandNotSupportedError('error')
|
||||||
|
drive_mock.return_value = {'has_rotational': True,
|
||||||
|
'rotational_drive_4800_rpm': True}
|
||||||
|
raid_mock.return_value = {'logical_raid_volume_0': 'true'}
|
||||||
expected_caps = {'secure_boot': 'true',
|
expected_caps = {'secure_boot': 'true',
|
||||||
'ilo_firmware_version': 'iLO 4 v2.20',
|
'ilo_firmware_version': 'iLO 4 v2.20',
|
||||||
'rom_firmware_version': u'I36 v1.40 (01/28/2015)',
|
'rom_firmware_version': u'I36 v1.40 (01/28/2015)',
|
||||||
@ -516,7 +530,10 @@ class IloRisTestCase(testtools.TestCase):
|
|||||||
'nvdimm_n': 'true',
|
'nvdimm_n': 'true',
|
||||||
'sriov_enabled': 'true',
|
'sriov_enabled': 'true',
|
||||||
'boot_mode_bios': 'true',
|
'boot_mode_bios': 'true',
|
||||||
'boot_mode_uefi': 'true'}
|
'boot_mode_uefi': 'true',
|
||||||
|
'has_rotational': True,
|
||||||
|
'rotational_drive_4800_rpm': True,
|
||||||
|
'logical_raid_volume_0': 'true'}
|
||||||
capabilities = self.client.get_server_capabilities()
|
capabilities = self.client.get_server_capabilities()
|
||||||
self.assertEqual(expected_caps, capabilities)
|
self.assertEqual(expected_caps, capabilities)
|
||||||
|
|
||||||
@ -1775,6 +1792,160 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
|
|||||||
self.client._get_pci_devices)
|
self.client._get_pci_devices)
|
||||||
get_details_mock.assert_called_once_with()
|
get_details_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||||
|
def test__get_storage_resource(self, get_host_details_mock, get_mock):
|
||||||
|
system_data = json.loads(ris_outputs.REST_GET_SMART_STORAGE)
|
||||||
|
get_host_details_mock.return_value = system_data
|
||||||
|
storage_uri = '/rest/v1/Systems/1/SmartStorage'
|
||||||
|
storage_settings = json.loads(ris_outputs.STORAGE_SETTINGS)
|
||||||
|
|
||||||
|
get_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||||
|
storage_settings)
|
||||||
|
self.client._get_storage_resource()
|
||||||
|
get_mock.assert_called_once_with(storage_uri)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||||
|
def test__get_storage_resource_fail(self, get_host_details_mock,
|
||||||
|
get_mock):
|
||||||
|
system_data = json.loads(ris_outputs.REST_GET_SMART_STORAGE)
|
||||||
|
get_host_details_mock.return_value = system_data
|
||||||
|
storage_uri = '/rest/v1/Systems/1/SmartStorage'
|
||||||
|
storage_settings = json.loads(ris_outputs.STORAGE_SETTINGS)
|
||||||
|
|
||||||
|
get_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||||
|
storage_settings)
|
||||||
|
self.assertRaises(exception.IloError,
|
||||||
|
self.client._get_storage_resource)
|
||||||
|
get_mock.assert_called_once_with(storage_uri)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||||
|
def test__get_storage_resource_not_supported(self,
|
||||||
|
get_host_details_mock):
|
||||||
|
system_data = json.loads(ris_outputs.REST_GET_SMART_STORAGE)
|
||||||
|
del system_data['Oem']['Hp']['links']['SmartStorage']
|
||||||
|
get_host_details_mock.return_value = system_data
|
||||||
|
self.assertRaises(exception.IloCommandNotSupportedError,
|
||||||
|
self.client._get_storage_resource)
|
||||||
|
get_host_details_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_storage_resource')
|
||||||
|
def test__get_array_controller_resource(self, storage_mock, get_mock):
|
||||||
|
storage_data = json.loads(ris_outputs.STORAGE_SETTINGS)
|
||||||
|
storage_uri = '/rest/v1/Systems/1/SmartStorage'
|
||||||
|
storage_mock.return_value = (ris_outputs.GET_HEADERS,
|
||||||
|
storage_uri,
|
||||||
|
storage_data)
|
||||||
|
array_uri = '/rest/v1/Systems/1/SmartStorage/ArrayControllers'
|
||||||
|
array_settings = json.loads(ris_outputs.ARRAY_SETTINGS)
|
||||||
|
|
||||||
|
get_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||||
|
array_settings)
|
||||||
|
self.client._get_array_controller_resource()
|
||||||
|
get_mock.assert_called_once_with(array_uri)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_storage_resource')
|
||||||
|
def test__get_array_controller_resource_fail(self, storage_mock,
|
||||||
|
get_mock):
|
||||||
|
storage_data = json.loads(ris_outputs.STORAGE_SETTINGS)
|
||||||
|
storage_uri = '/rest/v1/Systems/1/SmartStorage'
|
||||||
|
storage_mock.return_value = (ris_outputs.GET_HEADERS,
|
||||||
|
storage_uri,
|
||||||
|
storage_data)
|
||||||
|
array_uri = '/rest/v1/Systems/1/SmartStorage/ArrayControllers'
|
||||||
|
array_settings = json.loads(ris_outputs.ARRAY_SETTINGS)
|
||||||
|
|
||||||
|
get_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||||
|
array_settings)
|
||||||
|
self.assertRaises(exception.IloError,
|
||||||
|
self.client._get_array_controller_resource)
|
||||||
|
get_mock.assert_called_once_with(array_uri)
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_storage_resource')
|
||||||
|
def test__get_array_controller_resource_not_supported(self,
|
||||||
|
storage_mock):
|
||||||
|
storage_data = json.loads(ris_outputs.STORAGE_SETTINGS)
|
||||||
|
storage_uri = '/rest/v1/Systems/1/SmartStorage'
|
||||||
|
del storage_data['links']['ArrayControllers']
|
||||||
|
storage_mock.return_value = (ris_outputs.GET_HEADERS,
|
||||||
|
storage_uri,
|
||||||
|
storage_data)
|
||||||
|
self.assertRaises(exception.IloCommandNotSupportedError,
|
||||||
|
self.client._get_array_controller_resource)
|
||||||
|
storage_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_array_controller_resource')
|
||||||
|
def test__create_list_of_array_controllers(self, array_mock):
|
||||||
|
array_data = json.loads(ris_outputs.ARRAY_SETTINGS)
|
||||||
|
array_uri = '/rest/v1/Systems/1/SmartStorage/ArrayControllers'
|
||||||
|
array_mock.return_value = (ris_outputs.GET_HEADERS,
|
||||||
|
array_uri,
|
||||||
|
array_data)
|
||||||
|
expected_uri_links = (
|
||||||
|
[{u'href': u'/rest/v1/Systems/1/SmartStorage/ArrayControllers/0'}])
|
||||||
|
uri_links = self.client._create_list_of_array_controllers()
|
||||||
|
self.assertEqual(expected_uri_links, uri_links)
|
||||||
|
array_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_array_controller_resource')
|
||||||
|
def test__create_list_of_array_controllers_fail(self, array_mock):
|
||||||
|
array_data = json.loads(ris_outputs.ARRAY_SETTINGS)
|
||||||
|
array_uri = '/rest/v1/Systems/1/SmartStorage/ArrayControllers'
|
||||||
|
del array_data['links']['Member']
|
||||||
|
array_mock.return_value = (ris_outputs.GET_HEADERS,
|
||||||
|
array_uri,
|
||||||
|
array_data)
|
||||||
|
self.assertRaises(exception.IloCommandNotSupportedError,
|
||||||
|
self.client._create_list_of_array_controllers)
|
||||||
|
array_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_get_physical_drive_resource')
|
||||||
|
def test__get_drive_type_and_speed(self, disk_details_mock):
|
||||||
|
disk_details_mock.return_value = (
|
||||||
|
json.loads(ris_outputs.DISK_DETAILS_LIST))
|
||||||
|
expected_out = {'has_rotational': 'true',
|
||||||
|
'rotational_drive_10000_rpm': 'true'}
|
||||||
|
out = self.client._get_drive_type_and_speed()
|
||||||
|
self.assertEqual(expected_out, out)
|
||||||
|
disk_details_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_create_list_of_array_controllers')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
def test__get_drive_resource_physical(self, get_mock, array_mock):
|
||||||
|
array_mock.return_value = (
|
||||||
|
[{u'href': u'/rest/v1/Systems/1/SmartStorage/ArrayControllers/0'}])
|
||||||
|
get_mock.side_effect = [(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.ARRAY_MEM_SETTINGS)),
|
||||||
|
(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.DISK_COLLECTION)),
|
||||||
|
(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.DISK_DETAILS_LIST))]
|
||||||
|
out = self.client._get_physical_drive_resource()
|
||||||
|
expected_out = []
|
||||||
|
expected_out.append(json.loads(ris_outputs.DISK_DETAILS_LIST))
|
||||||
|
self.assertEqual(expected_out, out)
|
||||||
|
array_mock.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch.object(ris.RISOperations, '_create_list_of_array_controllers')
|
||||||
|
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||||
|
def test__get_drive_resource_logical(self, get_mock, array_mock):
|
||||||
|
array_mock.return_value = (
|
||||||
|
[{u'href': u'/rest/v1/Systems/1/SmartStorage/ArrayControllers/0'}])
|
||||||
|
get_mock.side_effect = [(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.ARRAY_MEM_SETTINGS)),
|
||||||
|
(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.LOGICAL_COLLECTION)),
|
||||||
|
(ris_outputs.GET_HEADERS, 'xyz',
|
||||||
|
json.loads(ris_outputs.LOGICAL_DETAILS))]
|
||||||
|
out = self.client._get_logical_drive_resource()
|
||||||
|
expected_out = []
|
||||||
|
expected_out.append(json.loads(ris_outputs.LOGICAL_DETAILS))
|
||||||
|
self.assertEqual(expected_out, out)
|
||||||
|
array_mock.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch.object(ris.RISOperations, '_get_pci_devices')
|
@mock.patch.object(ris.RISOperations, '_get_pci_devices')
|
||||||
def test__get_gpu_pci_devices(self, pci_mock):
|
def test__get_gpu_pci_devices(self, pci_mock):
|
||||||
pci_mock.return_value = json.loads(ris_outputs.PCI_DEVICE_DETAILS)
|
pci_mock.return_value = json.loads(ris_outputs.PCI_DEVICE_DETAILS)
|
||||||
|
Loading…
Reference in New Issue
Block a user