vaultrs/
kv2.rs

1use crate::{
2    api::{
3        self,
4        kv2::{
5            requests::{
6                DeleteLatestSecretVersionRequest, DeleteSecretMetadataRequest,
7                DeleteSecretVersionsRequest, DestroySecretVersionsRequest, ListSecretsRequest,
8                ReadSecretMetadataRequest, ReadSecretRequest, SetSecretMetadataRequest,
9                SetSecretMetadataRequestBuilder, SetSecretRequest, SetSecretRequestOptions,
10                UndeleteSecretVersionsRequest,
11            },
12            responses::{ReadSecretMetadataResponse, SecretVersionMetadata},
13        },
14    },
15    client::Client,
16    error::ClientError,
17};
18use serde::{de::DeserializeOwned, Serialize};
19
20/// Soft-delete the latest version of a secret
21///
22/// See [DeleteLatestSecretVersionRequest]
23pub async fn delete_latest(
24    client: &impl Client,
25    mount: &str,
26    path: &str,
27) -> Result<(), ClientError> {
28    let endpoint = DeleteLatestSecretVersionRequest::builder()
29        .mount(mount)
30        .path(path)
31        .build()
32        .unwrap();
33    api::exec_with_empty(client, endpoint).await
34}
35
36/// Delete all metadata and versions of a secret
37///
38/// See [DeleteSecretMetadataRequest]
39pub async fn delete_metadata(
40    client: &impl Client,
41    mount: &str,
42    path: &str,
43) -> Result<(), ClientError> {
44    let endpoint = DeleteSecretMetadataRequest::builder()
45        .mount(mount)
46        .path(path)
47        .build()
48        .unwrap();
49    api::exec_with_empty(client, endpoint).await
50}
51
52/// Soft-delete specific versions of a secret
53///
54/// See [DeleteSecretVersionsRequest]
55pub async fn delete_versions(
56    client: &impl Client,
57    mount: &str,
58    path: &str,
59    versions: Vec<u64>,
60) -> Result<(), ClientError> {
61    let endpoint = DeleteSecretVersionsRequest::builder()
62        .mount(mount)
63        .path(path)
64        .versions(versions)
65        .build()
66        .unwrap();
67    api::exec_with_empty(client, endpoint).await
68}
69
70/// Permanently delete specific versions of a secret
71///
72/// See [DestroySecretVersionsRequest]
73pub async fn destroy_versions(
74    client: &impl Client,
75    mount: &str,
76    path: &str,
77    versions: Vec<u64>,
78) -> Result<(), ClientError> {
79    let endpoint = DestroySecretVersionsRequest::builder()
80        .mount(mount)
81        .path(path)
82        .versions(versions)
83        .build()
84        .unwrap();
85    api::exec_with_empty(client, endpoint).await
86}
87
88/// Lists all secret keys at the given path
89///
90/// See [ListSecretsRequest]
91pub async fn list(
92    client: &impl Client,
93    mount: &str,
94    path: &str,
95) -> Result<Vec<String>, ClientError> {
96    let endpoint = ListSecretsRequest::builder()
97        .mount(mount)
98        .path(path)
99        .build()
100        .unwrap();
101    Ok(api::exec_with_result(client, endpoint).await?.keys)
102}
103
104/// Reads the value of the secret at the given path
105///
106/// See [ReadSecretRequest]
107pub async fn read<D: DeserializeOwned>(
108    client: &impl Client,
109    mount: &str,
110    path: &str,
111) -> Result<D, ClientError> {
112    let endpoint = ReadSecretRequest::builder()
113        .mount(mount)
114        .path(path)
115        .build()
116        .unwrap();
117    let res = api::exec_with_result(client, endpoint).await?;
118    serde_json::value::from_value(res.data).map_err(|e| ClientError::JsonParseError { source: e })
119}
120
121/// Reads the metadata of the secret at the given path
122///
123/// See [ReadSecretMetadataRequest]
124pub async fn read_metadata(
125    client: &impl Client,
126    mount: &str,
127    path: &str,
128) -> Result<ReadSecretMetadataResponse, ClientError> {
129    let endpoint = ReadSecretMetadataRequest::builder()
130        .mount(mount)
131        .path(path)
132        .build()
133        .unwrap();
134    api::exec_with_result(client, endpoint).await
135}
136
137/// Reads the value of the secret at the given version and path
138///
139/// See [ReadSecretRequest]
140pub async fn read_version<D: DeserializeOwned>(
141    client: &impl Client,
142    mount: &str,
143    path: &str,
144    version: u64,
145) -> Result<D, ClientError> {
146    let endpoint = ReadSecretRequest::builder()
147        .mount(mount)
148        .path(path)
149        .version(Some(version))
150        .build()
151        .unwrap();
152    let res = api::exec_with_result(client, endpoint).await?;
153    serde_json::value::from_value(res.data).map_err(|e| ClientError::JsonParseError { source: e })
154}
155
156/// Sets the value of the secret at the given path
157///
158/// See [SetSecretRequest]
159pub async fn set<T: Serialize>(
160    client: &impl Client,
161    mount: &str,
162    path: &str,
163    data: &T,
164) -> Result<SecretVersionMetadata, ClientError> {
165    let data_value = data
166        .serialize(serde_json::value::Serializer)
167        .map_err(|e| ClientError::JsonParseError { source: e })?;
168    let endpoint = SetSecretRequest::builder()
169        .mount(mount)
170        .path(path)
171        .data(data_value)
172        .build()
173        .unwrap();
174    api::exec_with_result(client, endpoint).await
175}
176
177/// Sets the value of the secret at the given path
178/// including an argument for [SetSecretRequestOptions]
179///
180/// See [SetSecretRequest]
181pub async fn set_with_options<T: Serialize>(
182    client: &impl Client,
183    mount: &str,
184    path: &str,
185    data: &T,
186    options: SetSecretRequestOptions,
187) -> Result<SecretVersionMetadata, ClientError> {
188    let data_value = data
189        .serialize(serde_json::value::Serializer)
190        .map_err(|e| ClientError::JsonParseError { source: e })?;
191    let endpoint = SetSecretRequest::builder()
192        .mount(mount)
193        .path(path)
194        .data(data_value)
195        .options(options)
196        .build()
197        .unwrap();
198    api::exec_with_result(client, endpoint).await
199}
200
201/// Sets the value of the secret at the given path
202///
203/// See [SetSecretMetadataRequest]
204pub async fn set_metadata(
205    client: &impl Client,
206    mount: &str,
207    path: &str,
208    opts: Option<&mut SetSecretMetadataRequestBuilder>,
209) -> Result<(), ClientError> {
210    let mut t = SetSecretMetadataRequest::builder();
211    let endpoint = opts
212        .unwrap_or(&mut t)
213        .mount(mount)
214        .path(path)
215        .build()
216        .unwrap();
217    api::exec_with_empty(client, endpoint).await
218}
219
220/// Undelete specific versions of a secret
221///
222/// See [UndeleteSecretVersionsRequest]
223pub async fn undelete_versions(
224    client: &impl Client,
225    mount: &str,
226    path: &str,
227    versions: Vec<u64>,
228) -> Result<(), ClientError> {
229    let endpoint = UndeleteSecretVersionsRequest::builder()
230        .mount(mount)
231        .path(path)
232        .versions(versions)
233        .build()
234        .unwrap();
235    api::exec_with_empty(client, endpoint).await
236}
237
238pub mod config {
239    use crate::{
240        api::{
241            self,
242            kv2::{
243                requests::{
244                    ReadConfigurationRequest, SetConfigurationRequest,
245                    SetConfigurationRequestBuilder,
246                },
247                responses::ReadConfigurationResponse,
248            },
249        },
250        client::Client,
251        error::ClientError,
252    };
253
254    /// Read the configuration of the mounted KV engine
255    ///
256    /// See [ReadConfigurationResponse]
257    pub async fn read(
258        client: &impl Client,
259        mount: &str,
260    ) -> Result<ReadConfigurationResponse, ClientError> {
261        let endpoint = ReadConfigurationRequest::builder()
262            .mount(mount)
263            .build()
264            .unwrap();
265        api::exec_with_result(client, endpoint).await
266    }
267
268    /// Update the configuration of the mounted KV engine
269    ///
270    /// See [SetConfigurationRequest]
271    pub async fn set(
272        client: &impl Client,
273        mount: &str,
274        opts: Option<&mut SetConfigurationRequestBuilder>,
275    ) -> Result<(), ClientError> {
276        let mut t = SetConfigurationRequest::builder();
277        let endpoint = opts.unwrap_or(&mut t).mount(mount).build().unwrap();
278        api::exec_with_empty(client, endpoint).await
279    }
280}