Redfish: Adds manager support for redfish API's.
This commit enables the support for all redfish API's to make use of Manager features. This patch also includes a temporary hack for manager as 'manager_mock.py' file which needs to be removed once new Sushy version is released with manager feature. Added the 'utils' file containing the utility function, ``get_subresource_path_by``. Co-Authored-By: Aparna Vikraman <aparnavtce@gmail.com> Co-Authored-By: Debayan Ray <debayan.ray@gmail.com> Partial-Bug: 1691955 Change-Id: Iffec7e2e459455dba3b5bac817faa89341b4b9d3
This commit is contained in:
parent
e39fd72626
commit
5dab85a2a4
|
@ -14,9 +14,12 @@
|
||||||
|
|
||||||
__author__ = 'HPE'
|
__author__ = 'HPE'
|
||||||
|
|
||||||
from proliantutils.redfish.resources.system import system
|
|
||||||
import sushy
|
import sushy
|
||||||
|
|
||||||
|
from proliantutils.redfish.resources.manager import manager
|
||||||
|
from proliantutils.redfish.resources.system import system
|
||||||
|
from proliantutils.redfish import utils
|
||||||
|
|
||||||
|
|
||||||
class HPESushy(sushy.Sushy):
|
class HPESushy(sushy.Sushy):
|
||||||
"""Class that extends base Sushy class
|
"""Class that extends base Sushy class
|
||||||
|
@ -25,6 +28,9 @@ class HPESushy(sushy.Sushy):
|
||||||
required to customize the functionality of different resources
|
required to customize the functionality of different resources
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def get_system_collection_path(self):
|
||||||
|
return utils.get_subresource_path_by(self, 'Systems')
|
||||||
|
|
||||||
def get_system(self, identity):
|
def get_system(self, identity):
|
||||||
"""Given the identity return a HPESystem object
|
"""Given the identity return a HPESystem object
|
||||||
|
|
||||||
|
@ -33,3 +39,15 @@ class HPESushy(sushy.Sushy):
|
||||||
"""
|
"""
|
||||||
return system.HPESystem(self._conn, identity,
|
return system.HPESystem(self._conn, identity,
|
||||||
redfish_version=self.redfish_version)
|
redfish_version=self.redfish_version)
|
||||||
|
|
||||||
|
def get_manager_collection_path(self):
|
||||||
|
return utils.get_subresource_path_by(self, 'Managers')
|
||||||
|
|
||||||
|
def get_manager(self, identity):
|
||||||
|
"""Given the identity return a HPEManager object
|
||||||
|
|
||||||
|
:param identity: The identity of the Manager resource
|
||||||
|
:returns: The Manager object
|
||||||
|
"""
|
||||||
|
return manager.HPEManager(self._conn, identity,
|
||||||
|
redfish_version=self.redfish_version)
|
||||||
|
|
|
@ -103,14 +103,6 @@ class RedfishOperations(operations.IloOperations):
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
raise exception.IloConnectionError(msg)
|
raise exception.IloConnectionError(msg)
|
||||||
|
|
||||||
def _get_system_collection_path(self):
|
|
||||||
"""Helper function to find the SystemCollection path"""
|
|
||||||
systems_col = self._sushy.json.get('Systems')
|
|
||||||
if not systems_col:
|
|
||||||
raise exception.MissingAttributeError(attribute='Systems',
|
|
||||||
resource=self._root_prefix)
|
|
||||||
return systems_col.get('@odata.id')
|
|
||||||
|
|
||||||
def _get_sushy_system(self, system_id):
|
def _get_sushy_system(self, system_id):
|
||||||
"""Get the sushy system for system_id
|
"""Get the sushy system for system_id
|
||||||
|
|
||||||
|
@ -118,7 +110,7 @@ class RedfishOperations(operations.IloOperations):
|
||||||
:returns: the Sushy system instance
|
:returns: the Sushy system instance
|
||||||
:raises: IloError
|
:raises: IloError
|
||||||
"""
|
"""
|
||||||
system_url = parse.urljoin(self._get_system_collection_path(),
|
system_url = parse.urljoin(self._sushy.get_system_collection_path(),
|
||||||
system_id)
|
system_id)
|
||||||
try:
|
try:
|
||||||
return self._sushy.get_system(system_url)
|
return self._sushy.get_system(system_url)
|
||||||
|
@ -129,6 +121,24 @@ class RedfishOperations(operations.IloOperations):
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
raise exception.IloError(msg)
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
|
def _get_sushy_manager(self, manager_id):
|
||||||
|
"""Get the sushy Manager for manager_id
|
||||||
|
|
||||||
|
:param manager_id: The identity of the Manager resource
|
||||||
|
:returns: the Sushy Manager instance
|
||||||
|
:raises: IloError
|
||||||
|
"""
|
||||||
|
manager_url = parse.urljoin(self._sushy.get_manager_collection_path(),
|
||||||
|
manager_id)
|
||||||
|
try:
|
||||||
|
return self._sushy.get_manager(manager_url)
|
||||||
|
except sushy.exceptions.SushyError as e:
|
||||||
|
msg = (self._('The Redfish Manager "%(manager)s" was not found. '
|
||||||
|
'Error %(error)s') %
|
||||||
|
{'manager': manager_id, 'error': str(e)})
|
||||||
|
LOG.debug(msg)
|
||||||
|
raise exception.IloError(msg)
|
||||||
|
|
||||||
def get_product_name(self):
|
def get_product_name(self):
|
||||||
"""Gets the product name of the server.
|
"""Gets the product name of the server.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
__author__ = 'HPE'
|
||||||
|
|
||||||
|
from sushy.resources.manager import manager
|
||||||
|
|
||||||
|
|
||||||
|
class HPEManager(manager.Manager):
|
||||||
|
"""Class that extends the functionality of Manager resource class
|
||||||
|
|
||||||
|
This class extends the functionality of Manager resource class
|
||||||
|
from sushy
|
||||||
|
"""
|
|
@ -0,0 +1,51 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
__author__ = 'HPE'
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from proliantutils import exception
|
||||||
|
|
||||||
|
|
||||||
|
def get_subresource_path_by(resource, subresource_path):
|
||||||
|
"""Helper function to find the resource path
|
||||||
|
|
||||||
|
:param resource: ResourceBase instance from which the path is loaded.
|
||||||
|
:param subresource_path: JSON field to fetch the value from.
|
||||||
|
Either a string, or a list of strings in case of a nested field.
|
||||||
|
It should also include the '@odata.id'
|
||||||
|
:raises: MissingAttributeError, if required path is missing.
|
||||||
|
:raises: ValueError, if path is empty.
|
||||||
|
:raises: AttributeError, if json attr not found in resource
|
||||||
|
"""
|
||||||
|
if isinstance(subresource_path, six.string_types):
|
||||||
|
subresource_path = [subresource_path]
|
||||||
|
elif not subresource_path:
|
||||||
|
raise ValueError('"subresource_path" cannot be empty')
|
||||||
|
|
||||||
|
body = resource.json
|
||||||
|
for path_item in subresource_path:
|
||||||
|
body = body.get(path_item, {})
|
||||||
|
|
||||||
|
if not body:
|
||||||
|
raise exception.MissingAttributeError(
|
||||||
|
attribute='/'.join(subresource_path), resource=resource.path)
|
||||||
|
|
||||||
|
if '@odata.id' not in body:
|
||||||
|
raise exception.MissingAttributeError(
|
||||||
|
attribute='/'.join(subresource_path)+'/@odata.id',
|
||||||
|
resource=resource.path)
|
||||||
|
|
||||||
|
return body['@odata.id']
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# TODO(deray): Need to remove this hack sooner
|
||||||
|
from proliantutils.tests.redfish import manager_mock # noqa
|
|
@ -0,0 +1,196 @@
|
||||||
|
{
|
||||||
|
"@odata.context": "/redfish/v1/$metadata#Managers/Members/$entity",
|
||||||
|
"@odata.etag": "W/\"FD28A1E2\"",
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/",
|
||||||
|
"@odata.type": "#Manager.v1_1_0.Manager",
|
||||||
|
"Actions": {
|
||||||
|
"#Manager.Reset": {
|
||||||
|
"target": "/redfish/v1/Managers/1/Actions/Manager.Reset/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"CommandShell": {
|
||||||
|
"ConnectTypesSupported": [
|
||||||
|
"SSH",
|
||||||
|
"Oem"
|
||||||
|
],
|
||||||
|
"MaxConcurrentSessions": 9,
|
||||||
|
"ServiceEnabled": true
|
||||||
|
},
|
||||||
|
"EthernetInterfaces": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces/"
|
||||||
|
},
|
||||||
|
"FirmwareVersion": "iLO 5 v1.15",
|
||||||
|
"GraphicalConsole": {
|
||||||
|
"ConnectTypesSupported": [
|
||||||
|
"KVMIP"
|
||||||
|
],
|
||||||
|
"MaxConcurrentSessions": 10,
|
||||||
|
"ServiceEnabled": true
|
||||||
|
},
|
||||||
|
"Id": "1",
|
||||||
|
"Links": {
|
||||||
|
"ManagerForChassis": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/1/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ManagerForServers": [
|
||||||
|
{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ManagerInChassis": {
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/1/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"LogServices": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/LogServices/"
|
||||||
|
},
|
||||||
|
"ManagerType": "BMC",
|
||||||
|
"Name": "Manager",
|
||||||
|
"NetworkProtocol": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/NetworkService/"
|
||||||
|
},
|
||||||
|
"Oem": {
|
||||||
|
"Hpe": {
|
||||||
|
"@odata.type": "#HpeiLO.v2_1_0.HpeiLO",
|
||||||
|
"Actions": {
|
||||||
|
"#HpeiLO.ClearRestApiState": {
|
||||||
|
"target": "/redfish/v1/Managers/1/Actions/Oem/Hpe/HpeiLO.ClearRestApiState/"
|
||||||
|
},
|
||||||
|
"#HpeiLO.DisableiLOFunctionality": {
|
||||||
|
"target": "/redfish/v1/Managers/1/Actions/Oem/Hpe/HpeiLO.DisableiLOFunctionality/"
|
||||||
|
},
|
||||||
|
"#HpeiLO.ResetToFactoryDefaults": {
|
||||||
|
"ResetType@Redfish.AllowableValues": [
|
||||||
|
"Default"
|
||||||
|
],
|
||||||
|
"target": "/redfish/v1/Managers/1/Actions/Oem/Hpe/HpeiLO.ResetToFactoryDefaults/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ClearRestApiStatus": "DataPresent",
|
||||||
|
"ConfigurationSettings": "Current",
|
||||||
|
"FederationConfig": {
|
||||||
|
"IPv6MulticastScope": "Site",
|
||||||
|
"MulticastAnnouncementInterval": 600,
|
||||||
|
"MulticastDiscovery": "Enabled",
|
||||||
|
"MulticastTimeToLive": 5,
|
||||||
|
"iLOFederationManagement": "Enabled"
|
||||||
|
},
|
||||||
|
"Firmware": {
|
||||||
|
"Current": {
|
||||||
|
"Date": "Jun 05 2017",
|
||||||
|
"DebugBuild": false,
|
||||||
|
"MajorVersion": 1,
|
||||||
|
"MinorVersion": 15,
|
||||||
|
"VersionString": "iLO 5 v1.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FrontPanelUSB": {
|
||||||
|
"State": "Ready"
|
||||||
|
},
|
||||||
|
"IdleConnectionTimeoutMinutes": 30,
|
||||||
|
"License": {
|
||||||
|
"LicenseKey": "XXXXX-XXXXX-XXXXX-XXXXX-456N6",
|
||||||
|
"LicenseString": "iLO Advanced limited-distribution test",
|
||||||
|
"LicenseType": "Internal"
|
||||||
|
},
|
||||||
|
"Links": {
|
||||||
|
"ActiveHealthSystem": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/ActiveHealthSystem/"
|
||||||
|
},
|
||||||
|
"DateTimeService": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/DateTime/"
|
||||||
|
},
|
||||||
|
"EmbeddedMediaService": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/EmbeddedMedia/"
|
||||||
|
},
|
||||||
|
"FederationDispatch": {
|
||||||
|
"extref": "/dispatch"
|
||||||
|
},
|
||||||
|
"FederationGroups": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/FederationGroups/"
|
||||||
|
},
|
||||||
|
"FederationPeers": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/FederationPeers/"
|
||||||
|
},
|
||||||
|
"LicenseService": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/LicenseService/"
|
||||||
|
},
|
||||||
|
"SecurityService": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/SecurityService/"
|
||||||
|
},
|
||||||
|
"Thumbnail": {
|
||||||
|
"extref": "/images/thumbnail.bmp"
|
||||||
|
},
|
||||||
|
"VSPLogLocation": {
|
||||||
|
"extref": "/sol.log.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PersistentMouseKeyboardEnabled": false,
|
||||||
|
"RIBCLEnabled": true,
|
||||||
|
"RequiredLoginForiLORBSU": false,
|
||||||
|
"SerialCLISpeed": 9600,
|
||||||
|
"SerialCLIStatus": "EnabledAuthReq",
|
||||||
|
"VSPDlLoggingEnabled": false,
|
||||||
|
"VSPLogDownloadEnabled": false,
|
||||||
|
"WebGuiEnabled": true,
|
||||||
|
"iLOFunctionalityRequired": false,
|
||||||
|
"iLORBSUEnabled": true,
|
||||||
|
"iLOSelfTestResults": [
|
||||||
|
{
|
||||||
|
"Notes": "",
|
||||||
|
"SelfTestName": "NVRAMData",
|
||||||
|
"Status": "OK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Notes": "Controller firmware revision 2.10.00 ",
|
||||||
|
"SelfTestName": "EmbeddedFlash",
|
||||||
|
"Status": "OK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Notes": "",
|
||||||
|
"SelfTestName": "HostRom",
|
||||||
|
"Status": "OK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Notes": "",
|
||||||
|
"SelfTestName": "SupportedHost",
|
||||||
|
"Status": "OK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Notes": "Version 1.0.2",
|
||||||
|
"SelfTestName": "PowerManagementController",
|
||||||
|
"Status": "Informational"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Notes": "ProLiant DL180 Gen10 System Programmable Logic Device 0x07",
|
||||||
|
"SelfTestName": "CPLDPAL0",
|
||||||
|
"Status": "Informational"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"iLOServicePort": {
|
||||||
|
"MassStorageAuthenticationRequired": false,
|
||||||
|
"USBEthernetAdaptersEnabled": true,
|
||||||
|
"USBFlashDriveEnabled": true,
|
||||||
|
"iLOServicePortEnabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SerialConsole": {
|
||||||
|
"ConnectTypesSupported": [
|
||||||
|
"SSH",
|
||||||
|
"IPMI",
|
||||||
|
"Oem"
|
||||||
|
],
|
||||||
|
"MaxConcurrentSessions": 13,
|
||||||
|
"ServiceEnabled": true
|
||||||
|
},
|
||||||
|
"Status": {
|
||||||
|
"State": "Enabled"
|
||||||
|
},
|
||||||
|
"UUID": null,
|
||||||
|
"VirtualMedia": {
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"Default": {
|
"default": {
|
||||||
"@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity",
|
"@odata.context": "/redfish/v1/$metadata#Systems/Members/$entity",
|
||||||
"@odata.etag": "W/\"0E79655D\"",
|
"@odata.etag": "W/\"0E79655D\"",
|
||||||
"@odata.id": "/redfish/v1/Systems/1/",
|
"@odata.id": "/redfish/v1/Systems/1/",
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# TODO(deray): Need to remove this hack sooner
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import mock
|
||||||
|
from oslo_utils import importutils
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
SUSHY_MANAGER_PACKAGE_SPEC = ('manager',)
|
||||||
|
|
||||||
|
sushy = importutils.try_import('sushy')
|
||||||
|
if sushy:
|
||||||
|
sushy_resources_manager = mock.MagicMock(
|
||||||
|
spec_set=SUSHY_MANAGER_PACKAGE_SPEC)
|
||||||
|
sys.modules['sushy.resources.manager'] = sushy_resources_manager
|
||||||
|
sushy.resources.common = mock.MagicMock()
|
||||||
|
sushy_resources_manager.manager.Manager = type(
|
||||||
|
'Manager', (sushy.resources.base.ResourceBase,), {})
|
||||||
|
sushy.resources.common.ResetActionField = type(
|
||||||
|
'ResetActionField', (sushy.resources.base.CompositeField,),
|
||||||
|
{"target_uri": sushy.resources.base.Field('target', required=True)})
|
||||||
|
if 'proliantutils.redfish' in sys.modules:
|
||||||
|
six.moves.reload_module(sys.modules['proliantutils.redfish'])
|
|
@ -31,7 +31,7 @@ class HPESystemTestCase(testtools.TestCase):
|
||||||
with open('proliantutils/tests/redfish/'
|
with open('proliantutils/tests/redfish/'
|
||||||
'json_samples/system.json', 'r') as f:
|
'json_samples/system.json', 'r') as f:
|
||||||
system_json = json.loads(f.read())
|
system_json = json.loads(f.read())
|
||||||
self.conn.get.return_value.json.return_value = system_json['Default']
|
self.conn.get.return_value.json.return_value = system_json['default']
|
||||||
|
|
||||||
self.sys_inst = system.HPESystem(
|
self.sys_inst = system.HPESystem(
|
||||||
self.conn, '/redfish/v1/Systems/1',
|
self.conn, '/redfish/v1/Systems/1',
|
||||||
|
|
|
@ -13,11 +13,15 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
from sushy import connector
|
from sushy import connector
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
|
from proliantutils import exception
|
||||||
from proliantutils.redfish import main
|
from proliantutils.redfish import main
|
||||||
|
from proliantutils.redfish.resources.manager import manager
|
||||||
from proliantutils.redfish.resources.system import system
|
from proliantutils.redfish.resources.system import system
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,10 +30,26 @@ class HPESushyTestCase(testtools.TestCase):
|
||||||
@mock.patch.object(connector, 'Connector', autospec=True)
|
@mock.patch.object(connector, 'Connector', autospec=True)
|
||||||
def setUp(self, connector_mock):
|
def setUp(self, connector_mock):
|
||||||
super(HPESushyTestCase, self).setUp()
|
super(HPESushyTestCase, self).setUp()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/root.json', 'r') as f:
|
||||||
|
root_json = json.loads(f.read())
|
||||||
|
connector_mock.return_value.get.return_value.json.return_value = (
|
||||||
|
root_json)
|
||||||
self.hpe_sushy = main.HPESushy('https://1.2.3.4',
|
self.hpe_sushy = main.HPESushy('https://1.2.3.4',
|
||||||
username='foo',
|
username='foo',
|
||||||
password='bar')
|
password='bar')
|
||||||
|
|
||||||
|
def test_get_system_collection_path(self):
|
||||||
|
self.assertEqual('/redfish/v1/Systems/',
|
||||||
|
self.hpe_sushy.get_system_collection_path())
|
||||||
|
|
||||||
|
def test_get_system_collection_path_missing_systems_attr(self):
|
||||||
|
self.hpe_sushy.json.pop('Systems')
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.MissingAttributeError,
|
||||||
|
'The attribute Systems is missing',
|
||||||
|
self.hpe_sushy.get_system_collection_path)
|
||||||
|
|
||||||
@mock.patch.object(system, 'HPESystem', autospec=True)
|
@mock.patch.object(system, 'HPESystem', autospec=True)
|
||||||
def test_get_system(self, mock_system):
|
def test_get_system(self, mock_system):
|
||||||
sys_inst = self.hpe_sushy.get_system('1234')
|
sys_inst = self.hpe_sushy.get_system('1234')
|
||||||
|
@ -38,3 +58,23 @@ class HPESushyTestCase(testtools.TestCase):
|
||||||
mock_system.assert_called_once_with(self.hpe_sushy._conn,
|
mock_system.assert_called_once_with(self.hpe_sushy._conn,
|
||||||
'1234',
|
'1234',
|
||||||
self.hpe_sushy.redfish_version)
|
self.hpe_sushy.redfish_version)
|
||||||
|
|
||||||
|
def test_get_manager_collection_path(self):
|
||||||
|
self.assertEqual('/redfish/v1/Managers/',
|
||||||
|
self.hpe_sushy.get_manager_collection_path())
|
||||||
|
|
||||||
|
def test_get_manager_collection_path_missing_systems_attr(self):
|
||||||
|
self.hpe_sushy.json.pop('Managers')
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.MissingAttributeError,
|
||||||
|
'The attribute Managers is missing',
|
||||||
|
self.hpe_sushy.get_manager_collection_path)
|
||||||
|
|
||||||
|
@mock.patch.object(manager, 'HPEManager', autospec=True)
|
||||||
|
def test_get_manager(self, mock_manager):
|
||||||
|
sys_inst = self.hpe_sushy.get_manager('1234')
|
||||||
|
self.assertTrue(isinstance(sys_inst,
|
||||||
|
manager.HPEManager.__class__))
|
||||||
|
mock_manager.assert_called_once_with(self.hpe_sushy._conn,
|
||||||
|
'1234',
|
||||||
|
self.hpe_sushy.redfish_version)
|
||||||
|
|
|
@ -32,6 +32,10 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
def setUp(self, sushy_mock):
|
def setUp(self, sushy_mock):
|
||||||
super(RedfishOperationsTestCase, self).setUp()
|
super(RedfishOperationsTestCase, self).setUp()
|
||||||
self.sushy = mock.MagicMock()
|
self.sushy = mock.MagicMock()
|
||||||
|
self.sushy.get_system_collection_path.return_value = (
|
||||||
|
'/redfish/v1/Systems')
|
||||||
|
self.sushy.get_manager_collection_path.return_value = (
|
||||||
|
'/redfish/v1/Managers')
|
||||||
sushy_mock.return_value = self.sushy
|
sushy_mock.return_value = self.sushy
|
||||||
with open('proliantutils/tests/redfish/'
|
with open('proliantutils/tests/redfish/'
|
||||||
'json_samples/root.json', 'r') as f:
|
'json_samples/root.json', 'r') as f:
|
||||||
|
@ -51,17 +55,6 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
redfish.RedfishOperations,
|
redfish.RedfishOperations,
|
||||||
'1.2.3.4', username='foo', password='bar')
|
'1.2.3.4', username='foo', password='bar')
|
||||||
|
|
||||||
def test__get_system_collection_path(self):
|
|
||||||
self.assertEqual('/redfish/v1/Systems/',
|
|
||||||
self.rf_client._get_system_collection_path())
|
|
||||||
|
|
||||||
def test__get_system_collection_path_missing_systems_attr(self):
|
|
||||||
self.rf_client._sushy.json.pop('Systems')
|
|
||||||
self.assertRaisesRegex(
|
|
||||||
exception.MissingAttributeError,
|
|
||||||
'The attribute Systems is missing',
|
|
||||||
self.rf_client._get_system_collection_path)
|
|
||||||
|
|
||||||
def test__get_sushy_system_fail(self):
|
def test__get_sushy_system_fail(self):
|
||||||
self.rf_client._sushy.get_system.side_effect = (
|
self.rf_client._sushy.get_system.side_effect = (
|
||||||
sushy.exceptions.SushyError)
|
sushy.exceptions.SushyError)
|
||||||
|
@ -70,11 +63,19 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
'The Redfish System "apple" was not found.',
|
'The Redfish System "apple" was not found.',
|
||||||
self.rf_client._get_sushy_system, 'apple')
|
self.rf_client._get_sushy_system, 'apple')
|
||||||
|
|
||||||
|
def test__get_sushy_manager_fail(self):
|
||||||
|
self.rf_client._sushy.get_manager.side_effect = (
|
||||||
|
sushy.exceptions.SushyError)
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.IloError,
|
||||||
|
'The Redfish Manager "banana" was not found.',
|
||||||
|
self.rf_client._get_sushy_manager, 'banana')
|
||||||
|
|
||||||
def test_get_product_name(self):
|
def test_get_product_name(self):
|
||||||
with open('proliantutils/tests/redfish/'
|
with open('proliantutils/tests/redfish/'
|
||||||
'json_samples/system.json', 'r') as f:
|
'json_samples/system.json', 'r') as f:
|
||||||
system_json = json.loads(f.read())
|
system_json = json.loads(f.read())
|
||||||
self.sushy.get_system().json = system_json['Default']
|
self.sushy.get_system().json = system_json['default']
|
||||||
product_name = self.rf_client.get_product_name()
|
product_name = self.rf_client.get_product_name()
|
||||||
self.assertEqual('ProLiant DL180 Gen10', product_name)
|
self.assertEqual('ProLiant DL180 Gen10', product_name)
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ class RedfishOperationsTestCase(testtools.TestCase):
|
||||||
with open('proliantutils/tests/redfish/'
|
with open('proliantutils/tests/redfish/'
|
||||||
'json_samples/system.json', 'r') as f:
|
'json_samples/system.json', 'r') as f:
|
||||||
system_json = json.loads(f.read())
|
system_json = json.loads(f.read())
|
||||||
self.sushy.get_system().json = system_json['Default']
|
self.sushy.get_system().json = system_json['default']
|
||||||
boot = self.rf_client.get_one_time_boot()
|
boot = self.rf_client.get_one_time_boot()
|
||||||
self.assertEqual('Normal', boot)
|
self.assertEqual('Normal', boot)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Copyright 2016 Hewlett Packard Enterprise Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Test class for Utils Module."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
import ddt
|
||||||
|
import mock
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from proliantutils import exception
|
||||||
|
from proliantutils.redfish.resources.system import system
|
||||||
|
from proliantutils.redfish import utils
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
|
class UtilsTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(UtilsTestCase, self).setUp()
|
||||||
|
self.conn = mock.MagicMock()
|
||||||
|
with open('proliantutils/tests/redfish/'
|
||||||
|
'json_samples/system.json', 'r') as f:
|
||||||
|
system_json = json.loads(f.read())
|
||||||
|
self.conn.get.return_value.json.return_value = system_json['default']
|
||||||
|
|
||||||
|
self.sys_inst = system.HPESystem(self.conn, '/redfish/v1/Systems/1',
|
||||||
|
redfish_version='1.0.2')
|
||||||
|
|
||||||
|
@ddt.data(('SecureBoot', '/redfish/v1/Systems/1/SecureBoot/'),
|
||||||
|
(['Oem', 'Hpe', 'Links', 'NetworkAdapters'],
|
||||||
|
'/redfish/v1/Systems/1/NetworkAdapters/'),
|
||||||
|
)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_get_subresource_path_by(self, subresource_path, expected_result):
|
||||||
|
value = utils.get_subresource_path_by(self.sys_inst,
|
||||||
|
subresource_path)
|
||||||
|
self.assertEqual(expected_result, value)
|
||||||
|
|
||||||
|
@ddt.data(('NonSecureBoot', 'attribute NonSecureBoot is missing'),
|
||||||
|
(['Links', 'Chassis'],
|
||||||
|
'attribute Links/Chassis/@odata.id is missing'),
|
||||||
|
)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_get_subresource_path_by_when_fails(
|
||||||
|
self, subresource_path, expected_exception_string_subset):
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
exception.MissingAttributeError,
|
||||||
|
expected_exception_string_subset,
|
||||||
|
utils.get_subresource_path_by,
|
||||||
|
self.sys_inst, subresource_path)
|
||||||
|
|
||||||
|
def test_get_subresource_path_by_fails_with_empty_path(self):
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
ValueError,
|
||||||
|
'"subresource_path" cannot be empty',
|
||||||
|
utils.get_subresource_path_by,
|
||||||
|
self.sys_inst, [])
|
Loading…
Reference in New Issue