Skip to content

Conversation

@franck-ada
Copy link

@franck-ada franck-ada commented Dec 8, 2025

What type of PR is this?
/kind bug
/kind deprecation

What this PR does / why we need it:
Correct issue link to upgrade of urlib3

Which issue(s) this PR fixes:
Fixes #2280 / #2477

Special notes for your reviewer:
Does this PR introduce a user-facing change?
NONE

Copilot AI review requested due to automatic review settings December 8, 2025 03:31
@k8s-ci-robot
Copy link
Contributor

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added kind/bug Categorizes issue or PR as related to a bug. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. kind/deprecation Categorizes issue or PR as related to a feature/enhancement marked for deprecation. labels Dec 8, 2025
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: franck-ada
Once this PR has been reviewed and has the lgtm label, please assign yliaog for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Dec 8, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes header retrieval in the RESTResponse class to support urllib3 v2.x compatibility. The PR addresses issue #2280 by adding compatibility checks that prefer the newer headers attribute (available in urllib3 v2.x) before falling back to the deprecated getheaders() and getheader() methods.

Note: The PR title contains a typo: "correect" should be "correct".

Key changes:

  • Added hasattr() checks to detect the presence of the headers attribute on urllib3 response objects
  • Updated getheaders() to use headers.items() when available, falling back to getheaders() for older versions
  • Updated getheader() to use headers.get() when available, falling back to getheader() for older versions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

self.data = resp.data

def getheaders(self):
"""Returns a dictionary of the response headers."""
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring states "Returns a dictionary of the response headers" but the method returns headers.items() which returns an iterable of tuples (key-value pairs), not a dictionary. Consider updating the docstring to accurately reflect the return type, such as "Returns an iterable of header key-value pairs" or "Returns header items as tuples".

Suggested change
"""Returns a dictionary of the response headers."""
"""Returns an iterable of header key-value pairs (tuples)."""

Copilot uses AI. Check for mistakes.
@efussi
Copy link
Contributor

efussi commented Dec 8, 2025

Here is another occurrence of getheaders:

self.headers = http_resp.getheaders()

From my sniff testing, this needs to be changed as well.

@franck-ada
Copy link
Author

http_resp

I was looking at it. this http_resp is an instance of RESTResponse so it should stay as it is

@efussi
Copy link
Contributor

efussi commented Dec 9, 2025

http_resp

I was looking at it. this http_resp is an instance of RESTResponse so it should stay as it is

@franck-ada I was testing an ansible playbook with urllib3 2.6.0 patched like this:

sed -i -e 's/urllib3_response.getheaders()/urllib3_response.headers/' -e 's/urllib3_response.getheader(name, default)/urllib3_response.headers.get(name, default)/' \
    $site_packages/kubernetes/client/rest.py

When trying to delete a configmap that doesn't exist through ansible's k8s task, I still got this error:

TASK [wca-base : Delete configmap in dev] *************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! =>                           
    ansible_facts:                                                                                                             
        discovered_interpreter_python: /home/vagrant/.cache/venv/ansible/bin/python3.12                                        
    changed: false                                                                                                             
    msg: 'Failed to retrieve requested object: ''HTTPResponse'' object has no attribute                                                                                                                                                                       
        ''getheaders'''                                                                                                                                                                                                                                       

I had to add this additional patch to get past this error:

sed -i -e 's/http_resp.getheaders()/http_resp.headers/' \
    $site_packages/kubernetes/client/exceptions.py

Unfortunately, I didn't find a way yet to have ansible print the full stack trace.

@yliaog
Copy link
Contributor

yliaog commented Dec 29, 2025

the file kubernetes/client/rest.py is generated, the fix needs to be done somewhere else, otherwise, it will be overwritten during next release.

@surbas
Copy link

surbas commented Jan 13, 2026

Thanks for working on this! Few things that might help:

The repo already has scripts/rest_urllib_headers.diff which patches exceptions.py to use .headers instead of .getheaders(). Gets applied via apply-hotfixes.sh.

But theres still the RESTResponse.getheaders() method in rest.py (~line 60) that calls self.urllib3_response.getheaders() which will also fail with urllib3 >= 2.6.0. This PR addresses it but as yliaog mentioned rest.py is auto-generated so changes get overwritten.

Maybe we could add another patch file like rest_getheaders_compat.diff? Same pattern as existing hotfixes and survives regeneration. Something like:

--- a/kubernetes/client/rest.py
+++ b/kubernetes/client/rest.py
@@ -58,7 +58,9 @@ class RESTResponse(io.IOBase):

   def getheaders(self):
       """Returns a dictionary of the response headers."""
  •    return self.urllib3_response.getheaders()
    
  •    if hasattr(self.urllib3_response, 'getheaders'):
    
  •        return self.urllib3_response.getheaders()
    
  •    return self.urllib3_response.headers.items()
    

This is blocking us from updating to urllib3 >= 2.6.3 which has security fixes. Happy to help test or submit a followup PR for the patch file approach if useful

@surbas
Copy link

surbas commented Jan 13, 2026

Thanks for working on this! Few things that might help:

The repo already has scripts/rest_urllib_headers.diff which patches exceptions.py to use .headers instead of .getheaders(). Gets applied via apply-hotfixes.sh.

But theres still the RESTResponse.getheaders() method in rest.py (~line 60) that calls self.urllib3_response.getheaders() which will also fail with urllib3 >= 2.6.0. This PR addresses it but as yliaog mentioned rest.py is auto-generated so changes get overwritten.

Maybe we could add another patch file like rest_getheaders_compat.diff? Same pattern as existing hotfixes and survives regeneration. Something like:

--- a/kubernetes/client/rest.py +++ b/kubernetes/client/rest.py @@ -58,7 +58,9 @@ class RESTResponse(io.IOBase):

   def getheaders(self):
       """Returns a dictionary of the response headers."""
* ```
     return self.urllib3_response.getheaders()
  ```


* ```
     if hasattr(self.urllib3_response, 'getheaders'):
  ```

* ```
         return self.urllib3_response.getheaders()
  ```

* ```
     return self.urllib3_response.headers.items()
  ```

This is blocking us from updating to urllib3 >= 2.6.3 which has security fixes. Happy to help test or submit a followup PR for the patch file approach if useful

Disregard. I found discussion in #2497.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. kind/bug Categorizes issue or PR as related to a bug. kind/deprecation Categorizes issue or PR as related to a feature/enhancement marked for deprecation. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

getheaders is deprecated in urllib3 >= 2.0.0

6 participants