cts_common/
service.rs

1use crate::{Region, RegionError};
2use regex::Regex;
3use std::sync::LazyLock;
4use url::Url;
5
6/// Regex to extract the region from a host FQDN or a URL.
7static REGION_HOST_REGEX: LazyLock<Regex> = LazyLock::new(|| {
8    Regex::new(r"^(?:https://){0,1}([^\.]+)\.([^\.]+)\.viturhosted\.net/?$").expect("Invalid regex")
9});
10
11/// Domain name for the service discovery.
12static DOMAIN_NAME: &str = "viturhosted.net";
13
14/// Simple service discover trait that defines the name of the service and the endpoint for a given region.
15pub trait ServiceDiscovery {
16    fn name(&self) -> &'static str;
17    fn fqdn(region: Region) -> String;
18    fn endpoint(region: Region) -> Result<Url, RegionError>;
19}
20
21/// ZeroKms service.
22pub struct ZeroKmsServiceDiscovery;
23
24impl ServiceDiscovery for ZeroKmsServiceDiscovery {
25    fn name(&self) -> &'static str {
26        "zerokms"
27    }
28
29    /// Returns the FQDN for the service in the given region.
30    /// The FQDN is in the format `<region>.<provider>.viturhosted.net`.
31    fn fqdn(region: Region) -> String {
32        format!("{}.viturhosted.net", region.identifier())
33    }
34
35    /// Returns the URL for the service in the given region.
36    /// The URL is in the format `https://<region>.<provider>.viturhosted.net/`.
37    fn endpoint(region: Region) -> Result<Url, RegionError> {
38        Url::parse(&format!("https://{}.{DOMAIN_NAME}/", region.identifier())).map_err(|e| {
39            RegionError::InvalidRegion(format!(
40                "Invalid service URL for ZeroKMS in region {}: {}",
41                region.identifier(),
42                e
43            ))
44        })
45    }
46}
47
48impl ZeroKmsServiceDiscovery {
49    /// Attempt to extract the region from a host FQDN or URL.
50    /// The FQDN must be in the format `<region>.<provider>.viturhosted.net`.
51    /// The URL must be in the format `https://<region>.<provider>.viturhosted.net/`.
52    pub fn region_from_host_fqdn(host_fqdn: &str) -> Result<Region, RegionError> {
53        REGION_HOST_REGEX
54            .captures(host_fqdn)
55            .ok_or_else(|| RegionError::InvalidHostFqdn(host_fqdn.to_string()))
56            .and_then(|caps| {
57                let region = caps.get(1).unwrap().as_str().to_string();
58                let provider = caps.get(2).unwrap().as_str().to_string();
59                Region::new(&format!("{}.{}", region, provider))
60            })
61    }
62}
63
64/// CTS service.
65pub struct CtsServiceDiscovery;
66
67impl ServiceDiscovery for CtsServiceDiscovery {
68    fn name(&self) -> &'static str {
69        "cts"
70    }
71
72    fn fqdn(region: Region) -> String {
73        format!("{}.auth.{DOMAIN_NAME}", region.identifier())
74    }
75
76    fn endpoint(region: Region) -> Result<Url, RegionError> {
77        if matches!(region, Region::Aws(crate::AwsRegion::ApSoutheast2)) {
78            return Url::parse(&format!(
79                "https://{}.auth.{DOMAIN_NAME}/",
80                region.identifier()
81            ))
82            .map_err(|e| {
83                RegionError::InvalidRegion(format!(
84                    "Invalid service URL for ZeroKMS in region {}: {}",
85                    region.identifier(),
86                    e
87                ))
88            });
89        }
90        Err(RegionError::InvalidRegion(format!(
91            "Region {} is not supported by the CTS service",
92            region.identifier()
93        )))
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn test_region_from_host_fqdn() -> anyhow::Result<()> {
103        let host_fqdn = "us-west-1.aws.viturhosted.net";
104        let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
105        assert_eq!(region.identifier(), "us-west-1.aws");
106
107        Ok(())
108    }
109
110    #[test]
111    fn test_region_from_host_endpoint() -> anyhow::Result<()> {
112        let host_fqdn = "https://us-west-1.aws.viturhosted.net";
113        let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
114        assert_eq!(region.identifier(), "us-west-1.aws");
115        Ok(())
116    }
117
118    #[test]
119    fn test_region_from_host_endpoint_with_trailing_slash() -> anyhow::Result<()> {
120        let host_fqdn = "https://us-west-1.aws.viturhosted.net/";
121        let region = ZeroKmsServiceDiscovery::region_from_host_fqdn(host_fqdn)?;
122        assert_eq!(region.identifier(), "us-west-1.aws");
123        Ok(())
124    }
125}