Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-sushy for openSUSE:Factory 
checked in at 2023-03-07 16:49:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sushy (Old)
 and      /work/SRC/openSUSE:Factory/.python-sushy.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sushy"

Tue Mar  7 16:49:39 2023 rev:12 rq:1069690 version:4.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sushy/python-sushy.changes        
2023-01-05 15:00:54.669038709 +0100
+++ /work/SRC/openSUSE:Factory/.python-sushy.new.31432/python-sushy.changes     
2023-03-07 16:50:14.049552939 +0100
@@ -1,0 +2,14 @@
+Mon Mar  6 15:52:38 UTC 2023 - [email protected]
+
+- update to version 4.4.2
+  - Fix exceeding retries
+  - Fix setting boot related attributes
+  - workaround: requests verify handling if env is set
+  - Fix tox4 and setuptools errors
+  - Remove setuptools workaround
+  - Handle a different error code for missing TransferProtocolType
+  - Retry on iDRAC SYS518 errors for all requests
+  - Handle proper code_status in unit test
+  - Fix volume deletion on newer iDRACs
+
+-------------------------------------------------------------------

Old:
----
  sushy-4.4.0.tar.gz

New:
----
  sushy-4.4.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sushy.spec ++++++
--- /var/tmp/diff_new_pack.5Jc9YE/_old  2023-03-07 16:50:14.681556265 +0100
+++ /var/tmp/diff_new_pack.5Jc9YE/_new  2023-03-07 16:50:14.689556307 +0100
@@ -17,13 +17,13 @@
 
 
 Name:           python-sushy
-Version:        4.4.0
+Version:        4.4.2
 Release:        0
 Summary:        Python library to communicate with Redfish based systems
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://docs.openstack.org/sushy
-Source0:        
https://files.pythonhosted.org/packages/source/s/sushy/sushy-4.4.0.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/s/sushy/sushy-4.4.2.tar.gz
 BuildRequires:  openstack-macros
 BuildRequires:  python3-oslotest
 BuildRequires:  python3-pbr >= 2.0.0
@@ -62,7 +62,7 @@
 This package contains the documentation.
 
 %prep
-%autosetup -p1 -n sushy-4.4.0
+%autosetup -p1 -n sushy-4.4.2
 %py_req_cleanup
 
 %build
@@ -74,7 +74,7 @@
 %{py3_install}
 
 %check
-python3 -m stestr.cli run
+%{openstack_stestr_run}
 
 %files -n python3-sushy
 %license LICENSE

++++++ sushy-4.4.0.tar.gz -> sushy-4.4.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/AUTHORS new/sushy-4.4.2/AUTHORS
--- old/sushy-4.4.0/AUTHORS     2022-11-22 16:26:19.000000000 +0100
+++ new/sushy-4.4.2/AUTHORS     2023-02-10 17:07:59.000000000 +0100
@@ -27,6 +27,7 @@
 Julia Kreger <[email protected]>
 Kafilat Adeleke <[email protected]>
 Kaifeng Wang <[email protected]>
+Kamlesh Chauvhan <[email protected]>
 LiZekun <[email protected]>
 Lin Yang <[email protected]>
 Lucas Alvares Gomes <[email protected]>
@@ -41,6 +42,7 @@
 Richard G. Pioso <[email protected]>
 Richard Pioso <[email protected]>
 Ruby Loo <[email protected]>
+Samuel Kunkel <[email protected]>
 Sayali Kutwal <[email protected]>
 Sean McGinnis <[email protected]>
 Shivanand Tendulker <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/ChangeLog new/sushy-4.4.2/ChangeLog
--- old/sushy-4.4.0/ChangeLog   2022-11-22 16:26:18.000000000 +0100
+++ new/sushy-4.4.2/ChangeLog   2023-02-10 17:07:59.000000000 +0100
@@ -1,6 +1,23 @@
 CHANGES
 =======
 
+4.4.2
+-----
+
+* workaround: requests verify handling if env is set
+* Remove setuptools workaround
+* Fix tox4 and setuptools errors
+* Fix exceeding retries
+* Fix volume deletion on newer iDRACs
+
+4.4.1
+-----
+
+* Handle proper code\_status in unit test
+* Handle a different error code for missing TransferProtocolType
+* Retry on iDRAC SYS518 errors for all requests
+* Fix setting boot related attributes
+
 4.4.0
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/PKG-INFO new/sushy-4.4.2/PKG-INFO
--- old/sushy-4.4.0/PKG-INFO    2022-11-22 16:26:19.412175000 +0100
+++ new/sushy-4.4.2/PKG-INFO    2023-02-10 17:08:00.087798600 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: sushy
-Version: 4.4.0
+Version: 4.4.2
 Summary: Sushy is a small Python library to communicate with Redfish based 
systems
 Home-page: https://docs.openstack.org/sushy/latest/
 Author: OpenStack
@@ -46,4 +46,5 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
 
new/sushy-4.4.2/releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
--- 
old/sushy-4.4.0/releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
        2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,14 @@
+---
+fixes:
+  - |
+    Adds an extra check for cases where the BMC provides a SettingsObject
+    URI through @Redfish.Settings but this URI does not allow setting boot
+    related attributes. Prior to sending a PATCH request to SettingsURI, a
+    GET request is issued to verify if it contains the attributes to be
+    updated. In case these attributes are missing, the request is made against
+    System URI instead.
+    Issues such as the one addressed with this change usually manifest
+    themselves with a Redfish response containing an error message similar to
+    the following: ``MessageId: Base.1.8.PropertyNotWritable, Message: The
+    property BootSourceOverrideEnabled is a read only property and cannot be
+    assigned a value.``
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml 
new/sushy-4.4.2/releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml
--- 
old/sushy-4.4.0/releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml  
    2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Fixes exceeding retries. Before this fix running sushy for longer it no
+    longer retried for temporary failures when it should.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/fix-retry_volume_operation-on_sys518-009f2b16e5c38a27.yaml
 
new/sushy-4.4.2/releasenotes/notes/fix-retry_volume_operation-on_sys518-009f2b16e5c38a27.yaml
--- 
old/sushy-4.4.0/releasenotes/notes/fix-retry_volume_operation-on_sys518-009f2b16e5c38a27.yaml
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/releasenotes/notes/fix-retry_volume_operation-on_sys518-009f2b16e5c38a27.yaml
       2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,8 @@
+---
+fixes:
+  - |
+    Add retries on iDRAC error with code SYS518 and message "iDRAC is
+    currently unable to display any information because data sources are
+    unavailable." for all request types in addition to existing GET methods.
+    This helps to fix a known intermittent issue when deleting set of volumes
+    one after another and iDRAC is reloading after deleting each volume.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/fix-volume-delete-configuration-unsuported-operational_time_property-f53f650d8612a847.yaml
 
new/sushy-4.4.2/releasenotes/notes/fix-volume-delete-configuration-unsuported-operational_time_property-f53f650d8612a847.yaml
--- 
old/sushy-4.4.0/releasenotes/notes/fix-volume-delete-configuration-unsuported-operational_time_property-f53f650d8612a847.yaml
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/releasenotes/notes/fix-volume-delete-configuration-unsuported-operational_time_property-f53f650d8612a847.yaml
       2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,4 @@
+fixes:
+  - |
+    Fixes 'Unsupported parameter name @Redfish.OperationApplyTime' error
+    on iDRAC firmware version 6.00.02.00 or newer when deleting volumes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/property-missing-7602c421ec177e9a.yaml 
new/sushy-4.4.2/releasenotes/notes/property-missing-7602c421ec177e9a.yaml
--- old/sushy-4.4.0/releasenotes/notes/property-missing-7602c421ec177e9a.yaml   
1970-01-01 01:00:00.000000000 +0100
+++ new/sushy-4.4.2/releasenotes/notes/property-missing-7602c421ec177e9a.yaml   
2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Correctly handles error code ``Base.1.5.PropertyMissing`` when dealing with
+    hardware that requires ``TransferProtocolType`` for virtual media
+    operations.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
 
new/sushy-4.4.2/releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
--- 
old/sushy-4.4.0/releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
  2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,9 @@
+---
+fixes:
+  - |
+    Workaround for https://github.com/psf/requests/issues/3829
+    If the env ``REQUESTS_CA_BUNDLE`` is set the ``requests.Session()``
+    ignores the verify parameter. Therefore the verify parameter
+    is moved directly into the function call of requests.
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/setup.cfg new/sushy-4.4.2/setup.cfg
--- old/sushy-4.4.0/setup.cfg   2022-11-22 16:26:19.412175000 +0100
+++ new/sushy-4.4.2/setup.cfg   2023-02-10 17:08:00.087798600 +0100
@@ -21,6 +21,7 @@
        Programming Language :: Python :: 3.7
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
+       Programming Language :: Python :: 3.10
 
 [files]
 packages = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/connector.py 
new/sushy-4.4.2/sushy/connector.py
--- old/sushy-4.4.0/sushy/connector.py  2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/connector.py  2023-02-10 17:07:32.000000000 +0100
@@ -20,6 +20,7 @@
 from urllib import parse as urlparse
 
 import requests
+from urllib3.exceptions import InsecureRequestWarning
 
 from sushy import exceptions
 from sushy.taskmonitor import TaskMonitor
@@ -37,7 +38,6 @@
         self._url = url
         self._verify = verify
         self._session = requests.Session()
-        self._session.verify = self._verify
         self._response_callback = response_callback
         self._auth = None
         self._server_side_retries = server_side_retries
@@ -68,6 +68,13 @@
                         'be removed in the future')
             self.set_http_basic_auth(username, password)
 
+        if not self._verify:
+            # As the user specifically needs to opt out of certificate
+            # validation the user is aware of the security implications
+            # and does not need to be overwhelmed by the urllib3 warnings
+            requests.packages.urllib3.disable_warnings(
+                category=InsecureRequestWarning)
+
     def set_auth(self, auth):
         """Sets the authentication mechanism for our connector."""
         self._auth = auth
@@ -85,8 +92,18 @@
         """Close this connector and the associated HTTP session."""
         self._session.close()
 
+    def check_retry_on_exception(self, exception_msg):
+        """Checks whether retry on exception is required."""
+        if ('SYS518' in str(exception_msg)):
+            LOG.debug('iDRAC is not yet ready after previous operation. '
+                      'Error: %(err)s', {'err': str(exception_msg)})
+            return True
+        else:
+            return False
+
     def _op(self, method, path='', data=None, headers=None, blocking=False,
-            timeout=60, **extra_session_req_kwargs):
+            timeout=60, server_side_retries_left=None,
+            **extra_session_req_kwargs):
         """Generic RESTful request handler.
 
         :param method: The HTTP method to be used, e.g: GET, POST,
@@ -96,6 +113,8 @@
         :param headers: Optional dictionary of headers.
         :param blocking: Whether to block for asynchronous operations.
         :param timeout: Max time in seconds to wait for blocking async call.
+        :param server_side_retries_left: Remaining retries. If not provided
+            will use limit provided by instance's server_side_retries
         :param extra_session_req_kwargs: Optional keyword argument to pass
          requests library arguments which would pass on to requests session
          object.
@@ -103,6 +122,10 @@
         :raises: ConnectionError
         :raises: HTTPError
         """
+
+        if server_side_retries_left is None:
+            server_side_retries_left = self._server_side_retries
+
         url = path if urlparse.urlparse(path).netloc else urlparse.urljoin(
             self._url, path)
         headers = headers or {}
@@ -124,6 +147,7 @@
         try:
             response = self._session.request(method, url, json=data,
                                              headers=headers,
+                                             verify=self._verify,
                                              **extra_session_req_kwargs)
         except requests.exceptions.RequestException as e:
             # Capture any general exception by looking for the parent
@@ -181,6 +205,7 @@
                     response = self._session.request(
                         method, url, json=data,
                         headers=headers,
+                        verify=self._verify,
                         **extra_session_req_kwargs)
                 except exceptions.HTTPError as retry_exc:
                     LOG.error("Failure occured while attempting to retry "
@@ -197,17 +222,23 @@
                               "%s", e.message)
                 raise
         except exceptions.ServerSideError as e:
-            if method.lower() != 'get' or self._server_side_retries <= 0:
-                raise
-            else:
+            if ((method.lower() == 'get'
+                or self.check_retry_on_exception(e.message))
+                    and server_side_retries_left > 0):
                 LOG.warning('Got server side error %s in response to a '
-                            'GET request, retrying after %d seconds',
-                            e, self._server_side_retries)
+                            'GET request, retrying after %d seconds. Retries '
+                            'left %d.',
+                            e, self._server_side_retries_delay,
+                            server_side_retries_left)
                 time.sleep(self._server_side_retries_delay)
-                self._server_side_retries -= 1
-                return self._op(method, path, data=data, headers=headers,
-                                blocking=blocking, timeout=timeout,
-                                **extra_session_req_kwargs)
+                server_side_retries_left -= 1
+                return self._op(
+                    method, path, data=data, headers=headers,
+                    blocking=blocking, timeout=timeout,
+                    server_side_retries_left=server_side_retries_left,
+                    **extra_session_req_kwargs)
+            else:
+                raise
 
         if blocking and response.status_code == 202:
             if not response.headers.get('Location'):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/exceptions.py 
new/sushy-4.4.2/sushy/exceptions.py
--- old/sushy-4.4.0/sushy/exceptions.py 2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/exceptions.py 2023-02-10 17:07:32.000000000 +0100
@@ -96,6 +96,9 @@
     message = ('HTTP %(method)s %(url)s returned code %(code)s. %(error)s '
                'Extended information: %(ext_info)s')
 
+    extended_info = None
+    """Extended information provided in the response."""
+
     def __init__(self, method, url, response):
         self.status_code = response.status_code
         try:
@@ -106,17 +109,16 @@
                         {'method': method, 'url': url, 'code':
                          self.status_code})
             error = 'unknown error'
-            ext_info = 'none'
         else:
             self.body = body.get('error', {})
             self.code = self.body.get('code', 'Base.1.0.GeneralError')
             self.detail = self.body.get('message')
-            ext_info = self.body.get('@Message.ExtendedInfo', [{}])
-            message = self._get_most_severe_msg(ext_info)
+            self.extended_info = self.body.get('@Message.ExtendedInfo')
+            message = self._get_most_severe_msg(self.extended_info or [{}])
             self.detail = message or self.detail
             error = '%s: %s' % (self.code, self.detail or 'unknown error.')
         kwargs = {'method': method, 'url': url, 'code': self.status_code,
-                  'error': error, 'ext_info': ext_info}
+                  'error': error, 'ext_info': self.extended_info}
         LOG.debug('HTTP response for %(method)s %(url)s: '
                   'status code: %(code)s, error: %(error)s, '
                   'extended: %(ext_info)s', kwargs)
@@ -132,6 +134,14 @@
                     if m.get('Severity') == sev:
                         return m.get('Message')
 
+    @property
+    def related_properties(self):
+        """List of properties related to the error."""
+        try:
+            return self.extended_info[0]['RelatedProperties']
+        except (IndexError, KeyError, TypeError):
+            return []
+
 
 class BadRequestError(HTTPError):
     pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/resources/manager/virtual_media.py 
new/sushy-4.4.2/sushy/resources/manager/virtual_media.py
--- old/sushy-4.4.0/sushy/resources/manager/virtual_media.py    2022-11-22 
16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/resources/manager/virtual_media.py    2023-02-10 
17:07:32.000000000 +0100
@@ -106,17 +106,16 @@
             eject_uri = eject_media.target_uri
         return eject_uri, use_patch
 
-    def is_transfer_protocol_required(self, response=None):
+    def is_transfer_protocol_required(self, error=None):
         """Check the response code and body and in case of failure
 
         Try to determine if it happened due to missing TransferProtocolType.
         """
-        if (response.code == "Base.1.5.ActionParameterMissing"
-           and response.body is not None):
-            if ("#/TransferProtocolType" in response.body
-               ["@Message.ExtendedInfo"][0]['RelatedProperties']):
-                return True
-        return False
+        return (
+            (error.code.endswith(".ActionParameterMissing")
+             or error.code.endswith(".PropertyMissing"))
+            and "#/TransferProtocolType" in error.related_properties
+        )
 
     def insert_media(self, image, inserted=True, write_protected=True,
                      username=None, password=None, transfer_method=None):
@@ -177,8 +176,8 @@
             # due to absence of TransferProtocolType param and if so adding it
             try:
                 self._conn.post(target_uri, data=payload)
-            except exceptions.HTTPError as response:
-                if self.is_transfer_protocol_required(response):
+            except exceptions.HTTPError as error:
+                if self.is_transfer_protocol_required(error):
                     if payload['Image'].startswith('https://'):
                         payload['TransferProtocolType'] = "HTTPS"
                     elif payload['Image'].startswith('http://'):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/resources/system/storage/volume.py 
new/sushy-4.4.2/sushy/resources/system/storage/volume.py
--- old/sushy-4.4.0/sushy/resources/system/storage/volume.py    2022-11-22 
16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/resources/system/storage/volume.py    2023-02-10 
17:07:32.000000000 +0100
@@ -136,8 +136,22 @@
         if (payload and payload.get(_OAT_PROP)
                 == res_cons.ApplyTime.IMMEDIATE.value):
             blocking = True
-        r = self._conn.delete(self._path, data=payload, blocking=blocking,
-                              timeout=timeout)
+        try:
+            r = self._conn.delete(self._path, data=payload,
+                                  blocking=blocking, timeout=timeout)
+        except exceptions.ServerSideError as exc:
+            if (_OAT_PROP in str(exc.message)
+                    and 'SYS029' in str(exc.message)):
+                LOG.debug('Retry volume delete without %(prop)s for %(path)s '
+                          'because got error: %(err)s',
+                          {'prop': _OAT_PROP,
+                           'path': self._path,
+                           'err': exc})
+                payload.pop(_OAT_PROP)
+                r = self._conn.delete(self._path, data=payload,
+                                      blocking=blocking, timeout=timeout)
+            else:
+                raise exc
         return r
 
     def delete(self, payload=None, apply_time=None, timeout=500):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/resources/system/system.py 
new/sushy-4.4.2/sushy/resources/system/system.py
--- old/sushy-4.4.0/sushy/resources/system/system.py    2022-11-22 
16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/resources/system/system.py    2023-02-10 
17:07:32.000000000 +0100
@@ -228,6 +228,13 @@
             invalid.
         """
         data = collections.defaultdict(dict)
+        settings_data = collections.defaultdict(dict)
+
+        if self._settings and self._settings.resource_uri:
+            settings_resp = self._conn.get(self._settings.resource_uri)
+            settings_boot_section = settings_resp.json().get('Boot', {})
+        else:
+            settings_resp = None
 
         if target is not None:
             valid_targets = self.get_allowed_system_boot_source_values()
@@ -253,8 +260,12 @@
                           'machine. Overriding boot device from %s to %s.',
                           target, sys_cons.BootSource.USB_CD)
                 target = sys_cons.BootSource.USB_CD
-
-            data['Boot']['BootSourceOverrideTarget'] = target.value
+            if (settings_resp and "BootSourceOverrideTarget" in
+                    settings_boot_section):
+                settings_data['Boot']['BootSourceOverrideTarget'] = \
+                    target.value
+            else:
+                data['Boot']['BootSourceOverrideTarget'] = target.value
 
         if enabled is not None:
             try:
@@ -263,8 +274,11 @@
                 raise exceptions.InvalidParameterValueError(
                     parameter='enabled', value=enabled,
                     valid_values=list(sys_cons.BootSourceOverrideEnabled))
-
-            data['Boot']['BootSourceOverrideEnabled'] = fishy_freq
+            if (settings_resp and "BootSourceOverrideEnabled" in
+                    settings_boot_section):
+                settings_data['Boot']['BootSourceOverrideEnabled'] = fishy_freq
+            else:
+                data['Boot']['BootSourceOverrideEnabled'] = fishy_freq
 
         if mode is not None:
             try:
@@ -273,23 +287,23 @@
                 raise exceptions.InvalidParameterValueError(
                     parameter='mode', value=mode,
                     valid_values=list(sys_cons.BootSourceOverrideMode))
-
-            data['Boot']['BootSourceOverrideMode'] = fishy_mode
-
-        etag = self._get_etag()
-        path = self.path
-
-        # NOTE(janders): checking if @Redfish.Settings are available; if so
-        # using the URI from the SettingsObject. Also ensuring the ETag URI
-        # matches in this case (the one above would not be valid for new URI).
-        if self._settings and self._settings.resource_uri:
-            path = self._settings.resource_uri
-            resp = self._conn.get(path)
-            etag = resp.headers.get('ETag')
+            if (settings_resp and "BootSourceOverrideMode" in
+                    settings_boot_section):
+                settings_data['Boot']['BootSourceOverrideMode'] = fishy_mode
+            else:
+                data['Boot']['BootSourceOverrideMode'] = fishy_mode
 
         # TODO(lucasagomes): Check the return code and response body ?
         #                    Probably we should call refresh() as well.
-        self._conn.patch(path, data=data, etag=etag)
+        if settings_data.get('Boot'):
+            etag = settings_resp.headers.get('ETag')
+            path = self._settings.resource_uri
+            self._conn.patch(path, data=settings_data,
+                             etag=etag)
+        if data.get('Boot'):
+            etag = self._get_etag()
+            path = self.path
+            self._conn.patch(path, data=data, etag=etag)
 
     # TODO(etingof): we should remove this method, eventually
     def set_system_boot_source(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-bootsourceoverridemode-only.json
 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-bootsourceoverridemode-only.json
--- 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-bootsourceoverridemode-only.json
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-bootsourceoverridemode-only.json
        2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,17 @@
+{
+    "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Settings",
+    "@odata.type": "#ComputerSystem.v1_18_0.ComputerSystem",
+    "@Redfish.SettingsApplyTime": {
+        "ApplyTime": "OnReset",
+        "@odata.type": "#Settings.v1_3_4.PreferredApplyTime"
+    },
+    "AssetTag": null,
+    "Boot": {
+        "BootOrder": [],
+        "BootSourceOverrideMode": null,
+        "UefiTargetBootSourceOverride": null,
+        "StopBootOnFault": null
+    },
+    "Id": "System.Embedded.1",
+    "Name": "System"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-lenovo-se450.json 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-lenovo-se450.json
--- 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-lenovo-se450.json   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-lenovo-se450.json   
    2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,17 @@
+{
+  "Description": "ComputerSystem 1 Pending Setting",
+  "Id": "Pending",
+  "@odata.type": "#ComputerSystem.v1_11_0.ComputerSystem",
+  "Boot": {
+    "BootOrder": [
+      "Boot0000",
+      "Boot0001",
+      "Boot0002",
+      "Boot0003",
+      "Boot0004"
+    ]
+  },
+  "Name": "Pending",
+  "@odata.etag": "\"21a8f5383ebb2a1fb41\"",
+  "@odata.id": "/redfish/v1/Systems/1/Pending"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-nokia.json 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-nokia.json
--- old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-body-nokia.json      
1970-01-01 01:00:00.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-body-nokia.json      
2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,50 @@
+{
+  "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
+  "@odata.etag": "\"1660209630\"",
+  "@odata.id": "/redfish/v1/Systems/Self/SD",
+  "@odata.type": "#ComputerSystem.v1_8_0.ComputerSystem",
+  "AssetTag": "AT18996926771_0101",
+  "Boot": {
+    "AliasBootOrder": null,
+    "BootNext": null,
+    "BootOrder": [
+      "Boot0001",
+      "Boot0003",
+      "Boot0002"
+    ],
+    "BootOrderPropertySelection": "BootOrder",
+    "BootSourceOverrideEnabled": "Disabled",
+    "[email protected]": [
+      "Disabled",
+      "Once",
+      "Continuous"
+    ],
+    "BootSourceOverrideMode": "UEFI",
+    "[email protected]": [
+      "UEFI"
+    ],
+    "BootSourceOverrideTarget": "Cd",
+    "[email protected]": [
+      "None",
+      "Pxe",
+      "Floppy",
+      "Cd",
+      "Usb",
+      "Hdd",
+      "BiosSetup",
+      "Utilities",
+      "Diags",
+      "UefiShell",
+      "UefiTarget",
+      "SDCard",
+      "UefiHttp",
+      "RemoteDrive",
+      "UefiBootNext"
+    ],
+    "UefiTargetBootSourceOverride": ""
+  },
+  "Description": "System Self",
+  "Id": "Self",
+  "Name": "System",
+  "SystemType": "Physical"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-lenovo-se450.json 
new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-lenovo-se450.json
--- old/sushy-4.4.0/sushy/tests/unit/json_samples/settings-lenovo-se450.json    
1970-01-01 01:00:00.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/json_samples/settings-lenovo-se450.json    
2023-02-10 17:07:32.000000000 +0100
@@ -0,0 +1,13 @@
+{
+  "@Redfish.Settings": {
+    "Time": null,
+    "SupportedApplyTimes": [
+      "OnReset"
+    ],
+    "Messages": [],
+    "@odata.type": "#Settings.v1_3_0.Settings",
+    "SettingsObject": {
+      "@odata.id": "/redfish/v1/Systems/1/Pending"
+    }
+  }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/resources/manager/test_virtual_media.py 
new/sushy-4.4.2/sushy/tests/unit/resources/manager/test_virtual_media.py
--- old/sushy-4.4.0/sushy/tests/unit/resources/manager/test_virtual_media.py    
2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/resources/manager/test_virtual_media.py    
2023-02-10 17:07:32.000000000 +0100
@@ -16,8 +16,6 @@
 import json
 from unittest import mock
 
-import requests
-
 import sushy
 from sushy import exceptions
 from sushy.resources.certificateservice import certificate
@@ -178,18 +176,25 @@
             headers={"If-Match": 'W/"3d7b8a7360bf2941d"'})
         self.assertTrue(self.sys_virtual_media._is_stale)
 
-    @mock.patch.object(requests, 'post', autospec=True)
-    def test_is_transfer_protocol_required(self, mock_post):
+    def test_is_transfer_protocol_required(self):
+        with open('sushy/tests/unit/json_samples/'
+                  'transfer_proto_required_error.json') as f:
+            response_obj = json.load(f)
+        response = mock.Mock(spec=['json', 'status_code'])
+        response.json.return_value = response_obj
+        error = exceptions.HTTPError('GET', 'VirtualMedia', response)
+        retval = self.sys_virtual_media.is_transfer_protocol_required(error)
+        self.assertTrue(retval)
+
+    def test_is_transfer_protocol_required_alt_code(self):
         with open('sushy/tests/unit/json_samples/'
                   'transfer_proto_required_error.json') as f:
             response_obj = json.load(f)
-        response = mock.MagicMock()
-        response.status_code = 400
-        response.code = "Base.1.5.ActionParameterMissing"
-        response.body = response_obj['error']
-        response.raise_for_status.side_effect = requests.exceptions.HTTPError
-        mock_post.return_value = response
-        retval = self.sys_virtual_media.is_transfer_protocol_required(response)
+        response_obj['error']['code'] = 'Base.1.5.PropertyMissing'
+        response = mock.Mock(spec=['json', 'status_code'])
+        response.json.return_value = response_obj
+        error = exceptions.HTTPError('GET', 'VirtualMedia', response)
+        retval = self.sys_virtual_media.is_transfer_protocol_required(error)
         self.assertTrue(retval)
 
     def test_eject_media_none(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/resources/system/storage/test_volume.py 
new/sushy-4.4.2/sushy/tests/unit/resources/system/storage/test_volume.py
--- old/sushy-4.4.0/sushy/tests/unit/resources/system/storage/test_volume.py    
2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/resources/system/storage/test_volume.py    
2023-02-10 17:07:32.000000000 +0100
@@ -16,6 +16,7 @@
 from dateutil import parser
 
 import sushy
+from sushy import exceptions
 from sushy.resources import constants as res_cons
 from sushy.resources.system.storage import constants as store_cons
 from sushy.resources.system.storage import volume
@@ -106,6 +107,84 @@
         self.assertEqual(task_mon.task_monitor_uri,
                          '/redfish/v1/taskmon/4608f7e6')
 
+    @mock.patch.object(volume.LOG, 'debug', autospec=True)
+    def test_delete_retry_on_501_sys029_apply_time(self, mock_debug):
+        payload = {}
+        _OAT_PROP = '@Redfish.OperationApplyTime'
+        payload[_OAT_PROP] = 'Immediate'
+        target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
+        response_info = {"error": {"@Message.ExtendedInfo": [
+            {'Message': '@Redfish.OperationApplyTime.',
+             'MessageId': 'IDRAC.2.7.SYS029'}]}}
+        mock_error = mock.Mock()
+        mock_error.status_code = 501
+        mock_error.json.return_value = response_info
+        mock_success = mock.Mock()
+        mock_success.status_code = 201
+        self.conn.delete.side_effect = [exceptions.ServerSideError(
+            method='DELETE', url=target_uri, response=mock_error),
+            mock_success]
+
+        resource = self.stor_volume.delete(
+            payload=payload, apply_time=res_cons.ApplyTime.IMMEDIATE)
+
+        self.assertIsNone(resource)
+        self.assertEqual(2, self.stor_volume._conn.delete.call_count)
+        expected_calls = [
+            mock.call(self.stor_volume._path, data=payload, blocking=True,
+                      timeout=500),
+            mock.call(self.stor_volume._path, data={}, blocking=True,
+                      timeout=500)
+        ]
+        self.stor_volume._conn.delete.assert_has_calls(expected_calls)
+        mock_debug.assert_called_once()
+
+    @mock.patch.object(volume.LOG, 'debug', autospec=True)
+    def test_delete_retry_on_501_sys029_other(self, mock_debug):
+        payload = {}
+        _OAT_PROP = '@Redfish.OperationApplyTime'
+        payload[_OAT_PROP] = 'Immediate'
+        target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
+        response_info = {"error": {"@Message.ExtendedInfo": [
+            {'Message': '@Redfish.SomethingElse.',
+             'MessageId': 'IDRAC.2.7.SYS029'}]}}
+        mock_error = mock.Mock()
+        mock_error.status_code = 501
+        mock_error.json.return_value = response_info
+        mock_success = mock.Mock()
+        mock_success.status_code = 201
+        self.conn.delete.side_effect = [exceptions.ServerSideError(
+            method='DELETE', url=target_uri, response=mock_error),
+            mock_success]
+
+        self.assertRaises(exceptions.ServerSideError, self.stor_volume.delete,
+                          payload=payload,
+                          apply_time=res_cons.ApplyTime.IMMEDIATE)
+        self.stor_volume._conn.delete.assert_called_once_with(
+            self.stor_volume._path, data=payload, blocking=True, timeout=500)
+        mock_debug.assert_not_called()
+
+    @mock.patch.object(volume.LOG, 'debug', autospec=True)
+    def test_delete_raise_on_501_other(self, mock_debug):
+        payload = {}
+        _OAT_PROP = '@Redfish.OperationApplyTime'
+        payload[_OAT_PROP] = 'Immediate'
+        target_uri = '/redfish/v1/Systems/437XR1138R2/Storage/1/Volumes/1'
+        response_info = {"error": {"@Message.ExtendedInfo": [
+            {'Message': 'Other message.'}]}}
+        mock_error = mock.Mock()
+        mock_error.status_code = 501
+        mock_error.json.return_value = response_info
+        self.conn.delete.side_effect = [exceptions.ServerSideError(
+            method='DELETE', url=target_uri, response=mock_error)]
+
+        self.assertRaises(exceptions.ServerSideError, self.stor_volume.delete,
+                          payload=payload,
+                          apply_time=res_cons.ApplyTime.IMMEDIATE)
+        self.stor_volume._conn.delete.assert_called_once_with(
+            self.stor_volume._path, data=payload, blocking=True, timeout=500)
+        mock_debug.assert_not_called()
+
 
 class VolumeCollectionTestCase(base.TestCase):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-4.4.0/sushy/tests/unit/resources/system/test_system.py 
new/sushy-4.4.2/sushy/tests/unit/resources/system/test_system.py
--- old/sushy-4.4.0/sushy/tests/unit/resources/system/test_system.py    
2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/resources/system/test_system.py    
2023-02-10 17:07:32.000000000 +0100
@@ -317,9 +317,7 @@
 
     def test_set_system_boot_options_nothing_specified(self):
         self.sys_inst.set_system_boot_options()
-        self.sys_inst._conn.patch.assert_called_once_with(
-            '/redfish/v1/Systems/437XR1138R2', data={},
-            etag=None)
+        self.sys_inst._conn.patch.assert_not_called()
 
     def test_set_system_boot_options_invalid_target(self):
         self.assertRaises(exceptions.InvalidParameterValueError,
@@ -366,13 +364,21 @@
             etag=None)
 
     def test_set_system_boot_options_settings_resource_nokia(self):
-        self.conn.get.return_value.headers = {'ETag': '"3d7b838291941d"'}
         with open('sushy/tests/unit/json_samples/settings-nokia.json') as f:
             settings_obj = json.load(f)
 
         self.json_doc.update(settings_obj)
         self.sys_inst._parse_attributes(self.json_doc)
 
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-body-nokia.json') as f:
+            settings_body = json.load(f)
+
+        get_settings = mock.MagicMock(headers={'ETag': '"3d7b838291941d"'})
+        get_settings.json.return_value = settings_body
+        get_system = mock.MagicMock(headers={'ETag': '"222"'})
+        self.conn.get.side_effect = [get_settings, get_system]
+
         self.sys_inst.set_system_boot_options(
             target=sushy.BootSource.CD,
             enabled=sushy.BootSourceOverrideEnabled.ONCE)
@@ -384,13 +390,23 @@
             etag='"3d7b838291941d"')
 
     def test_set_system_boot_options_settings_resource(self):
-        self.conn.get.return_value.headers = {'ETag': '"3d7b838291941d"'}
         with open('sushy/tests/unit/json_samples/settings.json') as f:
             settings_obj = json.load(f)
 
         self.json_doc.update(settings_obj)
         self.sys_inst._parse_attributes(self.json_doc)
 
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-body-nokia.json') as f:
+            settings_body = json.load(f)
+
+        get_settings = mock.MagicMock(headers={'ETag': '"3d7b838291941d"'})
+        get_settings.json.return_value = settings_body
+        get_system = mock.MagicMock(headers={'ETag': '"222"'})
+        self.conn.get.side_effect = [get_settings, get_system]
+
+        self.conn.get.return_value.json.return_value = settings_body
+
         self.sys_inst.set_system_boot_options(
             target=sushy.BootSource.CD,
             enabled=sushy.BootSourceOverrideEnabled.ONCE)
@@ -401,6 +417,66 @@
                            'BootSourceOverrideTarget': 'Cd'}},
             etag='"3d7b838291941d"')
 
+    def test_set_system_boot_options_settings_resource_lenovo(self):
+        self.sys_inst = system.System(
+            self.conn, '/redfish/v1/Systems/1',
+            redfish_version='1.0.2')
+
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-lenovo-se450.json') as f:
+            settings_obj = json.load(f)
+
+        self.json_doc.update(settings_obj)
+        self.sys_inst._parse_attributes(self.json_doc)
+
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-body-lenovo-se450.json') as f:
+            settings_body = json.load(f)
+
+        get_settings = mock.MagicMock(headers={'ETag': '"3d7b838291941d"'})
+        get_settings.json.return_value = settings_body
+        get_system = mock.MagicMock(headers={'ETag': '"222"'})
+        self.conn.get.side_effect = [get_settings, get_system]
+
+        self.sys_inst.set_system_boot_options(
+            target=sushy.BootSource.CD,
+            enabled=sushy.BootSourceOverrideEnabled.ONCE)
+
+        self.sys_inst._conn.patch.assert_called_once_with(
+            '/redfish/v1/Systems/1',
+            data={'Boot': {'BootSourceOverrideEnabled': 'Once',
+                           'BootSourceOverrideTarget': 'Cd'}},
+            etag='"222"')
+
+    def test_set_system_boot_options_settings_resource_bootmode_only(self):
+        self.sys_inst = system.System(
+            self.conn, '/redfish/v1/Systems/1',
+            redfish_version='1.0.2')
+
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-nokia.json') as f:
+            settings_obj = json.load(f)
+
+        self.json_doc.update(settings_obj)
+        self.sys_inst._parse_attributes(self.json_doc)
+
+        with open('sushy/tests/unit/json_samples/'
+                  'settings-body-bootsourceoverridemode-only.json') as f:
+            settings_body = json.load(f)
+
+        get_settings = mock.MagicMock(headers={'ETag': '"3d7b838291941d"'})
+        get_settings.json.return_value = settings_body
+        get_system = mock.MagicMock(headers={'ETag': '"222"'})
+        self.conn.get.side_effect = [get_settings, get_system]
+
+        self.sys_inst.set_system_boot_options(
+            mode=sushy.BootSourceOverrideMode.UEFI)
+
+        self.sys_inst._conn.patch.assert_called_with(
+            '/redfish/v1/Systems/Self/SD',
+            data={'Boot': {'BootSourceOverrideMode': 'UEFI'}},
+            etag='"3d7b838291941d"')
+
     def test_set_system_boot_source(self):
         self.sys_inst.set_system_boot_source(
             sushy.BootSource.PXE,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy/tests/unit/test_connector.py 
new/sushy-4.4.2/sushy/tests/unit/test_connector.py
--- old/sushy-4.4.0/sushy/tests/unit/test_connector.py  2022-11-22 
16:25:52.000000000 +0100
+++ new/sushy-4.4.2/sushy/tests/unit/test_connector.py  2023-02-10 
17:07:32.000000000 +0100
@@ -178,7 +178,7 @@
         self.conn._op('GET', path='fake/path', headers=self.headers)
         self.request.assert_called_once_with(
             'GET', 'http://foo.bar:1234/fake/path',
-            headers=self.headers, json=None)
+            headers=self.headers, json=None, verify=True)
 
     def test_response_callback(self):
         mock_response_callback = mock.MagicMock()
@@ -192,21 +192,22 @@
                       allow_redirects=False)
         self.request.assert_called_once_with(
             'GET', 'http://foo.bar:1234/fake/path',
-            headers=self.headers, json=None, allow_redirects=False)
+            headers=self.headers, json=None, allow_redirects=False,
+            verify=True)
 
     def test_ok_post(self):
         self.conn._op('POST', path='fake/path', data=self.data.copy(),
                       headers=self.headers)
         self.request.assert_called_once_with(
             'POST', 'http://foo.bar:1234/fake/path',
-            json=self.data, headers=self.headers)
+            json=self.data, headers=self.headers, verify=True)
 
     def test_ok_put(self):
         self.conn._op('PUT', path='fake/path', data=self.data.copy(),
                       headers=self.headers)
         self.request.assert_called_once_with(
             'PUT', 'http://foo.bar:1234/fake/path',
-            json=self.data, headers=self.headers)
+            json=self.data, headers=self.headers, verify=True)
 
     def test_ok_delete(self):
         expected_headers = self.headers.copy()
@@ -214,7 +215,7 @@
         self.conn._op('DELETE', path='fake/path', headers=self.headers.copy())
         self.request.assert_called_once_with(
             'DELETE', 'http://foo.bar:1234/fake/path',
-            headers=expected_headers, json=None)
+            headers=expected_headers, json=None, verify=True)
 
     def test_ok_post_with_session(self):
         self.conn._session.headers = {}
@@ -226,7 +227,7 @@
                       data=self.data)
         self.request.assert_called_once_with(
             'POST', 'http://foo.bar:1234/fake/path',
-            json=self.data, headers=expected_headers)
+            json=self.data, headers=expected_headers, verify=True)
         self.assertEqual(self.conn._session.headers,
                          {'X-Auth-Token': 'asdf1234'})
 
@@ -239,7 +240,7 @@
         self.conn._op('GET', path=path, headers=headers)
         self.request.assert_called_once_with(
             'GET', 'http://foo.bar:1234' + path,
-            headers=expected_headers, json=None)
+            headers=expected_headers, json=None, verify=True)
 
     def test_odata_version_header_redfish_no_headers(self):
         path = '/redfish/v1/bar'
@@ -247,7 +248,7 @@
         self.conn._op('GET', path=path)
         self.request.assert_called_once_with(
             'GET', 'http://foo.bar:1234' + path,
-            headers=expected_headers, json=None)
+            headers=expected_headers, json=None, verify=True)
 
     def test_odata_version_header_redfish_existing_header(self):
         path = '/redfish/v1/foo'
@@ -256,7 +257,7 @@
         self.conn._op('GET', path=path, headers=headers)
         self.request.assert_called_once_with(
             'GET', 'http://foo.bar:1234' + path,
-            headers=expected_headers, json=None)
+            headers=expected_headers, json=None, verify=True)
 
     def test_timed_out_session_unable_to_create_session(self):
         self.conn._auth.can_refresh_session.return_value = False
@@ -362,6 +363,7 @@
         self.assertEqual(http_client.BAD_REQUEST, exc.status_code)
         self.assertIsNotNone(exc.body)
         self.assertIn('body submitted was malformed JSON', exc.detail)
+        self.assertEqual(len(exc.extended_info), 3, exc.extended_info)
 
     def test_known_http_error_nonlist_ext_info(self):
         self.request.return_value.status_code =\
@@ -377,6 +379,8 @@
         self.assertEqual(http_client.UNSUPPORTED_MEDIA_TYPE, exc.status_code)
         self.assertIsNotNone(exc.body)
         self.assertIn('See Resolution for information', exc.detail)
+        self.assertIn('unsupported media type',
+                      exc.extended_info['Resolution'])
 
     @mock.patch('time.sleep', autospec=True)
     def test_not_found_error(self, mock_sleep):
@@ -405,6 +409,42 @@
         self.assertEqual(10, mock_sleep.call_count)
         self.assertEqual(11, self.request.call_count)
 
+    @mock.patch('time.sleep', autospec=True)
+    def test_op_retry_on_server_500_sys518(self, mock_sleep):
+        response_info = {"error": {"@Message.ExtendedInfo": [
+            {'MessageId': 'IDRAC.2.7.SYS518'}]}}
+        mock_error = mock.Mock()
+        mock_error.status_code = 500
+        mock_error.json.return_value = response_info
+        self.request.return_value.status_code = (
+            http_client.INTERNAL_SERVER_ERROR)
+        self.request.return_value.json.side_effect =\
+            exceptions.ServerSideError(
+                method='DELETE', url='http://foo.bar', response=mock_error)
+
+        self.assertRaises(exceptions.ServerSideError, self.conn._op, 'DELETE',
+                          'http://foo.bar')
+        self.assertEqual(10, mock_sleep.call_count)
+        self.assertEqual(11, self.request.call_count)
+
+    @mock.patch('time.sleep', autospec=True)
+    def test_op_retry_on_server_500_other_than_sys518(self, mock_sleep):
+        response_info = {"error": {"@Message.ExtendedInfo": [
+            {'MessageId': 'IDRAC.2.7.SYS999'}]}}
+        mock_error = mock.Mock()
+        mock_error.status_code = 500
+        mock_error.json.return_value = response_info
+        self.request.return_value.status_code = (
+            http_client.INTERNAL_SERVER_ERROR)
+        self.request.return_value.json.side_effect =\
+            exceptions.ServerSideError(
+                method='DELETE', url='http://foo.bar', response=mock_error)
+
+        self.assertRaises(exceptions.ServerSideError, self.conn._op, 'DELETE',
+                          'http://foo.bar')
+        self.assertEqual(0, mock_sleep.call_count)
+        self.assertEqual(1, self.request.call_count)
+
     def test_access_error(self):
         self.conn._auth = None
 
@@ -504,7 +544,7 @@
             'this is expected prior to authentication', 'HTTP GET '
             'http://redfish/v1/SessionService returned code '
             '%s. unknown error Extended information: '
-            'none' % http_client.FORBIDDEN)
+            'None' % http_client.FORBIDDEN)
         self.assertEqual(http_client.FORBIDDEN, exc.status_code)
 
     def test_blocking_no_location_header(self):
@@ -540,10 +580,10 @@
     def test_access_error_basic_auth(self, mock_log):
         self.conn._auth.can_refresh_session.return_value = False
         self.conn._session.auth = ('foo', 'bar')
-        self.request.return_value.status_code = http_client.FORBIDDEN
+        self.request.return_value.status_code = 403
         mock_response = mock.Mock()
         mock_response.json.side_effect = ValueError('no json')
-        mock_response.status_code = http_client.FORBIDDEN
+        mock_response.status_code = 403
         self.request.return_value.json.side_effect = ValueError('no json')
 
         with self.assertRaisesRegex(exceptions.AccessError,
@@ -552,12 +592,13 @@
         exc = cm.exception
         self.assertEqual(http_client.FORBIDDEN, exc.status_code)
         self.conn._auth.authenticate.assert_not_called()
+        error_msg = (f'HTTP GET http://redfish/v1/SessionService '
+                     f'returned code {exc.status_code}. unknown error '
+                     f'Extended information: None')
         mock_log.assert_called_once_with(
             "We have encountered an AccessError when using 'basic' "
             "authentication. %(err)s",
-            {'err': 'HTTP GET http://redfish/v1/SessionService '
-                    'returned code HTTPStatus.FORBIDDEN. unknown error '
-                    'Extended information: none'}
+            {'err': error_msg}
         )
 
     def test__op_raises_connection_error(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy.egg-info/PKG-INFO 
new/sushy-4.4.2/sushy.egg-info/PKG-INFO
--- old/sushy-4.4.0/sushy.egg-info/PKG-INFO     2022-11-22 16:26:19.000000000 
+0100
+++ new/sushy-4.4.2/sushy.egg-info/PKG-INFO     2023-02-10 17:07:59.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: sushy
-Version: 4.4.0
+Version: 4.4.2
 Summary: Sushy is a small Python library to communicate with Redfish based 
systems
 Home-page: https://docs.openstack.org/sushy/latest/
 Author: OpenStack
@@ -46,4 +46,5 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy.egg-info/SOURCES.txt 
new/sushy-4.4.2/sushy.egg-info/SOURCES.txt
--- old/sushy-4.4.0/sushy.egg-info/SOURCES.txt  2022-11-22 16:26:19.000000000 
+0100
+++ new/sushy-4.4.2/sushy.egg-info/SOURCES.txt  2023-02-10 17:07:59.000000000 
+0100
@@ -67,6 +67,7 @@
 releasenotes/notes/certificate-collection-acc67488c240274c.yaml
 releasenotes/notes/change-bootdev-smc-ab30317eaf5c37d9.yaml
 releasenotes/notes/change-vmedia-write-protected-attr-586370a552288801.yaml
+releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
 releasenotes/notes/config-server-side-retries-d16824019bd709a2.yaml
 releasenotes/notes/decouple-boot-params-c75e80f5951abb12.yaml
 releasenotes/notes/deprecate-system-leds-f1a72422c53d281e.yaml
@@ -80,6 +81,7 @@
 releasenotes/notes/expand-drive-schema-042901f919be646c.yaml
 
releasenotes/notes/fix-2008198-bios-factory-reset-400-bad-request-3f4a7a2aada0835b.yaml
 releasenotes/notes/fix-eject-media-empty-dict-573b4c9e06f52ce7.yaml
+releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml
 releasenotes/notes/fix-extended-info-error-handling-73fecb6bf5c852ff.yaml
 releasenotes/notes/fix-insert-media-payload-b5d4c707f81d9603.yaml
 releasenotes/notes/fix-malformed-boot-mode-1ba1117cad8dcc47.yaml
@@ -87,6 +89,7 @@
 releasenotes/notes/fix-oem-loading-52da045252b6c33e.yaml
 releasenotes/notes/fix-refine-resource-refresh-86c21ce230967251.yaml
 releasenotes/notes/fix-required-oem-attribute-parsing-205e4186275aa293.yaml
+releasenotes/notes/fix-retry_volume_operation-on_sys518-009f2b16e5c38a27.yaml
 releasenotes/notes/fix-return-full-weak-etag-04265472cbea9c0e.yaml
 
releasenotes/notes/fix-simple-storage-device-capacity-bytes-null-0672eed36d9da70a.yaml
 releasenotes/notes/fix-simple-update-e88838fab4170920.yaml
@@ -98,6 +101,7 @@
 releasenotes/notes/fix-use-headers-for-options-736940b87c06c189.yaml
 releasenotes/notes/fix-virtual-media-fallback-15a559414a65c014.yaml
 releasenotes/notes/fix-volume-actions-not-required-730fd637dd2587ce.yaml
+releasenotes/notes/fix-volume-delete-configuration-unsuported-operational_time_property-f53f650d8612a847.yaml
 
releasenotes/notes/fixes-ilo5-redfish-firmware-update-issue-273862b2a11e3536.yaml
 releasenotes/notes/get-retry-9ca311caf8a0b7bb.yaml
 releasenotes/notes/handle-basic-auth-access-errors-393b368b31f5cad2.yaml
@@ -111,6 +115,7 @@
 releasenotes/notes/message-registry-logging-39624ae114c02e15.yaml
 releasenotes/notes/monitor_firmware_update-664b0c6c1a0307cf.yaml
 releasenotes/notes/no-passwords-295207ac891d27ab.yaml
+releasenotes/notes/property-missing-7602c421ec177e9a.yaml
 releasenotes/notes/raise-error-on-async-task-failure-b67c7bc189a4d6ca.yaml
 
releasenotes/notes/reauthentication-session-fallback-failure-fixes-4f0dcfdad1afd2d7.yaml
 releasenotes/notes/redfish-response-log-294f3f10b770e356.yaml
@@ -132,6 +137,7 @@
 releasenotes/notes/vmedia-1.4.0-9957460fed59d85c.yaml
 releasenotes/notes/vmedia-certificate-06c367c6ef33d139.yaml
 releasenotes/notes/vmedia-credentials-14b7705c3c94cc07.yaml
+releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
 releasenotes/source/conf.py
 releasenotes/source/index.rst
 releasenotes/source/pike.rst
@@ -311,6 +317,10 @@
 sushy/tests/unit/json_samples/session_creation_headers_no_location.json
 sushy/tests/unit/json_samples/session_error.json
 sushy/tests/unit/json_samples/session_service.json
+sushy/tests/unit/json_samples/settings-body-bootsourceoverridemode-only.json
+sushy/tests/unit/json_samples/settings-body-lenovo-se450.json
+sushy/tests/unit/json_samples/settings-body-nokia.json
+sushy/tests/unit/json_samples/settings-lenovo-se450.json
 sushy/tests/unit/json_samples/settings-nokia.json
 sushy/tests/unit/json_samples/settings.json
 sushy/tests/unit/json_samples/simple_storage.json
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/sushy.egg-info/pbr.json 
new/sushy-4.4.2/sushy.egg-info/pbr.json
--- old/sushy-4.4.0/sushy.egg-info/pbr.json     2022-11-22 16:26:19.000000000 
+0100
+++ new/sushy-4.4.2/sushy.egg-info/pbr.json     2023-02-10 17:07:59.000000000 
+0100
@@ -1 +1 @@
-{"git_version": "56efdee", "is_release": true}
\ No newline at end of file
+{"git_version": "98c8999", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/tox.ini new/sushy-4.4.2/tox.ini
--- old/sushy-4.4.0/tox.ini     2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/tox.ini     2023-02-10 17:07:32.000000000 +0100
@@ -1,7 +1,6 @@
 [tox]
 minversion = 3.18.0
 envlist = py3,pep8
-skipsdist = True
 ignore_basepython_conflict=true
 
 [testenv]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-4.4.0/zuul.d/project.yaml 
new/sushy-4.4.2/zuul.d/project.yaml
--- old/sushy-4.4.0/zuul.d/project.yaml 2022-11-22 16:25:52.000000000 +0100
+++ new/sushy-4.4.2/zuul.d/project.yaml 2023-02-10 17:07:32.000000000 +0100
@@ -2,7 +2,7 @@
     templates:
       - check-requirements
       - openstack-cover-jobs
-      - openstack-python3-antelope-jobs
+      - openstack-python3-jobs
       - publish-openstack-docs-pti
       - release-notes-jobs-python3
     check:

Reply via email to