vaultrs/
ssh.rs

1use crate::api;
2use crate::api::ssh::requests::{GenerateSSHCredsRequest, VerifySSHOTPRequest};
3use crate::api::ssh::responses::{GenerateSSHCredsResponse, VerifySSHOTPResponse};
4use crate::client::Client;
5use crate::error::ClientError;
6
7/// Generates SSH credentials for the given role
8///
9/// See [GenerateSSHCredsRequest]
10pub async fn generate(
11    client: &impl Client,
12    mount: &str,
13    name: &str,
14    ip: &str,
15    username: Option<String>,
16) -> Result<GenerateSSHCredsResponse, ClientError> {
17    let mut endpoint = GenerateSSHCredsRequest::builder();
18    if let Some(u) = username {
19        endpoint.username(u);
20    }
21    api::exec_with_result(
22        client,
23        endpoint.mount(mount).name(name).ip(ip).build().unwrap(),
24    )
25    .await
26}
27
28/// Verify SSH OTP details
29///
30/// See [VerifySSHOTPRequest]
31pub async fn verify_otp(
32    client: &impl Client,
33    mount: &str,
34    otp: &str,
35) -> Result<VerifySSHOTPResponse, ClientError> {
36    let endpoint = VerifySSHOTPRequest::builder()
37        .mount(mount)
38        .otp(otp)
39        .build()
40        .unwrap();
41    api::exec_with_result(client, endpoint).await
42}
43
44pub mod ca {
45    use crate::api;
46    use crate::api::ssh::requests::{
47        DeleteCAInfoRequest, ReadPublicKeyRequest, SignSSHKeyRequest, SignSSHKeyRequestBuilder,
48        SubmitCAInfoRequest,
49    };
50    use crate::api::ssh::responses::{
51        ReadPublicKeyResponse, SignSSHKeyResponse, SubmitCAInfoResponse,
52    };
53    use crate::client::Client;
54    use crate::error::ClientError;
55
56    /// Deletes the stored keys for the CA.
57    ///
58    /// See [DeleteCAInfoRequest]
59    pub async fn delete(client: &impl Client, mount: &str) -> Result<(), ClientError> {
60        let endpoint = DeleteCAInfoRequest::builder().mount(mount).build().unwrap();
61        api::exec_with_empty(client, endpoint).await
62    }
63
64    /// Generates CA certificate internally and returns the public key.
65    ///
66    /// See [SubmitCAInfoRequest]
67    pub async fn generate(
68        client: &impl Client,
69        mount: &str,
70    ) -> Result<SubmitCAInfoResponse, ClientError> {
71        let endpoint = SubmitCAInfoRequest::builder()
72            .mount(mount)
73            .generate_signing_key(true)
74            .build()
75            .unwrap();
76        api::exec_with_result(client, endpoint).await
77    }
78
79    /// Reads the public key of the CA.
80    ///
81    /// See [ReadPublicKeyRequest]
82    pub async fn read(
83        client: &impl Client,
84        mount: &str,
85    ) -> Result<ReadPublicKeyResponse, ClientError> {
86        let endpoint = ReadPublicKeyRequest::builder()
87            .mount(mount)
88            .build()
89            .unwrap();
90        api::exec_with_result(client, endpoint).await
91    }
92
93    /// Signs a public key using the CA certificate.
94    ///
95    /// See [SignSSHKeyRequest]
96    pub async fn sign(
97        client: &impl Client,
98        mount: &str,
99        name: &str,
100        public_key: &str,
101        opts: Option<&mut SignSSHKeyRequestBuilder>,
102    ) -> Result<SignSSHKeyResponse, ClientError> {
103        let mut t = SignSSHKeyRequest::builder();
104        let endpoint = opts
105            .unwrap_or(&mut t)
106            .mount(mount)
107            .name(name)
108            .public_key(public_key)
109            .build()
110            .unwrap();
111        api::exec_with_result(client, endpoint).await
112    }
113
114    /// Sets the private and public key for the CA.
115    ///
116    /// See [SubmitCAInfoRequest]
117    pub async fn set(
118        client: &impl Client,
119        mount: &str,
120        private_key: &str,
121        public_key: &str,
122    ) -> Result<(), ClientError> {
123        let endpoint = SubmitCAInfoRequest::builder()
124            .mount(mount)
125            .private_key(private_key)
126            .public_key(public_key)
127            .build()
128            .unwrap();
129        api::exec_with_empty(client, endpoint).await
130    }
131}
132
133pub mod key {
134    use crate::api;
135    use crate::api::ssh::requests::{DeleteKeyRequest, SetKeyRequest};
136    use crate::client::Client;
137    use crate::error::ClientError;
138
139    /// Creates or updates a SSH key
140    ///
141    /// See [SetKeyRequest]
142    pub async fn set(
143        client: &impl Client,
144        mount: &str,
145        name: &str,
146        key: &str,
147    ) -> Result<(), ClientError> {
148        let endpoint = SetKeyRequest::builder()
149            .mount(mount)
150            .name(name)
151            .key(key)
152            .build()
153            .unwrap();
154        api::exec_with_empty(client, endpoint).await
155    }
156
157    /// Deletes a SSH key
158    ///
159    /// See [DeleteKeyRequest]
160    pub async fn delete(client: &impl Client, mount: &str, name: &str) -> Result<(), ClientError> {
161        let endpoint = DeleteKeyRequest::builder()
162            .mount(mount)
163            .name(name)
164            .build()
165            .unwrap();
166        api::exec_with_empty(client, endpoint).await
167    }
168}
169
170pub mod role {
171    use crate::api;
172    use crate::api::ssh::requests::ListRolesByIPRequest;
173    use crate::api::ssh::responses::ListRolesByIPResponse;
174    use crate::api::ssh::{
175        requests::{
176            DeleteRoleRequest, ListRolesRequest, ReadRoleRequest, SetRoleRequest,
177            SetRoleRequestBuilder,
178        },
179        responses::{ListRolesResponse, ReadRoleResponse},
180    };
181    use crate::client::Client;
182    use crate::error::ClientError;
183
184    /// Deletes a role
185    ///
186    /// See [DeleteRoleRequest]
187    pub async fn delete(client: &impl Client, mount: &str, name: &str) -> Result<(), ClientError> {
188        let endpoint = DeleteRoleRequest::builder()
189            .mount(mount)
190            .name(name)
191            .build()
192            .unwrap();
193        api::exec_with_empty(client, endpoint).await
194    }
195
196    /// Lists all roles
197    ///
198    /// See [ListRolesRequest]
199    pub async fn list(client: &impl Client, mount: &str) -> Result<ListRolesResponse, ClientError> {
200        let endpoint = ListRolesRequest::builder().mount(mount).build().unwrap();
201        api::exec_with_result(client, endpoint).await
202    }
203
204    /// Lists all roles by IP
205    ///
206    /// See [ListRolesByIPRequest]
207    pub async fn list_by_ip(
208        client: &impl Client,
209        mount: &str,
210        ip: &str,
211    ) -> Result<ListRolesByIPResponse, ClientError> {
212        let endpoint = ListRolesByIPRequest::builder()
213            .mount(mount)
214            .ip(ip)
215            .build()
216            .unwrap();
217        api::exec_with_result(client, endpoint).await
218    }
219
220    /// Reads a role
221    ///
222    /// See [ReadRoleRequest]
223    pub async fn read(
224        client: &impl Client,
225        mount: &str,
226        name: &str,
227    ) -> Result<ReadRoleResponse, ClientError> {
228        let endpoint = ReadRoleRequest::builder()
229            .mount(mount)
230            .name(name)
231            .build()
232            .unwrap();
233        api::exec_with_result(client, endpoint).await
234    }
235
236    /// Creates or updates a role
237    ///
238    /// See [SetRoleRequest]
239    pub async fn set(
240        client: &impl Client,
241        mount: &str,
242        name: &str,
243        opts: Option<&mut SetRoleRequestBuilder>,
244    ) -> Result<(), ClientError> {
245        let mut t = SetRoleRequest::builder();
246        let endpoint = opts
247            .unwrap_or(&mut t)
248            .mount(mount)
249            .name(name)
250            .build()
251            .unwrap();
252        api::exec_with_empty(client, endpoint).await
253    }
254}
255
256pub mod zero {
257    use crate::api;
258    use crate::api::ssh::requests::{
259        ConfigureZeroAddressRolesRequest, DeleteZeroAddressRolesRequest,
260        ListZeroAddressRolesRequest,
261    };
262    use crate::api::ssh::responses::ListZeroAddressRolesResponse;
263    use crate::client::Client;
264    use crate::error::ClientError;
265
266    /// Deletes all zero-address roles
267    ///
268    /// See [DeleteZeroAddressRolesRequest]
269    pub async fn delete(client: &impl Client, mount: &str) -> Result<(), ClientError> {
270        let endpoint = DeleteZeroAddressRolesRequest::builder()
271            .mount(mount)
272            .build()
273            .unwrap();
274        api::exec_with_empty(client, endpoint).await
275    }
276
277    /// Lists all zero-address roles
278    ///
279    /// See [ListZeroAddressRolesRequest]
280    pub async fn list(
281        client: &impl Client,
282        mount: &str,
283    ) -> Result<ListZeroAddressRolesResponse, ClientError> {
284        let endpoint = ListZeroAddressRolesRequest::builder()
285            .mount(mount)
286            .build()
287            .unwrap();
288        api::exec_with_result(client, endpoint).await
289    }
290
291    /// Sets zero-address roles
292    ///
293    /// See [ConfigureZeroAddressRolesRequest]
294    pub async fn set(
295        client: &impl Client,
296        mount: &str,
297        roles: Vec<String>,
298    ) -> Result<(), ClientError> {
299        let endpoint = ConfigureZeroAddressRolesRequest::builder()
300            .mount(mount)
301            .roles(roles)
302            .build()
303            .unwrap();
304        api::exec_with_empty(client, endpoint).await
305    }
306}