aster_server/routes/
utils.rs1use aster::config::declarative_providers::load_provider;
2use aster::config::Config;
3use aster::providers::base::{ConfigKey, ProviderMetadata, ProviderType};
4use serde::{Deserialize, Serialize};
5use std::env;
6use std::error::Error;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub enum KeyLocation {
10 Environment,
11 ConfigFile,
12 Keychain,
13 NotFound,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct KeyInfo {
18 pub name: String,
19 pub is_set: bool,
20 pub location: KeyLocation,
21 pub is_secret: bool,
22 pub value: Option<String>, }
24
25#[allow(dead_code)]
27pub fn inspect_key(key_name: &str, is_secret: bool) -> Result<KeyInfo, Box<dyn Error>> {
28 let config = Config::global();
29
30 let env_value = env::var(key_name).ok();
32
33 if let Some(value) = env_value {
34 return Ok(KeyInfo {
35 name: key_name.to_string(),
36 is_set: true,
37 location: KeyLocation::Environment,
38 is_secret,
39 value: if !is_secret { Some(value) } else { None },
41 });
42 }
43
44 let config_result = if is_secret {
46 config.get_secret(key_name).map(|v| (v, true))
47 } else {
48 config.get_param(key_name).map(|v| (v, false))
49 };
50
51 match config_result {
52 Ok((value, is_secret_actual)) => {
53 let location = if is_secret_actual {
55 KeyLocation::Keychain
56 } else {
57 KeyLocation::ConfigFile
58 };
59
60 Ok(KeyInfo {
61 name: key_name.to_string(),
62 is_set: true,
63 location,
64 is_secret: is_secret_actual,
65 value: if !is_secret_actual { Some(value) } else { None },
67 })
68 }
69 Err(_) => Ok(KeyInfo {
70 name: key_name.to_string(),
71 is_set: false,
72 location: KeyLocation::NotFound,
73 is_secret,
74 value: None,
75 }),
76 }
77}
78
79#[allow(dead_code)]
81pub fn inspect_keys(
82 keys: &[(String, bool)], ) -> Result<Vec<KeyInfo>, Box<dyn Error>> {
84 let mut results = Vec::new();
85
86 for (key_name, is_secret) in keys {
87 let info = inspect_key(key_name, *is_secret)?;
88 results.push(info);
89 }
90
91 Ok(results)
92}
93
94pub fn check_provider_configured(metadata: &ProviderMetadata, provider_type: ProviderType) -> bool {
95 let config = Config::global();
96
97 if provider_type == ProviderType::Custom || provider_type == ProviderType::Declarative {
98 if let Ok(loaded_provider) = load_provider(metadata.name.as_str()) {
99 return config
100 .get_secret::<String>(&loaded_provider.config.api_key_env)
101 .is_ok();
102 }
103 }
104 if metadata.config_keys.is_empty() {
106 let configured_marker = format!("{}_configured", metadata.name);
108 return config.get_param::<bool>(&configured_marker).is_ok();
109 }
110
111 let required_keys: Vec<&ConfigKey> = metadata
113 .config_keys
114 .iter()
115 .filter(|key| key.required)
116 .collect();
117
118 if required_keys.len() == 1 && required_keys[0].default.is_some() {
121 let key = &required_keys[0];
122
123 let is_set_in_env = env::var(&key.name).is_ok();
125 let is_set_in_config = config.get(&key.name, key.secret).is_ok();
126
127 return is_set_in_env || is_set_in_config;
128 }
129
130 if required_keys.is_empty() && !metadata.config_keys.is_empty() {
133 let all_optional_with_defaults = metadata
134 .config_keys
135 .iter()
136 .all(|key| !key.required && key.default.is_some());
137
138 if all_optional_with_defaults {
139 let configured_marker = format!("{}_configured", metadata.name);
141 return config.get_param::<bool>(&configured_marker).is_ok();
142 }
143 }
144
145 let required_non_default_keys: Vec<&ConfigKey> = required_keys
148 .iter()
149 .filter(|key| key.default.is_none())
150 .cloned()
151 .collect();
152
153 if required_non_default_keys.is_empty() {
155 return required_keys.iter().any(|key| {
156 let is_set_in_env = env::var(&key.name).is_ok();
157 let is_set_in_config = config.get(&key.name, key.secret).is_ok();
158
159 is_set_in_env || is_set_in_config
160 });
161 }
162
163 required_non_default_keys.iter().all(|key| {
165 let is_set_in_env = env::var(&key.name).is_ok();
166 let is_set_in_config = config.get(&key.name, key.secret).is_ok();
167
168 is_set_in_env || is_set_in_config
169 })
170}