vaultrs/
kv1.rs

1use crate::{
2    api::{
3        self,
4        kv1::{
5            requests::{
6                DeleteSecretRequest, GetSecretRequest, ListSecretRequest, SetSecretRequest,
7            },
8            responses::{GetSecretResponse, ListSecretResponse},
9        },
10    },
11    client::Client,
12    error::ClientError,
13};
14
15use serde::{de::DeserializeOwned, Serialize};
16use std::collections::HashMap;
17
18/// Sets the value of the secret at the given path
19///
20/// A key called ttl will trigger some special behavior. See the [Vault KV secrets engine documentation][<https://developer.hashicorp.com/vault/docs/secrets/kv>] for details.
21/// See [SetSecretRequest]
22pub async fn set<T: Serialize>(
23    client: &impl Client,
24    mount: &str,
25    path: &str,
26    data: &HashMap<&str, T>,
27) -> Result<(), ClientError> {
28    let data_value_json = data
29        .serialize(serde_json::value::Serializer)
30        .map_err(|e| ClientError::JsonParseError { source: e })?;
31
32    // Convert our JSON values as bytes to be sent to Vault
33    let data_u8 = serde_json::to_vec(&data_value_json)
34        .map_err(|e| ClientError::JsonParseError { source: e })?;
35
36    let endpoint = SetSecretRequest::builder()
37        .mount(mount)
38        .path(path)
39        .data(data_u8)
40        .build()
41        .unwrap();
42
43    api::exec_with_empty(client, endpoint).await
44}
45
46/// Get value of the secret at given path.
47/// Return the deserialized HashMap of secret directly,
48/// if you need to access additional fields such as lead_duration, use [get_raw]
49pub async fn get<D: DeserializeOwned>(
50    client: &impl Client,
51    mount: &str,
52    path: &str,
53) -> Result<D, ClientError> {
54    // let endpoint = GetSecretRequest::builder()
55    //     .mount(mount)
56    //     .path(path)
57    //     .build()
58    //     .unwrap();
59
60    // let res = api::exec_with_no_result(client, endpoint).await?;
61    let res = get_raw(client, mount, path).await?;
62    serde_json::value::from_value(res.data).map_err(|e| ClientError::JsonParseError { source: e })
63}
64
65/// Get value of the secret at given path, returning the raw response without deserialization
66/// Additional fields are available on raw response, such as lease_duration
67pub async fn get_raw(
68    client: &impl Client,
69    mount: &str,
70    path: &str,
71) -> Result<GetSecretResponse, ClientError> {
72    let endpoint = GetSecretRequest::builder()
73        .mount(mount)
74        .path(path)
75        .build()
76        .unwrap();
77
78    api::exec_with_no_result(client, endpoint).await
79}
80
81/// List secret keys at given location, returning raw server response
82///
83/// See [ListSecretRequest]
84pub async fn list(
85    client: &impl Client,
86    mount: &str,
87    path: &str,
88) -> Result<ListSecretResponse, ClientError> {
89    let endpoint = ListSecretRequest::builder()
90        .mount(mount)
91        .path(path)
92        .build()
93        .unwrap();
94
95    api::exec_with_no_result(client, endpoint).await
96}
97
98/// Delete secret at given location
99///
100/// See [DeleteSecretRequest]
101pub async fn delete(client: &impl Client, mount: &str, path: &str) -> Result<(), ClientError> {
102    let endpoint = DeleteSecretRequest::builder()
103        .mount(mount)
104        .path(path)
105        .build()
106        .unwrap();
107
108    api::exec_with_empty(client, endpoint).await
109}