1pub mod local;
2pub mod remote;
3
4#[cfg(feature = "aws-secretsmanager")]
5use aws_config::SdkConfig as AwsConfig;
6use serde::de::DeserializeOwned;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::fmt::Debug;
10#[allow(unused)]
11use tracing::{debug, error, info, trace, warn};
12
13use crate::error::RegentError;
14use crate::secrets::local::environment_variables::EnvVarSecretProvider;
15use crate::secrets::local::files::FilesSecretProvider;
16#[cfg(feature = "aws-secretsmanager")]
17use crate::secrets::remote::aws_secrets_manager::AwsSecretsManagerProvider;
18#[cfg(feature = "gcp-secretmanager")]
19use crate::secrets::remote::gcp_secret_manager::GcpSecretProvider;
20
21#[derive(Clone)]
22pub enum SecretProvider {
23 Files(FilesSecretProvider),
24 EnvironmentVariable(EnvVarSecretProvider),
25 #[cfg(feature = "aws-secretsmanager")]
26 AwsSecretsManager(AwsSecretsManagerProvider),
27 #[cfg(feature = "gcp-secretmanager")]
28 GcpSecretManager(GcpSecretProvider),
29 }
32
33impl SecretProvider {
34 pub fn files() -> Self {
35 Self::Files(FilesSecretProvider::new())
36 }
37
38 pub fn env_var() -> Self {
39 Self::EnvironmentVariable(EnvVarSecretProvider::new())
40 }
41
42 #[cfg(feature = "aws-secretsmanager")]
43 pub fn aws_secretsmanager(aws_config: AwsConfig) -> Self {
44 Self::AwsSecretsManager(AwsSecretsManagerProvider::from(aws_config))
45 }
46
47 #[cfg(feature = "gcp-secretmanager")]
48 pub async fn gcp_secretmanager() -> Result<Self, RegentError> {
49 match GcpSecretProvider::new().await {
50 Ok(gcp_secret_provider) => Ok(Self::GcpSecretManager(gcp_secret_provider)),
51 Err(details) => Err(RegentError::SecretsIssue(format!(
52 "Failed to create a GCP SecretManager client : {}",
53 details
54 ))),
55 }
56 }
57
58 pub async fn get_secret_typed<T: DeserializeOwned>(
59 &self,
60 secret_reference: &str,
61 ) -> Result<Secret<T>, RegentError> {
62 match self {
63 SecretProvider::Files(secret_provider) => {
64 secret_provider.get_secret_typed(secret_reference).await
65 }
66 SecretProvider::EnvironmentVariable(secret_provider) => {
67 secret_provider.get_secret_typed(secret_reference).await
68 }
69 #[cfg(feature = "aws-secretsmanager")]
70 SecretProvider::AwsSecretsManager(secret_provider) => {
71 secret_provider.get_secret_typed(secret_reference).await
72 }
73 #[cfg(feature = "gcp-secretmanager")]
74 SecretProvider::GcpSecretManager(secret_provider) => {
75 secret_provider.get_secret_typed(secret_reference).await
76 } }
79 }
80
81 pub async fn get_secret_raw(
82 &self,
83 secret_reference: &str,
84 ) -> Result<Secret<String>, RegentError> {
85 match self {
86 SecretProvider::Files(secret_provider) => {
87 secret_provider.get_secret_raw(secret_reference).await
88 }
89 SecretProvider::EnvironmentVariable(secret_provider) => {
90 secret_provider.get_secret_raw(secret_reference).await
91 }
92 #[cfg(feature = "aws-secretsmanager")]
93 SecretProvider::AwsSecretsManager(secret_provider) => {
94 secret_provider.get_secret_raw(secret_reference).await
95 }
96 #[cfg(feature = "gcp-secretmanager")]
97 SecretProvider::GcpSecretManager(secret_provider) => {
98 secret_provider.get_secret_raw(secret_reference).await
99 } }
102 }
103}
104
105pub trait SecretProvidingSolution {
107 async fn connect(&mut self) -> Result<(), RegentError>;
108 async fn get_secret_typed<T: DeserializeOwned>(
109 &self,
110 secret_reference: &str,
111 ) -> Result<Secret<T>, RegentError>;
112 async fn get_secret_raw(&self, secret_reference: &str) -> Result<Secret<String>, RegentError>;
113}
114
115pub trait AsyncSecretProvidingSolution {
116 async fn connect(&mut self) -> Result<(), RegentError>;
117 async fn get_secret_typed<T: DeserializeOwned>(
118 &self,
119 secret_reference: &str,
120 ) -> Result<Secret<T>, RegentError>;
121 async fn get_secret_raw(&self, secret_reference: &str) -> Result<Secret<String>, RegentError>;
122}
123
124#[derive(Clone, PartialEq, Serialize, Deserialize)]
126pub struct Secret<T> {
127 sec_ref: String,
128 inner: T,
129}
130
131impl<T> Debug for Secret<T>
132where
133 T: Debug,
134{
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 f.debug_struct("Secret")
137 .field("sec_ref", &self.sec_ref)
138 .field("inner", &format_args!("<redacted>"))
139 .finish()
140 }
141}
142
143impl<T> Secret<T> {
144 pub fn from(sec_ref: &str, inner: T) -> Self {
145 Self {
146 sec_ref: sec_ref.to_string(),
147 inner,
148 }
149 }
150
151 pub fn inner(self) -> T {
152 self.inner
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
157#[serde(rename_all = "PascalCase")]
158#[serde(deny_unknown_fields)]
159pub struct SecretReference {
160 sec_ref: String,
161 provider: Option<String>,
162}
163
164impl SecretReference {
165 pub fn from(sec_ref: &str, provider: Option<String>) -> Self {
166 Self {
167 sec_ref: sec_ref.to_string(),
168 provider,
169 }
170 }
171
172 pub fn sec_ref(&self) -> &str {
173 &self.sec_ref
174 }
175
176 pub fn provider(&self) -> &Option<String> {
177 &self.provider
178 }
179}
180
181pub struct SecretProvidersPoolBuilder {
182 providers: HashMap<String, SecretProvider>,
183 default_provider: Option<String>,
184}
185
186impl SecretProvidersPoolBuilder {
187 pub fn new() -> Self {
188 Self {
189 providers: HashMap::new(),
190 default_provider: None,
191 }
192 }
193
194 pub fn add_provider(mut self, name: &str, provider: SecretProvider) -> Self {
195 if let Some(_old_secret_provider) = self.providers.insert(name.to_string(), provider) {
196 warn!(
197 "You just overrided a secret provider in the pool, also identified by the name {}",
198 name
199 );
200 }
201 self
202 }
203
204 pub fn add_default_provider(mut self, name: &str, provider: SecretProvider) -> Self {
205 if let Some(_old_secret_provider) = self.providers.insert(name.to_string(), provider) {
206 warn!(
207 "You just overrided a secret provider in the pool, also identified by the name {}",
208 name
209 );
210 }
211 self.default_provider = Some(name.to_string());
212 self
213 }
214
215 pub fn set_default(mut self, name: String) -> Self {
216 self.default_provider = Some(name);
217 self
218 }
219
220 pub fn build(self) -> Result<SecretProvidersPool, RegentError> {
221 match self.default_provider {
222 Some(default_provider_name) => match self.providers.get(&default_provider_name) {
223 Some(_secrets_provider) => Ok(SecretProvidersPool {
224 providers: self.providers,
225 default_provider: default_provider_name,
226 }),
227 None => {
228 error!(
229 "Default secrets provider ({}) is not set",
230 default_provider_name
231 );
232 return Err(RegentError::SecretsIssue(format!(
233 "Default secrets provider ({}) is not set",
234 default_provider_name
235 )));
236 }
237 },
238 None => {
239 error!("No default secrets provider set");
240 return Err(RegentError::SecretsIssue(
241 "No default secrets provider set".to_string(),
242 ));
243 }
244 }
245 }
246}
247
248#[derive(Clone)]
249pub struct SecretProvidersPool {
250 providers: HashMap<String, SecretProvider>,
251 default_provider: String,
252}
253
254impl SecretProvidersPool {
255 pub fn from(name: &str, secret_provider: SecretProvider) -> Self {
256 let mut providers: HashMap<String, SecretProvider> = HashMap::new();
257 providers.insert(name.to_string(), secret_provider);
258 Self {
259 providers,
260 default_provider: name.to_string(),
261 }
262 }
263
264 pub async fn get_secret_typed<T: DeserializeOwned>(
265 &self,
266 secret_reference: &SecretReference,
267 ) -> Result<Secret<T>, RegentError> {
268 let provider = match secret_reference.provider() {
269 Some(user_defined_provider) => user_defined_provider,
270 None => &self.default_provider,
271 };
272
273 match self.providers.get(provider) {
274 Some(secret_provider) => {
275 secret_provider
276 .get_secret_typed(secret_reference.sec_ref())
277 .await
278 }
279 None => {
280 error!(
281 "Default secrets provider {} not found. Was the SecretProvidersPoolBuilder type used to build this SecretProvidersPool ?",
282 self.default_provider
283 );
284 return Err(RegentError::SecretsIssue(format!(
285 "Default secrets provider {} not found. Was the SecretProvidersPoolBuilder type used to build this SecretProvidersPool ?",
286 self.default_provider
287 )));
288 }
289 }
290 }
291
292 pub async fn get_secret_raw(
293 &self,
294 secret_reference: &SecretReference,
295 ) -> Result<Secret<String>, RegentError> {
296 let provider = match secret_reference.provider() {
297 Some(user_defined_provider) => user_defined_provider,
298 None => &self.default_provider,
299 };
300
301 match self.providers.get(provider) {
302 Some(secret_provider) => {
303 secret_provider
304 .get_secret_raw(secret_reference.sec_ref())
305 .await
306 }
307 None => {
308 error!(
309 "Default secrets provider {} not found. Was the SecretProvidersPoolBuilder type used to build this SecretProvidersPool ?",
310 self.default_provider
311 );
312 return Err(RegentError::SecretsIssue(format!(
313 "Default secrets provider {} not found. Was the SecretProvidersPoolBuilder type used to build this SecretProvidersPool ?",
314 self.default_provider
315 )));
316 }
317 }
318 }
319}