kube_core/
util.rs

1//! Utils and helpers
2
3use crate::{
4    params::{Patch, PatchParams},
5    request, Request,
6};
7use chrono::Utc;
8use k8s_openapi::api::apps::v1::{DaemonSet, Deployment, ReplicaSet, StatefulSet};
9
10/// Restartable Resource marker trait
11pub trait Restart {}
12
13impl Restart for Deployment {}
14impl Restart for DaemonSet {}
15impl Restart for StatefulSet {}
16impl Restart for ReplicaSet {}
17
18impl Request {
19    /// Restart a resource
20    pub fn restart(&self, name: &str) -> Result<http::Request<Vec<u8>>, request::Error> {
21        let patch = serde_json::json!({
22          "spec": {
23            "template": {
24              "metadata": {
25                "annotations": {
26                  "kube.kubernetes.io/restartedAt": Utc::now().to_rfc3339()
27                }
28              }
29            }
30          }
31        });
32
33        let pparams = PatchParams::default();
34        self.patch(name, &pparams, &Patch::Merge(patch))
35    }
36}
37
38impl Request {
39    /// Cordon a resource
40    pub fn cordon(&self, name: &str) -> Result<http::Request<Vec<u8>>, request::Error> {
41        self.set_unschedulable(name, true)
42    }
43
44    /// Uncordon a resource
45    pub fn uncordon(&self, name: &str) -> Result<http::Request<Vec<u8>>, request::Error> {
46        self.set_unschedulable(name, false)
47    }
48
49    fn set_unschedulable(
50        &self,
51        node_name: &str,
52        value: bool,
53    ) -> Result<http::Request<Vec<u8>>, request::Error> {
54        self.patch(
55            node_name,
56            &PatchParams::default(),
57            &Patch::Strategic(serde_json::json!({ "spec": { "unschedulable": value } })),
58        )
59    }
60}
61
62#[cfg(test)]
63mod test {
64    use crate::{params::Patch, request::Request, resource::Resource};
65
66    #[test]
67    fn restart_patch_is_correct() {
68        use k8s_openapi::api::apps::v1 as appsv1;
69
70        let url = appsv1::Deployment::url_path(&(), Some("ns"));
71        let req = Request::new(url).restart("mydeploy").unwrap();
72        assert_eq!(req.uri(), "/apis/apps/v1/namespaces/ns/deployments/mydeploy?");
73        assert_eq!(req.method(), "PATCH");
74        assert_eq!(
75            req.headers().get("Content-Type").unwrap().to_str().unwrap(),
76            Patch::Merge(()).content_type()
77        );
78    }
79
80    #[test]
81    fn cordon_patch_is_correct() {
82        use k8s_openapi::api::core::v1::Node;
83
84        let url = Node::url_path(&(), Some("ns"));
85        let req = Request::new(url).cordon("mynode").unwrap();
86        assert_eq!(req.uri(), "/api/v1/namespaces/ns/nodes/mynode?");
87        assert_eq!(req.method(), "PATCH");
88        assert_eq!(
89            req.headers().get("Content-Type").unwrap().to_str().unwrap(),
90            Patch::Strategic(()).content_type()
91        );
92    }
93}