Skip to content

Commit

Permalink
Merge pull request #584 from NevinDry/197-regions-in-csv
Browse files Browse the repository at this point in the history
Added regions inside a csv, load the csv
  • Loading branch information
demeringo authored Oct 21, 2024
2 parents 8c30c96 + ac01c8f commit 1e9eabc
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 44 deletions.
27 changes: 25 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions cloud-scanner-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ version = "3.0.1"

[dependencies]
chrono = { version = "^0.4", features = ["serde"] }
csv = "1.3.0"
isocountry = "^0.3"
log = "0.4"
loggerv = "0.7"
once_cell = "1.20.2"
pkg-version = "*"
prometheus-client = "*"
serde = "^1.0"
Expand Down
32 changes: 32 additions & 0 deletions cloud-scanner-cli/csv/cloud_providers_regions.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cloud provider,region,country code
aws,af-south-1,ZAF
aws,ap-east-1,HKG
aws,ap-northeast-1,JPN
aws,ap-northeast-2,KOR
aws,ap-northeast-3,JPN
aws,ap-south-1,IND
aws,ap-south-2,IND
aws,ap-southeast-1,SGP
aws,ap-southeast-2,AUS
aws,ap-southeast-3,IDN
aws,ap-southeast-4,AUS
aws,ca-central-1,CAN
aws,ca-west-1,CAN
aws,cn-north-1,CHN
aws,cn-northwest-1,CHN
aws,eu-central-1,DEU
aws,eu-central-2,CHE
aws,eu-north-1,SWE
aws,eu-south-1,ITA
aws,eu-south-2,ESP
aws,eu-west-1,IRL
aws,eu-west-2,GBR
aws,eu-west-3,FRA
aws,il-central-1,ISR
aws,me-central-1,ARE
aws,me-south-1,BHR
aws,sa-east-1,BRA
aws,us-east-1,USA
aws,us-east-2,USA
aws,us-west-1,USA
aws,us-west-2,USA
81 changes: 39 additions & 42 deletions cloud-scanner-cli/src/usage_location.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
//! The location where cloud resources are running.
use isocountry::CountryCode;
use rocket_okapi::okapi::schemars;
use csv::ReaderBuilder;
use log::error;
use once_cell::sync::Lazy;
use rocket_okapi::okapi::schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::error::Error;
use std::sync::Mutex;
use thiserror::Error;

// Use of static to load the region-country map once
static REGION_COUNTRY_MAP: Lazy<Mutex<HashMap<String, String>>> = Lazy::new(|| {
let map = load_region_country_map().unwrap_or_default();
Mutex::new(map)
});

#[derive(Error, Debug)]
pub enum RegionError {
#[error("Unsupported region ({0})")]
Expand All @@ -28,57 +37,45 @@ impl TryFrom<&str> for UsageLocation {
let cc = get_country_from_aws_region(aws_region)?;
Ok(UsageLocation {
aws_region: String::from(aws_region),
iso_country_code: cc.alpha3().to_owned(),
iso_country_code: cc,
})
}
type Error = RegionError;
}

/// Load the region-country map from a CSV file
fn load_region_country_map() -> Result<HashMap<String, String>, Box<dyn Error>> {
let csv_content = include_str!("../csv/cloud_providers_regions.csv");

let mut reader = ReaderBuilder::new()
.has_headers(true)
.from_reader(csv_content.as_bytes());

let mut region_country_map = HashMap::new();

for result in reader.records() {
let record = result?;
let region = &record[1]; // AWS region
let country_code = &record[2]; // country code
region_country_map.insert(region.to_string(), country_code.to_string());
}

Ok(region_country_map)
}

/// Converts AWS region as String into an ISO country code, returns FRA if not found
///
/// TODO! : do not convert to FRA by default, should rather fail explicitly if region is not found.
fn get_country_from_aws_region(aws_region: &str) -> Result<CountryCode, RegionError> {
let cc: CountryCode = match aws_region {
"af-south-1" => CountryCode::ZAF,
"ap-east-1" => CountryCode::HKG,
"ap-northeast-1" => CountryCode::JPN,
"ap-northeast-2" => CountryCode::KOR,
"ap-northeast-3" => CountryCode::JPN,
"ap-south-1" => CountryCode::IND,
"ap-south-2" => CountryCode::IND,
"ap-southeast-1" => CountryCode::SGP,
"ap-southeast-2" => CountryCode::AUS,
"ap-southeast-3" => CountryCode::IDN,
"ap-southeast-4" => CountryCode::AUS,
"ca-central-1" => CountryCode::CAN,
"ca-west-1" => CountryCode::CAN,
"cn-north-1" => CountryCode::CHN,
"cn-northwest-1" => CountryCode::CHN,
"eu-central-1" => CountryCode::DEU,
"eu-central-2" => CountryCode::CHE,
"eu-north-1" => CountryCode::SWE,
"eu-south-1" => CountryCode::ITA,
"eu-south-2" => CountryCode::ESP,
"eu-west-1" => CountryCode::IRL,
"eu-west-2" => CountryCode::GBR,
"eu-west-3" => CountryCode::FRA,
"il-central-1" => CountryCode::ISR,
"me-central-1" => CountryCode::ARE,
"me-south-1" => CountryCode::BHR,
"sa-east-1" => CountryCode::BRA,
"us-east-1" => CountryCode::USA,
"us-east-2" => CountryCode::USA,
"us-west-1" => CountryCode::USA,
"us-west-2" => CountryCode::USA,
_ => {
fn get_country_from_aws_region(aws_region: &str) -> Result<String, RegionError> {
let map = REGION_COUNTRY_MAP.lock().unwrap();
match map.get(aws_region) {
Some(country_code) => Ok(country_code.to_string()),
None => {
error!(
"Unsupported region: unable to match aws region [{}] to country code",
aws_region
);
return Err(RegionError::UnsupportedRegion(String::from(aws_region)));
}
};
Ok(cc)
}
}

#[cfg(test)]
Expand Down

0 comments on commit 1e9eabc

Please sign in to comment.