Skip to content

Commit

Permalink
Merge pull request #301 from MikailBag/discovery
Browse files Browse the repository at this point in the history
Add functions for runtime API discovery
  • Loading branch information
clux authored Aug 9, 2020
2 parents 5617130 + 3b4166e commit 130bc75
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
46 changes: 46 additions & 0 deletions kube/src/api/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
api::{typed::Api, Resource},
Client, Error, Result,
};
use k8s_openapi::apimachinery::pkg::apis::meta::v1::APIResource;
use std::convert::TryFrom;

use inflector::{cases::pascalcase::is_pascal_case, string::pluralize::to_plural};
Expand Down Expand Up @@ -99,6 +100,51 @@ impl DynamicResource {
phantom: iter::empty(),
})
}

/// Creates `DynamicResource`, based on `metav1::APIResource`.
/// If it does not specify version and/or group, they will be taken
/// from `api_resource_list_group_version`.
/// Example usage:
/// ```
/// use kube::api::DynamicResource;
/// # async fn scope(client: kube::Client) -> Result<(), Box<dyn std::error::Error>> {
/// let apps_apis = client.list_api_group_resources("apps", "v1").await?;
/// for api_res in &apps_apis.resources {
/// let kube_resource = DynamicResource::from_metav1_api_resource(api_res, &apps_apis.group_version);
/// // do not forget to select a namespace
/// let kube_resource = kube_resource.within("kube-system").into_resource();
/// dbg!(kube_resource);
/// }
/// # Ok(())
/// # }
/// ```
pub fn from_metav1_api_resource(
k8s_resource: &APIResource,
api_resource_list_group_version: &str,
) -> Self {
let (default_group, default_version) = if api_resource_list_group_version.contains('/') {
let mut iter = api_resource_list_group_version.splitn(2, '/');
let g = iter.next().unwrap();
let v = iter.next().unwrap();
(g, v)
} else {
("", api_resource_list_group_version)
};
let version = k8s_resource
.version
.clone()
.unwrap_or_else(|| default_version.to_string());
let group = k8s_resource
.group
.clone()
.unwrap_or_else(|| default_group.to_string());
DynamicResource {
kind: k8s_resource.kind.clone(),
version: Some(version),
group: Some(group),
namespace: None,
}
}
}

impl TryFrom<DynamicResource> for Resource {
Expand Down
45 changes: 44 additions & 1 deletion kube/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
use bytes::Bytes;
use either::{Either, Left, Right};
use futures::{self, Stream, TryStream, TryStreamExt};
use http::{self, StatusCode};
use http::{self, Request, StatusCode};
use serde::{de::DeserializeOwned, Deserialize};
use serde_json::{self, Value};

Expand Down Expand Up @@ -268,6 +268,49 @@ impl Client {

Ok(stream.map_ok(futures::stream::iter).try_flatten())
}

/// Returns apiserver version.
pub async fn apiserver_version(&self) -> Result<k8s_openapi::apimachinery::pkg::version::Info> {
self.request(Request::builder().uri("/version").body(Vec::new())?)
.await
}

/// Lists api groups that apiserver serves.
pub async fn list_api_groups(&self) -> Result<k8s_openapi::apimachinery::pkg::apis::meta::v1::APIGroupList> {
self.request(Request::builder().uri("/apis").body(Vec::new())?)
.await
}

/// Lists resources served in given API group.
/// There resources can be then converted to `kube::api::DynamicResource`
/// using the `from_metav1_api_resource` method.
pub async fn list_api_group_resources(
&self,
group: &str,
version: &str,
) -> Result<k8s_openapi::apimachinery::pkg::apis::meta::v1::APIResourceList> {
let url = format!("/apis/{}/{}", group, version);
self.request(Request::builder().uri(url).body(Vec::new())?).await
}

/// Lists versions of `core` a.k.a. `""` API group.
pub async fn list_core_api_versions(
&self,
) -> Result<k8s_openapi::apimachinery::pkg::apis::meta::v1::APIVersions> {
self.request(Request::builder().uri("/api").body(Vec::new())?)
.await
}

/// Lists resources served in particular `core` group version.
/// There resources can be then converted to `kube::api::DynamicResource`
/// using the `from_metav1_api_resource` method.
pub async fn list_core_api_resources(
&self,
version: &str,
) -> Result<k8s_openapi::apimachinery::pkg::apis::meta::v1::APIResourceList> {
let url = format!("/api/{}", version);
self.request(Request::builder().uri(url).body(Vec::new())?).await
}
}

/// Kubernetes returned error handling
Expand Down

0 comments on commit 130bc75

Please sign in to comment.