Skip to content

Commit f9eb3fe

Browse files
committed
fix: wait for pod to set its status labels
1 parent 02a726e commit f9eb3fe

File tree

4 files changed

+66
-37
lines changed

4 files changed

+66
-37
lines changed

src/helpers.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ pub fn is_sealed(pod: &Pod) -> anyhow::Result<bool> {
2727
}
2828
}
2929

30+
/// Check if the vault pod is active based on its labels
31+
/// Returns an error if the pod does not have the expected labels
32+
pub 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+
3046
/// Wrapper around the kube::Api type for the Vault pod
3147
#[derive(Clone)]
3248
pub struct PodApi {

src/upgrade.rs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use tokio_retry::{
88
use tracing::*;
99

1010
use crate::{
11-
ExecIn, StepDown, Unseal, VaultVersion, VAULT_PORT,
11+
is_active, is_pod_exporting_seal_status, ExecIn, StepDown, Unseal, VaultVersion, VAULT_PORT,
1212
{is_pod_ready, is_pod_standby, is_pod_unsealed}, {is_seal_status_initialized, GetSealStatus},
13-
{is_sealed, list_vault_pods, PodApi, StatefulSetApi, LABEL_KEY_VAULT_ACTIVE},
13+
{is_sealed, list_vault_pods, PodApi, StatefulSetApi},
1414
};
1515

1616
impl PodApi {
@@ -49,18 +49,7 @@ impl PodApi {
4949
// if Pod version is outdated (or upgrade is forced)
5050
if !Self::is_current(&pod, target)? || force_upgrade {
5151
// if Pod is active
52-
if pod
53-
.metadata
54-
.labels
55-
.ok_or(anyhow::anyhow!("pod does not have labels"))?
56-
.get(LABEL_KEY_VAULT_ACTIVE)
57-
.ok_or(anyhow::anyhow!(
58-
"pod does not have an {} label",
59-
LABEL_KEY_VAULT_ACTIVE
60-
))?
61-
.as_str()
62-
== "true"
63-
{
52+
if is_active(&pod)? {
6453
// Step down active pod
6554
self.http(name, VAULT_PORT).await?.step_down(token).await?;
6655

@@ -86,35 +75,45 @@ impl PodApi {
8675
anyhow::anyhow!("waiting for pod {} to be running: {}", name, e.to_string())
8776
})?;
8877

89-
let pod = self.api.get(name).await?;
90-
91-
let mut pf = Retry::spawn(
92-
ExponentialBackoff::from_millis(50).map(jitter).take(5),
93-
|| async move { self.http(name, VAULT_PORT).await },
78+
// Wait for pod to export its seal status
79+
kube::runtime::wait::await_condition(
80+
self.api.clone(),
81+
name,
82+
is_pod_exporting_seal_status(),
9483
)
95-
.await
96-
.map_err(|e| {
97-
anyhow::anyhow!(
98-
"attempting to forward http requests to {}: {}",
99-
name,
100-
e.to_string()
101-
)
102-
})?;
84+
.await?;
10385

104-
pf.await_seal_status(is_seal_status_initialized())
105-
.await
106-
.map_err(|e| {
107-
anyhow::anyhow!(
108-
"waiting for pod to have required seal status {}: {}",
109-
name,
110-
e.to_string()
111-
)
112-
})?;
86+
// Refresh pod
87+
let pod = self.api.get(name).await?;
11388

11489
if Self::is_current(&pod, target)? {
11590
// Pod is sealed
11691
if is_sealed(&pod)? {
11792
if should_unseal {
93+
let mut pf = Retry::spawn(
94+
ExponentialBackoff::from_millis(50).map(jitter).take(5),
95+
|| async move { self.http(name, VAULT_PORT).await },
96+
)
97+
.await
98+
.map_err(|e| {
99+
anyhow::anyhow!(
100+
"attempting to forward http requests to {}: {}",
101+
name,
102+
e.to_string()
103+
)
104+
})?;
105+
106+
// Wait for pod to have determined its seal status
107+
pf.await_seal_status(is_seal_status_initialized())
108+
.await
109+
.map_err(|e| {
110+
anyhow::anyhow!(
111+
"waiting for pod to have required seal status {}: {}",
112+
name,
113+
e.to_string()
114+
)
115+
})?;
116+
118117
// Unseal pod
119118
pf.unseal(keys).await.map_err(|e| {
120119
anyhow::anyhow!("unsealing pod {}: {}", name, e.to_string())

src/wait.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ pub fn is_pod_ready() -> impl Condition<Pod> {
7878
}
7979
}
8080

81+
/// Returns true if the Pod has the seal status label.
82+
/// This is determined by looking if the `vault-sealed` label exists.
83+
#[must_use]
84+
pub fn is_pod_exporting_seal_status() -> impl Condition<Pod> {
85+
|obj: Option<&Pod>| {
86+
if let Some(pod) = &obj {
87+
if let Some(labels) = &pod.metadata.labels {
88+
return labels.get("vault-sealed").is_some();
89+
}
90+
}
91+
false
92+
}
93+
}
94+
8195
/// Returns true if the Pod is unsealed.
8296
/// This is determined by looking at the `vault-sealed` label.
8397
#[must_use]

tests/e2e/upgrade.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ async fn upgrade_pod_succeeds_fails_with_missing_external_unseal() {
424424

425425
#[ignore = "needs a running kubernetes cluster and the helm cli"]
426426
#[tokio::test]
427-
async fn upgrade_pod_succeeds_succeeds_with_external_unseal() {
427+
async fn upgrade_pod_succeeds_with_external_unseal() {
428428
let client = Client::try_default().await.unwrap();
429429

430430
let namespace = &get_namespace();

0 commit comments

Comments
 (0)