cloud_meta/cloud/
oracle.rs

1use 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 Oracle {
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:           String,
18    pub display_name: String,
19    pub image:        String,
20    pub hostname:     String,
21
22    #[serde(flatten)]
23    pub extra: HashMap<String, Value>,
24}
25
26impl Oracle {
27    pub fn new(client: Client<HttpConnector, Body>) -> Self {
28        let endpoint = "http://169.254.169.254/opc/v2";
29        Self {
30            client:   client,
31            endpoint: endpoint.to_owned(),
32        }
33    }
34
35    pub async fn instance(&self) -> Result<Instance, Error> {
36        let bytes = self.get("instance").await?;
37        Ok(serde_json::from_slice(&bytes)?)
38    }
39
40    pub async fn get(&self, path: &str) -> Result<Bytes, Error> {
41        let endpoint = format!("{}/{}", self.endpoint, path);
42
43        let mut request = Request::new(Body::empty());
44        *request.method_mut() = Method::GET;
45        *request.uri_mut() = endpoint.try_into()?;
46
47        let header = "Authorization";
48        let value  = "Bearer Oracle".as_bytes().try_into()?;
49        request.headers_mut().insert(header, value);
50
51        let response = self.client.request(request).await?;
52        if !response.status().is_success() {
53            return Err(response.status().into());
54        }
55
56        Ok(to_bytes(response).await?)
57    }
58}