1use crate::{ApiResponse, CreateKeyRequest, CreateKeyResponse, KeyInfo};
7use anyhow::{Context, Result};
8
9pub struct GoutAdminClient {
26 inner: reqwest::Client,
27 base: String,
28 admin_key: String,
29}
30
31impl GoutAdminClient {
32 pub fn new(server_addr: &str, admin_key: &str) -> Self {
39 Self {
40 inner: reqwest::Client::new(),
41 base: format!("http://{server_addr}"),
42 admin_key: admin_key.to_string(),
43 }
44 }
45
46 pub async fn create_key(&self, name: &str) -> Result<CreateKeyResponse> {
54 let resp = self
55 .inner
56 .post(format!("{}/api/v1/keys", self.base))
57 .header("X-Admin-Key", &self.admin_key)
58 .json(&CreateKeyRequest { name: name.into() })
59 .send()
60 .await
61 .context("REST create key failed")?;
62
63 if !resp.status().is_success() {
64 let j: ApiResponse<CreateKeyResponse> = resp.json().await?;
65 anyhow::bail!("{}", j.error.unwrap_or_default());
66 }
67
68 let j: ApiResponse<CreateKeyResponse> = resp.json().await?;
69 j.data.context("no key data")
70 }
71
72 pub async fn list_keys(&self) -> Result<Vec<KeyInfo>> {
76 let resp = self
77 .inner
78 .get(format!("{}/api/v1/keys", self.base))
79 .header("X-Admin-Key", &self.admin_key)
80 .send()
81 .await
82 .context("REST list keys failed")?;
83
84 let j: ApiResponse<Vec<KeyInfo>> = resp.json().await?;
85 Ok(j.data.unwrap_or_default())
86 }
87
88 pub async fn delete_key(&self, key: &str) -> Result<bool> {
93 let resp = self
94 .inner
95 .delete(format!("{}/api/v1/keys/{}", self.base, key))
96 .header("X-Admin-Key", &self.admin_key)
97 .send()
98 .await
99 .context("REST delete key failed")?;
100
101 let j: ApiResponse<()> = resp.json().await?;
102 Ok(j.success)
103 }
104
105 pub fn admin_key(&self) -> &str {
107 &self.admin_key
108 }
109}