1mod azure_key_vault;
4mod env;
5mod statik;
6mod vault;
7
8pub use azure_key_vault::*;
9pub use env::*;
10pub use statik::*;
11pub use vault::*;
12
13use serde::Deserialize;
14use spin_expressions::Provider;
15use spin_factors::{anyhow, runtime_config::toml::GetTomlValue};
16
17use spin_factor_variables::runtime_config::RuntimeConfig;
18
19pub fn runtime_config_from_toml(table: &impl GetTomlValue) -> anyhow::Result<RuntimeConfig> {
21 let var_provider = vec![Box::<EnvVariablesProvider>::default() as _];
23 let value = table
24 .get("variables_provider")
25 .or_else(|| table.get("config_provider"));
26 let Some(array) = value else {
27 return Ok(RuntimeConfig {
28 providers: var_provider,
29 });
30 };
31
32 let provider_configs: Vec<VariableProviderConfiguration> = array.clone().try_into()?;
33 let mut providers = provider_configs
34 .into_iter()
35 .map(VariableProviderConfiguration::into_provider)
36 .collect::<anyhow::Result<Vec<_>>>()?;
37 providers.extend(var_provider);
38 Ok(RuntimeConfig { providers })
39}
40
41#[derive(Debug, Deserialize)]
43#[serde(rename_all = "snake_case", tag = "type")]
44pub enum VariableProviderConfiguration {
45 AzureKeyVault(AzureKeyVaultVariablesConfig),
47 Static(StaticVariablesProvider),
49 Vault(VaultVariablesProvider),
51 Env(EnvVariablesConfig),
53}
54
55impl VariableProviderConfiguration {
56 pub fn into_provider(self) -> anyhow::Result<Box<dyn Provider>> {
58 let provider: Box<dyn Provider> = match self {
59 VariableProviderConfiguration::Static(provider) => Box::new(provider),
60 VariableProviderConfiguration::Env(config) => Box::new(env::EnvVariablesProvider::new(
61 config.prefix,
62 |s| std::env::var(s),
63 config.dotenv_path,
64 )),
65 VariableProviderConfiguration::Vault(provider) => Box::new(provider),
66 VariableProviderConfiguration::AzureKeyVault(config) => Box::new(
67 AzureKeyVaultProvider::create(config.vault_url.clone(), config.try_into()?)?,
68 ),
69 };
70 Ok(provider)
71 }
72}