kube_client/discovery/
parse.rs
1use crate::{error::DiscoveryError, Error, Result};
3use k8s_openapi::apimachinery::pkg::apis::meta::v1::{APIResource, APIResourceList};
4use kube_core::{
5 discovery::{ApiCapabilities, ApiResource, Scope},
6 gvk::{GroupVersion, ParseGroupVersionError},
7};
8
9pub(crate) fn parse_apiresource(
13 ar: &APIResource,
14 group_version: &str,
15) -> Result<ApiResource, ParseGroupVersionError> {
16 let gv: GroupVersion = group_version.parse()?;
17 Ok(ApiResource {
19 group: ar.group.clone().unwrap_or_else(|| gv.group.clone()),
20 version: ar.version.clone().unwrap_or_else(|| gv.version.clone()),
21 api_version: gv.api_version(),
22 kind: ar.kind.to_string(),
23 plural: ar.name.clone(),
24 })
25}
26
27pub(crate) fn parse_apicapabilities(list: &APIResourceList, name: &str) -> Result<ApiCapabilities> {
31 let ar = list
32 .resources
33 .iter()
34 .find(|r| r.name == name)
35 .ok_or_else(|| Error::Discovery(DiscoveryError::MissingResource(name.into())))?;
36 let scope = if ar.namespaced {
37 Scope::Namespaced
38 } else {
39 Scope::Cluster
40 };
41
42 let subresource_name_prefix = format!("{name}/");
43 let mut subresources = vec![];
44 for res in &list.resources {
45 if let Some(subresource_name) = res.name.strip_prefix(&subresource_name_prefix) {
46 let mut api_resource =
47 parse_apiresource(res, &list.group_version).map_err(|ParseGroupVersionError(s)| {
48 Error::Discovery(DiscoveryError::InvalidGroupVersion(s))
49 })?;
50 api_resource.plural = subresource_name.to_string();
51 let caps = parse_apicapabilities(list, &res.name)?; subresources.push((api_resource, caps));
53 }
54 }
55 Ok(ApiCapabilities {
56 scope,
57 subresources,
58 operations: ar.verbs.clone(),
59 })
60}
61
62pub(crate) struct GroupVersionData {
64 pub(crate) version: String,
66 pub(crate) resources: Vec<(ApiResource, ApiCapabilities)>,
68}
69
70impl GroupVersionData {
71 pub(crate) fn new(version: String, list: APIResourceList) -> Result<Self> {
73 let mut resources = vec![];
74 for res in &list.resources {
75 if res.name.contains('/') {
77 continue;
78 }
79 let ar = parse_apiresource(res, &list.group_version).map_err(|ParseGroupVersionError(s)| {
81 Error::Discovery(DiscoveryError::InvalidGroupVersion(s))
82 })?;
83 let caps = parse_apicapabilities(&list, &res.name)?;
84 resources.push((ar, caps));
85 }
86 Ok(GroupVersionData { version, resources })
87 }
88}