diff --git a/examples/custom_client.rs b/examples/custom_client.rs index b035fa9d1..b464afb82 100644 --- a/examples/custom_client.rs +++ b/examples/custom_client.rs @@ -18,6 +18,7 @@ async fn main() -> anyhow::Result<()> { let client = Client::new( ServiceBuilder::new() .layer(config.base_uri_layer()) + .option_layer(config.auth_layer()?) .service(hyper::Client::builder().build(https)), ); diff --git a/kube/src/client/config_ext.rs b/kube/src/client/config_ext.rs index eac05bf7f..9c5d6f48f 100644 --- a/kube/src/client/config_ext.rs +++ b/kube/src/client/config_ext.rs @@ -5,7 +5,7 @@ use tower::util::Either; #[cfg(any(feature = "native-tls", feature = "rustls-tls"))] use super::tls; use super::{ auth::Auth, - middleware::{AddAuthorizationLayer, RefreshTokenLayer, SetBaseUriLayer}, + middleware::{AddAuthorizationLayer, AuthLayer, RefreshTokenLayer, SetBaseUriLayer}, }; use crate::{Config, Result}; @@ -16,6 +16,9 @@ pub trait ConfigExt: private::Sealed { /// Layer to set the base URI of requests to the configured server. fn base_uri_layer(&self) -> SetBaseUriLayer; + /// Optional layer to set up `Authorization` header depending on the config. + fn auth_layer(&self) -> Result>; + /// Create `native_tls::TlsConnector` #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] #[cfg(feature = "native-tls")] @@ -35,13 +38,6 @@ pub trait ConfigExt: private::Sealed { #[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))] #[cfg(feature = "rustls-tls")] fn rustls_https_connector(&self) -> Result>; - - // TODO Try reducing exported types to minimize API surface before making this public. - #[doc(hidden)] - /// Optional layer to set up `Authorization` header depending on the config. - /// - /// Users are not allowed to call this for now. - fn auth_layer(&self) -> Result>>; } mod private { @@ -54,6 +50,15 @@ impl ConfigExt for Config { SetBaseUriLayer::new(self.cluster_url.clone()) } + fn auth_layer(&self) -> Result> { + Ok(match Auth::try_from(&self.auth_info)? { + Auth::None => None, + Auth::Basic(user, pass) => Some(AuthLayer(Either::A(AddAuthorizationLayer::basic(&user, &pass)))), + Auth::Bearer(token) => Some(AuthLayer(Either::A(AddAuthorizationLayer::bearer(&token)))), + Auth::RefreshableToken(r) => Some(AuthLayer(Either::B(RefreshTokenLayer::new(r)))), + }) + } + #[cfg(feature = "native-tls")] fn native_tls_connector(&self) -> Result { tls::native_tls::native_tls_connector( @@ -87,13 +92,4 @@ impl ConfigExt for Config { http.enforce_http(false); Ok(hyper_rustls::HttpsConnector::from((http, rustls_config))) } - - fn auth_layer(&self) -> Result>> { - Ok(match Auth::try_from(&self.auth_info)? { - Auth::None => None, - Auth::Basic(user, pass) => Some(Either::A(AddAuthorizationLayer::basic(&user, &pass))), - Auth::Bearer(token) => Some(Either::A(AddAuthorizationLayer::bearer(&token))), - Auth::RefreshableToken(r) => Some(Either::B(RefreshTokenLayer::new(r))), - }) - } } diff --git a/kube/src/client/middleware/mod.rs b/kube/src/client/middleware/mod.rs index 1b88b16f5..dbcb02d16 100644 --- a/kube/src/client/middleware/mod.rs +++ b/kube/src/client/middleware/mod.rs @@ -1,4 +1,6 @@ //! Middleware types returned from `ConfigExt` methods. +use tower::{util::Either, Layer}; + mod add_authorization; mod base_uri; mod refresh_token; @@ -6,3 +8,14 @@ mod refresh_token; pub(crate) use add_authorization::AddAuthorizationLayer; pub use base_uri::{SetBaseUri, SetBaseUriLayer}; pub(crate) use refresh_token::RefreshTokenLayer; +/// Layer to set up `Authorization` header depending on the config. +pub struct AuthLayer(pub(crate) Either); + +impl Layer for AuthLayer { + type Service = + Either<>::Service, >::Service>; + + fn layer(&self, inner: S) -> Self::Service { + self.0.layer(inner) + } +}