oz_keystore/hashicorp/
cloud.rs1use reqwest::{Client, Error};
2use serde::Deserialize;
3
4pub struct HashicorpCloudClient {
5 client: Client,
6 client_id: String,
7 client_secret: String,
8 org_id: String,
9 project_id: String,
10 app_name: String,
11}
12
13#[derive(Debug, Deserialize)]
14struct TokenResponse {
15 access_token: String,
16}
17
18#[derive(Debug, Deserialize)]
19pub struct StaticVersion {
20 pub value: String,
21}
22
23#[derive(Debug, Deserialize)]
24pub struct HashicorpSecret {
25 pub static_version: StaticVersion,
26}
27
28#[derive(Debug, Deserialize)]
29pub struct HashicorpResponse {
30 pub secret: HashicorpSecret,
31}
32
33impl HashicorpCloudClient {
34 pub fn new(
35 client_id: String,
36 client_secret: String,
37 org_id: String,
38 project_id: String,
39 app_name: String,
40 ) -> Self {
41 Self {
42 client: Client::new(),
43 client_id,
44 client_secret,
45 org_id,
46 project_id,
47 app_name,
48 }
49 }
50
51 async fn get_token(&self) -> Result<String, Error> {
52 let token_response = self.client
53 .post("https://auth.idp.hashicorp.com/oauth2/token")
54 .form(&[
55 ("client_id", &self.client_id),
56 ("client_secret", &self.client_secret),
57 ("grant_type", &String::from("client_credentials")),
58 ("audience", &String::from("https://api.hashicorp.cloud")),
59 ])
60 .send()
61 .await?
62 .json::<TokenResponse>()
63 .await?;
64
65 Ok(token_response.access_token)
66 }
67
68 pub async fn get_secret(&self, secret_name: &str) -> Result<HashicorpResponse, Error> {
69 let token = self.get_token().await?;
70
71 let url = format!(
72 "https://api.cloud.hashicorp.com/secrets/2023-11-28/organizations/{}/projects/{}/apps/{}/secrets/{}:open",
73 self.org_id, self.project_id, self.app_name, secret_name
74 );
75
76 self.client
77 .get(url)
78 .header("Authorization", format!("Bearer {}", token))
79 .send()
80 .await?
81 .json()
82 .await
83 }
84}