Skip to main content

azure_lite_rs/ops/
resource_graph.rs

1//! Operation contracts for the Azure Resource Graph API (v1).
2//!
3//! Auto-generated from the Azure ARM REST Specification.
4//! **Do not edit manually** — modify the manifest and re-run codegen.
5//!
6//! These are the raw HTTP operations with correct URLs, methods,
7//! and parameter ordering. The hand-written `api/resource_graph.rs` wraps
8//! these with ergonomic builders, operation polling, etc.
9
10use crate::types::resource_graph::*;
11use crate::{AzureHttpClient, Result};
12
13/// Raw HTTP operations for the Azure Resource Graph API.
14///
15/// These methods encode the correct URL paths, HTTP methods, and
16/// parameter ordering from the Azure ARM REST Specification.
17/// They are `pub(crate)` — use the ergonomic wrappers in
18/// [`super::resource_graph::ResourceGraphClient`] instead.
19pub struct ResourceGraphOps<'a> {
20    pub(crate) client: &'a AzureHttpClient,
21}
22
23impl<'a> ResourceGraphOps<'a> {
24    pub(crate) fn new(client: &'a AzureHttpClient) -> Self {
25        Self { client }
26    }
27
28    fn base_url(&self) -> &str {
29        #[cfg(any(test, feature = "test-support"))]
30        {
31            if let Some(ref base) = self.client.base_url {
32                return base.trim_end_matches('/');
33            }
34        }
35        "https://management.azure.com"
36    }
37
38    /// Execute a KQL query across one or more subscriptions.
39    ///
40    /// **Azure API**: `POST /providers/Microsoft.ResourceGraph/resources`
41    ///
42    /// # Request Body
43    /// [`ResourceGraphRequest`]
44    ///
45    /// # Response
46    /// [`ResourceGraphResponse`]
47    #[allow(dead_code)]
48    pub(crate) async fn query_resources(
49        &self,
50        body: &ResourceGraphRequest,
51    ) -> Result<ResourceGraphResponse> {
52        let url = format!(
53            "{}/providers/Microsoft.ResourceGraph/resources",
54            self.base_url(),
55        );
56        let sep = if url.contains('?') { "&" } else { "?" };
57        let url = format!("{}{}api-version=2021-03-01", url, sep);
58        let body_bytes =
59            serde_json::to_vec(body).map_err(|e| crate::AzureError::InvalidResponse {
60                message: format!("Failed to serialize query_resources request: {e}"),
61                body: None,
62            })?;
63        let response = self.client.post(&url, &body_bytes).await?;
64        let response = response.error_for_status().await?;
65        let response_bytes =
66            response
67                .bytes()
68                .await
69                .map_err(|e| crate::AzureError::InvalidResponse {
70                    message: format!("Failed to read query_resources response: {e}"),
71                    body: None,
72                })?;
73        serde_json::from_slice(&response_bytes).map_err(|e| crate::AzureError::InvalidResponse {
74            message: format!("Failed to parse query_resources response: {e}"),
75            body: Some(String::from_utf8_lossy(&response_bytes).to_string()),
76        })
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[tokio::test]
85    async fn test_query_resources() {
86        let mut mock = crate::MockClient::new();
87
88        mock.expect_post("/providers/Microsoft.ResourceGraph/resources")
89            .returning_json(serde_json::to_value(ResourceGraphResponse::fixture()).unwrap());
90
91        let client = crate::AzureHttpClient::from_mock(mock);
92        let ops = ResourceGraphOps::new(&client);
93
94        let body = ResourceGraphRequest::fixture();
95        let result = ops.query_resources(&body).await;
96        assert!(result.is_ok());
97    }
98}