Skip to content

Commit

Permalink
Merge branch 'main' into hyper-1.0-upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
clux authored Jan 21, 2024
2 parents bbaecf4 + 73af88d commit 10a67e8
Show file tree
Hide file tree
Showing 30 changed files with 436 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM docker.io/rust:1.65.0-bullseye
FROM docker.io/rust:1.70.0-bullseye

ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && apt upgrade -y
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ jobs:
fail-fast: false
matrix:
# Run these tests against older clusters as well
k8s: [v1.23, latest]
k8s: [v1.24, latest]
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
Expand Down Expand Up @@ -216,7 +216,7 @@ jobs:

- uses: nolar/setup-k3d-k3s@v1
with:
version: v1.23
version: v1.24
# k3d-kube
k3d-name: kube
# Used to avoid rate limits when fetching the releases from k3s repo.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
cluster-name: "test-cluster-1"
args: >-
--agents 1
--image docker.io/rancher/k3s:v1.23.4-k3s1
--image docker.io/rancher/k3s:v1.24.4-k3s1
--k3s-arg "--no-deploy=traefik,servicelb,metrics-server@server:*"
- name: Run cargo-tarpaulin
uses: actions-rs/[email protected]
Expand Down
35 changes: 31 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,42 @@
<!-- next-header -->
UNRELEASED
===================
* see https://github.com/kube-rs/kube/compare/0.87.1...main
* see https://github.com/kube-rs/kube/compare/0.88.0...main

[0.88.0](https://github.com/kube-rs/kube/releases/tag/0.88.0) / 2024-01-21
===================
<!-- Release notes generated using configuration in .github/release.yml at 0.88.0 -->

## Kubernetes `v1_29` support via `k8s-openapi` [0.21](https://github.com/Arnavion/k8s-openapi/releases/tag/v0.21.0)
Please [upgrade k8s-openapi along with kube](https://kube.rs/upgrading/) to avoid conflicts.

## What's Changed
### Added
* Add type meta data for list types by @Danil-Grigorev in https://github.com/kube-rs/kube/pull/1380
### Changed
* Bump MSRV to 1.70 by @clux in https://github.com/kube-rs/kube/pull/1384
* Upgrade `k8s-openapi` for Kubernetes `v1_29` support by @clux in https://github.com/kube-rs/kube/pull/1394

[0.87.2](https://github.com/kube-rs/kube/releases/tag/0.87.2) / 2023-12-22
===================
<!-- Release notes generated using configuration in .github/release.yml at 0.87.2 -->

## What's Changed
### Added
* Add support for `LogParams::since_time` by @clux in https://github.com/kube-rs/kube/pull/1342
* Provide cluster info to exec plugins by @aviramha in https://github.com/kube-rs/kube/pull/1331
* Allow setting a description on a derived CRD by @sbernauer in https://github.com/kube-rs/kube/pull/1359
### Changed
* Bump MSRV from 1.64 to 1.65 by @clux in https://github.com/kube-rs/kube/pull/1353
* Switch from `jsonpath_lib` to `jsonpath-rust` by @ilya-bobyr in https://github.com/kube-rs/kube/pull/1345

[0.87.1](https://github.com/kube-rs/kube/releases/tag/0.87.1) / 2023-11-01
===================
<!-- Release notes generated using configuration in .github/release.yml at 0.87.1 -->
## Headlines
- fixed a `Controller` issue with reconciliation requests disappearing when using `concurrency` #1324
- improved `Client` with better exec auth behaviour #1320, timeout control #1314, and socks5 proxy handling #1311
- small changes to an unstable streams feature #1304, and a a derive property that is now illegal with `syn` 2 #1307
- fixed a `Controller` issue with reconciliation requests disappearing when using `concurrency` [#1324](https://github.com/kube-rs/kube/issues/1324)
- improved `Client` with better exec auth behaviour [#1320](https://github.com/kube-rs/kube/issues/1320), timeout control [#1314](https://github.com/kube-rs/kube/issues/1314), and socks5 proxy handling [#1311](https://github.com/kube-rs/kube/issues/1311)
- small changes to an unstable streams feature [#1304](https://github.com/kube-rs/kube/issues/1304), and a a derive property that is now illegal with `syn` 2 [#1307](https://github.com/kube-rs/kube/issues/1307)

Big thanks to everyone involved 🎃

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# kube-rs

[![Crates.io](https://img.shields.io/crates/v/kube.svg)](https://crates.io/crates/kube)
[![Rust 1.65](https://img.shields.io/badge/MSRV-1.65-dea584.svg)](https://github.com/rust-lang/rust/releases/tag/1.65.0)
[![Tested against Kubernetes v1_23 and above](https://img.shields.io/badge/MK8SV-v1_23-326ce5.svg)](https://kube.rs/kubernetes-version)
[![Rust 1.70](https://img.shields.io/badge/MSRV-1.70-dea584.svg)](https://github.com/rust-lang/rust/releases/tag/1.70.0)
[![Tested against Kubernetes v1_24 and above](https://img.shields.io/badge/MK8SV-v1_24-326ce5.svg)](https://kube.rs/kubernetes-version)
[![Best Practices](https://bestpractices.coreinfrastructure.org/projects/5413/badge)](https://bestpractices.coreinfrastructure.org/projects/5413)
[![Discord chat](https://img.shields.io/discord/500028886025895936.svg?logo=discord&style=plastic)](https://discord.gg/tokio)

Expand All @@ -16,8 +16,8 @@ Select a version of `kube` along with the generated [k8s-openapi](https://github

```toml
[dependencies]
kube = { version = "0.87.1", features = ["runtime", "derive"] }
k8s-openapi = { version = "0.20.0", features = ["latest"] }
kube = { version = "0.88.0", features = ["runtime", "derive"] }
k8s-openapi = { version = "0.21.0", features = ["latest"] }
```

[Features are available](https://github.com/kube-rs/kube/blob/main/kube/Cargo.toml#L18).
Expand Down Expand Up @@ -152,8 +152,8 @@ By default [rustls](https://github.com/ctz/rustls) is used for TLS, but `openssl

```toml
[dependencies]
kube = { version = "0.87.1", default-features = false, features = ["client", "openssl-tls"] }
k8s-openapi = { version = "0.20.0", features = ["latest"] }
kube = { version = "0.88.0", default-features = false, features = ["client", "openssl-tls"] }
k8s-openapi = { version = "0.21.0", features = ["latest"] }
```

This will pull in `openssl` and `hyper-openssl`. If `default-features` is left enabled, you will pull in two TLS stacks, and the default will remain as `rustls`.
Expand Down
6 changes: 3 additions & 3 deletions e2e/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ path = "boot.rs"

[features]
latest = ["k8s-openapi/latest"]
mk8sv = ["k8s-openapi/v1_23"]
mk8sv = ["k8s-openapi/v1_24"]
rustls = ["kube/rustls-tls"]
openssl = ["kube/openssl-tls"]

Expand All @@ -28,7 +28,7 @@ anyhow = "1.0.44"
tracing = "0.1.36"
tracing-subscriber = "0.3.3"
futures = "0.3.17"
kube = { path = "../kube", version = "^0.87.1", default-features = false, features = ["client", "runtime", "ws", "admission", "gzip"] }
k8s-openapi = { version = "0.20.0", default-features = false }
kube = { path = "../kube", version = "^0.88.0", default-features = false, features = ["client", "runtime", "ws", "admission", "gzip"] }
k8s-openapi = { version = "0.21.0", default-features = false }
serde_json = "1.0.68"
tokio = { version = "1.14.0", features = ["full"] }
10 changes: 5 additions & 5 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ latest = ["k8s-openapi/latest"]
[dev-dependencies]
tokio-util = "0.7.0"
assert-json-diff = "2.0.1"
garde = { version = "0.16.1", default-features = false, features = ["derive"] }
garde = { version = "0.17.0", default-features = false, features = ["derive"] }
anyhow = "1.0.44"
futures = "0.3.17"
jsonpath-rust = "0.3.4"
kube = { path = "../kube", version = "^0.87.1", default-features = false, features = ["admission"] }
kube-derive = { path = "../kube-derive", version = "^0.87.1", default-features = false } # only needed to opt out of schema
k8s-openapi = { version = "0.20.0", default-features = false }
jsonpath-rust = "0.4.0"
kube = { path = "../kube", version = "^0.88.0", default-features = false, features = ["admission"] }
kube-derive = { path = "../kube-derive", version = "^0.88.0", default-features = false } # only needed to opt out of schema
k8s-openapi = { version = "0.21.0", default-features = false }
serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.68"
serde_yaml = "0.9.19"
Expand Down
3 changes: 2 additions & 1 deletion examples/crd_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use serde::{Deserialize, Serialize};
plural = "fooz",
root = "FooCrd",
namespaced,
doc = "Custom resource representing a Foo",
status = "FooStatus",
derive = "PartialEq",
derive = "Default",
Expand Down Expand Up @@ -119,7 +120,7 @@ fn verify_crd() {
],
"schema": {
"openAPIV3Schema": {
"description": "Auto-generated derived type for MyFoo via `CustomResource`",
"description": "Custom resource representing a Foo",
"properties": {
"spec": {
"description": "Our spec for Foo\n\nA struct with our chosen Kind will be created for us, using the following kube attrs",
Expand Down
57 changes: 51 additions & 6 deletions examples/crd_derive_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ pub struct FooSpec {
#[serde(default)]
#[schemars(schema_with = "set_listable_schema")]
set_listable: Vec<u32>,
// Field with CEL validation
#[serde(default)]
#[schemars(schema_with = "cel_validations")]
cel_validated: Option<String>,
}

// https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy
fn set_listable_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
serde_json::from_value(serde_json::json!({
Expand All @@ -101,6 +104,18 @@ fn set_listable_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::sche
.unwrap()
}

// https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules
fn cel_validations(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
serde_json::from_value(serde_json::json!({
"type": "string",
"x-kubernetes-validations": [{
"rule": "self != 'illegal'",
"message": "string cannot be illegal"
}]
}))
.unwrap()
}

fn default_value() -> String {
"default_value".into()
}
Expand Down Expand Up @@ -144,6 +159,7 @@ async fn main() -> Result<()> {
// Empty listables to be patched in later
default_listable: Default::default(),
set_listable: Default::default(),
cel_validated: Default::default(),
});

// Set up dynamic resource to test using raw values.
Expand Down Expand Up @@ -190,10 +206,8 @@ async fn main() -> Result<()> {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert_eq!(
err.message,
"Foo.clux.dev \"qux\" is invalid: spec.non_nullable: Required value"
);
assert!(err.message.contains("clux.dev \"qux\" is invalid"));
assert!(err.message.contains("spec.non_nullable: Required value"));
}
_ => panic!(),
}
Expand All @@ -213,8 +227,39 @@ async fn main() -> Result<()> {
assert_eq!(pres.spec.set_listable, vec![2, 3]);
println!("{:?}", serde_json::to_value(pres.spec));

delete_crd(client.clone()).await?;
// cel validation triggers:
let cel_patch = serde_json::json!({
"apiVersion": "clux.dev/v1",
"kind": "Foo",
"spec": {
"cel_validated": Some("illegal")
}
});
let cel_res = foos.patch("baz", &ssapply, &Patch::Apply(cel_patch)).await;
assert!(cel_res.is_err());
match cel_res.err() {
Some(kube::Error::Api(err)) => {
assert_eq!(err.code, 422);
assert_eq!(err.reason, "Invalid");
assert_eq!(err.status, "Failure");
assert!(err.message.contains("Foo.clux.dev \"baz\" is invalid"));
assert!(err.message.contains("spec.cel_validated: Invalid value"));
assert!(err.message.contains("string cannot be illegal"));
}
_ => panic!(),
}
// cel validation happy:
let cel_patch_ok = serde_json::json!({
"apiVersion": "clux.dev/v1",
"kind": "Foo",
"spec": {
"cel_validated": Some("legal")
}
});
foos.patch("baz", &ssapply, &Patch::Apply(cel_patch_ok)).await?;

// all done
delete_crd(client.clone()).await?;
Ok(())
}

Expand Down
12 changes: 6 additions & 6 deletions kube-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "kube-client"
version = "0.87.1"
version = "0.88.0"
description = "Kubernetes client"
authors = [
"clux <[email protected]>",
Expand All @@ -12,7 +12,7 @@ repository = "https://github.com/kube-rs/kube"
readme = "../README.md"
keywords = ["kubernetes", "client",]
categories = ["web-programming::http-client", "configuration", "network-programming", "api-bindings"]
rust-version = "1.65.0"
rust-version = "1.70.0"
edition = "2021"

[features]
Expand Down Expand Up @@ -55,8 +55,8 @@ rustls = { version = "0.21.4", features = ["dangerous_configuration"], optional
rustls-pemfile = { version = "1.0.0", optional = true }
bytes = { version = "1.1.0", optional = true }
tokio = { version = "1.14.0", features = ["time", "signal", "sync"], optional = true }
kube-core = { path = "../kube-core", version = "=0.87.1" }
jsonpath-rust = { version = "0.3.4", optional = true }
kube-core = { path = "../kube-core", version = "=0.88.0" }
jsonpath-rust = { version = "0.4.0", optional = true }
tokio-util = { version = "0.7.0", optional = true, features = ["io", "codec"] }
hyper = { version = "1.0.1", optional = true, features = ["client", "http1"] }
hyper-rustls = { version = "0.24.0", optional = true }
Expand All @@ -77,7 +77,7 @@ hyper-openssl = { version = "0.10.1", optional = true }
form_urlencoded = { version = "1.2.0", optional = true }

[dependencies.k8s-openapi]
version = "0.20.0"
version = "0.21.0"
default-features = false
features = []

Expand All @@ -90,6 +90,6 @@ tokio-test = "0.4.0"
tower-test = "0.4.0"

[dev-dependencies.k8s-openapi]
version = "0.20.0"
version = "0.21.0"
default-features = false
features = ["latest"]
10 changes: 10 additions & 0 deletions kube-client/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ impl<K: Resource> Api<K> {
/// Cluster level resources, or resources viewed across all namespaces
///
/// This function accepts `K::DynamicType` so it can be used with dynamic resources.
///
/// # Warning
///
/// This variant **can only `list` and `watch` namespaced resources** and is commonly used with a `watcher`.
/// If you need to create/patch/replace/get on a namespaced resource, you need a separate `Api::namespaced`.
pub fn all_with(client: Client, dyntype: &K::DynamicType) -> Self {
let url = K::url_path(dyntype, None);
Self {
Expand Down Expand Up @@ -149,6 +154,11 @@ where
/// use k8s_openapi::api::core::v1::Node;
/// let api: Api<Node> = Api::all(client);
/// ```
///
/// # Warning
///
/// This variant **can only `list` and `watch` namespaced resources** and is commonly used with a `watcher`.
/// If you need to create/patch/replace/get on a namespaced resource, you need a separate `Api::namespaced`.
pub fn all(client: Client) -> Self {
Self::all_with(client, &K::DynamicType::default())
}
Expand Down
22 changes: 18 additions & 4 deletions kube-client/src/client/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use thiserror::Error;
use tokio::sync::{Mutex, RwLock};
use tower::{filter::AsyncPredicate, BoxError};

use crate::config::{AuthInfo, AuthProviderConfig, ExecConfig, ExecInteractiveMode};
use crate::config::{AuthInfo, AuthProviderConfig, ExecAuthCluster, ExecConfig, ExecInteractiveMode};

#[cfg(feature = "oauth")] mod oauth;
#[cfg(feature = "oauth")] pub use oauth::Error as OAuthError;
Expand Down Expand Up @@ -98,6 +98,10 @@ pub enum Error {
#[cfg_attr(docsrs, doc(cfg(feature = "oidc")))]
#[error("failed OIDC: {0}")]
Oidc(#[source] oidc_errors::Error),

/// cluster spec missing while `provideClusterInfo` is true
#[error("Cluster spec must be populated when `provideClusterInfo` is true")]
ExecMissingClusterInfo,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -521,6 +525,9 @@ pub struct ExecCredential {
pub struct ExecCredentialSpec {
#[serde(skip_serializing_if = "Option::is_none")]
interactive: Option<bool>,

#[serde(skip_serializing_if = "Option::is_none")]
cluster: Option<ExecAuthCluster>,
}

/// ExecCredentialStatus holds credentials for the transport to use.
Expand Down Expand Up @@ -561,13 +568,20 @@ fn auth_exec(auth: &ExecConfig) -> Result<ExecCredential, Error> {
cmd.stdin(std::process::Stdio::piped());
}

let mut exec_credential_spec = ExecCredentialSpec {
interactive: Some(interactive),
cluster: None,
};

if auth.provide_cluster_info {
exec_credential_spec.cluster = Some(auth.cluster.clone().ok_or(Error::ExecMissingClusterInfo)?);
}

// Provide exec info to child process
let exec_info = serde_json::to_string(&ExecCredential {
api_version: auth.api_version.clone(),
kind: "ExecCredential".to_string().into(),
spec: Some(ExecCredentialSpec {
interactive: Some(interactive),
}),
spec: Some(exec_credential_spec),
status: None,
})
.map_err(Error::AuthExecSerialize)?;
Expand Down
Loading

0 comments on commit 10a67e8

Please sign in to comment.