use std::path::PathBuf;
use url::Url;
use crate::credentials::service_credentials::ServiceAccessKeyCredentials;
use crate::logger_client::LoggerClient;
use super::cts_config::CtsConfig;
use super::errors::ConfigError;
use super::paths::resolve_config_dir;
use super::vars::CS_CLIENT_ACCESS_KEY;
use super::workspace::resolve_workspace;
pub const DEFAULT_LOG_ENDPOINT_URL: &str = "https://console-api.stashdata.net/api/log_ingestion";
pub const DEFAULT_LOG_AUDIENCE: &str = "https://console-api.stashdata.net";
#[derive(Default)]
pub struct LoggerConfigBuilder {
config_dir: Option<String>,
endpoint_url: Option<String>,
audience: Option<String>,
cts_config: Option<CtsConfig>,
access_key: Option<String>,
workspace_id: Option<String>,
}
impl LoggerConfigBuilder {
pub fn build(self) -> Result<LoggerConfig, ConfigError> {
let config_dir = resolve_config_dir(self.config_dir.map(PathBuf::from))
.map_err(|_| ConfigError::ValueNotSet("config_dir"))?;
std::fs::create_dir_all(&config_dir).map_err(|e| {
ConfigError::Io(
e.to_string(),
config_dir.to_str().unwrap_or("Unknown").to_string(),
)
})?;
let workspace_id = resolve_workspace(&config_dir, self.workspace_id.as_deref())
.ok_or(ConfigError::ValueNotSet("workspace_id"))?;
let workspace_dir = config_dir.join(&workspace_id);
std::fs::create_dir_all(workspace_dir).map_err(|e| {
ConfigError::Io(
e.to_string(),
config_dir.to_str().unwrap_or("Unknown").to_string(),
)
})?;
let endpoint_url = match &self.endpoint_url {
Some(s) => s,
None => DEFAULT_LOG_ENDPOINT_URL,
};
let endpoint_url = endpoint_url.parse()?;
let audience = match &self.audience {
Some(s) => s.to_owned(),
None => DEFAULT_LOG_AUDIENCE.to_owned(),
};
let cts_config = if let Some(cts_config) = self.cts_config {
cts_config
} else {
CtsConfig::builder().build()?
};
let Some(access_key) = self.access_key else {
return Err(ConfigError::ValueNotSet("access_key"));
};
Ok(LoggerConfig {
config_dir,
endpoint_url,
audience,
cts_config,
access_key,
workspace_id,
})
}
pub fn access_key(mut self, value: &str) -> Self {
self.access_key = Some(value.to_string());
self
}
pub fn endpoint_url(mut self, value: &str) -> Self {
self.endpoint_url = Some(value.to_string());
self
}
pub fn audience(mut self, value: &str) -> Self {
self.audience = Some(value.to_string());
self
}
pub fn config_dir(mut self, value: &str) -> Self {
self.config_dir = Some(value.to_owned());
self
}
pub fn cts_config(mut self, value: &CtsConfig) -> Self {
self.cts_config = Some(value.to_owned());
self
}
pub fn workspace_id(mut self, value: &str) -> Self {
self.workspace_id = Some(value.to_string());
self
}
pub fn with_env(mut self) -> Self {
if let Ok(value) = std::env::var(CS_CLIENT_ACCESS_KEY) {
self.access_key = Some(value);
}
self
}
}
#[derive(Clone)]
pub struct LoggerConfig {
config_dir: PathBuf,
endpoint_url: Url,
audience: String,
cts_config: CtsConfig,
access_key: String,
workspace_id: String,
}
impl LoggerConfig {
pub fn builder() -> LoggerConfigBuilder {
LoggerConfigBuilder::default()
}
pub fn audience(&self) -> String {
self.audience.to_owned()
}
pub fn endpoint_url(&self) -> Url {
self.endpoint_url.to_owned()
}
pub fn token_path(&self) -> PathBuf {
self.config_dir
.join(&self.workspace_id)
.join("logger-access-key-auth.json")
}
pub fn credentials(&self) -> ServiceAccessKeyCredentials {
ServiceAccessKeyCredentials::new(
&self.token_path(),
&self.access_key,
&self.cts_config.base_url(),
Some(&self.audience()),
)
}
pub fn client(&self) -> LoggerClient<ServiceAccessKeyCredentials> {
LoggerClient::new(&self.endpoint_url, self.credentials())
}
}