Skip to content

Conversation

@SWITCHin2
Copy link

fixes: #540

@github-actions github-actions bot added the kr8s label Dec 4, 2025
@SWITCHin2
Copy link
Author

Hi @jacobtomlinson , I’ve attempted to fix the issue mentioned in the PR description. Could you please take a look when you get a chance? Thank you

@codecov
Copy link

codecov bot commented Dec 5, 2025

Codecov Report

❌ Patch coverage is 22.22222% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.50%. Comparing base (87063fc) to head (e3f26d7).
⚠️ Report is 286 commits behind head on main.

Files with missing lines Patch % Lines
kr8s/_portforward.py 22.22% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #712      +/-   ##
==========================================
- Coverage   94.61%   94.50%   -0.12%     
==========================================
  Files          29       33       +4     
  Lines        3141     5095    +1954     
==========================================
+ Hits         2972     4815    +1843     
- Misses        169      280     +111     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

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

This looks good thanks!

Could I ask you to add a test that verifies this behaviour. I would start by finding a test that creates a temporary copy of the kubeconfig copy that. Then change token in the kubeconfig to something invalid and then trying to open a port forward

Comment on lines 242 to 251
if (
isinstance(e, httpx_ws.WebSocketUpgradeError)
and hasattr(e, "response")
and e.response.status_code in (401, 403)
):
error_message = f"Permission denied: {e.response.status_code}"
with suppress(httpx.StreamClosed, httpx.ResponseNotRead):
await e.response.aread()
error_message = e.response.text
raise ServerError(error_message, response=e.response) from e
Copy link
Member

Choose a reason for hiding this comment

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

This bypasses the connection attempts. There may be cases where auth tokens expire and open_websocket will rotate them, so we don't want to raise here prematurely. Can you move this block inside the if connection_attempts > 5: section. That way we raise a ServerError if we have one, but a more generic ConnectionClosedError if we don't.

Copy link
Author

Choose a reason for hiding this comment

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

Ummm yes thats makes sense, sure will do that

@SWITCHin2
Copy link
Author

This looks good thanks!

Could I ask you to add a test that verifies this behaviour. I would start by finding a test that creates a temporary copy of the kubeconfig copy that. Then change token in the kubeconfig to something invalid and then trying to open a port forward

Sure, actually I had an testing script which does something like this will add the same in to /test dir

@github-actions github-actions bot added the tests label Dec 6, 2025
@SWITCHin2
Copy link
Author

SWITCHin2 commented Dec 6, 2025

hey @jacobtomlinson

  • have handled premature error throwing case as you mentioned
  • modified my test script as per you said , pushed them and also fixed some pre checks

Copy link
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

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

Thanks for pushing the test. I left a few comments but overall there is a lot of unnecessary code in there.

I think you just need to:

  • Create the temporary credentials with bad token
  • Create the api_invalid
  • Create the invalid Pod object (but not actually create the resource)
  • Try to call the port forward and assert that it raises the ServerError

Comment on lines +15 to +23
# Override the k8s_cluster fixture to avoid creating a Kind cluster
@pytest.fixture
def k8s_cluster():
class MockCluster:
@property
def kubeconfig_path(self):
return Path(os.environ.get("KUBECONFIG", "~/.kube/config")).expanduser()

return MockCluster()
Copy link
Member

Choose a reason for hiding this comment

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

I assume you did this for local development? In CI we need to this run against the kind cluster.

Comment on lines +60 to +65
# Delete if exists
if await pod.exists():
await pod.delete()
await pod.wait("condition=Deleted")

await pod.create()
Copy link
Member

Choose a reason for hiding this comment

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

Does the Pod actually need to exist? It never gets used other than to create pod_invalid.

Comment on lines +153 to +160
if __name__ == "__main__":

class MockCluster:
@property
def kubeconfig_path(self):
return Path(os.environ.get("KUBECONFIG", "~/.kube/config")).expanduser()

asyncio.run(test_portforward_invalid_token(MockCluster()))
Copy link
Member

Choose a reason for hiding this comment

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

In future instead of this you could just run pytest -k test_portforward_invalid_token and pytest will find the test and run it

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

portforward obfuscates permissions issues

3 participants