Mark Systems/Managers/SessionService optional

Apparently in Redfish standard the root resource doesn't enforce any
of the depicted top level attributes to be mandatory. Till now all
those attributes are mandatory parameters for Sushy object creation.
Therefore, to keep Sushy aligned to standard Redfish this patch marks
them as optional.

Change-Id: Ic7750b48e5f5f3b5976f0a020d68c7d3197eaa8d
Closes-Bug: #1754514
(cherry picked from commit 8c12c2505c)
This commit is contained in:
Debayan Ray 2018-03-14 07:29:48 +00:00 committed by Dmitry Tantsur
parent 446bb945dd
commit ae06c028d4
4 changed files with 62 additions and 5 deletions

View File

@ -0,0 +1,5 @@
---
critical:
- |
Fixes authentication failure when SessionService attribute is
not present in the root resource.

View File

@ -16,6 +16,7 @@ import logging
from sushy import auth as sushy_auth
from sushy import connector as sushy_connector
from sushy import exceptions
from sushy.resources import base
from sushy.resources.manager import manager
from sushy.resources.sessionservice import session
@ -36,14 +37,13 @@ class Sushy(base.ResourceBase):
uuid = base.Field('UUID')
"""The Redfish root service UUID"""
_systems_path = base.Field(['Systems', '@odata.id'], required=True)
_systems_path = base.Field(['Systems', '@odata.id'])
"""SystemCollection path"""
_managers_path = base.Field(['Managers', '@odata.id'], required=True)
_managers_path = base.Field(['Managers', '@odata.id'])
"""ManagerCollection path"""
_session_service_path = base.Field(['SessionService', '@odata.id'],
required=True)
_session_service_path = base.Field(['SessionService', '@odata.id'])
"""SessionService path"""
def __init__(self, base_url, username=None, password=None,
@ -96,6 +96,10 @@ class Sushy(base.ResourceBase):
not found
:returns: a SystemCollection object
"""
if not self._systems_path:
raise exceptions.MissingAttributeError(
attribute='Systems/@odata.id', resource=self._path)
return system.SystemCollection(self._conn, self._systems_path,
redfish_version=self.redfish_version)
@ -115,6 +119,10 @@ class Sushy(base.ResourceBase):
not found
:returns: a ManagerCollection object
"""
if not self._managers_path:
raise exceptions.MissingAttributeError(
attribute='Managers/@odata.id', resource=self._path)
return manager.ManagerCollection(self._conn, self._managers_path,
redfish_version=self.redfish_version)
@ -130,9 +138,14 @@ class Sushy(base.ResourceBase):
def get_session_service(self):
"""Get the SessionService object
:raises: MissingAttributeError, if the collection attribue is not found
:raises: MissingAttributeError, if the collection attribute is
not found
:returns: as SessionCollection object
"""
if not self._session_service_path:
raise exceptions.MissingAttributeError(
attribute='SessionService/@odata.id', resource=self._path)
return sessionservice.SessionService(
self._conn, self._session_service_path,
redfish_version=self.redfish_version)

View File

@ -0,0 +1,11 @@
{
"@odata.type": "#ServiceRoot.v1_0_2.ServiceRoot",
"Id": "RootService",
"Name": "Root Service",
"RedfishVersion": "1.0.2",
"UUID": "92384634-2938-2342-8820-489239905423",
"Oem": {},
"@odata.context": "/redfish/v1/$metadata#ServiceRoot",
"@odata.id": "/redfish/v1/",
"@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
}

View File

@ -19,6 +19,7 @@ import mock
from sushy import auth
from sushy import connector
from sushy import exceptions
from sushy import main
from sushy.resources.manager import manager
from sushy.resources.sessionservice import session
@ -117,3 +118,30 @@ class MainTestCase(base.TestCase):
mock_sess.assert_called_once_with(
self.root._conn, 'asdf',
redfish_version=self.root.redfish_version)
class BareMinimumMainTestCase(base.TestCase):
def setUp(self):
super(BareMinimumMainTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('sushy/tests/unit/json_samples/'
'bare_minimum_root.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
self.root = main.Sushy('http://foo.bar:1234', verify=True,
auth=mock.MagicMock(), connector=self.conn)
def test_get_system_collection_when_systems_attr_absent(self):
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'Systems/@odata.id', self.root.get_system_collection)
def test_get_manager_collection_when_managers_attr_absent(self):
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'Managers/@odata.id', self.root.get_manager_collection)
def test_get_session_service_when_sessionservice_attr_absent(self):
self.assertRaisesRegex(
exceptions.MissingAttributeError,
'SessionService/@odata.id', self.root.get_session_service)