Skip to main content

systemprompt_cloud/api_client/
tenant_api.rs

1//! Tenant-scoped endpoints for [`super::CloudApiClient`].
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use serde::Serialize;
7use systemprompt_identifiers::TenantId;
8use systemprompt_models::modules::ApiPaths;
9
10use super::CloudApiClient;
11use super::types::{
12    CloudApiResponse, CloudTenantSecrets, CloudTenantStatusResponse, DeployResponse, RegistryToken,
13    RotateCredentialsResponse, SetSecretsRequest,
14};
15use crate::error::CloudResult;
16
17#[derive(Serialize)]
18struct DeployRequest {
19    image: String,
20}
21
22impl CloudApiClient {
23    pub async fn get_tenant_status(
24        &self,
25        tenant_id: &TenantId,
26    ) -> CloudResult<CloudTenantStatusResponse> {
27        let response: CloudApiResponse<CloudTenantStatusResponse> =
28            self.tenant_get(&ApiPaths::tenant_status(tenant_id)).await?;
29        Ok(response.data)
30    }
31
32    pub async fn get_registry_token(&self, tenant_id: &TenantId) -> CloudResult<RegistryToken> {
33        let response: CloudApiResponse<RegistryToken> = self
34            .tenant_get(&ApiPaths::tenant_registry_token(tenant_id))
35            .await?;
36        Ok(response.data)
37    }
38
39    pub async fn deploy(&self, tenant_id: &TenantId, image: &str) -> CloudResult<DeployResponse> {
40        let request = DeployRequest {
41            image: image.to_owned(),
42        };
43        let response: CloudApiResponse<DeployResponse> = self
44            .tenant_post(&ApiPaths::tenant_deploy(tenant_id), &request)
45            .await?;
46        Ok(response.data)
47    }
48
49    pub async fn fetch_secrets(&self, secrets_url: &str) -> CloudResult<CloudTenantSecrets> {
50        let path = secrets_url
51            .strip_prefix(&self.api_url)
52            .unwrap_or(secrets_url);
53        self.tenant_get(path).await
54    }
55
56    pub async fn delete_tenant(&self, tenant_id: &TenantId) -> CloudResult<()> {
57        self.tenant_delete(&ApiPaths::tenant(tenant_id)).await
58    }
59
60    pub async fn set_secrets(
61        &self,
62        tenant_id: &TenantId,
63        secrets: std::collections::HashMap<String, String>,
64    ) -> CloudResult<Vec<String>> {
65        let keys: Vec<String> = secrets.keys().cloned().collect();
66        let request = SetSecretsRequest { secrets };
67        self.tenant_put_no_content(&ApiPaths::tenant_secrets(tenant_id), &request)
68            .await?;
69        Ok(keys)
70    }
71
72    pub async fn rotate_credentials(
73        &self,
74        tenant_id: &TenantId,
75    ) -> CloudResult<RotateCredentialsResponse> {
76        self.tenant_post_empty(&ApiPaths::tenant_rotate_credentials(tenant_id))
77            .await
78    }
79}