kube_client/api/util/
mod.rsuse crate::{
api::{Api, Resource},
Error, Result,
};
use k8s_openapi::api::{
authentication::v1::TokenRequest,
core::v1::{Node, ServiceAccount},
};
use kube_core::{params::PostParams, util::Restart};
use serde::de::DeserializeOwned;
mod csr;
impl<K> Api<K>
where
K: Restart + Resource + DeserializeOwned,
{
pub async fn restart(&self, name: &str) -> Result<K> {
let mut req = self.request.restart(name).map_err(Error::BuildRequest)?;
req.extensions_mut().insert("restart");
self.client.request::<K>(req).await
}
}
impl Api<Node> {
pub async fn cordon(&self, name: &str) -> Result<Node> {
let mut req = self.request.cordon(name).map_err(Error::BuildRequest)?;
req.extensions_mut().insert("cordon");
self.client.request::<Node>(req).await
}
pub async fn uncordon(&self, name: &str) -> Result<Node> {
let mut req = self.request.uncordon(name).map_err(Error::BuildRequest)?;
req.extensions_mut().insert("cordon");
self.client.request::<Node>(req).await
}
}
impl Api<ServiceAccount> {
pub async fn create_token_request(
&self,
name: &str,
pp: &PostParams,
token_request: &TokenRequest,
) -> Result<TokenRequest> {
let bytes = serde_json::to_vec(token_request).map_err(Error::SerdeError)?;
let mut req = self
.request
.create_subresource("token", name, pp, bytes)
.map_err(Error::BuildRequest)?;
req.extensions_mut().insert("create_token_request");
self.client.request::<TokenRequest>(req).await
}
}
#[cfg(test)]
#[cfg(feature = "client")]
mod test {
use crate::{
api::{Api, DeleteParams, ListParams, PostParams},
Client,
};
use k8s_openapi::api::{
authentication::v1::{TokenRequest, TokenRequestSpec, TokenReview, TokenReviewSpec},
core::v1::{Node, ServiceAccount},
};
use serde_json::json;
#[tokio::test]
#[ignore = "needs kubeconfig"]
async fn node_cordon_and_uncordon_works() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::try_default().await?;
let node_name = "fakenode";
let fake_node = serde_json::from_value(json!({
"apiVersion": "v1",
"kind": "Node",
"metadata": {
"name": node_name,
},
}))?;
let nodes: Api<Node> = Api::all(client.clone());
nodes.create(&PostParams::default(), &fake_node).await?;
let schedulables = ListParams::default().fields("spec.unschedulable==false");
let nodes_init = nodes.list(&schedulables).await?;
let num_nodes_before_cordon = nodes_init.items.len();
nodes.cordon(node_name).await?;
let nodes_after_cordon = nodes.list(&schedulables).await?;
assert_eq!(nodes_after_cordon.items.len(), num_nodes_before_cordon - 1);
nodes.uncordon(node_name).await?;
let nodes_after_uncordon = nodes.list(&schedulables).await?;
assert_eq!(nodes_after_uncordon.items.len(), num_nodes_before_cordon);
nodes.delete(node_name, &DeleteParams::default()).await?;
Ok(())
}
#[tokio::test]
#[ignore = "requires a cluster"]
async fn create_token_request() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::try_default().await?;
let serviceaccount_name = "fakesa";
let serviceaccount_namespace = "default";
let audiences = vec!["api".to_string()];
let serviceaccounts: Api<ServiceAccount> = Api::namespaced(client.clone(), serviceaccount_namespace);
let tokenreviews: Api<TokenReview> = Api::all(client);
let fake_sa = serde_json::from_value(json!({
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": {
"name": serviceaccount_name,
},
}))?;
serviceaccounts.create(&PostParams::default(), &fake_sa).await?;
let tokenrequest = serviceaccounts
.create_token_request(serviceaccount_name, &PostParams::default(), &TokenRequest {
metadata: Default::default(),
spec: TokenRequestSpec {
audiences: audiences.clone(),
bound_object_ref: None,
expiration_seconds: None,
},
status: None,
})
.await?;
let token = tokenrequest.status.unwrap().token;
assert!(!token.is_empty());
let tokenreview = tokenreviews
.create(&PostParams::default(), &TokenReview {
metadata: Default::default(),
spec: TokenReviewSpec {
audiences: Some(audiences.clone()),
token: Some(token),
},
status: None,
})
.await?;
let tokenreviewstatus = tokenreview.status.unwrap();
assert_eq!(tokenreviewstatus.audiences, Some(audiences));
assert_eq!(tokenreviewstatus.authenticated, Some(true));
assert_eq!(tokenreviewstatus.error, None);
assert_eq!(
tokenreviewstatus.user.unwrap().username,
Some(format!(
"system:serviceaccount:{serviceaccount_namespace}:{serviceaccount_name}"
))
);
serviceaccounts
.delete(serviceaccount_name, &DeleteParams::default())
.await?;
Ok(())
}
}