use cloud_terrastodon_azure_types::AzureLocation;
use cloud_terrastodon_azure_types::SubscriptionId;
use cloud_terrastodon_command::CacheKey;
use cloud_terrastodon_command::CacheableCommand;
use cloud_terrastodon_command::CommandBuilder;
use cloud_terrastodon_command::CommandKind;
use cloud_terrastodon_command::async_trait;
use std::path::PathBuf;
pub struct LocationListRequest {
pub subscription_id: SubscriptionId,
}
pub fn fetch_all_locations(subscription_id: SubscriptionId) -> LocationListRequest {
LocationListRequest { subscription_id }
}
#[async_trait]
impl CacheableCommand for LocationListRequest {
type Output = Vec<AzureLocation>;
fn cache_key(&self) -> CacheKey {
CacheKey::new(PathBuf::from_iter([
"az",
"account",
"list-locations",
"--subscription",
&self.subscription_id.to_string(),
]))
}
async fn run(self) -> eyre::Result<Self::Output> {
let url = format!(
"https://management.azure.com/subscriptions/{}/locations?api-version=2022-12-01",
self.subscription_id
);
let mut cmd = CommandBuilder::new(CommandKind::CloudTerrastodon);
cmd.args(["rest", "--method", "GET", "--url", &url]);
cmd.cache(self.cache_key());
#[derive(serde::Deserialize)]
struct Response {
value: Vec<AzureLocation>,
}
let rtn = cmd.run::<Response>().await?;
Ok(rtn.value)
}
}
cloud_terrastodon_command::impl_cacheable_into_future!(LocationListRequest);
#[cfg(test)]
mod test {
use crate::fetch_all_locations;
use crate::fetch_all_subscriptions;
use crate::get_test_tenant_id;
#[tokio::test]
pub async fn it_works() -> eyre::Result<()> {
let tenant_id = get_test_tenant_id().await?;
let subs = fetch_all_subscriptions(tenant_id).await?;
let mut found_unrecognized_location = false;
for sub in subs {
let locations = fetch_all_locations(sub.id).await?;
found_unrecognized_location |= locations
.iter()
.any(|location| location.name.as_other().is_some());
}
if found_unrecognized_location {
eyre::bail!("One or more subscriptions had unrecognized locations");
}
Ok(())
}
}