Skip to content
This repository was archived by the owner on Mar 13, 2022. It is now read-only.

Implement port forwarding. - #210

Merged
k8s-ci-robot merged 7 commits into
kubernetes-client:masterfrom
iciclespider:port-forward
Sep 8, 2020
Merged

k8s-ci-robot merged 7 commits into
kubernetes-client:masterfrom
iciclespider:port-forward

Conversation

@iciclespider

@iciclespider iciclespider commented Aug 24, 2020 •

Copy link
Copy Markdown
Contributor

Looking for feed back if this looks on track as a way of implementing port forwarding.

See the example and unittests added in this PR kubernetes-client/python#1237 for usage.

kubernetes-client/python#166

@k8s-ci-robot

Copy link
Copy Markdown
Contributor

Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA.

It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.


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/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label Aug 24, 2020
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

Welcome @iciclespider!

It looks like this is your first PR to kubernetes-client/python-base 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-client/python-base has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 24, 2020
@codecov-commenter

codecov-commenter commented Aug 24, 2020 •

Copy link
Copy Markdown

Codecov Report

Merging #210 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #210   +/-   ##
=======================================
  Coverage   92.37%   92.37%           
=======================================
  Files          13       13           
  Lines        1613     1613           
=======================================
  Hits         1490     1490           
  Misses        123      123           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 471a678...7bf04b3. Read the comment docs.

@iciclespider

Copy link
Copy Markdown
Contributor Author

/check-cla

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Aug 24, 2020
@iciclespider

Copy link
Copy Markdown
Contributor Author

/check-cla

@iciclespider

Copy link
Copy Markdown
Contributor Author

/assign @mbohlool

@yliaog

yliaog commented Aug 24, 2020

Copy link
Copy Markdown
Contributor

/assign

@yliaog

yliaog commented Aug 26, 2020

Copy link
Copy Markdown
Contributor

thanks for the PR. it looks good overall.

could you please split this PR into two PRs, the first PR is for refactoring the existing code to make it reusable for port forwarding, the second PR is for port forwarding.

this makes it easier to review, and also easier to rollback or fix the portforward PR in case it has any issue.

@iciclespider

Copy link
Copy Markdown
Contributor Author

@yliaog PR to refactor existing implementation in preparation for implementing port forwarding: #211

@iciclespider

Copy link
Copy Markdown
Contributor Author

@yliaog I rebased this PR against the merged master with the refactored code. I also updated the PR in kubernetes-client/python#1237 with a pod_portforward.py example.

Comment thread stream/ws_client.py
Comment on lines +453 to +465
ports = []
for key, value in query_params:
if key == 'ports':
for port in value.split(','):
try:
port = int(port)
if not (0 < port < 65536):
raise ValueError
ports.append(port)
except ValueError:
raise ApiValueError("Invalid port number `" + str(port) + "`")
if not ports:
raise ApiValueError("Missing required parameter `ports`")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this logic can be abstracted out to another function with a simpler implementation like below.

def _valid_ports(ports):
    _ports = []

    for p in ports:
        try:
            p = int(p)
        except ValueError:
            raise ApiValueError("Invalid port number `{}`. Port number must be an integer".format(p))

        if (p < 0) or (p > 65536):
            raise ApiValueError("Invalid port number `{}`. Port number must be between 0 and 65536".format(p))

        _ports.append(p)

    return _ports

ports = query_params.get("ports", "")
if not ports:
    raise ApiValueError("Missing required parameter `ports`")

ports = ports.split(",")
ports = _valid_ports(ports)

# There is no check required here, since any unwanted port value would be checked in _valid_ports itself.
# We can be assured that we get a non-empty port list here.

@iciclespider iciclespider Aug 31, 2020 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This line will not work:

ports = query_params.get("ports", "")

query_params is not a dictionary, it a list of two element tuples.

@palnabarun

Copy link
Copy Markdown
Member

/assign

Comment thread stream/stream.py
Comment thread stream/ws_client.py
raise ValueError("Invalid port number")
return self.ports[port_number].socket

def error(self, port_number):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please change it to error_channel or something more descriptive. 'error' looks like error/exception, which is confusing.

@iciclespider iciclespider Sep 1, 2020 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just pushed the change to error_channel.

However, a little clarification. This is not really a "channel" that can send and receive data. From the client perspective, it is read only and cannot be written to. And the only time it is written to by kubernetes is when there is an error/exception case on the server and that port is unusable. It is written as the parting message.

See: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/cri/streaming/portforward/websocket.go#L184-L197

func (h *websocketStreamHandler) portForward(p *websocketStreamPair) {
	defer p.dataStream.Close()
	defer p.errorStream.Close()

	klog.V(5).Infof("(conn=%p) invoking forwarder.PortForward for port %d", h.conn, p.port)
	err := h.forwarder.PortForward(h.pod, h.uid, p.port, p.dataStream)
	klog.V(5).Infof("(conn=%p) done invoking forwarder.PortForward for port %d", h.conn, p.port)

	if err != nil {
		msg := fmt.Errorf("error forwarding port %d to pod %s, uid %v: %v", p.port, h.pod, h.uid, err)
		runtime.HandleError(msg)
		fmt.Fprint(p.errorStream, msg.Error())
	}
}

Comment thread stream/ws_client.py
Comment thread stream/ws_client.py
Comment thread stream/ws_client.py
Comment thread stream/ws_client.py Outdated
def _proxy(self):
channel_ports = []
channel_initialized = []
python_ports = {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what about call it local_port?

Comment thread stream/ws_client.py
Comment thread stream/ws_client.py
* Rename `_Port.error` to be `_Port.error_channel`.
* Correct comment about where setsockopt is being called.
* Add comments clarifying why the double call to the same methods to setup channel information.
* Allow for ports specified with both local and remote port numbers.
Comment thread stream/stream.py
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py
Comment thread stream/ws_client.py
@iciclespider

Copy link
Copy Markdown
Contributor Author

@yliaog I submitted another commit for review.

Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py Outdated

@iciclespider iciclespider left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@yliaog I pushed a commit that addresses the comments.

Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py Outdated
Comment thread stream/ws_client.py
Comment thread stream/ws_client.py
@yliaog

yliaog commented Sep 8, 2020

Copy link
Copy Markdown
Contributor

thanks for the PR, really appreciate it.

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Sep 8, 2020
@k8s-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: iciclespider, yliaog

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

The pull request process is described 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 the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 8, 2020
@k8s-ci-robot
k8s-ci-robot merged commit 3dc7fe0 into kubernetes-client:master Sep 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants