kube_client/discovery/oneshot.rs
1//! single use discovery utils
2//!
3//! These helpers provides a simpler discovery interface, but do not offer any built-in caching.
4//!
5//! This can provide specific information for 3 cases:
6//! - single kind in a particular group at a pinned version via [`oneshot::pinned_kind`]
7//! - all kinds in a group at pinned version: "apiregistration.k8s.io/v1" via [`oneshot::pinned_group`]
8//! - all kinds/version combinations in a group: "apiregistration.k8s.io" via [`oneshot::group`]
9//!
10//! [`oneshot::group`]: crate::discovery::group
11//! [`oneshot::pinned_group`]: crate::discovery::pinned_group
12//! [`oneshot::pinned_kind`]: crate::discovery::pinned_kind
13
14use super::ApiGroup;
15use crate::{error::DiscoveryError, Client, Error, Result};
16use kube_core::{
17 discovery::{ApiCapabilities, ApiResource},
18 gvk::{GroupVersion, GroupVersionKind},
19};
20
21/// Discovers all APIs available under a certain group at all versions
22///
23/// This is recommended if you work with one group, but do not want to pin the version
24/// of the apigroup. You can instead work with a recommended version (preferred or latest).
25///
26/// ```no_run
27/// use kube::{Client, api::{Api, DynamicObject}, discovery, ResourceExt};
28/// #[tokio::main]
29/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
30/// let client = Client::try_default().await?;
31/// let apigroup = discovery::group(&client, "apiregistration.k8s.io").await?;
32/// let (ar, caps) = apigroup.recommended_kind("APIService").unwrap();
33/// let api: Api<DynamicObject> = Api::all_with(client.clone(), &ar);
34/// for service in api.list(&Default::default()).await? {
35/// println!("Found APIService: {}", service.name_any());
36/// }
37/// Ok(())
38/// }
39/// ```
40pub async fn group(client: &Client, apigroup: &str) -> Result<ApiGroup> {
41 if apigroup == ApiGroup::CORE_GROUP {
42 let coreapis = client.list_core_api_versions().await?;
43 return ApiGroup::query_core(client, coreapis).await;
44 } else {
45 let api_groups = client.list_api_groups().await?;
46 for g in api_groups.groups {
47 if g.name != apigroup {
48 continue;
49 }
50 return ApiGroup::query_apis(client, g).await;
51 }
52 }
53 Err(Error::Discovery(DiscoveryError::MissingApiGroup(
54 apigroup.to_string(),
55 )))
56}
57
58/// Discovers all APIs available under a certain group at a pinned version
59///
60/// This is a cheaper variant of [`oneshot::group`](crate::discovery::oneshot::group) when you know what version you want.
61///
62/// ```no_run
63/// use kube::{Client, api::{Api, DynamicObject}, discovery, ResourceExt};
64/// #[tokio::main]
65/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
66/// let client = Client::try_default().await?;
67/// let gv = "apiregistration.k8s.io/v1".parse()?;
68/// let apigroup = discovery::pinned_group(&client, &gv).await?;
69/// let (ar, caps) = apigroup.recommended_kind("APIService").unwrap();
70/// let api: Api<DynamicObject> = Api::all_with(client.clone(), &ar);
71/// for service in api.list(&Default::default()).await? {
72/// println!("Found APIService: {}", service.name_any());
73/// }
74/// Ok(())
75/// }
76/// ```
77///
78/// While this example only uses a single kind, this type of discovery works best when you need more
79/// than a single `kind`.
80/// If you only need a single `kind`, [`oneshot::pinned_kind`](crate::discovery::pinned_kind) is the best solution.
81pub async fn pinned_group(client: &Client, gv: &GroupVersion) -> Result<ApiGroup> {
82 ApiGroup::query_gv(client, gv).await
83}
84
85/// Single discovery for a single GVK
86///
87/// This is an optimized function that avoids the unnecessary listing of api groups.
88/// It merely requests the api group resources for the specified apigroup, and then resolves the kind.
89///
90/// ```no_run
91/// use kube::{Client, api::{Api, DynamicObject, GroupVersionKind}, discovery, ResourceExt};
92/// #[tokio::main]
93/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
94/// let client = Client::try_default().await?;
95/// let gvk = GroupVersionKind::gvk("apiregistration.k8s.io", "v1", "APIService");
96/// let (ar, caps) = discovery::pinned_kind(&client, &gvk).await?;
97/// let api: Api<DynamicObject> = Api::all_with(client.clone(), &ar);
98/// for service in api.list(&Default::default()).await? {
99/// println!("Found APIService: {}", service.name_any());
100/// }
101/// Ok(())
102/// }
103/// ```
104pub async fn pinned_kind(client: &Client, gvk: &GroupVersionKind) -> Result<(ApiResource, ApiCapabilities)> {
105 ApiGroup::query_gvk(client, gvk).await
106}