serves3/src/settings.rs

67 lines
1.9 KiB
Rust

// SPDX-FileCopyrightText: © Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: EUPL-1.2
use {
object_store::{BackoffConfig, ObjectStore, RetryConfig, aws},
rocket::serde::Deserialize,
serde::de::Error,
std::time::Duration,
};
#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct Settings {
#[serde(deserialize_with = "deserialize_s3_bucket")]
pub s3_bucket: Box<dyn ObjectStore>,
}
fn deserialize_s3_bucket<'de, D>(deserializer: D) -> Result<Box<dyn ObjectStore>, D::Error>
where
D: serde::Deserializer<'de>,
{
let config = S3Config::deserialize(deserializer)?;
config.try_into().map_err(D::Error::custom)
}
#[derive(Deserialize)]
pub struct S3Config {
pub name: String,
pub endpoint: String,
pub region: String,
#[serde(default)]
pub path_style: bool,
pub access_key_id: String,
pub secret_access_key: String,
}
impl TryInto<Box<dyn ObjectStore>> for S3Config {
type Error = anyhow::Error;
fn try_into(self) -> Result<Box<dyn ObjectStore>, Self::Error> {
// TODO: support object stores other than than AWS
let object_store = aws::AmazonS3Builder::new()
.with_region(self.region)
.with_endpoint(&self.endpoint)
.with_bucket_name(&self.name)
.with_access_key_id(self.access_key_id)
.with_secret_access_key(self.secret_access_key)
.with_virtual_hosted_style_request(!self.path_style)
.with_allow_http(true)
.with_retry(RetryConfig {
max_retries: 1,
backoff: BackoffConfig::default(),
retry_timeout: Duration::from_millis(500),
})
.build()?;
log::info!(
"Serving contents from bucket {} at {}",
self.endpoint,
self.name,
);
Ok(Box::new(object_store))
}
}