Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove native-tls feature #1044

Merged
merged 1 commit into from Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -55,9 +55,6 @@ jobs:
run: cargo build -j4 -p kube-examples

# Feature tests
- name: Test kube with features native-tls,ws,oauth
run: cargo test -p kube --lib --no-default-features --features=native-tls,ws,oauth
if: matrix.os == 'ubuntu-latest'
- name: Test kube with features rustls-tls,ws,oauth
run: cargo test -p kube --lib --no-default-features --features=rustls-tls,ws,oauth
if: matrix.os == 'ubuntu-latest'
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_client_tls.rs
@@ -1,4 +1,4 @@
// Custom client supporting both native-tls and rustls-tls
// Custom client supporting both openssl-tls and rustls-tls
// Must enable `rustls-tls` feature to run this.
// Run with `USE_RUSTLS=1` to pick rustls.
use k8s_openapi::api::core::v1::Pod;
Expand Down
1 change: 0 additions & 1 deletion justfile
Expand Up @@ -21,7 +21,6 @@ test:
cargo test --doc --all
cargo test -p kube-examples --examples
cargo test -p kube --lib --no-default-features --features=rustls-tls,ws,oauth
cargo test -p kube --lib --no-default-features --features=native-tls,ws,oauth
cargo test -p kube --lib --no-default-features --features=openssl-tls,ws,oauth
cargo test -p kube --lib --no-default-features

Expand Down
5 changes: 1 addition & 4 deletions kube-client/Cargo.toml
Expand Up @@ -17,7 +17,6 @@ edition = "2021"

[features]
default = ["client", "openssl-tls"]
native-tls = ["openssl", "hyper-tls", "tokio-native-tls"]
rustls-tls = ["rustls", "rustls-pemfile", "hyper-rustls"]
openssl-tls = ["openssl", "hyper-openssl"]
ws = ["client", "tokio-tungstenite", "rand", "kube-core/ws"]
Expand All @@ -32,7 +31,7 @@ config = ["__non_core", "pem", "dirs"]
__non_core = ["tracing", "serde_yaml", "base64"]

[package.metadata.docs.rs]
features = ["client", "native-tls", "rustls-tls", "openssl-tls", "ws", "oauth", "jsonpatch", "admission", "k8s-openapi/v1_25"]
features = ["client", "rustls-tls", "openssl-tls", "ws", "oauth", "jsonpatch", "admission", "k8s-openapi/v1_25"]
# Define the configuration attribute `docsrs`. Used to enable `doc_cfg` feature.
rustdoc-args = ["--cfg", "docsrs"]

Expand All @@ -50,7 +49,6 @@ thiserror = "1.0.29"
futures = { version = "0.3.17", optional = true }
pem = { version = "1.0.1", optional = true }
openssl = { version = "0.10.36", optional = true }
tokio-native-tls = { version = "0.3.0", optional = true }
rustls = { version = "0.20.3", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "1.0.0", optional = true }
bytes = { version = "1.1.0", optional = true }
Expand All @@ -59,7 +57,6 @@ kube-core = { path = "../kube-core", version = "=0.75.0" }
jsonpath_lib = { version = "0.3.0", optional = true }
tokio-util = { version = "0.7.0", optional = true, features = ["io", "codec"] }
hyper = { version = "0.14.13", optional = true, features = ["client", "http1", "stream", "tcp"] }
hyper-tls = { version = "0.5.0", optional = true }
hyper-rustls = { version = "0.23.0", optional = true }
tokio-tungstenite = { version = "0.17.1", optional = true }
tower = { version = "0.4.6", optional = true, features = ["buffer", "filter", "util"] }
Expand Down
14 changes: 4 additions & 10 deletions kube-client/src/client/auth/oauth.rs
Expand Up @@ -103,23 +103,17 @@ impl Gcp {
Ok(TokenOrRequest::Request {
request, scope_hash, ..
}) => {
#[cfg(not(any(feature = "native-tls", feature = "rustls-tls", feature = "openssl-tls")))]
#[cfg(not(any(feature = "rustls-tls", feature = "openssl-tls")))]
compile_error!(
"At least one of native-tls or rustls-tls or openssl-tls feature must be enabled to use oauth feature"
"At least one of rustls-tls or openssl-tls feature must be enabled to use oauth feature"
);
// Current TLS feature precedence when more than one are set:
// 1. openssl-tls
// 2. native-tls
// 3. rustls-tls
// 2. rustls-tls
#[cfg(feature = "openssl-tls")]
let https =
hyper_openssl::HttpsConnector::new().map_err(Error::CreateOpensslHttpsConnector)?;
#[cfg(all(not(feature = "openssl-tls"), feature = "native-tls"))]
let https = hyper_tls::HttpsConnector::new();
#[cfg(all(
not(any(feature = "openssl-tls", feature = "native-tls")),
feature = "rustls-tls"
))]
#[cfg(all(not(feature = "openssl-tls"), feature = "rustls-tls"))]
let https = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_only()
Expand Down
13 changes: 2 additions & 11 deletions kube-client/src/client/builder.rs
Expand Up @@ -79,21 +79,12 @@ impl TryFrom<Config> for ClientBuilder<BoxService<Request<hyper::Body>, Response

// Current TLS feature precedence when more than one are set:
// 1. openssl-tls
// 2. native-tls
// 3. rustls-tls
// 2. rustls-tls
// Create a custom client to use something else.
// If TLS features are not enabled, http connector will be used.
#[cfg(feature = "openssl-tls")]
let connector = config.openssl_https_connector_with_connector(connector)?;
#[cfg(all(not(feature = "openssl-tls"), feature = "native-tls"))]
let connector = hyper_tls::HttpsConnector::from((
connector,
tokio_native_tls::TlsConnector::from(config.native_tls_connector()?),
));
#[cfg(all(
not(any(feature = "openssl-tls", feature = "native-tls")),
feature = "rustls-tls"
))]
#[cfg(all(not(feature = "openssl-tls"), feature = "rustls-tls"))]
let connector = hyper_rustls::HttpsConnector::from((
connector,
std::sync::Arc::new(config.rustls_client_config()?),
Expand Down
61 changes: 1 addition & 60 deletions kube-client/src/client/config_ext.rs
Expand Up @@ -4,8 +4,7 @@ use http::{header::HeaderName, HeaderValue};
use secrecy::ExposeSecret;
use tower::{filter::AsyncFilterLayer, util::Either};

#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "openssl-tls"))]
use super::tls;
#[cfg(any(feature = "rustls-tls", feature = "openssl-tls"))] use super::tls;
use super::{
auth::Auth,
middleware::{AddAuthorizationLayer, AuthLayer, BaseUriLayer, ExtraHeadersLayer},
Expand All @@ -27,23 +26,6 @@ pub trait ConfigExt: private::Sealed {
/// Layer to add non-authn HTTP headers depending on the config.
fn extra_headers_layer(&self) -> Result<ExtraHeadersLayer>;

/// Create [`hyper_tls::HttpsConnector`] based on config.
///
/// # Example
///
/// ```rust
/// # async fn doc() -> Result<(), Box<dyn std::error::Error>> {
/// # use kube::{client::ConfigExt, Config};
/// let config = Config::infer().await?;
/// let https = config.native_tls_https_connector()?;
/// let hyper_client: hyper::Client<_, hyper::Body> = 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<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>;

/// Create [`hyper_rustls::HttpsConnector`] based on config.
///
/// # Example
Expand All @@ -61,29 +43,6 @@ pub trait ConfigExt: private::Sealed {
#[cfg(feature = "rustls-tls")]
fn rustls_https_connector(&self) -> Result<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>;

/// Create [`native_tls::TlsConnector`](tokio_native_tls::native_tls::TlsConnector) based on config.
/// # Example
///
/// ```rust
/// # async fn doc() -> Result<(), Box<dyn std::error::Error>> {
/// # 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<tokio_native_tls::native_tls::TlsConnector>;

/// Create [`rustls::ClientConfig`] based on config.
/// # Example
///
Expand Down Expand Up @@ -213,24 +172,6 @@ impl ConfigExt for Config {
})
}

#[cfg(feature = "native-tls")]
fn native_tls_connector(&self) -> Result<tokio_native_tls::native_tls::TlsConnector> {
tls::native_tls::native_tls_connector(
self.identity_pem().as_ref(),
self.root_cert.as_ref(),
self.accept_invalid_certs,
)
.map_err(Error::NativeTls)
}

#[cfg(feature = "native-tls")]
fn native_tls_https_connector(&self) -> Result<hyper_tls::HttpsConnector<hyper::client::HttpConnector>> {
let tls = tokio_native_tls::TlsConnector::from(self.native_tls_connector()?);
let mut http = hyper::client::HttpConnector::new();
http.enforce_http(false);
Ok(hyper_tls::HttpsConnector::from((http, tls)))
}

#[cfg(feature = "rustls-tls")]
fn rustls_client_config(&self) -> Result<rustls::ClientConfig> {
tls::rustls_tls::rustls_client_config(
Expand Down
4 changes: 1 addition & 3 deletions kube-client/src/client/mod.rs
Expand Up @@ -36,10 +36,8 @@ mod config_ext;
pub use auth::Error as AuthError;
pub use config_ext::ConfigExt;
pub mod middleware;
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "openssl-tls"))]
mod tls;
#[cfg(any(feature = "rustls-tls", feature = "openssl-tls"))] mod tls;

#[cfg(feature = "native-tls")] pub use tls::native_tls::Error as NativeTlsError;
#[cfg(feature = "openssl-tls")]
pub use tls::openssl_tls::Error as OpensslTlsError;
#[cfg(feature = "rustls-tls")] pub use tls::rustls_tls::Error as RustlsTlsError;
Expand Down
80 changes: 0 additions & 80 deletions kube-client/src/client/tls.rs
@@ -1,83 +1,3 @@
#[cfg(feature = "native-tls")]
pub mod native_tls {
use thiserror::Error;
use tokio_native_tls::native_tls::{Certificate, Identity, TlsConnector};

const IDENTITY_PASSWORD: &str = " ";

/// Errors from native TLS
#[derive(Debug, Error)]
pub enum Error {
/// Failed to deserialize PEM-encoded X509 certificate
#[error("failed to deserialize PEM-encoded X509 certificate: {0}")]
DeserializeCertificate(#[source] openssl::error::ErrorStack),

/// Failed to deserialize PEM-encoded private key
#[error("failed to deserialize PEM-encoded private key: {0}")]
DeserializePrivateKey(#[source] openssl::error::ErrorStack),

/// Failed to create PKCS #12 archive
#[error("failed to create PKCS #12 archive: {0}")]
CreatePkcs12(#[source] openssl::error::ErrorStack),

/// Failed to serialize PKCS #12 archive to DER
#[error("failed to serialize PKCS #12 archive to DER encoding: {0}")]
SerializePkcs12(#[source] openssl::error::ErrorStack),

/// Failed to deserialize DER-encoded PKCS #12 archive
#[error("failed to deserialize DER-encoded PKCS #12 archive: {0}")]
DeserializePkcs12(#[source] tokio_native_tls::native_tls::Error),

/// Failed to deserialize DER-encoded X509 certificate
#[error("failed to deserialize DER-encoded X509 certificate: {0}")]
DeserializeRootCertificate(#[source] tokio_native_tls::native_tls::Error),

/// Failed to create `TlsConnector`
#[error("failed to create `TlsConnector`: {0}")]
CreateTlsConnector(#[source] tokio_native_tls::native_tls::Error),
}

/// Create `native_tls::TlsConnector`.
pub fn native_tls_connector(
identity_pem: Option<&Vec<u8>>,
root_cert: Option<&Vec<Vec<u8>>>,
accept_invalid: bool,
) -> Result<TlsConnector, Error> {
let mut builder = TlsConnector::builder();
if let Some(pem) = identity_pem {
let identity = pkcs12_from_pem(pem, IDENTITY_PASSWORD)?;
builder.identity(
Identity::from_pkcs12(&identity, IDENTITY_PASSWORD).map_err(Error::DeserializePkcs12)?,
);
}

if let Some(ders) = root_cert {
for der in ders {
builder.add_root_certificate(
Certificate::from_der(der).map_err(Error::DeserializeRootCertificate)?,
);
}
}

if accept_invalid {
builder.danger_accept_invalid_certs(true);
}

builder.build().map_err(Error::CreateTlsConnector)
}

// TODO Switch to PKCS8 support when https://github.com/sfackler/rust-native-tls/pull/209 is merged
fn pkcs12_from_pem(pem: &[u8], password: &str) -> Result<Vec<u8>, Error> {
use openssl::{pkcs12::Pkcs12, pkey::PKey, x509::X509};
let x509 = X509::from_pem(pem).map_err(Error::DeserializeCertificate)?;
let pkey = PKey::private_key_from_pem(pem).map_err(Error::DeserializePrivateKey)?;
let p12 = Pkcs12::builder()
.build(password, "kubeconfig", &pkey, &x509)
.map_err(Error::CreatePkcs12)?;
p12.to_der().map_err(Error::SerializePkcs12)
}
}

#[cfg(feature = "rustls-tls")]
pub mod rustls_tls {
use hyper_rustls::ConfigBuilderExt;
Expand Down
21 changes: 1 addition & 20 deletions kube-client/src/config/mod.rs
Expand Up @@ -308,13 +308,10 @@ impl Config {
.clone()
.unwrap_or_else(|| String::from("default"));

let mut accept_invalid_certs = loader.cluster.insecure_skip_tls_verify.unwrap_or(false);
let accept_invalid_certs = loader.cluster.insecure_skip_tls_verify.unwrap_or(false);
let mut root_cert = None;

if let Some(ca_bundle) = loader.ca_bundle()? {
for ca in &ca_bundle {
accept_invalid_certs = hacky_cert_lifetime_for_macos(ca);
}
root_cert = Some(ca_bundle);
}

Expand Down Expand Up @@ -396,22 +393,6 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(295);
const DEFAULT_CONNECT_TIMEOUT: Duration = Duration::from_secs(30);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(295);

// temporary catalina hack for openssl only
#[cfg(all(target_os = "macos", feature = "native-tls"))]
fn hacky_cert_lifetime_for_macos(ca: &[u8]) -> bool {
use openssl::x509::X509;
let ca = X509::from_der(ca).expect("valid der is a der");
ca.not_before()
.diff(ca.not_after())
.map(|d| d.days.abs() > 824)
.unwrap_or(false)
}

#[cfg(any(not(target_os = "macos"), not(feature = "native-tls")))]
fn hacky_cert_lifetime_for_macos(_: &[u8]) -> bool {
false
}

// Expose raw config structs
pub use file_config::{
AuthInfo, AuthProviderConfig, Cluster, Context, ExecConfig, Kubeconfig, NamedAuthInfo, NamedCluster,
Expand Down
6 changes: 0 additions & 6 deletions kube-client/src/error.rs
Expand Up @@ -59,12 +59,6 @@ pub enum Error {
#[error("Error from discovery: {0}")]
Discovery(#[source] DiscoveryError),

/// Errors from Native TLS
#[cfg(feature = "native-tls")]
#[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))]
#[error("native tls error: {0}")]
NativeTls(#[source] crate::client::NativeTlsError),

/// Errors from OpenSSL TLS
#[cfg(feature = "openssl-tls")]
#[cfg_attr(docsrs, doc(cfg(feature = "openssl-tls")))]
Expand Down
15 changes: 0 additions & 15 deletions kube-client/src/lib.rs
Expand Up @@ -163,21 +163,6 @@ mod test {
Ok(())
}

#[tokio::test]
#[ignore] // needs cluster (lists pods)
#[cfg(all(feature = "native-tls"))]
async fn custom_client_native_tls_configuration() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::infer().await?;
let https = config.native_tls_https_connector()?;
let service = ServiceBuilder::new()
.layer(config.base_uri_layer())
.service(hyper::Client::builder().build(https));
let client = Client::new(service, config.default_namespace);
let pods: Api<Pod> = Api::default_namespaced(client);
pods.list(&Default::default()).await?;
Ok(())
}

#[tokio::test]
#[ignore] // needs cluster (lists pods)
#[cfg(all(feature = "openssl-tls"))]
Expand Down
3 changes: 1 addition & 2 deletions kube/Cargo.toml
Expand Up @@ -17,7 +17,6 @@ edition = "2021"

[features]
default = ["client", "openssl-tls"]
native-tls = ["kube-client/native-tls"]
rustls-tls = ["kube-client/rustls-tls"]
openssl-tls = ["kube-client/openssl-tls"]
ws = ["kube-client/ws", "kube-core/ws"]
Expand All @@ -31,7 +30,7 @@ config = ["kube-client/config"]
runtime = ["kube-runtime"]

[package.metadata.docs.rs]
features = ["client", "native-tls", "rustls-tls", "openssl-tls", "derive", "ws", "oauth", "jsonpatch", "admission", "runtime", "k8s-openapi/v1_25"]
features = ["client", "rustls-tls", "openssl-tls", "derive", "ws", "oauth", "jsonpatch", "admission", "runtime", "k8s-openapi/v1_25"]
# Define the configuration attribute `docsrs`. Used to enable `doc_cfg` feature.
rustdoc-args = ["--cfg", "docsrs"]

Expand Down