kube-rs / kube

Rust Kubernetes client and controller runtime
https://kube.rs
Apache License 2.0
3.06k stars 320 forks source link

Support for NO_PROXY #1203

Open goenning opened 1 year ago

goenning commented 1 year ago

Would you like to work on this feature?

yes

What problem are you trying to solve?

kube-rs currently supports the HTTP_PROXY (and all its variants) environment variable, but not the NO_PROXY var.

https://github.com/kube-rs/kube/blob/be15f7aab94863b24b7c903dc08812044504b1e3/kube-client/src/config/file_loader.rs#L110-L127

The NO_PROXY var is not standardised, but it's supported by Go and I think we could follow with similar support in here.

Describe the solution you'd like

change the proxy_url fn so that if NO_PROXY is set and the content matches the cluster.server url, return None, otherwise continue as usual.

The matching impl could be similar to https://github.com/seanmonstar/reqwest/pull/877

Describe alternatives you've considered

None

Documentation, Adoption, Migration Strategy

N/A

Target crate for feature

kube-client

goenning commented 1 year ago

Go's NO_PROXY impl also supports cidr blocks which would require something like the ipnet crate.

clux commented 1 year ago

Seems reasonable to me. PRs welcome.

goenning commented 1 year ago

Ok so I spent some time on this and I had a look at reqwest, attohttpc, the no_proxy crate, Go's implementation and that article.

It's a big mess πŸ™ˆ

The rust implementations above seem to be closer to curl although they all have some minor differences. They all seem to support CIDR (which curl doesn't), but they are missing support for ports. I'm not sure why they decided to ignore ports, maybe because it simplifies the impl?

As for Kube, given the context we're in, IMO we should match Go's implementation as much as possible. Given the no_proxy's crate goal of following the proposed standard from this article, it's unlikely that it'll ever match Go's. And given that Go has had this feature for years, they probably won't be introducing a breaking change either.

I ended up authoring this crate proxyvars with the explicit goal of matching Go's impl, which I'll be using until no_proxy support lands on kube-rs itself.

But before we move on, what are your thoughts on this? Adding either no_proxy or proxyvars to kube would result in something like:

    pub fn proxy_url(&self) -> Result<Option<http::Uri>, KubeconfigError> {
        if let Some(server_url) = &self.cluster.server {
            if let Some(no_proxy) = proxyvars::no_proxy() {
                if no_proxy.matches(server_url) {
                    return Ok(None);
                }
            }
        }
WeetA34 commented 1 year ago

Hello, Proxy through environment variables doesn't work for me. I see that proxy_url is properly detected and set in config but connections to GKE cluster are direct. Any ideas? Thank you

edit: I'm using rust 1.69.0 on macOS arm64 with kube 0.82.2, k8s-openapi 0.18.0

goenning commented 1 year ago

This package does not actually proxy the connection, you'll need to use something like hyper-proxy for that

WeetA34 commented 1 year ago

Ok. So, it supports http(s)_proxy environment variables but not proxies calls itself. It’s a bit curious for me πŸ˜€ thx

nobody4t commented 1 year ago

Ok. So, it supports http(s)_proxy environment variables but not proxies calls itself. It’s a bit curious for me πŸ˜€ thx

So the proxy functionality is not implemented here.