pub mod apply;
pub mod cosmos_config;
pub mod indexer;
pub mod plan;
pub mod rigg;
use std::sync::Arc;
use anyhow::{Context, Result};
use azure_identity::DefaultAzureCredentialBuilder;
use crate::config::schema::Config;
use cosmos_config::ArmCosmosClient;
use rigg::RiggClientAdapter;
const SEARCH_PREVIEW_API_VERSION: &str = "2025-11-01-preview";
pub fn build_cosmos_client(cfg: &Config) -> Result<ArmCosmosClient> {
let cosmos = &cfg.azure.cosmos;
let subscription_id = cosmos.subscription_id.clone().ok_or_else(|| {
anyhow::anyhow!(
"control-plane fields missing in `azure.cosmos` — `subscription_id` is required \
for `azure plan` / `azure apply`"
)
})?;
let resource_group = cosmos.resource_group.clone().ok_or_else(|| {
anyhow::anyhow!(
"control-plane fields missing in `azure.cosmos` — `resource_group` is required \
for `azure plan` / `azure apply`"
)
})?;
let account = cosmos.account.clone().ok_or_else(|| {
anyhow::anyhow!(
"control-plane fields missing in `azure.cosmos` — `account` is required \
for `azure plan` / `azure apply`"
)
})?;
let credential = DefaultAzureCredentialBuilder::default()
.build()
.context("build DefaultAzureCredential for ARM access")?;
Ok(ArmCosmosClient {
credential: Arc::new(credential),
http: reqwest::Client::new(),
subscription_id,
resource_group,
account,
})
}
pub fn build_rigg_client(cfg: &Config) -> Result<RiggClientAdapter> {
let search = cfg.azure.search.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"`azure.search.endpoint` missing — required for AI Search configuration \
(`azure plan` / `azure apply`)"
)
})?;
RiggClientAdapter::new(
search.endpoint.clone(),
SEARCH_PREVIEW_API_VERSION.to_string(),
)
.context("build rigg AI Search client")
}