systemprompt_cloud/api_client/
tenant_api.rs1use serde::Serialize;
7use systemprompt_identifiers::TenantId;
8use systemprompt_models::modules::ApiPaths;
9
10use super::CloudApiClient;
11use super::types::{
12 ApiResponse, CustomDomainResponse, DeployResponse, ExternalDbAccessResponse,
13 ListSecretsResponse, RegistryToken, RotateCredentialsResponse, SetCustomDomainRequest,
14 SetExternalDbAccessRequest, SetSecretsRequest, StatusResponse, TenantSecrets, TenantStatus,
15};
16use crate::error::CloudResult;
17
18#[derive(Serialize)]
19struct DeployRequest {
20 image: String,
21}
22
23impl CloudApiClient {
24 pub async fn get_tenant_status(&self, tenant_id: &TenantId) -> CloudResult<TenantStatus> {
25 let response: ApiResponse<TenantStatus> =
26 self.tenant_get(&ApiPaths::tenant_status(tenant_id)).await?;
27 Ok(response.data)
28 }
29
30 pub async fn get_registry_token(&self, tenant_id: &TenantId) -> CloudResult<RegistryToken> {
31 let response: ApiResponse<RegistryToken> = self
32 .tenant_get(&ApiPaths::tenant_registry_token(tenant_id))
33 .await?;
34 Ok(response.data)
35 }
36
37 pub async fn deploy(&self, tenant_id: &TenantId, image: &str) -> CloudResult<DeployResponse> {
38 let request = DeployRequest {
39 image: image.to_owned(),
40 };
41 let response: ApiResponse<DeployResponse> = self
42 .tenant_post(&ApiPaths::tenant_deploy(tenant_id), &request)
43 .await?;
44 Ok(response.data)
45 }
46
47 pub async fn fetch_secrets(&self, secrets_url: &str) -> CloudResult<TenantSecrets> {
48 let path = secrets_url
49 .strip_prefix(&self.api_url)
50 .unwrap_or(secrets_url);
51 self.tenant_get(path).await
52 }
53
54 pub async fn delete_tenant(&self, tenant_id: &TenantId) -> CloudResult<()> {
55 self.tenant_delete(&ApiPaths::tenant(tenant_id)).await
56 }
57
58 pub async fn restart_tenant(&self, tenant_id: &TenantId) -> CloudResult<StatusResponse> {
59 self.tenant_post_empty(&ApiPaths::tenant_restart(tenant_id))
60 .await
61 }
62
63 pub async fn retry_provision(&self, tenant_id: &TenantId) -> CloudResult<StatusResponse> {
64 self.tenant_post_empty(&ApiPaths::tenant_retry_provision(tenant_id))
65 .await
66 }
67
68 pub async fn set_secrets(
69 &self,
70 tenant_id: &TenantId,
71 secrets: std::collections::HashMap<String, String>,
72 ) -> CloudResult<Vec<String>> {
73 let keys: Vec<String> = secrets.keys().cloned().collect();
74 let request = SetSecretsRequest { secrets };
75 self.tenant_put_no_content(&ApiPaths::tenant_secrets(tenant_id), &request)
76 .await?;
77 Ok(keys)
78 }
79
80 pub async fn unset_secret(&self, tenant_id: &TenantId, key: &str) -> CloudResult<()> {
81 let path = format!("{}/{}", ApiPaths::tenant_secrets(tenant_id), key);
82 self.tenant_delete(&path).await
83 }
84
85 pub async fn set_external_db_access(
86 &self,
87 tenant_id: &TenantId,
88 enabled: bool,
89 ) -> CloudResult<ExternalDbAccessResponse> {
90 let request = SetExternalDbAccessRequest { enabled };
91 let response: ApiResponse<ExternalDbAccessResponse> = self
92 .tenant_put(&ApiPaths::tenant_external_db_access(tenant_id), &request)
93 .await?;
94 Ok(response.data)
95 }
96
97 pub async fn rotate_credentials(
98 &self,
99 tenant_id: &TenantId,
100 ) -> CloudResult<RotateCredentialsResponse> {
101 self.tenant_post_empty(&ApiPaths::tenant_rotate_credentials(tenant_id))
102 .await
103 }
104
105 pub async fn list_secrets(&self, tenant_id: &TenantId) -> CloudResult<ListSecretsResponse> {
106 self.tenant_get(&ApiPaths::tenant_secrets(tenant_id)).await
107 }
108
109 pub async fn set_custom_domain(
110 &self,
111 tenant_id: &TenantId,
112 domain: &str,
113 ) -> CloudResult<CustomDomainResponse> {
114 let request = SetCustomDomainRequest {
115 domain: domain.to_owned(),
116 };
117 let response: ApiResponse<CustomDomainResponse> = self
118 .tenant_post(&ApiPaths::tenant_custom_domain(tenant_id), &request)
119 .await?;
120 Ok(response.data)
121 }
122
123 pub async fn get_custom_domain(
124 &self,
125 tenant_id: &TenantId,
126 ) -> CloudResult<CustomDomainResponse> {
127 let response: ApiResponse<CustomDomainResponse> = self
128 .tenant_get(&ApiPaths::tenant_custom_domain(tenant_id))
129 .await?;
130 Ok(response.data)
131 }
132
133 pub async fn delete_custom_domain(&self, tenant_id: &TenantId) -> CloudResult<()> {
134 self.tenant_delete(&ApiPaths::tenant_custom_domain(tenant_id))
135 .await
136 }
137
138 pub async fn cancel_subscription(&self, tenant_id: &TenantId) -> CloudResult<()> {
139 self.tenant_post_empty(&ApiPaths::tenant_subscription_cancel(tenant_id))
140 .await
141 }
142}