use crate::{Region, RegionError};
use regex::Regex;
use std::sync::LazyLock;
use url::Url;
static REGION_HOST_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^(?:https://){0,1}([^\.]+)\.([^\.]+)\.viturhosted\.net/?$").expect("Invalid regex")
});
static DOMAIN_NAME: &str = "viturhosted.net";
pub trait ServiceDiscovery {
fn name(&self) -> &'static str;
fn fqdn(region: Region) -> String;
fn endpoint(region: Region) -> Result<Url, RegionError>;
}
pub struct ZeroKmsServiceDiscovery;
impl ServiceDiscovery for ZeroKmsServiceDiscovery {
fn name(&self) -> &'static str {
"zerokms"
}
fn fqdn(region: Region) -> String {
format!("{}.viturhosted.net", region.identifier())
}
fn endpoint(region: Region) -> Result<Url, RegionError> {
Url::parse(&format!("https://{}.{DOMAIN_NAME}/", region.identifier())).map_err(|e| {
RegionError::InvalidRegion(format!(
"Invalid service URL for ZeroKMS in region {}: {}",
region.identifier(),
e
))
})
}
}
impl ZeroKmsServiceDiscovery {
pub fn region_from_host_fqdn(host_fqdn: &str) -> Result<Region, RegionError> {
REGION_HOST_REGEX
.captures(host_fqdn)
.ok_or_else(|| RegionError::InvalidHostFqdn(host_fqdn.to_string()))
.and_then(|caps| {
let region = caps.get(1).unwrap().as_str().to_string();
let provider = caps.get(2).unwrap().as_str().to_string();
Region::new(&format!("{region}.{provider}"))
})
}
}
pub struct CtsServiceDiscovery;
impl ServiceDiscovery for CtsServiceDiscovery {
fn name(&self) -> &'static str {
"cts"
}
fn fqdn(region: Region) -> String {
format!("{}.auth.{DOMAIN_NAME}", region.identifier())
}
fn endpoint(region: Region) -> Result<Url, RegionError> {
if matches!(region, Region::Aws(crate::AwsRegion::ApSoutheast2)) {
return Url::parse(&format!(
"https://{}.auth.{DOMAIN_NAME}/",
region.identifier()
))
.map_err(|e| {
RegionError::InvalidRegion(format!(
"Invalid service URL for ZeroKMS in region {}: {}",
region.identifier(),
e
))
});
}
Err(RegionError::InvalidRegion(format!(
"Region {} is not supported by the CTS service",
region.identifier()
)))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_region_from_host_fqdn() -> anyhow::Result<()> {
let host_fqdn = "us-west-1.aws.viturhosted.net";
let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
assert_eq!(region.identifier(), "us-west-1.aws");
Ok(())
}
#[test]
fn test_region_from_host_endpoint() -> anyhow::Result<()> {
let host_fqdn = "https://us-west-1.aws.viturhosted.net";
let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
assert_eq!(region.identifier(), "us-west-1.aws");
Ok(())
}
#[test]
fn test_region_from_host_endpoint_with_trailing_slash() -> anyhow::Result<()> {
let host_fqdn = "https://us-west-1.aws.viturhosted.net/";
let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
assert_eq!(region.identifier(), "us-west-1.aws");
Ok(())
}
}