cloud_meta/cloud/
google.rs1use std::collections::HashMap;
2use hyper::{Body, Method, Request};
3use hyper::body::{to_bytes, Bytes};
4use hyper::client::{Client, HttpConnector};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use crate::Error;
8
9pub struct Google {
10 client: Client<HttpConnector, Body>,
11 endpoint: String,
12}
13
14#[derive(Debug, Deserialize, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub struct Instance {
17 pub id: u64,
18 pub name: String,
19 pub image: String,
20 pub hostname: String,
21 pub cpu_platform: String,
22 pub machine_type: String,
23 pub zone: String,
24
25 #[serde(flatten)]
26 pub extra: HashMap<String, Value>,
27}
28
29impl Google {
30 pub fn new(client: Client<HttpConnector, Body>) -> Self {
31 let endpoint = "http://metadata.google.internal/computeMetadata/v1";
32 Self {
33 client: client,
34 endpoint: endpoint.to_owned(),
35 }
36 }
37
38 pub async fn instance(&self) -> Result<Instance, Error> {
39 let bytes = self.get("instance/", true).await?;
40 Ok(serde_json::from_slice(&bytes)?)
41 }
42
43 pub async fn get(&self, path: &str, recursive: bool) -> Result<Bytes, Error> {
44 let endpoint = format!("{}/{}?recursive={}", self.endpoint, path, recursive);
45
46 let mut request = Request::new(Body::empty());
47 *request.method_mut() = Method::GET;
48 *request.uri_mut() = endpoint.try_into()?;
49
50 let header = "Metadata-Flavor";
51 let value = "Google".as_bytes().try_into()?;
52 request.headers_mut().insert(header, value);
53
54 let response = self.client.request(request).await?;
55 if !response.status().is_success() {
56 return Err(response.status().into());
57 }
58
59 Ok(to_bytes(response).await?)
60 }
61}