From 05809f2ee57e6b5703760dff19a82cfdc534a046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Tue, 5 Nov 2024 10:20:40 +0100 Subject: [PATCH 1/2] Warn when trying to use an unsupported proxy protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Natalie Klestrup Röijezon --- kube-client/src/client/builder.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/kube-client/src/client/builder.rs b/kube-client/src/client/builder.rs index 05edf80b4..9948922f7 100644 --- a/kube-client/src/client/builder.rs +++ b/kube-client/src/client/builder.rs @@ -91,9 +91,12 @@ impl TryFrom for ClientBuilder { } } + const PROXY_SCHEME_SOCKS5: &str = "socks5"; + const PROXY_SCHEME_HTTP: &str = "http"; + match config.proxy_url.as_ref() { #[cfg(feature = "socks5")] - Some(proxy_url) if proxy_url.scheme_str() == Some("socks5") => { + Some(proxy_url) if proxy_url.scheme_str() == Some(PROXY_SCHEME_SOCKS5) => { let connector = hyper_socks2::SocksConnector { proxy_addr: proxy_url.clone(), auth: None, @@ -104,14 +107,36 @@ impl TryFrom for ClientBuilder { } #[cfg(feature = "http-proxy")] - Some(proxy_url) if proxy_url.scheme_str() == Some("http") => { + Some(proxy_url) if proxy_url.scheme_str() == Some(PROXY_SCHEME_HTTP) => { let proxy = hyper_http_proxy::Proxy::new(hyper_http_proxy::Intercept::All, proxy_url.clone()); let connector = hyper_http_proxy::ProxyConnector::from_proxy_unsecured(connector, proxy); make_generic_builder(connector, config) } - _ => make_generic_builder(connector, config), + proxy_url => { + if let Some(proxy_url) = proxy_url { + let missing_proxy_feature = match proxy_url.scheme_str() { + Some(PROXY_SCHEME_SOCKS5) => Some("kube/socks5"), + Some(PROXY_SCHEME_HTTP) => Some("kube/http-proxy"), + _ => None, + }; + if let Some(missing_proxy_feature) = missing_proxy_feature { + tracing::warn!( + ?proxy_url, + missing_proxy_feature, + "proxy URL is set but kube was built without support for that protocol, ignoring..." + ); + } else { + tracing::warn!( + ?proxy_url, + "proxy URL is set but kube does not support that protocol, ignoring..." + ); + } + } + + make_generic_builder(connector, config) + } } } } From e81e3ac8f17d4e1e8516b54e401e91f60e8cdc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natalie=20Klestrup=20R=C3=B6ijezon?= Date: Thu, 7 Nov 2024 12:58:58 +0100 Subject: [PATCH 2/2] Convert warnings to hard errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Natalie Klestrup Röijezon --- kube-client/src/client/builder.rs | 73 ++++++++++++++----------------- kube-client/src/error.rs | 16 +++++++ 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/kube-client/src/client/builder.rs b/kube-client/src/client/builder.rs index 9948922f7..05ff85343 100644 --- a/kube-client/src/client/builder.rs +++ b/kube-client/src/client/builder.rs @@ -91,52 +91,47 @@ impl TryFrom for ClientBuilder { } } - const PROXY_SCHEME_SOCKS5: &str = "socks5"; - const PROXY_SCHEME_HTTP: &str = "http"; - match config.proxy_url.as_ref() { - #[cfg(feature = "socks5")] - Some(proxy_url) if proxy_url.scheme_str() == Some(PROXY_SCHEME_SOCKS5) => { - let connector = hyper_socks2::SocksConnector { - proxy_addr: proxy_url.clone(), - auth: None, - connector, - }; - - make_generic_builder(connector, config) - } - - #[cfg(feature = "http-proxy")] - Some(proxy_url) if proxy_url.scheme_str() == Some(PROXY_SCHEME_HTTP) => { - let proxy = hyper_http_proxy::Proxy::new(hyper_http_proxy::Intercept::All, proxy_url.clone()); - let connector = hyper_http_proxy::ProxyConnector::from_proxy_unsecured(connector, proxy); + Some(proxy_url) if proxy_url.scheme_str() == Some("socks5") => { + #[cfg(feature = "socks5")] + { + let connector = hyper_socks2::SocksConnector { + proxy_addr: proxy_url.clone(), + auth: None, + connector, + }; + make_generic_builder(connector, config) + } - make_generic_builder(connector, config) + #[cfg(not(feature = "socks5"))] + Err(Error::ProxyProtocolDisabled { + proxy_url: proxy_url.clone(), + protocol_feature: "kube/socks5", + }) } - proxy_url => { - if let Some(proxy_url) = proxy_url { - let missing_proxy_feature = match proxy_url.scheme_str() { - Some(PROXY_SCHEME_SOCKS5) => Some("kube/socks5"), - Some(PROXY_SCHEME_HTTP) => Some("kube/http-proxy"), - _ => None, - }; - if let Some(missing_proxy_feature) = missing_proxy_feature { - tracing::warn!( - ?proxy_url, - missing_proxy_feature, - "proxy URL is set but kube was built without support for that protocol, ignoring..." - ); - } else { - tracing::warn!( - ?proxy_url, - "proxy URL is set but kube does not support that protocol, ignoring..." - ); - } + Some(proxy_url) if proxy_url.scheme_str() == Some("http") => { + #[cfg(feature = "http-proxy")] + { + let proxy = + hyper_http_proxy::Proxy::new(hyper_http_proxy::Intercept::All, proxy_url.clone()); + let connector = hyper_http_proxy::ProxyConnector::from_proxy_unsecured(connector, proxy); + + make_generic_builder(connector, config) } - make_generic_builder(connector, config) + #[cfg(not(feature = "http-proxy"))] + Err(Error::ProxyProtocolDisabled { + proxy_url: proxy_url.clone(), + protocol_feature: "kube/http-proxy", + }) } + + Some(proxy_url) => Err(Error::ProxyProtocolUnsupported { + proxy_url: proxy_url.clone(), + }), + + None => make_generic_builder(connector, config), } } } diff --git a/kube-client/src/error.rs b/kube-client/src/error.rs index 23bd2a6a9..28296c6c5 100644 --- a/kube-client/src/error.rs +++ b/kube-client/src/error.rs @@ -1,4 +1,5 @@ //! Error handling and error types +use http::Uri; use thiserror::Error; pub use kube_core::ErrorResponse; @@ -25,6 +26,21 @@ pub enum Error { #[error("ServiceError: {0}")] Service(#[source] tower::BoxError), + /// Returned when the configured proxy uses an unsupported protocol. + #[error("configured proxy {proxy_url:?} uses an unsupported protocol")] + ProxyProtocolUnsupported { + /// The URL of the proxy. + proxy_url: Uri, + }, + /// Returned when the configured proxy uses a protocol that requires a Cargo feature that is currently disabled + #[error("configured proxy {proxy_url:?} requires the disabled feature {protocol_feature:?}")] + ProxyProtocolDisabled { + /// The URL of the proxy. + proxy_url: Uri, + /// The Cargo feature that the proxy protocol requires. + protocol_feature: &'static str, + }, + /// UTF-8 Error #[error("UTF-8 Error: {0}")] FromUtf8(#[source] std::string::FromUtf8Error),