k8s_test_framework/
wait_for_resource.rs

1//! Wait for a resource to reach a certain condition.
2
3use std::{ffi::OsStr, process::Stdio};
4
5use tokio::process::Command;
6
7use super::Result;
8use crate::util::run_command;
9
10/// Specify what condition to wait for.
11#[derive(Debug)]
12pub enum WaitFor<C>
13where
14    C: std::fmt::Display,
15{
16    /// Wait for resource deletion.
17    Delete,
18    /// Wait for the specified condition.
19    Condition(C),
20}
21
22/// Wait for a set of `resources` within a `namespace` to reach a `wait_for`
23/// condition.
24/// Use `extra` to pass additional arguments to `kubectl`.
25pub async fn namespace<Cmd, NS, R, Cond, Ex>(
26    kubectl_command: Cmd,
27    namespace: NS,
28    resources: impl IntoIterator<Item = R>,
29    wait_for: WaitFor<Cond>,
30    extra: impl IntoIterator<Item = Ex>,
31) -> Result<()>
32where
33    Cmd: AsRef<OsStr>,
34    NS: AsRef<OsStr>,
35    R: AsRef<OsStr>,
36    Cond: std::fmt::Display,
37    Ex: AsRef<OsStr>,
38{
39    let mut command = prepare_base_command(kubectl_command, resources, wait_for, extra);
40    command.arg("-n").arg(namespace);
41    run_command(command).await
42}
43
44/// Wait for a set of `resources` at any namespace to reach a `wait_for`
45/// condition.
46/// Use `extra` to pass additional arguments to `kubectl`.
47pub async fn all_namespaces<Cmd, R, Cond, Ex>(
48    kubectl_command: Cmd,
49    resources: impl IntoIterator<Item = R>,
50    wait_for: WaitFor<Cond>,
51    extra: impl IntoIterator<Item = Ex>,
52) -> Result<()>
53where
54    Cmd: AsRef<OsStr>,
55    R: AsRef<OsStr>,
56    Cond: std::fmt::Display,
57    Ex: AsRef<OsStr>,
58{
59    let mut command = prepare_base_command(kubectl_command, resources, wait_for, extra);
60    command.arg("--all-namespaces=true");
61    run_command(command).await
62}
63
64fn prepare_base_command<Cmd, R, Cond, Ex>(
65    kubectl_command: Cmd,
66    resources: impl IntoIterator<Item = R>,
67    wait_for: WaitFor<Cond>,
68    extra: impl IntoIterator<Item = Ex>,
69) -> Command
70where
71    Cmd: AsRef<OsStr>,
72    R: AsRef<OsStr>,
73    Cond: std::fmt::Display,
74    Ex: AsRef<OsStr>,
75{
76    let mut command = Command::new(kubectl_command);
77
78    command
79        .stdin(Stdio::null())
80        .stdout(Stdio::inherit())
81        .stderr(Stdio::inherit());
82
83    command.arg("wait");
84    command.args(resources);
85
86    command.arg("--for");
87    match wait_for {
88        WaitFor::Delete => command.arg("delete"),
89        WaitFor::Condition(cond) => command.arg(format!("condition={cond}")),
90    };
91
92    command.args(extra);
93    command
94}