k8s_test_framework/
namespace.rs

1//! Manage namespaces.
2
3use std::{
4    collections::BTreeMap,
5    process::{Command, Stdio},
6};
7
8use k8s_openapi::{api::core::v1::Namespace, apimachinery::pkg::apis::meta::v1::ObjectMeta};
9
10use super::{resource_file::ResourceFile, Result};
11use crate::up_down;
12
13/// A config that holds a test `Namespace` resource file.
14#[derive(Debug)]
15pub struct Config {
16    test_namespace_resource_file: ResourceFile,
17}
18
19impl Config {
20    /// Create a [`Config`] using a structured [`Namespace`] object.
21    pub fn from_namespace(namespace: &Namespace) -> Result<Self> {
22        Self::from_resource_string(serde_json::to_string(namespace)?.as_str())
23    }
24
25    /// Create a [`Config`] using an unstructured resource string.
26    pub fn from_resource_string(resource: &str) -> Result<Self> {
27        let test_namespace_resource_file = ResourceFile::new(resource)?;
28        Ok(Self {
29            test_namespace_resource_file,
30        })
31    }
32}
33
34/// Parameters required to build a `kubectl` command to manage the namespace.
35#[derive(Debug)]
36pub struct CommandBuilder {
37    kubectl_command: String,
38    config: Config,
39}
40
41impl up_down::CommandBuilder for CommandBuilder {
42    fn build(&self, command_to_build: up_down::CommandToBuild) -> Command {
43        let mut command = Command::new(&self.kubectl_command);
44        command
45            .arg(match command_to_build {
46                up_down::CommandToBuild::Up => "apply",
47                up_down::CommandToBuild::Down => "delete",
48            })
49            .arg("--filename")
50            .arg(self.config.test_namespace_resource_file.path());
51
52        if matches!(command_to_build, up_down::CommandToBuild::Down) {
53            // We don't need a graceful shutdown
54            command.arg("--force=true");
55            command.arg("--grace-period=0");
56            command.arg("--wait=false");
57        }
58
59        command.stdin(Stdio::null());
60        command
61    }
62}
63
64/// Create a new [`up_down::Manager`] for the specified `namespace` and using
65/// the specified `kubectl_command`.
66pub fn manager(kubectl_command: &str, config: Config) -> up_down::Manager<CommandBuilder> {
67    up_down::Manager::new(CommandBuilder {
68        kubectl_command: kubectl_command.to_owned(),
69        config,
70    })
71}
72
73/// Helper to create a Namespace resource during tests
74pub fn make_namespace(name: String, labels: Option<BTreeMap<String, String>>) -> Namespace {
75    Namespace {
76        metadata: ObjectMeta {
77            name: Some(name),
78            labels,
79            ..Default::default()
80        },
81        spec: None,
82        status: None,
83    }
84}