testcontainers_modules/hashicorp_vault/
mod.rs1use std::{borrow::Cow, collections::BTreeMap};
2
3use testcontainers::{
4 core::{wait::HttpWaitStrategy, ContainerPort, WaitFor},
5 Image,
6};
7
8const DEFAULT_IMAGE_NAME: &str = "hashicorp/vault";
9const DEFAULT_IMAGE_TAG: &str = "1.17";
10
11#[derive(Debug, Clone)]
29pub struct HashicorpVault {
30 name: String,
31 tag: String,
32 env_vars: BTreeMap<String, String>,
33}
34
35impl Default for HashicorpVault {
36 fn default() -> Self {
41 let mut env_vars = BTreeMap::new();
42 env_vars.insert("VAULT_DEV_ROOT_TOKEN_ID".to_string(), "myroot".to_string());
43 HashicorpVault::new(
44 DEFAULT_IMAGE_NAME.to_string(),
45 DEFAULT_IMAGE_TAG.to_string(),
46 env_vars,
47 )
48 }
49}
50
51impl HashicorpVault {
52 fn new(name: String, tag: String, env_vars: BTreeMap<String, String>) -> Self {
53 HashicorpVault {
54 name,
55 tag,
56 env_vars,
57 }
58 }
59}
60
61impl Image for HashicorpVault {
62 fn name(&self) -> &str {
63 &self.name
64 }
65
66 fn tag(&self) -> &str {
67 &self.tag
68 }
69
70 fn ready_conditions(&self) -> Vec<WaitFor> {
71 let http_strategy = HttpWaitStrategy::new("/sys/health")
72 .with_port(ContainerPort::Tcp(8200))
73 .with_response_matcher(|resp| resp.status().as_u16() == 200);
74 vec![WaitFor::http(http_strategy)]
75 }
76
77 fn env_vars(
78 &self,
79 ) -> impl IntoIterator<Item = (impl Into<Cow<'_, str>>, impl Into<Cow<'_, str>>)> {
80 &self.env_vars
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use serde::{Deserialize, Serialize};
87 use vaultrs::{
88 client::{VaultClient, VaultClientSettingsBuilder},
89 kv2,
90 };
91
92 use super::*;
93 use crate::testcontainers::runners::AsyncRunner;
94
95 #[derive(Debug, Deserialize, Serialize)]
97 struct MySecret {
98 key: String,
99 password: String,
100 }
101
102 #[tokio::test]
103 async fn hashicorp_vault_secret_set_and_read(
104 ) -> Result<(), Box<dyn std::error::Error + 'static>> {
105 let vault = HashicorpVault::default().start().await.unwrap();
106 let endpoint = format!("http://0.0.0.0:{}", vault.get_host_port_ipv4(8200).await?);
107
108 let client = VaultClient::new(
110 VaultClientSettingsBuilder::default()
111 .address(endpoint)
112 .token("myroot")
113 .build()
114 .unwrap(),
115 )
116 .unwrap();
117
118 let secret = MySecret {
119 key: "super".to_string(),
120 password: "secret".to_string(),
121 };
122 kv2::set(&client, "secret", "mysecret", &secret).await?;
123
124 let secret: MySecret = kv2::read(&client, "secret", "mysecret").await.unwrap();
125 assert_eq!(secret.key, "super");
126 assert_eq!(secret.password, "secret");
127 Ok(())
128 }
129}