From bb115c99c10cb115047dbee324f3ee13f56f6aa7 Mon Sep 17 00:00:00 2001 From: kazk Date: Fri, 4 Jun 2021 22:54:24 -0700 Subject: [PATCH] Document custom client --- kube/Cargo.toml | 2 +- kube/src/client/config_ext.rs | 82 ++++++++++++++++++++++++++++++----- kube/src/client/mod.rs | 31 +++++++++++-- 3 files changed, 100 insertions(+), 15 deletions(-) diff --git a/kube/Cargo.toml b/kube/Cargo.toml index fede18b1c..c0d101bc0 100644 --- a/kube/Cargo.toml +++ b/kube/Cargo.toml @@ -32,7 +32,7 @@ config = ["__non_core", "pem", "dirs"] __non_core = ["tracing", "serde_yaml", "base64"] [package.metadata.docs.rs] -features = ["derive", "ws", "oauth", "jsonpatch", "admission"] +features = ["client", "native-tls", "rustls-tls", "derive", "ws", "oauth", "jsonpatch", "admission"] # Define the configuration attribute `docsrs`. Used to enable `doc_cfg` feature. rustdoc-args = ["--cfg", "docsrs"] diff --git a/kube/src/client/config_ext.rs b/kube/src/client/config_ext.rs index 9c5d6f48f..6cd546c81 100644 --- a/kube/src/client/config_ext.rs +++ b/kube/src/client/config_ext.rs @@ -9,7 +9,9 @@ use super::{ }; use crate::{Config, Result}; -/// Extensions to `Config` for `Client`. +/// Extensions to [`Config`](crate::Config) for custom [`Client`](crate::Client). +/// +/// See [`Client::new`](crate::Client::new) for an example. /// /// This trait is sealed and cannot be implemented. pub trait ConfigExt: private::Sealed { @@ -19,25 +21,83 @@ pub trait ConfigExt: private::Sealed { /// 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")] - fn native_tls_connector(&self) -> Result; - - /// Create `hyper_tls::HttpsConnector` + /// Create [`hyper_tls::HttpsConnector`] based on config. + /// + /// # Example + /// + /// ```rust + /// # async fn doc() -> Result<(), Box> { + /// # use kube::{client::ConfigExt, Config}; + /// let config = Config::infer().await?; + /// let https = config.native_tls_https_connector()?; + /// let hyper_client = hyper::Client::builder().build(https); + /// # Ok(()) + /// # } + /// ``` #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] #[cfg(feature = "native-tls")] fn native_tls_https_connector(&self) -> Result>; - /// Create `rustls::ClientConfig` + /// Create [`hyper_rustls::HttpsConnector`] based on config. + /// + /// # Example + /// + /// ```rust + /// # async fn doc() -> Result<(), Box> { + /// # use kube::{client::ConfigExt, Config}; + /// let config = Config::infer().await?; + /// let https = config.rustls_https_connector()?; + /// let hyper_client = hyper::Client::builder().build(https); + /// # Ok(()) + /// # } + /// ``` #[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))] #[cfg(feature = "rustls-tls")] - fn rustls_client_config(&self) -> Result; + fn rustls_https_connector(&self) -> Result>; - /// Create `hyper_rustls::HttpsConnector` + /// Create [`native_tls::TlsConnector`](tokio_native_tls::native_tls::TlsConnector) based on config. + /// # Example + /// + /// ```rust + /// # async fn doc() -> Result<(), Box> { + /// # use hyper::client::HttpConnector; + /// # use kube::{client::ConfigExt, Client, Config}; + /// let config = Config::infer().await?; + /// let https = { + /// let tls = tokio_native_tls::TlsConnector::from( + /// config.native_tls_connector()? + /// ); + /// let mut http = HttpConnector::new(); + /// http.enforce_http(false); + /// hyper_tls::HttpsConnector::from((http, tls)) + /// }; + /// # Ok(()) + /// # } + /// ``` + #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] + #[cfg(feature = "native-tls")] + fn native_tls_connector(&self) -> Result; + + /// Create [`rustls::ClientConfig`] based on config. + /// # Example + /// + /// ```rust + /// # async fn doc() -> Result<(), Box> { + /// # use hyper::client::HttpConnector; + /// # use kube::{client::ConfigExt, Config}; + /// let config = Config::infer().await?; + /// let https = { + /// let rustls_config = std::sync::Arc::new(config.rustls_client_config()?); + /// let mut http = HttpConnector::new(); + /// http.enforce_http(false); + /// hyper_rustls::HttpsConnector::from((http, rustls_config)) + /// }; + /// # Ok(()) + /// # } + /// ``` #[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))] #[cfg(feature = "rustls-tls")] - fn rustls_https_connector(&self) -> Result>; + fn rustls_client_config(&self) -> Result; } mod private { diff --git a/kube/src/client/mod.rs b/kube/src/client/mod.rs index af03b56b9..fcd754b72 100644 --- a/kube/src/client/mod.rs +++ b/kube/src/client/mod.rs @@ -48,7 +48,7 @@ const WS_PROTOCOL: &str = "v4.channel.k8s.io"; /// Client for connecting with a Kubernetes cluster. /// -/// The best way to instantiate the client is either by +/// The easiest way to instantiate the client is either by /// inferring the configuration from the environment using /// [`Client::try_default`] or with an existing [`Config`] /// using [`Client::try_from`]. @@ -61,9 +61,34 @@ pub struct Client { } impl Client { - /// Create and initialize a [`Client`] using the given `Service`. + /// Create a [`Client`] using a custom `Service` stack. /// - /// Use [`Client::try_from`](Self::try_from) to create with a [`Config`]. + /// [`ConfigExt`](crate::client::ConfigExt) provides extensions for + /// building a custom stack. + /// + /// To create with the default stack with a [`Config`], use + /// [`Client::try_from`]. + /// + /// To create with the default stack with an inferred [`Config`], use + /// [`Client::try_default`]. + /// + /// # Example + /// + /// ```rust + /// # async fn doc() -> Result<(), Box> { + /// use kube::{client::ConfigExt, Client, Config}; + /// use tower::ServiceBuilder; + /// + /// let config = Config::infer().await?; + /// let client = Client::new( + /// ServiceBuilder::new() + /// .layer(config.base_uri_layer()) + /// .option_layer(config.auth_layer()?) + /// .service(hyper::Client::new()), + /// ); + /// # Ok(()) + /// # } + /// ``` pub fn new(service: S) -> Self where S: Service, Response = Response> + Send + 'static,