vault_mgmt_lib/
show.rs

1use k8s_openapi::api::core::v1::Pod;
2use kube::api::Api;
3use prettytable::{color, Attr, Cell, Row, Table};
4
5use crate::list_vault_pods;
6
7#[tracing::instrument(skip_all)]
8pub async fn construct_table(api: &Api<Pod>) -> anyhow::Result<Table> {
9    let mut table = Table::new();
10    table.set_titles(row![
11        "NAME",
12        "STATUS",
13        "IMAGE",
14        "INITIALIZED",
15        "SEALED",
16        "ACTIVE",
17        "READY",
18    ]);
19
20    let pods = api.list(&list_vault_pods()).await?;
21
22    let get_vault_label = |pod: &Pod, label: &str| match pod.metadata.labels {
23        Some(ref labels) => labels
24            .get(label)
25            .unwrap_or(&String::from("unknown"))
26            .to_string(),
27        None => String::from("unknown"),
28    };
29
30    for p in pods.iter() {
31        let name = p
32            .metadata
33            .name
34            .clone()
35            .ok_or(anyhow::anyhow!("pod does not have a name"))?;
36        let status = p
37            .status
38            .as_ref()
39            .ok_or(anyhow::anyhow!("pod does not have a status"))?
40            .phase
41            .clone()
42            .ok_or(anyhow::anyhow!("pod does not have a phase"))?;
43        let image = p
44            .spec
45            .as_ref()
46            .ok_or(anyhow::anyhow!("pod does not have a spec"))?
47            .containers
48            .first()
49            .ok_or(anyhow::anyhow!("pod does not have a container"))?
50            .image
51            .clone()
52            .ok_or(anyhow::anyhow!("container does not have an image"))?;
53
54        let initialized = get_vault_label(p, "vault-initialized");
55        let initialized =
56            Cell::new(&initialized).with_style(Attr::ForegroundColor(match initialized.as_str() {
57                "true" => color::GREEN,
58                "false" => color::RED,
59                _ => color::YELLOW,
60            }));
61
62        let sealed = get_vault_label(p, "vault-sealed");
63        let sealed = Cell::new(&sealed).with_style(Attr::ForegroundColor(match sealed.as_str() {
64            "true" => color::RED,
65            "false" => color::GREEN,
66            _ => color::YELLOW,
67        }));
68
69        let active = get_vault_label(p, "vault-active");
70        let active = Cell::new(&active).with_style(Attr::ForegroundColor(match active.as_str() {
71            "true" => color::GREEN,
72            "false" => color::WHITE,
73            _ => color::YELLOW,
74        }));
75
76        let ready = {
77            let mut ready = "unknown".to_string();
78
79            for c in p
80                .status
81                .as_ref()
82                .ok_or(anyhow::anyhow!("pod does not have a status"))?
83                .conditions
84                .as_ref()
85                .ok_or(anyhow::anyhow!("pod does not have status conditions"))?
86            {
87                if c.type_ == "Ready" {
88                    ready = match c.status.as_str() {
89                        "True" => "true".to_string(),
90                        "False" => "false".to_string(),
91                        _ => "unknown".to_string(),
92                    };
93
94                    break;
95                }
96            }
97
98            ready
99        };
100        let ready = Cell::new(&ready).with_style(Attr::ForegroundColor(match ready.as_str() {
101            "true" => color::GREEN,
102            "false" => color::WHITE,
103            _ => color::YELLOW,
104        }));
105
106        table.add_row(Row::new(vec![
107            Cell::new(&name),
108            Cell::new(&status),
109            Cell::new(&image),
110            initialized,
111            sealed,
112            active,
113            ready,
114        ]));
115    }
116
117    Ok(table)
118}