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 2026-05-20 15:25:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sushy (Old) and /work/SRC/openSUSE:Factory/.python-sushy.new.1966 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sushy" Wed May 20 15:25:11 2026 rev:23 rq:1354133 version:5.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sushy/python-sushy.changes 2026-04-12 17:52:26.291474012 +0200 +++ /work/SRC/openSUSE:Factory/.python-sushy.new.1966/python-sushy.changes 2026-05-20 15:26:29.090993998 +0200 @@ -1,0 +2,19 @@ +Tue May 19 22:20:18 UTC 2026 - Dirk Müller <[email protected]> + +- update to 5.11.0: + * Update hacking to 7.0.0 + * tls: Short circuit retries on hard tls errors + * Fix verify option usage with tls version settings + * Add TLS configuration support to sushy + * Prevent double-wrapping timeout tuple in Connector _op + * Revert "Skipping UsbCd workaround on Supermicro ARS-111GL- + NHR" + * Add missing __init__.py + * Fix docs lint issue in docstring + * Update master for stable/2026.1 + * Handle missing RelatedProperties in TransferProtocolType + detection +- drop Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch + (upstream) + +------------------------------------------------------------------- Old: ---- Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch sushy-5.10.0.tar.gz New: ---- sushy-5.11.0.tar.gz ----------(Old B)---------- Old: detection - drop Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch (upstream) ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sushy.spec ++++++ --- /var/tmp/diff_new_pack.AQ9x0n/_old 2026-05-20 15:26:30.043033227 +0200 +++ /var/tmp/diff_new_pack.AQ9x0n/_new 2026-05-20 15:26:30.043033227 +0200 @@ -17,22 +17,22 @@ Name: python-sushy -Version: 5.10.0 +Version: 5.11.0 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-%{version}.tar.gz -# [PATCH] Prevent double-wrapping timeout tuple in Connector _op -Patch0: Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch -BuildRequires: %{python_module oslotest} +BuildRequires: %{python_module oslotest >= 3.2.0} +BuildRequires: %{python_module pbr >= 6.0.0} BuildRequires: %{python_module pip} BuildRequires: %{python_module pytest} BuildRequires: %{python_module python-dateutil >= 2.7.0} BuildRequires: %{python_module requests >= 2.14.2} BuildRequires: %{python_module stevedore >= 1.29.0} BuildRequires: %{python_module wheel} +Requires: python-pbr >= 6.0.0 Requires: python-python-dateutil >= 2.7.0 Requires: python-requests >= 2.14.2 Requires: python-stevedore >= 1.29.0 @@ -54,7 +54,7 @@ This package contains the documentation. %prep -%autosetup -p1 -n sushy-%{version} +%autosetup -n sushy-%{version} %build %pyproject_wheel ++++++ sushy-5.10.0.tar.gz -> sushy-5.11.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/.pre-commit-config.yaml new/sushy-5.11.0/.pre-commit-config.yaml --- old/sushy-5.10.0/.pre-commit-config.yaml 2026-02-23 11:14:11.000000000 +0100 +++ new/sushy-5.11.0/.pre-commit-config.yaml 2026-05-05 14:01:27.000000000 +0200 @@ -24,7 +24,7 @@ - id: remove-tabs exclude: '.*\.(svg)$' - repo: https://opendev.org/openstack/hacking - rev: 6.1.0 + rev: 7.0.0 hooks: - id: hacking additional_dependencies: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/AUTHORS new/sushy-5.11.0/AUTHORS --- old/sushy-5.10.0/AUTHORS 2026-02-23 11:14:54.000000000 +0100 +++ new/sushy-5.11.0/AUTHORS 2026-05-05 14:02:17.000000000 +0200 @@ -26,6 +26,7 @@ Ilya Etingof <[email protected]> Iury Gregory Melo Ferreira <[email protected]> Iury Gregory Melo Ferreira <[email protected]> +Jacob Anders <[email protected]> Jacob Anders <[email protected]> James E. Blair <[email protected]> Javier Pena <[email protected]> @@ -37,6 +38,7 @@ Kaifeng Wang <[email protected]> Kamil Gustab <[email protected]> Kamlesh Chauvhan <[email protected]> +Lennart Jern <[email protected]> LiZekun <[email protected]> Lin Yang <[email protected]> Lucas Alvares Gomes <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/ChangeLog new/sushy-5.11.0/ChangeLog --- old/sushy-5.10.0/ChangeLog 2026-02-23 11:14:54.000000000 +0100 +++ new/sushy-5.11.0/ChangeLog 2026-05-05 14:02:17.000000000 +0200 @@ -1,6 +1,20 @@ CHANGES ======= +5.11.0 +------ + +* Update hacking to 7.0.0 +* tls: Short circuit retries on hard tls errors +* Fix verify option usage with tls version settings +* Add TLS configuration support to sushy +* Prevent double-wrapping timeout tuple in Connector \_op +* Revert "Skipping UsbCd workaround on Supermicro ARS-111GL-NHR" +* Add missing \_\_init\_\_.py +* Fix docs lint issue in docstring +* Update master for stable/2026.1 +* Handle missing RelatedProperties in TransferProtocolType detection + 5.10.0 ------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/PKG-INFO new/sushy-5.11.0/PKG-INFO --- old/sushy-5.10.0/PKG-INFO 2026-02-23 11:14:54.779126400 +0100 +++ new/sushy-5.11.0/PKG-INFO 2026-05-05 14:02:17.764028300 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: sushy -Version: 5.10.0 +Version: 5.11.0 Summary: Sushy is a small Python library to communicate with Redfish based systems Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml new/sushy-5.11.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml --- old/sushy-5.10.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,22 @@ +--- +features: + - | + Adds configurable TLS settings to the ``Sushy`` class constructor to + allow operators to specify minimum TLS protocol versions and cipher + suites for HTTPS connections to Redfish BMCs. + + * ``tls_min_version``: Minimum TLS version to use for HTTPS + connections. Supported values are '1.1', '1.2', and '1.3'. If not + specified, the default TLS version negotiation is used. Note that TLS + 1.1 is deprecated and should only be used for compatibility with + legacy BMC hardware. + + * ``tls_ciphers``: Colon-separated list of allowed cipher suites in + OpenSSL format for HTTPS connections. If not specified, the default + cipher suites are used. + + This change is fully backwards compatible. When TLS settings are + provided, a custom HTTPAdapter is mounted that configures an + ssl.SSLContext with the specified settings. This allows operators to + enforce security policies requiring specific TLS versions or cipher + suites when communicating with BMCs. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml new/sushy-5.11.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml --- old/sushy-5.10.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes virtual media insertion on BMCs (such as Cisco C845A M8 with + Redfish Base.1.18.1) that return ``ActionParameterMissing`` for the + missing ``TransferProtocolType`` parameter without including a + ``RelatedProperties`` field in the error response. The + ``is_transfer_protocol_required`` method now also checks for the + parameter name in ``MessageArgs`` as a fallback. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml new/sushy-5.11.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml --- old/sushy-5.10.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,12 @@ +--- +fixes: + - | + Fixes a bug where the ``connect_timeout`` parameter caused an + ``Invalid timeout`` error on any HTTP retry inside ``Connector._op()``. + When ``connect_timeout`` is set, the timeout is wrapped into a + ``(connect, read)`` tuple, but on recursive retries (server-side errors, + re-authentication, or redirect following) the already-wrapped tuple was + wrapped again, producing a nested tuple like ``(30, (30, 60))`` that the + ``requests`` library rejects. The timeout tuple is now passed through + unchanged on retries. + See `LP#2146416 <https://bugs.launchpad.net/sushy/+bug/2146416>`_. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml new/sushy-5.11.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml --- old/sushy-5.10.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,14 @@ +--- +fixes: + - | + Fixes virtual media boot failure on Supermicro ARS-111GL-NHR with newer + BMC firmware, where the virtual media device string has changed back to + 'UsbCd' consistent with other Supermicro servers. The model-specific + exception that previously skipped the CD-to-UsbCd override for this model + has been reverted. +upgrade: + - | + The CD-to-UsbCd boot source override is now applied unconditionally to all + Supermicro machines. Users running older ARS-111GL-NHR firmware where 'Cd' + was the correct virtual media device string will need to upgrade their BMC + firmware. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/source/2026.1.rst new/sushy-5.11.0/releasenotes/source/2026.1.rst --- old/sushy-5.10.0/releasenotes/source/2026.1.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/source/2026.1.rst 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,6 @@ +=========================== +2026.1 Series Release Notes +=========================== + +.. release-notes:: + :branch: stable/2026.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/releasenotes/source/index.rst new/sushy-5.11.0/releasenotes/source/index.rst --- old/sushy-5.10.0/releasenotes/source/index.rst 2026-02-23 11:14:11.000000000 +0100 +++ new/sushy-5.11.0/releasenotes/source/index.rst 2026-05-05 14:01:27.000000000 +0200 @@ -6,6 +6,7 @@ :maxdepth: 1 unreleased + 2026.1 2025.2 2025.1 2024.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/connector.py new/sushy-5.11.0/sushy/connector.py --- old/sushy-5.10.0/sushy/connector.py 2026-02-23 11:14:11.000000000 +0100 +++ new/sushy-5.11.0/sushy/connector.py 2026-05-05 14:01:27.000000000 +0200 @@ -16,10 +16,12 @@ from http import client as http_client import logging import re +import ssl import time from urllib import parse as urlparse import requests +from requests.adapters import HTTPAdapter from requests import exceptions as req_exc from urllib3.exceptions import InsecureRequestWarning @@ -39,6 +41,59 @@ ) +class TLSHttpAdapter(HTTPAdapter): + """HTTP adapter that configures TLS settings for HTTPS connections.""" + + def __init__(self, tls_min_version=None, tls_ciphers=None, verify=True, + *args, **kwargs): + """Initialize the TLS adapter. + + :param tls_min_version: Minimum TLS version ('1.1', '1.2', or '1.3'). + Note: TLS 1.1 is deprecated and should only be used for + compatibility with legacy BMC hardware. + :param tls_ciphers: Colon-separated string of allowed cipher suites + :param verify: Whether to verify SSL certificates + """ + self.tls_min_version = tls_min_version + self.tls_ciphers = tls_ciphers + self.verify = verify + super().__init__(*args, **kwargs) + + def init_poolmanager(self, *args, **kwargs): + """Override to set up TLS configuration.""" + if self.tls_min_version or self.tls_ciphers: + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + + if self.tls_min_version == '1.3': + ctx.minimum_version = ssl.TLSVersion.TLSv1_3 + elif self.tls_min_version == '1.2': + ctx.minimum_version = ssl.TLSVersion.TLSv1_2 + elif self.tls_min_version == '1.1': + ctx.minimum_version = ssl.TLSVersion.TLSv1_1 + elif self.tls_min_version is not None: + raise ValueError( + f"tls_min_version must be '1.1', '1.2', or '1.3', " + f"got: {self.tls_min_version}") + + if self.tls_ciphers: + try: + ctx.set_ciphers(self.tls_ciphers) + except ssl.SSLError as e: + raise ValueError( + f"Invalid cipher specification: {str(e)}") + + if self.verify: + ctx.check_hostname = True + ctx.verify_mode = ssl.CERT_REQUIRED + else: + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + + kwargs['ssl_context'] = ctx + + return super().init_poolmanager(*args, **kwargs) + + class Connector: def __init__( @@ -46,7 +101,9 @@ response_callback=None, server_side_retries=0, server_side_retries_delay=0, default_request_timeout=60, - connect_timeout=None): + connect_timeout=None, + tls_min_version=None, + tls_ciphers=None): self._url = url self._verify = verify self._session = requests.Session() @@ -60,6 +117,14 @@ # unreachable while still allowing longer read timeouts for slow BMCs. self._connect_timeout = connect_timeout + # Mount TLS adapter for HTTPS connections if TLS settings are provided + if tls_min_version or tls_ciphers: + adapter = TLSHttpAdapter( + tls_min_version=tls_min_version, + tls_ciphers=tls_ciphers, + verify=self._verify) + self._session.mount('https://', adapter) + # NOTE(TheJulia): In order to help prevent recursive post operations # by allowing us to understand that we should stop authentication. self._sessions_uri = None @@ -147,7 +212,8 @@ timeout = timeout or self._default_request_timeout # If connect_timeout is configured, use a tuple (connect, read) for # the requests timeout to allow faster failure on unreachable BMCs. - if self._connect_timeout is not None: + if (self._connect_timeout is not None + and not isinstance(timeout, tuple)): timeout = (self._connect_timeout, timeout) url = path if urlparse.urlparse(path).netloc else urlparse.urljoin( @@ -195,6 +261,11 @@ **extra_session_req_kwargs ) break + except req_exc.SSLError as e: + # SSL errors (handshake failures, certificate issues) are + # configuration problems, not transient errors. Do not retry. + LOG.error("SSL/TLS error connecting to %s: %s", url, e) + raise exceptions.ConnectionError(url=url, error=e) except _RETRYABLE_EXCEPTIONS as e: if attempt < retries - 1: LOG.warning( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/main.py new/sushy-5.11.0/sushy/main.py --- old/sushy-5.10.0/sushy/main.py 2026-02-23 11:14:11.000000000 +0100 +++ new/sushy-5.11.0/sushy/main.py 2026-05-05 14:01:27.000000000 +0200 @@ -161,7 +161,9 @@ language='en', server_side_retries=10, server_side_retries_delay=3, read_timeout=60, - connect_timeout=None): + connect_timeout=None, + tls_min_version=None, + tls_ciphers=None): """A class representing a RootService :param base_url: The base URL to the Redfish controller. It @@ -196,6 +198,14 @@ BMC to be established. If not specified, read_timeout is used for both connect and read timeouts. Setting this to a lower value (e.g., 10) allows faster failure when a BMC is unreachable. + :param tls_min_version: Minimum TLS version to use for HTTPS + connections. Supported values are '1.1', '1.2', and '1.3'. If not + specified, the default TLS version negotiation is used. Note: TLS + 1.1 is deprecated and should only be used for compatibility with + legacy BMC hardware. + :param tls_ciphers: Colon-separated list of allowed cipher suites + in OpenSSL format for HTTPS connections. If not specified, the + default cipher suites are used. """ self._root_prefix = root_prefix if (auth is not None and (password is not None @@ -214,7 +224,9 @@ server_side_retries=server_side_retries, server_side_retries_delay=server_side_retries_delay, default_request_timeout=read_timeout, - connect_timeout=connect_timeout), + connect_timeout=connect_timeout, + tls_min_version=tls_min_version, + tls_ciphers=tls_ciphers), path=self._root_prefix) self._public_connector = public_connector or requests self._language = language diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/oem/dell/resources/system/storage/controller.py new/sushy-5.11.0/sushy/oem/dell/resources/system/storage/controller.py --- old/sushy-5.10.0/sushy/oem/dell/resources/system/storage/controller.py 2026-02-23 11:14:11.000000000 +0100 +++ new/sushy-5.11.0/sushy/oem/dell/resources/system/storage/controller.py 2026-05-05 14:01:27.000000000 +0200 @@ -34,8 +34,9 @@ to RAID mode. No changes made for PERC 11 and above as they support only RAID mode, and BOSS controller as it does not have controller mode. + :returns: TaskMonitor if controller mode changes applied and need to - reboot, otherwise None + reboot, otherwise None """ # Some controllers do not have controller_mode try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/resources/manager/virtual_media.py new/sushy-5.11.0/sushy/resources/manager/virtual_media.py --- old/sushy-5.10.0/sushy/resources/manager/virtual_media.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/resources/manager/virtual_media.py 2026-05-05 14:01:27.000000000 +0200 @@ -118,12 +118,26 @@ and 'TransferProtocolType' in error.detail): return True - return ( - (error.code.endswith(".ActionParameterMissing") - or error.code.endswith(".PropertyMissing")) - and (("#/TransferProtocolType" in error.related_properties) - or ("/TransferProtocolType" in error.related_properties)) - ) + if not (error.code.endswith(".ActionParameterMissing") + or error.code.endswith(".PropertyMissing")): + return False + + if (("#/TransferProtocolType" in error.related_properties) + or ("/TransferProtocolType" in error.related_properties)): + return True + + # NOTE(janders) Some BMCs (e.g. Cisco C845A M8 with Redfish + # Base.1.18.1) do not include RelatedProperties in the error + # response, but do include the missing parameter name in + # MessageArgs. Check for that as a fallback. + try: + args = error.extended_info[0].get('MessageArgs', []) + if 'TransferProtocolType' in args: + return True + except (IndexError, KeyError, TypeError): + pass + + return False def is_transfer_method_required(self, error=None): """Check the response code and body and in case of failure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/resources/system/system.py new/sushy-5.11.0/sushy/resources/system/system.py --- old/sushy-5.10.0/sushy/resources/system/system.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/resources/system/system.py 2026-05-05 14:01:27.000000000 +0200 @@ -252,7 +252,6 @@ of a Resource Ref: http://redfish.dmtf.org/schemas/DSP0266_1.7.0.html#settings-resource """ - _supermicro_models_cd_vmedia = frozenset(['ars-111gl-nhr']) _actions = ActionsField('Actions') @@ -379,20 +378,14 @@ target = sys_cons.BootSource(target) # NOTE(janders) on SuperMicro X11 and X12 machines, virtual media - # is presented as an "USB CD" drive as opposed to a CD drive. - # On Supermicro ARS-111GL-NHR however, a more common "CD" device - # is used. On both "families" of hardware, both "USB CD" and "CD" + # is presented as an "USB CD" drive as opposed to a CD drive. Both # are present in the list of boot devices, however only selecting - # the appropriate one for the platform as the boot source results - # in a successful boot from vMedia. Unless the appropriate option - # for a given model is selected, boot fails even if vMedia is + # UsbCd as the boot source results in a successful boot from + # vMedia. If "CD" is selected, boot fails even if vMedia is # inserted. This code detects a case where a SuperMicro machine is # about to attempt boot from CD and overrides the boot device to - # UsbCd if required, depending on the model. This makes boot from - # vMedia work as expected on both variants. + # UsbCd instead which makes boot from vMedia work as expected. if (self.manufacturer and self.manufacturer.lower() == 'supermicro' - and self.model.lower() not in - self._supermicro_models_cd_vmedia and target == sys_cons.BootSource.CD and self.boot and sys_cons.BootSource.USB_CD.value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json new/sushy-5.11.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json --- old/sushy-5.10.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.11.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json 2026-05-05 14:01:27.000000000 +0200 @@ -0,0 +1,19 @@ +{ + "error": { + "@Message.ExtendedInfo": [ + { + "@odata.type": "#Message.v1_1_1.Message", + "Message": "The action InsertMedia requires the parameter TransferProtocolType to be present in the request body.", + "MessageArgs": [ + "InsertMedia", + "TransferProtocolType" + ], + "MessageId": "Base.1.18.1.ActionParameterMissing", + "MessageSeverity": "Critical", + "Resolution": "Supply the action with the required parameter in the request body when the request is resubmitted." + } + ], + "code": "Base.1.18.1.ActionParameterMissing", + "message": "The action InsertMedia requires the parameter TransferProtocolType to be present in the request body." + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/resources/manager/test_virtual_media.py new/sushy-5.11.0/sushy/tests/unit/resources/manager/test_virtual_media.py --- old/sushy-5.10.0/sushy/tests/unit/resources/manager/test_virtual_media.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/tests/unit/resources/manager/test_virtual_media.py 2026-05-05 14:01:27.000000000 +0200 @@ -254,6 +254,16 @@ retval = self.sys_virtual_media.is_transfer_protocol_required(error) self.assertTrue(retval) + def test_is_transfer_protocol_required_no_related_properties(self): + with open('sushy/tests/unit/json_samples/' + 'transfer_proto_required_error4.json') as f: + response_obj = json.load(f) + response = mock.Mock(spec=['json', 'status_code']) + response.json.return_value = response_obj + error = exceptions.HTTPError('POST', 'VirtualMedia', response) + retval = self.sys_virtual_media.is_transfer_protocol_required(error) + self.assertTrue(retval) + def test_is_transfer_method_required(self): with open('sushy/tests/unit/json_samples/' 'transfer_method_required_error.json') as f: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/resources/system/test_system.py new/sushy-5.11.0/sushy/tests/unit/resources/system/test_system.py --- old/sushy-5.10.0/sushy/tests/unit/resources/system/test_system.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/tests/unit/resources/system/test_system.py 2026-05-05 14:01:27.000000000 +0200 @@ -349,23 +349,6 @@ 'BootSourceOverrideTarget': 'UsbCd'}}, etag='81802dbf61beb0bd') - def test_set_system_boot_options_supermicro_usb_cd_boot_ars111glnhr(self): - (self.json_doc["Boot"] - ["[email protected]"]).append("UsbCd") - self.sys_inst._parse_attributes(self.json_doc) - - self.sys_inst.manufacturer = "supermicro" - self.sys_inst.model = "ARS-111GL-NHR" - 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/437XR1138R2', - data={'Boot': {'BootSourceOverrideEnabled': 'Once', - 'BootSourceOverrideTarget': 'Cd'}}, - etag='81802dbf61beb0bd') - def test_set_system_boot_options_supermicro_no_usb_cd_boot(self): self.sys_inst.manufacturer = "supermicro" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/test_connector.py new/sushy-5.11.0/sushy/tests/unit/test_connector.py --- old/sushy-5.10.0/sushy/tests/unit/test_connector.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/tests/unit/test_connector.py 2026-05-05 14:01:27.000000000 +0200 @@ -203,6 +203,36 @@ 'GET', 'http://foo.bar:1234/fake/path', headers=self.headers, json=None, verify=True, timeout=(10, 60)) + def test_connect_timeout_not_double_wrapped_on_retry(self): + """Test that timeout tuple is not double-wrapped on recursive retry. + + When connect_timeout is set, _op() wraps timeout into a + (connect, read) tuple. On retry _op() calls itself recursively, + passing the already-wrapped tuple. Without the isinstance guard + this results in (connect, (connect, read)) which requests rejects. + Regression test for https://bugs.launchpad.net/sushy/+bug/2146416 + """ + self.conn._connect_timeout = 10 + self.conn._default_request_timeout = 60 + self.request.side_effect = [ + mock.Mock(status_code=http_client.NOT_ACCEPTABLE), + mock.Mock(status_code=http_client.OK), + ] + self.conn._op('GET', 'http://foo.bar') + + self.assertEqual(2, self.request.call_count) + headers_no_accept = self.headers.copy() + headers_no_accept.pop('Accept-Encoding') + # Both the original and the retried request must use the same + # (connect, read) timeout tuple - never a nested tuple. + self.request.assert_has_calls([ + mock.call('GET', 'http://foo.bar', headers=self.headers, + json=None, verify=True, timeout=(10, 60)), + mock.call('GET', 'http://foo.bar', + headers=headers_no_accept, + json=None, verify=True, timeout=(10, 60)), + ]) + def test_response_callback(self): mock_response_callback = mock.MagicMock() self.conn._response_callback = mock_response_callback @@ -1016,3 +1046,122 @@ target_uri) self.assertEqual(self.request.call_count, self.conn._server_side_retries) + + @mock.patch.object(time, 'sleep', autospec=True) + def test_ssl_error_not_retried(self, mock_sleep): + """Test that SSL errors are not retried.""" + target_uri = '/redfish/v1/Systems/1' + self.request.side_effect = requests.exceptions.SSLError( + "SSL handshake failed") + self.assertRaises(exceptions.ConnectionError, self.conn.get, + target_uri) + # SSL errors should fail immediately without retries + self.assertEqual(self.request.call_count, 1) + # Sleep should not be called since there are no retries + mock_sleep.assert_not_called() + + +class TLSHttpAdapterTestCase(base.TestCase): + + def test_init_with_tls_settings(self): + adapter = connector.TLSHttpAdapter( + tls_min_version='1.3', + tls_ciphers='ECDHE-RSA-AES256-GCM-SHA384') + self.assertEqual(adapter.tls_min_version, '1.3') + self.assertEqual(adapter.tls_ciphers, + 'ECDHE-RSA-AES256-GCM-SHA384') + + def test_init_without_tls_settings(self): + adapter = connector.TLSHttpAdapter() + self.assertIsNone(adapter.tls_min_version) + self.assertIsNone(adapter.tls_ciphers) + + +class ConnectorTLSTestCase(base.TestCase): + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_with_tls_min_version_1_3(self, mock_auth): + mock_auth.get_session_key.return_value = None + conn = connector.Connector( + 'https://foo.bar:1234', + tls_min_version='1.3', + verify=True) + # Verify adapter is mounted + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertIsInstance(adapter, connector.TLSHttpAdapter) + self.assertEqual(adapter.tls_min_version, '1.3') + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_with_tls_min_version_1_2(self, mock_auth): + mock_auth.get_session_key.return_value = None + conn = connector.Connector( + 'https://foo.bar:1234', + tls_min_version='1.2', + verify=True) + # Verify adapter is mounted + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertIsInstance(adapter, connector.TLSHttpAdapter) + self.assertEqual(adapter.tls_min_version, '1.2') + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_with_tls_min_version_1_1(self, mock_auth): + mock_auth.get_session_key.return_value = None + conn = connector.Connector( + 'https://foo.bar:1234', + tls_min_version='1.1', + verify=True) + # Verify adapter is mounted + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertIsInstance(adapter, connector.TLSHttpAdapter) + self.assertEqual(adapter.tls_min_version, '1.1') + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_with_tls_ciphers(self, mock_auth): + mock_auth.get_session_key.return_value = None + conn = connector.Connector( + 'https://foo.bar:1234', + tls_ciphers='ECDHE-RSA-AES256-GCM-SHA384', + verify=True) + # Verify adapter is mounted + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertIsInstance(adapter, connector.TLSHttpAdapter) + self.assertEqual(adapter.tls_ciphers, + 'ECDHE-RSA-AES256-GCM-SHA384') + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_without_tls_settings(self, mock_auth): + mock_auth.get_session_key.return_value = None + conn = connector.Connector( + 'https://foo.bar:1234', + verify=True) + # Default adapter should not be TLSHttpAdapter + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertNotIsInstance(adapter, connector.TLSHttpAdapter) + + def test_adapter_with_invalid_tls_version(self): + self.assertRaisesRegex( + ValueError, + "tls_min_version must be '1.1', '1.2', or '1.3'", + connector.TLSHttpAdapter, + tls_min_version='1.0') + + def test_adapter_with_invalid_ciphers(self): + self.assertRaisesRegex( + ValueError, + "Invalid cipher specification", + connector.TLSHttpAdapter, + tls_ciphers='INVALID_CIPHER') + + @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True) + def test_connector_with_tls_and_verify_false(self, mock_auth): + mock_auth.get_session_key.return_value = None + # This should not raise an error + conn = connector.Connector( + 'https://foo.bar:1234', + tls_min_version='1.1', + verify=False) + # Verify adapter is mounted and has verify=False + adapter = conn._session.get_adapter('https://foo.bar:1234') + self.assertIsInstance(adapter, connector.TLSHttpAdapter) + self.assertEqual(adapter.tls_min_version, '1.1') + self.assertFalse(adapter.verify) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/test_main.py new/sushy-5.11.0/sushy/tests/unit/test_main.py --- old/sushy-5.10.0/sushy/tests/unit/test_main.py 2026-02-23 11:14:12.000000000 +0100 +++ new/sushy-5.11.0/sushy/tests/unit/test_main.py 2026-05-05 14:01:27.000000000 +0200 @@ -55,7 +55,7 @@ mock_connector.assert_called_once_with( 'http://foo.bar:1234', verify=True, server_side_retries=10, server_side_retries_delay=3, default_request_timeout=60, - connect_timeout=None) + connect_timeout=None, tls_min_version=None, tls_ciphers=None) def test__parse_attributes(self): self.root._parse_attributes(self.json_doc) @@ -99,7 +99,7 @@ mock_connector.assert_called_once_with( 'http://foo.bar:1234', verify=True, server_side_retries=10, server_side_retries_delay=3, default_request_timeout=30, - connect_timeout=None) + connect_timeout=None, tls_min_version=None, tls_ciphers=None) @mock.patch.object(auth, 'SessionOrBasicAuth', autospec=True) @mock.patch.object(connector, 'Connector', autospec=True) @@ -112,7 +112,7 @@ mock_connector.assert_called_once_with( 'http://foo.bar:1234', verify=True, server_side_retries=10, server_side_retries_delay=3, default_request_timeout=60, - connect_timeout=10) + connect_timeout=10, tls_min_version=None, tls_ciphers=None) @mock.patch.object(connector, 'Connector', autospec=True) def test_custom_connector(self, mock_Sushy_Connector): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/PKG-INFO new/sushy-5.11.0/sushy.egg-info/PKG-INFO --- old/sushy-5.10.0/sushy.egg-info/PKG-INFO 2026-02-23 11:14:54.000000000 +0100 +++ new/sushy-5.11.0/sushy.egg-info/PKG-INFO 2026-05-05 14:02:17.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: sushy -Version: 5.10.0 +Version: 5.11.0 Summary: Sushy is a small Python library to communicate with Redfish based systems Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/SOURCES.txt new/sushy-5.11.0/sushy.egg-info/SOURCES.txt --- old/sushy-5.10.0/sushy.egg-info/SOURCES.txt 2026-02-23 11:14:54.000000000 +0100 +++ new/sushy-5.11.0/sushy.egg-info/SOURCES.txt 2026-05-05 14:02:17.000000000 +0200 @@ -66,6 +66,7 @@ releasenotes/notes/add-task-monitor-support-21f711927ad6ec91.yaml releasenotes/notes/add-task-service-c751ce51e0b8dc11.yaml releasenotes/notes/add-thermal-resource-5c965a3c940f9028.yaml +releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml releasenotes/notes/add-virtual-media-support-f522fbec4420341c.yaml releasenotes/notes/add_composition_service-84750d8d1d96474a.yaml releasenotes/notes/add_ethernet_interface-df308f814f0e4bce.yaml @@ -83,6 +84,7 @@ 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/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml releasenotes/notes/config-server-side-retries-d16824019bd709a2.yaml releasenotes/notes/decouple-boot-params-c75e80f5951abb12.yaml releasenotes/notes/deprecate-system-leds-f1a72422c53d281e.yaml @@ -97,6 +99,7 @@ releasenotes/notes/event-service-d6607420effc3df8.yaml releasenotes/notes/expand-drive-schema-042901f919be646c.yaml releasenotes/notes/fix-2008198-bios-factory-reset-400-bad-request-3f4a7a2aada0835b.yaml +releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml releasenotes/notes/fix-dell-bmc-404-race-condition-6000e47436cd4d6e.yaml releasenotes/notes/fix-eject-media-empty-dict-573b4c9e06f52ce7.yaml releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml @@ -155,6 +158,7 @@ releasenotes/notes/retry-ilo-not-ready-error-0b4dce882282eaac.yaml releasenotes/notes/retry-on-missing-managedby-b2a5240eab8b4262.yaml releasenotes/notes/retry-transient-connection-failures-5d3217a9166bb0d2.yaml +releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml releasenotes/notes/secure-boot-76c5b80371ea85d1.yaml releasenotes/notes/secure-boot-database-7fae673722d7cf4f.yaml releasenotes/notes/sessions.yml @@ -184,6 +188,7 @@ releasenotes/source/2024.2.rst releasenotes/source/2025.1.rst releasenotes/source/2025.2.rst +releasenotes/source/2026.1.rst releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/pike.rst @@ -229,11 +234,14 @@ sushy/oem/dell/resources/manager/job_service.py sushy/oem/dell/resources/manager/lifecycle_service.py sushy/oem/dell/resources/manager/manager.py +sushy/oem/dell/resources/system/__init__.py sushy/oem/dell/resources/system/constants.py sushy/oem/dell/resources/system/raid_service.py sushy/oem/dell/resources/system/system.py +sushy/oem/dell/resources/system/storage/__init__.py sushy/oem/dell/resources/system/storage/constants.py sushy/oem/dell/resources/system/storage/controller.py +sushy/oem/dell/resources/taskservice/__init__.py sushy/oem/dell/resources/taskservice/constants.py sushy/oem/dell/resources/taskservice/task.py sushy/resources/__init__.py @@ -471,6 +479,7 @@ sushy/tests/unit/json_samples/transfer_proto_required_error.json sushy/tests/unit/json_samples/transfer_proto_required_error2.json sushy/tests/unit/json_samples/transfer_proto_required_error3.json +sushy/tests/unit/json_samples/transfer_proto_required_error4.json sushy/tests/unit/json_samples/updateservice.json sushy/tests/unit/json_samples/updateservice_no_inv.json sushy/tests/unit/json_samples/virtual_media.json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/pbr.json new/sushy-5.11.0/sushy.egg-info/pbr.json --- old/sushy-5.10.0/sushy.egg-info/pbr.json 2026-02-23 11:14:54.000000000 +0100 +++ new/sushy-5.11.0/sushy.egg-info/pbr.json 2026-05-05 14:02:17.000000000 +0200 @@ -1 +1 @@ -{"git_version": "4db9fc0", "is_release": true} \ No newline at end of file +{"git_version": "1909826", "is_release": true} \ No newline at end of file
