From 1d36d8781607e852f68de9189387af1b977a90c3 Mon Sep 17 00:00:00 2001 From: clux Date: Thu, 12 Oct 2023 22:46:19 +0100 Subject: [PATCH 1/3] Create an `Api::dynamic` and `Api::cluster` and scope limit more Signed-off-by: clux --- kube-client/src/api/core_methods.rs | 2 +- kube-client/src/api/mod.rs | 118 +++++++++++++++++++++++--- kube-client/src/api/util/mod.rs | 4 +- kube-client/src/discovery/apigroup.rs | 6 +- kube-client/src/discovery/oneshot.rs | 6 +- kube-client/src/lib.rs | 2 +- 6 files changed, 114 insertions(+), 24 deletions(-) diff --git a/kube-client/src/api/core_methods.rs b/kube-client/src/api/core_methods.rs index db149890f..86ca1fec6 100644 --- a/kube-client/src/api/core_methods.rs +++ b/kube-client/src/api/core_methods.rs @@ -266,7 +266,7 @@ where /// # async fn wrapper() -> Result<(), Box> { /// # let client: kube::Client = todo!(); - /// let crds: Api = Api::all(client); + /// let crds: Api = Api::cluster(client); /// crds.delete("foos.clux.dev", &DeleteParams::default()).await? /// .map_left(|o| println!("Deleting CRD: {:?}", o.status)) /// .map_right(|s| println!("Deleted CRD: {:?}", s)); diff --git a/kube-client/src/api/mod.rs b/kube-client/src/api/mod.rs index 88342025b..a840fc97e 100644 --- a/kube-client/src/api/mod.rs +++ b/kube-client/src/api/mod.rs @@ -4,6 +4,7 @@ mod core_methods; #[cfg(feature = "ws")] mod remote_command; use std::fmt::Debug; +use k8s_openapi::ClusterResourceScope; #[cfg(feature = "ws")] pub use remote_command::{AttachedProcess, TerminalSize}; #[cfg(feature = "ws")] mod portforward; #[cfg(feature = "ws")] pub use portforward::Portforwarder; @@ -29,6 +30,7 @@ pub mod entry; pub use kube_core::admission; pub(crate) use kube_core::params; pub use kube_core::{ + discovery::Scope, dynamic::{ApiResource, DynamicObject}, gvk::{GroupVersionKind, GroupVersionResource}, metadata::{ListMeta, ObjectMeta, PartialObjectMeta, PartialObjectMetaExt, TypeMeta}, @@ -67,10 +69,51 @@ pub struct Api { /// /// This generally means resources created via [`DynamicObject`](crate::api::DynamicObject). impl Api { + /// Discovered scope in the default configuration + /// + /// This returns an `Api` scoped at the appropriate setting based on a [`discovery`](crate::discovery) result. + /// + /// ```no_run + /// # use kube::{Api, Client, discovery::{ApiResource, ApiCapabilities}, core::DynamicObject}; + /// # let client: Client = todo!(); + /// # let ar: ApiResource = todo!(); + /// # let caps: ApiCapabilities = todo!(); + /// let api: Api = Api::dynamic(client, &ar, caps.scope); + /// ``` + pub fn dynamic(client: Client, dyntype: &K::DynamicType, scope: Scope) -> Self + where + K: Resource, + { + match scope { + Scope::Cluster => Api::cluster_with(client, dyntype), + Scope::Namespaced => Api::default_namespaced_with(client, dyntype), + } + } + /// Cluster level resources, or resources viewed across all namespaces /// /// This function accepts `K::DynamicType` so it can be used with dynamic resources. - pub fn all_with(client: Client, dyntype: &K::DynamicType) -> Self { + pub fn all_with(client: Client, dyntype: &K::DynamicType) -> Self + where + K: Resource, + { + let url = K::url_path(dyntype, None); + Self { + client, + request: Request::new(url), + namespace: None, + _phantom: std::iter::empty(), + } + } + + /// Cluster level resources + /// + /// This function accepts `K::DynamicType` so it can be used with dynamic resources. + pub fn cluster_with(client: Client, dyntype: &K::DynamicType) -> Self + where + K: Resource, + { + // TODO: inspect dyntype scope to verify somehow? let url = K::url_path(dyntype, None); Self { client, @@ -130,27 +173,35 @@ impl Api where ::DynamicType: Default, { - /// Cluster level resources, or resources viewed across all namespaces - /// - /// Namespace scoped resource allowing querying across all namespaces: + /// Cluster scoped resource /// /// ```no_run /// # use kube::{Api, Client}; /// # let client: Client = todo!(); - /// use k8s_openapi::api::core::v1::Pod; - /// let api: Api = Api::all(client); + /// use k8s_openapi::api::core::v1::Node; + /// let api: Api = Api::cluster(client); /// ``` /// - /// Cluster scoped resources also use this entrypoint: + /// This will ONLY work on cluster level resources as set by `Scope`: /// - /// ```no_run + /// ```compile_fail /// # use kube::{Api, Client}; /// # let client: Client = todo!(); - /// use k8s_openapi::api::core::v1::Node; - /// let api: Api = Api::all(client); + /// use k8s_openapi::api::core::v1::Pod; + /// let api: Api = Api::cluster(client); // resource not cluster-level! /// ``` - pub fn all(client: Client) -> Self { - Self::all_with(client, &K::DynamicType::default()) + pub fn cluster(client: Client) -> Self + where + K: Resource, + { + let dyntype = K::DynamicType::default(); + let url = K::url_path(&dyntype, None); + Self { + client, + request: Request::new(url), + namespace: None, + _phantom: std::iter::empty(), + } } /// Namespaced resource within a given namespace @@ -214,6 +265,44 @@ where let ns = client.default_namespace().to_string(); Self::namespaced(client, &ns) } + + /// A list/watch only view into namespaced resources across all namespaces + /// + /// ```no_run + /// # use kube::{Api, Client}; + /// # let client: Client = todo!(); + /// use k8s_openapi::api::core::v1::Pod; + /// let api: Api = Api::all(client.clone()); + /// ``` + /// + /// This will ONLY work on namespaced resources as set by `Scope`: + /// + /// ```compile_fail + /// # use kube::{Api, Client}; + /// # let client: Client = todo!(); + /// use k8s_openapi::api::core::v1::Node; + /// let api: Api = Api::default_namespaced(client); // resource not namespaced! + /// ``` + /// + /// See [`Api::cluster`] for cluster level 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(client: Client) -> Self + where + K: Resource, + { + let dyntype = K::DynamicType::default(); + let url = K::url_path(&dyntype, None); + Self { + client, + request: Request::new(url), + namespace: None, + _phantom: std::iter::empty(), + } + } } impl From> for Client { @@ -254,9 +343,10 @@ mod test { let (mock_service, _handle) = mock::pair::, Response>(); let client = Client::new(mock_service, "default"); - let _: Api = Api::all(client.clone()); + let _: Api = Api::cluster(client.clone()); let _: Api = Api::default_namespaced(client.clone()); - let _: Api = Api::all(client.clone()); + let _: Api = Api::all(client.clone()); + let _: Api = Api::cluster(client.clone()); let _: Api = Api::namespaced(client, "default"); } } diff --git a/kube-client/src/api/util/mod.rs b/kube-client/src/api/util/mod.rs index 06923a0d6..043d3b8cd 100644 --- a/kube-client/src/api/util/mod.rs +++ b/kube-client/src/api/util/mod.rs @@ -86,7 +86,7 @@ mod test { }, }))?; - let nodes: Api = Api::all(client.clone()); + let nodes: Api = Api::cluster(client.clone()); nodes.create(&PostParams::default(), &fake_node).await?; let schedulables = ListParams::default().fields("spec.unschedulable==false"); @@ -114,7 +114,7 @@ mod test { let audiences = vec!["api".to_string()]; let serviceaccounts: Api = Api::namespaced(client.clone(), serviceaccount_namespace); - let tokenreviews: Api = Api::all(client); + let tokenreviews: Api = Api::cluster(client); // Create ServiceAccount let fake_sa = serde_json::from_value(json!({ diff --git a/kube-client/src/discovery/apigroup.rs b/kube-client/src/discovery/apigroup.rs index 42f2f1740..823ae250c 100644 --- a/kube-client/src/discovery/apigroup.rs +++ b/kube-client/src/discovery/apigroup.rs @@ -46,7 +46,7 @@ use std::{cmp::Reverse, collections::HashMap, iter::Iterator}; /// let client = Client::try_default().await?; /// let apigroup = discovery::group(&client, "apiregistration.k8s.io").await?; /// let (ar, caps) = apigroup.recommended_kind("APIService").unwrap(); -/// let api: Api = Api::all_with(client.clone(), &ar); +/// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for service in api.list(&Default::default()).await? { /// println!("Found APIService: {}", service.name_any()); /// } @@ -238,7 +238,7 @@ impl ApiGroup { /// if !caps.supports_operation(verbs::LIST) { /// continue; /// } - /// let api: Api = Api::all_with(client.clone(), &ar); + /// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for inst in api.list(&Default::default()).await? { /// println!("Found {}: {}", ar.kind, inst.name_any()); /// } @@ -267,7 +267,7 @@ impl ApiGroup { /// if !caps.supports_operation(verbs::LIST) { /// continue; /// } - /// let api: Api = Api::all_with(client.clone(), &ar); + /// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for inst in api.list(&Default::default()).await? { /// println!("Found {}: {}", ar.kind, inst.name_any()); /// } diff --git a/kube-client/src/discovery/oneshot.rs b/kube-client/src/discovery/oneshot.rs index 942f013fd..90f5489fb 100644 --- a/kube-client/src/discovery/oneshot.rs +++ b/kube-client/src/discovery/oneshot.rs @@ -30,7 +30,7 @@ use kube_core::{ /// let client = Client::try_default().await?; /// let apigroup = discovery::group(&client, "apiregistration.k8s.io").await?; /// let (ar, caps) = apigroup.recommended_kind("APIService").unwrap(); -/// let api: Api = Api::all_with(client.clone(), &ar); +/// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for service in api.list(&Default::default()).await? { /// println!("Found APIService: {}", service.name_any()); /// } @@ -67,7 +67,7 @@ pub async fn group(client: &Client, apigroup: &str) -> Result { /// let gv = "apiregistration.k8s.io/v1".parse()?; /// let apigroup = discovery::pinned_group(&client, &gv).await?; /// let (ar, caps) = apigroup.recommended_kind("APIService").unwrap(); -/// let api: Api = Api::all_with(client.clone(), &ar); +/// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for service in api.list(&Default::default()).await? { /// println!("Found APIService: {}", service.name_any()); /// } @@ -94,7 +94,7 @@ pub async fn pinned_group(client: &Client, gv: &GroupVersion) -> Result = Api::all_with(client.clone(), &ar); +/// let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); /// for service in api.list(&Default::default()).await? { /// println!("Found APIService: {}", service.name_any()); /// } diff --git a/kube-client/src/lib.rs b/kube-client/src/lib.rs index d662ff4fa..fc6a1a1aa 100644 --- a/kube-client/src/lib.rs +++ b/kube-client/src/lib.rs @@ -574,7 +574,7 @@ mod test { }))?; let client = Client::try_default().await?; - let csr: Api = Api::all(client.clone()); + let csr: Api = Api::cluster(client.clone()); assert!(csr.create(&PostParams::default(), &dummy_csr).await.is_ok()); // Patch the approval and approve the CSR From 50fda7154a3fe192c5b0d9164447e9192b858c24 Mon Sep 17 00:00:00 2001 From: clux Date: Thu, 12 Oct 2023 22:47:21 +0100 Subject: [PATCH 2/3] Fix build Signed-off-by: clux --- examples/crd_api.rs | 2 +- examples/crd_apply.rs | 2 +- examples/crd_derive_multi.rs | 4 ++-- examples/crd_derive_schema.rs | 4 ++-- examples/crd_reflector.rs | 2 +- examples/dynamic_api.rs | 8 ++------ examples/kubectl.rs | 17 +++++++++++------ examples/node_reflector.rs | 2 +- examples/node_watcher.rs | 2 +- kube-derive/src/lib.rs | 2 +- kube-runtime/src/controller/mod.rs | 6 +++--- kube-runtime/src/events.rs | 2 +- kube-runtime/src/reflector/mod.rs | 2 +- kube-runtime/src/wait.rs | 2 +- kube/src/lib.rs | 14 +++++--------- kube/src/mock_tests.rs | 2 +- 16 files changed, 35 insertions(+), 38 deletions(-) diff --git a/examples/crd_api.rs b/examples/crd_api.rs index cdb908bab..51c49f335 100644 --- a/examples/crd_api.rs +++ b/examples/crd_api.rs @@ -43,7 +43,7 @@ async fn main() -> Result<()> { let client = Client::try_default().await?; // Manage CRDs first - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); // Delete any old versions of it first: let dp = DeleteParams::default(); diff --git a/examples/crd_apply.rs b/examples/crd_apply.rs index eae7d49fe..801da08ea 100644 --- a/examples/crd_apply.rs +++ b/examples/crd_apply.rs @@ -40,7 +40,7 @@ async fn main() -> anyhow::Result<()> { // 0. Ensure the CRD is installed (you probably just want to do this on CI) // (crd file can be created by piping `Foo::crd`'s yaml ser to kubectl apply) - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); info!("Creating crd: {}", serde_yaml::to_string(&Foo::crd())?); crds.patch("foos.clux.dev", &ssapply, &Patch::Apply(Foo::crd())) .await?; diff --git a/examples/crd_derive_multi.rs b/examples/crd_derive_multi.rs index f96342cc0..23f0c3a5f 100644 --- a/examples/crd_derive_multi.rs +++ b/examples/crd_derive_multi.rs @@ -101,7 +101,7 @@ async fn main() -> anyhow::Result<()> { } async fn apply_crd(client: Client, crd: CustomResourceDefinition) -> anyhow::Result<()> { - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); info!("Creating crd: {}", serde_yaml::to_string(&crd)?); let ssapply = PatchParams::apply("crd_derive_multi").force(); crds.patch("manyderives.kube.rs", &ssapply, &Patch::Apply(&crd)) @@ -116,7 +116,7 @@ async fn apply_crd(client: Client, crd: CustomResourceDefinition) -> anyhow::Res } async fn cleanup(client: Client) -> anyhow::Result<()> { - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); let obj = crds.delete("manyderives.kube.rs", &Default::default()).await?; if let either::Either::Left(o) = obj { let uid = o.uid().unwrap(); diff --git a/examples/crd_derive_schema.rs b/examples/crd_derive_schema.rs index 25efb32ff..ada0e249d 100644 --- a/examples/crd_derive_schema.rs +++ b/examples/crd_derive_schema.rs @@ -220,7 +220,7 @@ async fn main() -> Result<()> { // Create CRD and wait for it to be ready. async fn create_crd(client: Client) -> Result { - let api = Api::::all(client); + let api = Api::::cluster(client); api.create(&PostParams::default(), &Foo::crd()).await?; // Wait until it's accepted and established by the api-server @@ -235,7 +235,7 @@ async fn create_crd(client: Client) -> Result { // Delete the CRD if it exists and wait until it's deleted. async fn delete_crd(client: Client) -> Result<()> { - let api = Api::::all(client); + let api = Api::::cluster(client); if api.get("foos.clux.dev").await.is_ok() { api.delete("foos.clux.dev", &DeleteParams::default()).await?; diff --git a/examples/crd_reflector.rs b/examples/crd_reflector.rs index f01fb9165..3bed887c1 100644 --- a/examples/crd_reflector.rs +++ b/examples/crd_reflector.rs @@ -25,7 +25,7 @@ async fn main() -> anyhow::Result<()> { // 0. Ensure the CRD is installed (you probably just want to do this on CI) // (crd file can be created by piping `Foo::crd`'s yaml ser to kubectl apply) - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); info!("Creating crd: {}", serde_yaml::to_string(&Foo::crd())?); let ssapply = PatchParams::apply("crd_reflector_example").force(); crds.patch("foos.clux.dev", &ssapply, &Patch::Apply(Foo::crd())) diff --git a/examples/dynamic_api.rs b/examples/dynamic_api.rs index 879417528..b5bf612ba 100644 --- a/examples/dynamic_api.rs +++ b/examples/dynamic_api.rs @@ -2,7 +2,7 @@ use kube::{ api::{Api, DynamicObject, ResourceExt}, - discovery::{verbs, Discovery, Scope}, + discovery::{verbs, Discovery}, Client, }; use tracing::*; @@ -18,11 +18,7 @@ async fn main() -> anyhow::Result<()> { if !caps.supports_operation(verbs::LIST) { continue; } - let api: Api = if caps.scope == Scope::Cluster { - Api::all_with(client.clone(), &ar) - } else { - Api::default_namespaced_with(client.clone(), &ar) - }; + let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); info!("{}/{} : {}", group.name(), ar.version, ar.kind); diff --git a/examples/kubectl.rs b/examples/kubectl.rs index 2dcb3aa60..d9a6c5320 100644 --- a/examples/kubectl.rs +++ b/examples/kubectl.rs @@ -228,12 +228,17 @@ fn dynamic_api( ns: Option<&str>, all: bool, ) -> Api { - if caps.scope == Scope::Cluster || all { - Api::all_with(client, &ar) - } else if let Some(namespace) = ns { - Api::namespaced_with(client, namespace, &ar) - } else { - Api::default_namespaced_with(client, &ar) + match caps.scope { + Scope::Cluster => Api::cluster_with(client, &ar), + Scope::Namespaced => { + if all { + Api::all_with(client, &ar) + } else if let Some(namespace) = ns { + Api::namespaced_with(client, namespace, &ar) + } else { + Api::default_namespaced_with(client, &ar) + } + } } } diff --git a/examples/node_reflector.rs b/examples/node_reflector.rs index 32339bdf3..1d81b7ec1 100644 --- a/examples/node_reflector.rs +++ b/examples/node_reflector.rs @@ -12,7 +12,7 @@ async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let client = Client::try_default().await?; - let nodes: Api = Api::all(client.clone()); + let nodes: Api = Api::cluster(client.clone()); let wc = watcher::Config::default() .labels("kubernetes.io/arch=amd64") // filter instances by label .timeout(10); // short watch timeout in this example diff --git a/examples/node_watcher.rs b/examples/node_watcher.rs index 1391abe11..474b57000 100644 --- a/examples/node_watcher.rs +++ b/examples/node_watcher.rs @@ -12,7 +12,7 @@ async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let client = Client::try_default().await?; let events: Api = Api::all(client.clone()); - let nodes: Api = Api::all(client.clone()); + let nodes: Api = Api::cluster(client.clone()); let use_watchlist = std::env::var("WATCHLIST").map(|s| s == "1").unwrap_or(false); let wc = if use_watchlist { diff --git a/kube-derive/src/lib.rs b/kube-derive/src/lib.rs index 7e296c3e1..5c4ee691f 100644 --- a/kube-derive/src/lib.rs +++ b/kube-derive/src/lib.rs @@ -53,7 +53,7 @@ mod custom_resource; /// # struct FooSpec {} /// # let client: Client = todo!(); /// let foos: Api = Api::default_namespaced(client.clone()); -/// let crds: Api = Api::all(client.clone()); +/// let crds: Api = Api::cluster(client.clone()); /// crds.patch("foos.clux.dev", &PatchParams::apply("myapp"), &Patch::Apply(Foo::crd())).await; /// # Ok(()) /// # } diff --git a/kube-runtime/src/controller/mod.rs b/kube-runtime/src/controller/mod.rs index cd85f241f..560e891d3 100644 --- a/kube-runtime/src/controller/mod.rs +++ b/kube-runtime/src/controller/mod.rs @@ -855,10 +855,10 @@ where /// ``` /// # use kube::runtime::{Controller, controller::Action, reflector::ObjectRef, watcher}; /// # use kube::{Api, ResourceExt}; - /// # use k8s_openapi::api::core::v1::{ConfigMap, Namespace}; + /// # use k8s_openapi::api::core::v1::{ConfigMap, Pod}; /// # use futures::StreamExt; /// # use std::sync::Arc; - /// # type WatchedResource = Namespace; + /// # type WatchedResource = Pod; /// # struct Context; /// # async fn reconcile(_: Arc, _: Arc) -> Result { /// # Ok(Action::await_change()) @@ -963,7 +963,7 @@ where /// fn mapper(_: DaemonSet) -> Option> { todo!() } /// # async fn doc(client: kube::Client) { /// let api: Api = Api::all(client.clone()); - /// let cr: Api = Api::all(client.clone()); + /// let cr: Api = Api::default_namespaced(client.clone()); /// let daemons = watcher(api, watcher::Config::default()) /// .touched_objects() /// .predicate_filter(predicates::generation); diff --git a/kube-runtime/src/events.rs b/kube-runtime/src/events.rs index 2db94f3f5..991b62841 100644 --- a/kube-runtime/src/events.rs +++ b/kube-runtime/src/events.rs @@ -292,7 +292,7 @@ mod test { async fn event_recorder_attaches_events_without_namespace() -> Result<(), Box> { let client = Client::try_default().await?; - let svcs: Api = Api::all(client.clone()); + let svcs: Api = Api::cluster(client.clone()); let s = svcs.get("system:basic-user").await?; // always get this default ClusterRole let recorder = Recorder::new(client.clone(), "kube".into(), s.object_ref(&())); recorder diff --git a/kube-runtime/src/reflector/mod.rs b/kube-runtime/src/reflector/mod.rs index d0a724b53..ab1ddd3b3 100644 --- a/kube-runtime/src/reflector/mod.rs +++ b/kube-runtime/src/reflector/mod.rs @@ -39,7 +39,7 @@ pub use store::{store, Store}; /// # async fn wrapper() -> Result<(), Box> { /// # let client: kube::Client = todo!(); /// -/// let nodes: Api = Api::all(client); +/// let nodes: Api = Api::cluster(client); /// let node_filter = Config::default().labels("kubernetes.io/arch=amd64"); /// let (reader, writer) = reflector::store(); /// diff --git a/kube-runtime/src/wait.rs b/kube-runtime/src/wait.rs index e657cbb36..e940437c4 100644 --- a/kube-runtime/src/wait.rs +++ b/kube-runtime/src/wait.rs @@ -39,7 +39,7 @@ pub enum Error { /// # async fn wrapper() -> Result<(), Box> { /// # let client: kube::Client = todo!(); /// -/// let crds: Api = Api::all(client); +/// let crds: Api = Api::cluster(client); /// // .. create or apply a crd here .. /// let establish = await_condition(crds, "foos.clux.dev", conditions::is_crd_established()); /// let _ = tokio::time::timeout(std::time::Duration::from_secs(10), establish).await?; diff --git a/kube/src/lib.rs b/kube/src/lib.rs index f82046664..4babd7b0b 100644 --- a/kube/src/lib.rs +++ b/kube/src/lib.rs @@ -70,7 +70,7 @@ //! #[tokio::main] //! async fn main() -> Result<(), Box> { //! let client = Client::try_default().await?; -//! let crds: Api = Api::all(client.clone()); +//! let crds: Api = Api::cluster(client.clone()); //! //! // Apply the CRD so users can create Foo instances in Kubernetes //! crds.patch("foos.clux.dev", @@ -241,7 +241,7 @@ mod test { use serde_json::json; let client = Client::try_default().await?; let ssapply = PatchParams::apply("kube").force(); - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); // Server-side apply CRD and wait for it to get ready crds.patch("foos.clux.dev", &ssapply, &Patch::Apply(Foo::crd())) .await?; @@ -365,7 +365,7 @@ mod test { async fn derived_resources_discoverable() -> Result<(), Box> { use crate::{ core::{DynamicObject, GroupVersion, GroupVersionKind}, - discovery::{self, verbs, ApiGroup, Discovery, Scope}, + discovery::{self, verbs, ApiGroup, Discovery}, runtime::wait::{await_condition, conditions, Condition}, }; @@ -377,7 +377,7 @@ mod test { let client = Client::try_default().await?; // install crd is installed - let crds: Api = Api::all(client.clone()); + let crds: Api = Api::cluster(client.clone()); let ssapply = PatchParams::apply("kube").force(); crds.patch("testcrs.kube.rs", &ssapply, &Patch::Apply(TestCr::crd())) .await?; @@ -421,11 +421,7 @@ mod test { if !caps.supports_operation(verbs::LIST) { continue; } - let api: Api = if caps.scope == Scope::Namespaced { - Api::default_namespaced_with(client.clone(), &ar) - } else { - Api::all_with(client.clone(), &ar) - }; + let api: Api = Api::dynamic(client.clone(), &ar, caps.scope); api.list(&Default::default()).await?; } } diff --git a/kube/src/mock_tests.rs b/kube/src/mock_tests.rs index 8bfbb818a..f958fcfa1 100644 --- a/kube/src/mock_tests.rs +++ b/kube/src/mock_tests.rs @@ -32,7 +32,7 @@ async fn watchers_respect_pagination_limits() { // NB: scenario only responds responds to TWO paginated list calls with two objects let mocksrv = fakeserver.run(Scenario::PaginatedList); - let api: Api = Api::all(client); + let api: Api = Api::cluster(client); let cfg = Config::default().page_size(1); let mut stream = watcher(api, cfg).applied_objects().boxed(); let first: Hack = stream.try_next().await.unwrap().unwrap(); From ef77240c7ce7351e8d23920c126e088fa0aebb20 Mon Sep 17 00:00:00 2001 From: clux Date: Fri, 13 Oct 2023 09:47:01 +0100 Subject: [PATCH 3/3] doc tweaks Signed-off-by: clux --- kube-client/src/api/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kube-client/src/api/mod.rs b/kube-client/src/api/mod.rs index a840fc97e..93bc50365 100644 --- a/kube-client/src/api/mod.rs +++ b/kube-client/src/api/mod.rs @@ -90,7 +90,7 @@ impl Api { } } - /// Cluster level resources, or resources viewed across all namespaces + /// A list/watch only view into namespaced resources across all namespaces /// /// This function accepts `K::DynamicType` so it can be used with dynamic resources. pub fn all_with(client: Client, dyntype: &K::DynamicType) -> Self @@ -281,7 +281,7 @@ where /// # use kube::{Api, Client}; /// # let client: Client = todo!(); /// use k8s_openapi::api::core::v1::Node; - /// let api: Api = Api::default_namespaced(client); // resource not namespaced! + /// let api: Api = Api::all(client); // resource not namespaced! /// ``` /// /// See [`Api::cluster`] for cluster level resources.