vault_mgmt_lib/
helpers.rs1use k8s_openapi::api::{apps::v1::StatefulSet, core::v1::Pod};
2use kube::{api::ListParams, Api};
3use tokio::io::{AsyncRead, AsyncWrite};
4
5use crate::{BytesBody, HttpForwarderService};
6
7pub const LABEL_KEY_VAULT_ACTIVE: &str = "vault-active";
8pub const LABEL_KEY_VAULT_SEALED: &str = "vault-sealed";
9
10pub fn list_vault_pods() -> ListParams {
11 ListParams::default().labels("app.kubernetes.io/name=vault")
12}
13
14pub fn is_sealed(pod: &Pod) -> anyhow::Result<bool> {
17 match pod.metadata.labels.as_ref() {
18 None => Err(anyhow::anyhow!("pod does not have labels")),
19 Some(labels) => match labels.get(LABEL_KEY_VAULT_SEALED) {
20 Some(x) if x.as_str() == "true" => Ok(true),
21 Some(x) if x.as_str() == "false" => Ok(false),
22 _ => Err(anyhow::anyhow!(
23 "pod does not have a {} label",
24 LABEL_KEY_VAULT_SEALED
25 )),
26 },
27 }
28}
29
30pub fn is_active(pod: &Pod) -> anyhow::Result<bool> {
33 match pod.metadata.labels.as_ref() {
34 None => Err(anyhow::anyhow!("pod does not have labels")),
35 Some(labels) => match labels.get(LABEL_KEY_VAULT_ACTIVE) {
36 Some(x) if x.as_str() == "true" => Ok(true),
37 Some(x) if x.as_str() == "false" => Ok(false),
38 _ => Err(anyhow::anyhow!(
39 "pod does not have a {} label",
40 LABEL_KEY_VAULT_ACTIVE
41 )),
42 },
43 }
44}
45
46#[derive(Clone)]
48pub struct PodApi {
49 pub api: Api<Pod>,
50 tls: bool,
51 domain: String,
52}
53
54impl PodApi {
55 pub fn new(api: Api<Pod>, tls: bool, domain: String) -> Self {
56 Self { api, tls, domain }
57 }
58}
59
60impl PodApi {
61 pub async fn portforward(
64 &self,
65 pod: &str,
66 port: u16,
67 ) -> anyhow::Result<impl AsyncRead + AsyncWrite + Unpin> {
68 let mut pf = self.api.portforward(pod, &[port]).await?;
69 pf.take_stream(port).ok_or(anyhow::anyhow!(
70 "port {} is not available on pod {}",
71 port,
72 pod
73 ))
74 }
75
76 pub async fn http(
77 &self,
78 pod: &str,
79 port: u16,
80 ) -> anyhow::Result<HttpForwarderService<BytesBody>> {
81 let pf = self.portforward(pod, port).await?;
82
83 if self.tls {
84 return HttpForwarderService::https(&self.domain, pf).await;
85 }
86
87 HttpForwarderService::http(pf).await
88 }
89}
90
91pub struct StatefulSetApi {
93 pub api: Api<StatefulSet>,
94}
95
96impl From<Api<StatefulSet>> for StatefulSetApi {
97 fn from(api: Api<StatefulSet>) -> Self {
98 Self { api }
99 }
100}