diff --git a/releasenotes/notes/bug-1754514-ca6ebe16c4e4b3b0.yaml b/releasenotes/notes/bug-1754514-ca6ebe16c4e4b3b0.yaml new file mode 100644 index 00000000..e8e6f8a8 --- /dev/null +++ b/releasenotes/notes/bug-1754514-ca6ebe16c4e4b3b0.yaml @@ -0,0 +1,5 @@ +--- +critical: + - | + Fixes authentication failure when SessionService attribute is + not present in the root resource. diff --git a/sushy/main.py b/sushy/main.py index ec178225..b0a4334d 100644 --- a/sushy/main.py +++ b/sushy/main.py @@ -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) diff --git a/sushy/tests/unit/json_samples/bare_minimum_root.json b/sushy/tests/unit/json_samples/bare_minimum_root.json new file mode 100644 index 00000000..1f558141 --- /dev/null +++ b/sushy/tests/unit/json_samples/bare_minimum_root.json @@ -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." +} diff --git a/sushy/tests/unit/test_main.py b/sushy/tests/unit/test_main.py index 362cbb4b..8b1a969b 100644 --- a/sushy/tests/unit/test_main.py +++ b/sushy/tests/unit/test_main.py @@ -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)