resource_tracker/collector/clouds/
ovh.rs1use crate::metrics::CloudInfo;
2use serde::Deserialize;
3
4use super::{imds_get, new_imds_agent};
5
6#[derive(Debug, Deserialize)]
7struct NetworkService {
8 #[serde(rename = "type")]
9 service_type: Option<String>,
10 address: Option<String>,
11}
12
13#[derive(Debug, Deserialize)]
14struct NetworkData {
15 services: Option<Vec<NetworkService>>,
16}
17
18#[derive(Debug, Deserialize)]
19struct MetaData {
20 availability_zone: Option<String>,
21}
22
23pub fn probe() -> Option<CloudInfo> {
32 let agent = new_imds_agent();
33
34 let network_body = imds_get(
36 &agent,
37 "http://169.254.169.254/openstack/latest/network_data.json",
38 )?;
39 let network_data: NetworkData = serde_json::from_str(&network_body).ok()?;
40 let is_ovh = network_data
41 .services
42 .as_deref()
43 .unwrap_or_default()
44 .iter()
45 .any(|s| {
46 s.service_type.as_deref() == Some("dns")
47 && s.address.as_deref() == Some("213.186.33.99")
48 });
49 if !is_ovh {
50 return None;
51 }
52
53 let cloud_region_id = imds_get(
55 &agent,
56 "http://169.254.169.254/openstack/latest/meta_data.json",
57 )
58 .and_then(|body| serde_json::from_str::<MetaData>(&body).ok())
59 .and_then(|m| m.availability_zone)
60 .filter(|az| !az.is_empty() && az != "unknown" && az != "nova");
61
62 let cloud_instance_type = imds_get(
64 &agent,
65 "http://169.254.169.254/latest/meta-data/instance-type",
66 )
67 .filter(|s| !s.is_empty() && s != "unknown");
68
69 Some(CloudInfo {
70 cloud_vendor_id: Some("ovh".to_string()),
71 cloud_account_id: None,
72 cloud_region_id,
73 cloud_zone_id: None,
74 cloud_instance_type,
75 })
76}