1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//! # vaultrs
//!
//! > An asynchronous Rust client library for the [Hashicorp Vault][1] API
//!
//! The following backends are currently supported:
//!
//! * Auth
//!   * [AppleRole](https://www.vaultproject.io/docs/auth/approle)
//!   * [JWT/OIDC](https://www.vaultproject.io/api-docs/auth/jwt)
//!   * [Token](https://www.vaultproject.io/docs/auth/token)
//!   * [Userpass](https://www.vaultproject.io/docs/auth/userpass)
//! * Secrets
//!   * [Databases](https://www.vaultproject.io/api-docs/secret/databases)
//!   * [KV v2](https://www.vaultproject.io/docs/secrets/kv/kv-v2)
//!   * [PKI](https://www.vaultproject.io/docs/secrets/pki)
//!   * [SSH](https://www.vaultproject.io/docs/secrets/ssh)
//! * Sys
//!   * [Health](https://www.vaultproject.io/api-docs/system/health)
//!   * [Policies](https://www.vaultproject.io/api-docs/system/policy)
//!   * [Sealing](https://www.vaultproject.io/api-docs/system/seal)
//!   * [Wrapping](https://www.vaultproject.io/docs/concepts/response-wrapping)
//!
//! See something missing?
//! [Open an issue](https://github.com/jmgilman/vaultrs/issues/new).
//!
//! ## Installation
//!
//! Add vaultrs as a dependency to your cargo.toml:
//! ```ignore
//! [dependencies]
//! vaultrs = "0.6.2"
//! ```
//!
//! ## Usage
//!
//! ### Basic
//!
//! The client is used to configure the connection to Vault and is required to
//! be passed to all API calls for execution. Behind the scenes it uses an
//! asynchronous client from [Reqwest](https://docs.rs/reqwest/) for
//! communicating to Vault.
//!
//! ```rust
//! use vaultrs::client::{Client, VaultClient, VaultClientSettingsBuilder};
//!
//! // Create a client
//! let mut client = VaultClient::new(
//!     VaultClientSettingsBuilder::default()
//!         .address("https://127.0.0.1:8200")
//!         .token("TOKEN")
//!         .build()
//!         .unwrap()
//! ).unwrap();
//!
//! ```
//!
//! ### Secrets
//!
//! The library currently supports all operations available for version 2 of the
//! key/value store.
//!
//! ```should_panic
//! use serde::{Deserialize, Serialize};
//! use vaultrs::kv2;
//! # use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};
//!
//! # let client = VaultClient::new(
//! #     VaultClientSettingsBuilder::default()
//! #         .address("https://127.0.0.1:8200")
//! #         .token("TOKEN")
//! #         .build()
//! #         .unwrap()
//! # ).unwrap();
//! #
//! // Create and read secrets
//! #[derive(Debug, Deserialize, Serialize)]
//! struct MySecret {
//!     key: String,
//!     password: String,
//! }
//!
//! let secret = MySecret {
//!     key: "super".to_string(),
//!     password: "secret".to_string(),
//! };
//! # tokio_test::block_on(async {
//! kv2::set(
//!     &client,
//!     "secret",
//!     "mysecret",
//!     &secret,
//! ).await;
//!
//! let secret: MySecret = kv2::read(&client, "secret", "mysecret").await.unwrap();
//! println!("{}", secret.password) // "secret"
//! # })
//! ```
//!
//! ### PKI
//!
//! The library currently supports all operations available for the PKI secrets
//! engine.
//!
//! ```should_panic
//! use vaultrs::api::pki::requests::GenerateCertificateRequest;
//! # use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};
//! use vaultrs::pki::cert;
//!
//! # let client = VaultClient::new(
//! #     VaultClientSettingsBuilder::default()
//! #         .address("https://127.0.0.1:8200")
//! #         .token("TOKEN")
//! #         .build()
//! #         .unwrap()
//! # ).unwrap();
//! #
//! # tokio_test::block_on(async {
//! // Generate a certificate using the PKI backend
//! let cert = cert::generate(
//!     &client,
//!     "pki",
//!     "my_role",
//!     Some(GenerateCertificateRequest::builder().common_name("test.com")),
//! ).await.unwrap();
//! println!("{}", cert.certificate) // "{PEM encoded certificate}"
//! # })
//! ```
//!
//! ### Wrapping
//!
//! All requests implement the ability to be
//! [wrapped](https://www.vaultproject.io/docs/concepts/response-wrapping). These
//! can be passed in your application internally before being unwrapped.
//!
//! ```should_panic
//! use vaultrs::api::ResponseWrapper;
//! use vaultrs::api::sys::requests::ListMountsRequest;
//! # use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};
//!
//! # let client = VaultClient::new(
//! #     VaultClientSettingsBuilder::default()
//! #         .address("https://127.0.0.1:8200")
//! #         .token("TOKEN")
//! #         .build()
//! #         .unwrap()
//! # ).unwrap();
//! #
//! # tokio_test::block_on(async {
//! let endpoint = ListMountsRequest::builder().build().unwrap();
//! let wrap_resp = endpoint.wrap(&client).await; // Wrapped response
//! assert!(wrap_resp.is_ok());
//!
//! let wrap_resp = wrap_resp.unwrap(); // Unwrap Result<>
//! let info = wrap_resp.lookup(&client).await; // Check status of this wrapped response
//! assert!(info.is_ok());
//!
//! let unwrap_resp = wrap_resp.unwrap(&client).await; // Unwrap the response
//! assert!(unwrap_resp.is_ok());
//!
//! let info = wrap_resp.lookup(&client).await; // Error: response already unwrapped
//! assert!(info.is_err());
//! # })
//! ```
//!
//! ## Error Handling
//!
//! All errors generated by this crate are wrapped in the `ClientError` enum
//! provided by the crate. API warnings are automatically captured via `log` and
//! API errors are captured and returned as their own variant. Connection
//! related errors from `rusify` are wrapped and returned as a single variant.
//!
//! ## Testing
//!
//! See the the [tests](tests) directory for tests. Run tests with `cargo test`.
//!
//! **Note**: All tests rely on bringing up a local Vault development server
//! using Docker. In order to run tests Docker must be running locally (Docker
//! Desktop works).
//!
//! ## Contributing
//!
//! 1. Fork it (https://github.com/jmgilman/vaultrs/fork)
//! 2. Create your feature branch (git checkout -b feature/fooBar)
//! 3. Commit your changes (git commit -am 'Add some fooBar')
//! 4. Push to the branch (git push origin feature/fooBar)
//! 5. Create a new Pull Request
//!
//! See [CONTRIBUTING](CONTRIBUTING.md) for extensive documentation on the
//! architecture of this library and how to add additional functionality to it.
//!
//! [1]: https://www.vaultproject.io/
#[macro_use]
extern crate derive_builder;
#[macro_use]
extern crate tracing;

pub mod api;
pub mod auth;
pub mod client;
pub mod database;
pub mod error;
pub mod kv2;
pub mod pki;
pub mod ssh;
pub mod sys;
pub mod token;