vaultrs/
sys.rs

1use crate::{
2    api::{
3        self,
4        sys::{
5            requests::{
6                ReadHealthRequest, SealRequest, StartInitializationRequest,
7                StartInitializationRequestBuilder, UnsealRequest,
8            },
9            responses::{ReadHealthResponse, StartInitializationResponse, UnsealResponse},
10        },
11    },
12    client::Client,
13    error::ClientError,
14};
15
16/// Represents the status of a Vault server.
17#[derive(Debug)]
18pub enum ServerStatus {
19    OK,
20    PERFSTANDBY,
21    RECOVERY,
22    SEALED,
23    STANDBY,
24    UNINITIALIZED,
25    UNKNOWN,
26}
27
28/// Returns health information about the Vault server.
29///
30/// See [ReadHealthRequest]
31pub async fn health(client: &impl Client) -> Result<ReadHealthResponse, ClientError> {
32    let endpoint = ReadHealthRequest::builder().build().unwrap();
33    api::exec_with_no_result(client, endpoint).await
34}
35
36/// Initialize a new Vault. The Vault must not have been previously initialized.
37///
38/// See [StartInitializationRequest]
39pub async fn start_initialization(
40    client: &impl Client,
41    secret_shares: u64,
42    secret_threshold: u64,
43    opts: Option<&mut StartInitializationRequestBuilder>,
44) -> Result<StartInitializationResponse, ClientError> {
45    let mut t = StartInitializationRequest::builder();
46    let endpoint = opts
47        .unwrap_or(&mut t)
48        .secret_shares(secret_shares)
49        .secret_threshold(secret_threshold)
50        .build()
51        .unwrap();
52    api::exec_with_no_result(client, endpoint).await
53}
54
55/// Seals the Vault server.
56///
57/// See [SealRequest]
58pub async fn seal(client: &impl Client) -> Result<(), ClientError> {
59    let endpoint = SealRequest::builder().build().unwrap();
60    api::exec_with_empty(client, endpoint).await
61}
62
63/// Unseals the Vault server.
64///
65/// See [UnsealRequest]
66pub async fn unseal(
67    client: &impl Client,
68    key: Option<String>,
69    reset: Option<bool>,
70    migrate: Option<bool>,
71) -> Result<UnsealResponse, ClientError> {
72    let endpoint = UnsealRequest::builder()
73        .key(key)
74        .reset(reset)
75        .migrate(migrate)
76        .build()
77        .unwrap();
78    api::exec_with_no_result(client, endpoint).await
79}
80
81/// Returns the status of the Vault server.
82///
83/// See [ReadHealthRequest]
84pub async fn status(client: &impl Client) -> Result<ServerStatus, ClientError> {
85    let result = health(client).await;
86    match result {
87        Ok(_) => Ok(ServerStatus::OK),
88        Err(e) => match e {
89            ClientError::RestClientError { source } => match source {
90                rustify::errors::ClientError::ServerResponseError {
91                    code: 429,
92                    content: _,
93                } => Ok(ServerStatus::STANDBY),
94                rustify::errors::ClientError::ServerResponseError {
95                    code: 472,
96                    content: _,
97                } => Ok(ServerStatus::RECOVERY),
98                rustify::errors::ClientError::ServerResponseError {
99                    code: 473,
100                    content: _,
101                } => Ok(ServerStatus::PERFSTANDBY),
102                rustify::errors::ClientError::ServerResponseError {
103                    code: 501,
104                    content: _,
105                } => Ok(ServerStatus::UNINITIALIZED),
106                rustify::errors::ClientError::ServerResponseError {
107                    code: 503,
108                    content: _,
109                } => Ok(ServerStatus::SEALED),
110                _ => Err(ClientError::RestClientError { source }),
111            },
112            _ => Err(e),
113        },
114    }
115}
116
117pub mod auth {
118    use std::collections::HashMap;
119
120    use crate::api;
121    use crate::api::sys::requests::{
122        DisableAuthRequest, EnableAuthRequest, EnableAuthRequestBuilder, ListAuthsRequest,
123    };
124    use crate::api::sys::responses::AuthResponse;
125    use crate::client::Client;
126    use crate::error::ClientError;
127
128    /// Enables an auth engine at the given path
129    ///
130    /// See [EnableAuthRequest]
131    pub async fn enable(
132        client: &impl Client,
133        path: &str,
134        engine_type: &str,
135        opts: Option<&mut EnableAuthRequestBuilder>,
136    ) -> Result<(), ClientError> {
137        let mut t = EnableAuthRequest::builder();
138        let endpoint = opts
139            .unwrap_or(&mut t)
140            .path(path)
141            .engine_type(engine_type)
142            .build()
143            .unwrap();
144        api::exec_with_empty(client, endpoint).await
145    }
146
147    /// Disables the auth method at the given auth path.
148    ///
149    /// `sudo` required - This endpoint requires `sudo` capability in
150    ///  addition to any path-specific capabilities.
151    ///
152    /// See [DisableAuthRequest]
153    pub async fn disable(client: &impl Client, path: &str) -> Result<(), ClientError> {
154        let endpoint = DisableAuthRequest::builder().path(path).build().unwrap();
155        api::exec_with_empty(client, endpoint).await
156    }
157
158    /// Lists all mounted auth engines
159    ///
160    /// See [ListAuthsRequest]
161    pub async fn list(client: &impl Client) -> Result<HashMap<String, AuthResponse>, ClientError> {
162        let endpoint = ListAuthsRequest::builder().build().unwrap();
163        api::exec_with_result(client, endpoint).await
164    }
165}
166
167pub mod mount {
168    use std::collections::HashMap;
169
170    use crate::api;
171    use crate::api::sys::requests::{
172        DisableEngineRequest, EnableEngineRequest, EnableEngineRequestBuilder,
173        GetConfigurationOfTheSecretEngineRequest, ListMountsRequest,
174    };
175    use crate::api::sys::responses::{GetConfigurationOfTheSecretEngineResponse, MountResponse};
176    use crate::client::Client;
177    use crate::error::ClientError;
178
179    /// Enables a secret engine at the given path
180    ///
181    /// See [EnableEngineRequest]
182    pub async fn enable(
183        client: &impl Client,
184        path: &str,
185        engine_type: &str,
186        opts: Option<&mut EnableEngineRequestBuilder>,
187    ) -> Result<(), ClientError> {
188        let mut t = EnableEngineRequest::builder();
189        let endpoint = opts
190            .unwrap_or(&mut t)
191            .path(path)
192            .engine_type(engine_type)
193            .build()
194            .unwrap();
195        api::exec_with_empty(client, endpoint).await
196    }
197
198    /// Disable a secret engine at the given path
199    ///
200    /// See [DisableEngineRequest]
201    #[instrument(skip(client), err)]
202    pub async fn disable(client: &impl Client, path: &str) -> Result<(), ClientError> {
203        let endpoint = DisableEngineRequest::builder().path(path).build().unwrap();
204        api::exec_with_empty(client, endpoint).await
205    }
206
207    /// This endpoint returns the configuration of a specific secret engine.
208    ///
209    /// See [GetConfigurationOfTheSecretEngineRequest]
210    #[instrument(skip(client), err)]
211    pub async fn get_configuration_of_a_secret_engine(
212        client: &impl Client,
213        path: &str,
214    ) -> Result<GetConfigurationOfTheSecretEngineResponse, ClientError> {
215        let endpoint = GetConfigurationOfTheSecretEngineRequest::builder()
216            .path(path)
217            .build()
218            .unwrap();
219        api::exec_with_result(client, endpoint).await
220    }
221
222    /// Lists all mounted secret engines
223    ///
224    /// See [ListMountsRequest]
225    pub async fn list(client: &impl Client) -> Result<HashMap<String, MountResponse>, ClientError> {
226        let endpoint = ListMountsRequest::builder().build().unwrap();
227        api::exec_with_result(client, endpoint).await
228    }
229}
230
231pub mod remount {
232    use crate::{
233        api::{
234            self,
235            sys::{
236                requests::{RemountRequest, RemountStatusRequest},
237                responses::{RemountResponse, RemountStatusResponse},
238            },
239        },
240        client::Client,
241        error::ClientError,
242    };
243
244    /// This endpoint moves an already-mounted backend to a new mount point.
245    ///
246    /// See [RemountRequest]
247    pub async fn remount(
248        client: &impl Client,
249        from: &str,
250        to: &str,
251    ) -> Result<RemountResponse, ClientError> {
252        let endpoint = RemountRequest::builder().from(from).to(to).build().unwrap();
253        dbg!(&endpoint);
254        api::exec_with_result(client, endpoint).await
255    }
256
257    /// This endpoint is used to monitor the status of a mount migration operation.
258    ///
259    /// See [RemountStatusRequest]
260    #[instrument(skip(client), err)]
261    pub async fn remount_status(
262        client: &impl Client,
263        migration_id: &str,
264    ) -> Result<RemountStatusResponse, ClientError> {
265        let endpoint = RemountStatusRequest::builder()
266            .migration_id(migration_id)
267            .build()
268            .unwrap();
269        api::exec_with_result(client, endpoint).await
270    }
271}
272
273pub mod policy {
274    use crate::{
275        api::{
276            self,
277            sys::{
278                requests::{
279                    CreatePolicyRequest, DeletePolicyRequest, ListPoliciesRequest,
280                    ReadPolicyRequest,
281                },
282                responses::{ListPoliciesResponse, ReadPolicyResponse},
283            },
284        },
285        client::Client,
286        error::ClientError,
287    };
288
289    /// Deletes the given policy.
290    ///
291    /// See [DeletePolicyRequest]
292    pub async fn delete(client: &impl Client, name: &str) -> Result<(), ClientError> {
293        let endpoint = DeletePolicyRequest::builder().name(name).build().unwrap();
294        api::exec_with_empty(client, endpoint).await
295    }
296
297    /// Lists all configured policies.
298    ///
299    /// See [ListPoliciesRequest]
300    pub async fn list(client: &impl Client) -> Result<ListPoliciesResponse, ClientError> {
301        let endpoint = ListPoliciesRequest::builder().build().unwrap();
302        api::exec_with_result(client, endpoint).await
303    }
304
305    /// Reads the given policy.
306    ///
307    /// See [ReadPolicyRequest]
308    pub async fn read(client: &impl Client, name: &str) -> Result<ReadPolicyResponse, ClientError> {
309        let endpoint = ReadPolicyRequest::builder().name(name).build().unwrap();
310        api::exec_with_result(client, endpoint).await
311    }
312
313    /// Sets the given policy.
314    ///
315    /// See [CreatePolicyRequest]
316    pub async fn set(client: &impl Client, name: &str, policy: &str) -> Result<(), ClientError> {
317        let endpoint = CreatePolicyRequest::builder()
318            .name(name)
319            .policy(policy)
320            .build()
321            .unwrap();
322        api::exec_with_empty(client, endpoint).await
323    }
324}
325
326pub mod wrapping {
327    use serde::de::DeserializeOwned;
328
329    use crate::{
330        api::{
331            self,
332            sys::{
333                requests::{UnwrapRequest, WrappingLookupRequest},
334                responses::WrappingLookupResponse,
335            },
336        },
337        client::Client,
338        error::ClientError,
339    };
340
341    /// Looks up information about a token wrapping response
342    ///
343    /// See [WrappingLookupResponse]
344    pub async fn lookup(
345        client: &impl Client,
346        token: &str,
347    ) -> Result<WrappingLookupResponse, ClientError> {
348        let endpoint = WrappingLookupRequest::builder()
349            .token(token)
350            .build()
351            .unwrap();
352        api::exec_with_result(client, endpoint).await
353    }
354
355    /// Unwraps a token wrapped response
356    ///
357    /// See [UnwrapRequest]
358    pub async fn unwrap<D: DeserializeOwned>(
359        client: &impl Client,
360        token: Option<&str>,
361    ) -> Result<D, ClientError> {
362        let endpoint = UnwrapRequest {
363            token: token.map(|v| v.to_string()),
364        };
365        let res = api::exec_with_result(client, endpoint).await?;
366        serde_json::value::from_value(res).map_err(|e| ClientError::JsonParseError { source: e })
367    }
368}
369
370pub mod tools {
371    use crate::{
372        api::{
373            self,
374            sys::{
375                requests::{RandomRequest, RandomRequestBuilder},
376                responses::RandomResponse,
377            },
378        },
379        client::Client,
380        error::ClientError,
381    };
382
383    /// Returns high-quality random bytes of the specified length.
384    ///
385    /// See [RandomResponse]
386    #[instrument(skip(client, opts), err)]
387    pub async fn random(
388        client: &impl Client,
389        opts: Option<&mut RandomRequestBuilder>,
390    ) -> Result<RandomResponse, ClientError> {
391        let mut t = RandomRequest::builder();
392        let endpoint = opts.unwrap_or(&mut t).build().unwrap();
393        api::exec_with_result(client, endpoint).await
394    }
395}