vaultrs_test/
vault.rs

1use crate::docker::{Server, ServerConfig, TestInstance};
2use dockertest::{waitfor, Composition, DockerOperations, Image, PullPolicy, Source};
3
4/// Configuration for bringing up a container running a dev instance of Vault.
5#[derive(Clone)]
6pub struct VaultServerConfig {
7    pub handle: String,
8    pub timeout: u16,
9    pub token: String,
10    pub port: u32,
11    pub version: String,
12}
13
14impl ServerConfig for VaultServerConfig {
15    fn to_comp(&self) -> Composition {
16        const IMAGE_NAME: &str = "vault";
17        const IMAGE_PORT: u32 = 8200;
18        const WAIT_MESSAGE: &str =
19            "Development mode should NOT be used in production installations!";
20
21        const PULL_POLICY: PullPolicy = PullPolicy::IfNotPresent;
22        const SOURCE: Source = Source::DockerHub(PULL_POLICY);
23
24        // Build image
25        let image = Image::with_repository(IMAGE_NAME)
26            .source(SOURCE)
27            .tag(&self.version);
28
29        // Build composition
30        let wait = Box::new(waitfor::MessageWait {
31            message: String::from(WAIT_MESSAGE),
32            source: waitfor::MessageSource::Stdout,
33            timeout: self.timeout,
34        });
35
36        let mut comp = Composition::with_image(image);
37        comp.env("VAULT_DEV_ROOT_TOKEN_ID", &self.token);
38        comp.port_map(IMAGE_PORT, self.port);
39        comp.with_wait_for(wait).with_container_name(&self.handle)
40    }
41
42    fn to_instance(&self) -> TestInstance {
43        TestInstance::new(vec![self.to_comp()])
44    }
45}
46
47impl VaultServerConfig {
48    pub fn new(
49        handle: &str,
50        port: u32,
51        version: &str,
52        token: &str,
53        timeout: u16,
54    ) -> VaultServerConfig {
55        VaultServerConfig {
56            handle: handle.to_string(),
57            port,
58            timeout,
59            token: token.to_string(),
60            version: version.to_string(),
61        }
62    }
63
64    /// If version is [None], defaults to `latest`.
65    pub fn default(version: Option<&str>) -> VaultServerConfig {
66        VaultServerConfig {
67            handle: String::from("vaultrs-vault"),
68            port: 8300,
69            timeout: 15,
70            token: String::from("test"),
71            version: version
72                .map(|v| v.to_string())
73                .unwrap_or_else(|| String::from("latest")),
74        }
75    }
76}
77
78/// Represents a running instance of a Vault server.
79///
80/// This should be built after the [TestInstance] has started and will use the
81/// details from a [VaultServerConfig] to instantiate a new [VaultClient] which
82/// can be used for interacting with the Vault server running in the container.
83pub struct VaultServer {
84    pub address: String,
85    pub address_internal: String,
86    pub config: VaultServerConfig,
87}
88
89impl Server for VaultServer {
90    type Config = VaultServerConfig;
91
92    fn new(opts: &DockerOperations, config: &Self::Config) -> Self {
93        let cont = opts.handle(config.handle.as_str());
94        let address = format!("http://localhost:{}", config.port);
95        let address_internal = format!("http://{}:{}", cont.ip(), config.port);
96
97        VaultServer {
98            address,
99            address_internal,
100            config: config.clone(),
101        }
102    }
103}