use crate::error::Error;
use crate::models::*;
#[derive(Debug, Clone)]
enum Auth {
Basic { key_id: String, key_secret: String },
Bearer { token: String },
}
enum QueryAuth<'a> {
Basic {
key_id: &'a str,
key_secret: &'a str,
},
Bearer {
token: &'a str,
},
}
#[derive(Debug, Clone)]
pub struct Client {
http: reqwest::Client,
base_url: String,
auth: Auth,
query_host: Option<String>,
}
fn derive_query_host(base_url: &str) -> Option<String> {
let parsed = url::Url::parse(base_url).ok()?;
let rest = parsed.host_str()?.strip_prefix("api.")?;
let rest = rest.strip_prefix("control-plane.").unwrap_or(rest);
let port = parsed.port().map(|p| format!(":{p}")).unwrap_or_default();
Some(format!("{}://queries.{}{}", parsed.scheme(), rest, port))
}
impl Client {
pub fn new(key_id: impl Into<String>, key_secret: impl Into<String>) -> Self {
Self::with_base_url("https://api.clickhouse.cloud", key_id, key_secret)
}
pub fn with_base_url(
base_url: impl Into<String>,
key_id: impl Into<String>,
key_secret: impl Into<String>,
) -> Self {
Self {
http: reqwest::Client::new(),
base_url: base_url.into().trim_end_matches('/').to_string(),
auth: Auth::Basic {
key_id: key_id.into(),
key_secret: key_secret.into(),
},
query_host: None,
}
}
pub fn with_bearer_token(base_url: impl Into<String>, token: impl Into<String>) -> Self {
Self {
http: reqwest::Client::new(),
base_url: base_url.into().trim_end_matches('/').to_string(),
auth: Auth::Bearer {
token: token.into(),
},
query_host: None,
}
}
pub fn with_http_client(
http: reqwest::Client,
base_url: impl Into<String>,
key_id: impl Into<String>,
key_secret: impl Into<String>,
) -> Self {
Self {
http,
base_url: base_url.into().trim_end_matches('/').to_string(),
auth: Auth::Basic {
key_id: key_id.into(),
key_secret: key_secret.into(),
},
query_host: None,
}
}
pub fn with_http_client_bearer(
http: reqwest::Client,
base_url: impl Into<String>,
token: impl Into<String>,
) -> Self {
Self {
http,
base_url: base_url.into().trim_end_matches('/').to_string(),
auth: Auth::Bearer {
token: token.into(),
},
query_host: None,
}
}
pub fn set_bearer_token(&mut self, token: impl Into<String>) -> Result<(), Error> {
match &mut self.auth {
Auth::Bearer { token: t } => {
*t = token.into();
Ok(())
}
Auth::Basic { .. } => Err(Error::AuthMismatch(
"set_bearer_token called on a Basic-auth client".into(),
)),
}
}
pub fn with_query_host(mut self, host: impl Into<String>) -> Self {
self.query_host = Some(host.into().trim_end_matches('/').to_string());
self
}
fn resolved_query_host(&self) -> String {
if let Some(host) = &self.query_host {
return host.clone();
}
if let Ok(host) = std::env::var("CLICKHOUSE_CLOUD_QUERY_HOST") {
return host;
}
derive_query_host(&self.base_url)
.unwrap_or_else(|| "https://queries.clickhouse.cloud".to_string())
}
fn request(&self, method: reqwest::Method, path: &str) -> reqwest::RequestBuilder {
let builder = self
.http
.request(method, format!("{}{}", self.base_url, path));
match &self.auth {
Auth::Basic { key_id, key_secret } => builder.basic_auth(key_id, Some(key_secret)),
Auth::Bearer { token } => builder.bearer_auth(token),
}
}
#[allow(clippy::too_many_arguments)]
pub async fn run_query(
&self,
service_id: &str,
key_id: &str,
key_secret: &str,
sql: &str,
database: Option<&str>,
format: &str,
wake_service: bool,
) -> Result<reqwest::Response, Error> {
self.run_query_with(
QueryAuth::Basic { key_id, key_secret },
service_id,
sql,
database,
format,
wake_service,
)
.await
}
pub async fn run_query_bearer(
&self,
service_id: &str,
sql: &str,
database: Option<&str>,
format: &str,
wake_service: bool,
) -> Result<reqwest::Response, Error> {
let token = match &self.auth {
Auth::Bearer { token } => token,
Auth::Basic { .. } => {
return Err(Error::AuthMismatch(
"run_query_bearer called on a Basic-auth client".into(),
));
}
};
self.run_query_with(
QueryAuth::Bearer { token },
service_id,
sql,
database,
format,
wake_service,
)
.await
}
async fn run_query_with(
&self,
auth: QueryAuth<'_>,
service_id: &str,
sql: &str,
database: Option<&str>,
format: &str,
wake_service: bool,
) -> Result<reqwest::Response, Error> {
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
struct RunQueryBody<'a> {
run_id: String,
sql: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
database: Option<&'a str>,
}
let url = format!(
"{}/service/{}/run",
self.resolved_query_host().trim_end_matches('/'),
service_id,
);
let body = RunQueryBody {
run_id: uuid::Uuid::new_v4().to_string(),
sql,
database,
};
let request = self
.http
.post(url)
.query(&[("format", format)])
.header("content-type", "text/plain;charset=UTF-8")
.header("x-service-type", "clickhouse");
let request = if wake_service {
request.header("wake-service", "true")
} else {
request
};
let request = match auth {
QueryAuth::Basic { key_id, key_secret } => request
.basic_auth(key_id, Some(key_secret))
.header("auth-provider", "custom"),
QueryAuth::Bearer { token } => request.bearer_auth(token),
};
let response = request.json(&body).send().await?;
let status = response.status();
if status.as_u16() == 206 {
let body_text = response.text().await.unwrap_or_default();
#[derive(serde::Deserialize)]
struct StateBody {
data: Option<String>,
}
let data = serde_json::from_str::<StateBody>(&body_text)
.ok()
.and_then(|b| b.data);
return Err(match data.as_deref() {
Some("Confirm wake service") => Error::ServiceIdle,
Some("Service is stopped") => Error::ServiceStopped,
_ => Error::Api {
status: 206,
message: body_text,
},
});
}
if !status.is_success() {
let body_text = response.text().await.unwrap_or_default();
return Err(Error::Api {
status: status.as_u16(),
message: if body_text.is_empty() {
format!("Query API returned {status}")
} else {
body_text
},
});
}
Ok(response)
}
pub async fn organization_get_list(&self) -> Result<ApiResponse<Vec<Organization>>, Error> {
let path = "/v1/organizations".to_string();
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_get(
&self,
organization_id: &str,
) -> Result<ApiResponse<Organization>, Error> {
let path = format!("/v1/organizations/{organization_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_quotas_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<OrganizationQuota>>, Error> {
let path = format!("/v1/organizations/{organization_id}/quotas");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_quota_get(
&self,
organization_id: &str,
quota_code: &str,
) -> Result<ApiResponse<OrganizationQuota>, Error> {
let path = format!("/v1/organizations/{organization_id}/quotas/{quota_code}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_update(
&self,
organization_id: &str,
body: &OrganizationPatchRequest,
) -> Result<ApiResponse<Organization>, Error> {
let path = format!("/v1/organizations/{organization_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn activity_get_list(
&self,
organization_id: &str,
from_date: Option<&str>,
to_date: Option<&str>,
) -> Result<ApiResponse<Vec<Activity>>, Error> {
let path = format!("/v1/organizations/{organization_id}/activities");
let mut req = self.request(reqwest::Method::GET, &path);
if let Some(v) = from_date {
req = req.query(&[("from_date", v)]);
}
if let Some(v) = to_date {
req = req.query(&[("to_date", v)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn activity_get(
&self,
organization_id: &str,
activity_id: &str,
) -> Result<ApiResponse<Activity>, Error> {
let path = format!("/v1/organizations/{organization_id}/activities/{activity_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_byoc_infrastructure_create(
&self,
organization_id: &str,
body: &ByocInfrastructurePostRequest,
) -> Result<ApiResponse<ByocConfig>, Error> {
let path = format!("/v1/organizations/{organization_id}/byocInfrastructure");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_byoc_infrastructure_delete(
&self,
organization_id: &str,
byoc_infrastructure_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/byocInfrastructure/{byoc_infrastructure_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_byoc_infrastructure_update(
&self,
organization_id: &str,
byoc_infrastructure_id: &str,
body: &ByocInfrastructurePatchRequest,
) -> Result<ApiResponse<ByocConfig>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/byocInfrastructure/{byoc_infrastructure_id}"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn invitation_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<Invitation>>, Error> {
let path = format!("/v1/organizations/{organization_id}/invitations");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn invitation_create(
&self,
organization_id: &str,
body: &InvitationPostRequest,
) -> Result<ApiResponse<Invitation>, Error> {
let path = format!("/v1/organizations/{organization_id}/invitations");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn invitation_get(
&self,
organization_id: &str,
invitation_id: &str,
) -> Result<ApiResponse<Invitation>, Error> {
let path = format!("/v1/organizations/{organization_id}/invitations/{invitation_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn invitation_delete(
&self,
organization_id: &str,
invitation_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/invitations/{invitation_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn openapi_key_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<ApiKey>>, Error> {
let path = format!("/v1/organizations/{organization_id}/keys");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn openapi_key_create(
&self,
organization_id: &str,
body: &ApiKeyPostRequest,
) -> Result<ApiResponse<ApiKeyPostResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/keys");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn openapi_key_get(
&self,
organization_id: &str,
key_id: &str,
) -> Result<ApiResponse<ApiKey>, Error> {
let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn openapi_key_update(
&self,
organization_id: &str,
key_id: &str,
body: &ApiKeyPatchRequest,
) -> Result<ApiResponse<ApiKey>, Error> {
let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn openapi_key_delete(
&self,
organization_id: &str,
key_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn member_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<Member>>, Error> {
let path = format!("/v1/organizations/{organization_id}/members");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn member_get(
&self,
organization_id: &str,
user_id: &str,
) -> Result<ApiResponse<Member>, Error> {
let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn member_update(
&self,
organization_id: &str,
user_id: &str,
body: &MemberPatchRequest,
) -> Result<ApiResponse<Member>, Error> {
let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn member_delete(
&self,
organization_id: &str,
user_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_roles_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<RBACRole>>, Error> {
let path = format!("/v1/organizations/{organization_id}/roles");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_role_post(
&self,
organization_id: &str,
body: &RoleCreateRequest,
) -> Result<ApiResponse<RBACRole>, Error> {
let path = format!("/v1/organizations/{organization_id}/roles");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_role_get(
&self,
organization_id: &str,
role_id: &str,
) -> Result<ApiResponse<RBACRole>, Error> {
let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_role_patch(
&self,
organization_id: &str,
role_id: &str,
body: &RoleUpdateRequest,
) -> Result<ApiResponse<RBACRole>, Error> {
let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_role_delete(
&self,
organization_id: &str,
role_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_create(
&self,
organization_id: &str,
body: &PostgresServicePostRequest,
) -> Result<ApiResponse<PostgresService>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_get_list(
&self,
organization_id: &str,
) -> Result<ApiResponse<Vec<PostgresServiceListItem>>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_get(
&self,
organization_id: &str,
postgres_id: &str,
) -> Result<ApiResponse<PostgresService>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_delete(
&self,
organization_id: &str,
postgres_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_patch(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresServicePatchRequest,
) -> Result<ApiResponse<PostgresService>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_certs_get(
&self,
organization_id: &str,
postgres_id: &str,
) -> Result<String, Error> {
let path =
format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/caCertificates");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(body_text)
}
pub async fn postgres_instance_config_get(
&self,
organization_id: &str,
postgres_id: &str,
) -> Result<ApiResponse<PostgresInstanceConfigResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_instance_config_post(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresInstanceConfig,
) -> Result<ApiResponse<PostgresInstanceUpdateConfigResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_instance_config_patch(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresInstanceConfig,
) -> Result<ApiResponse<PostgresInstanceUpdateConfigResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_set_password(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresServiceSetPassword,
) -> Result<ApiResponse<PostgresServicePasswordResource>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/password");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_instance_create_read_replica(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresServiceReadReplicaRequest,
) -> Result<ApiResponse<PostgresService>, Error> {
let path =
format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/readReplica");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_instance_prometheus_get(
&self,
organization_id: &str,
postgres_id: &str,
) -> Result<String, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/prometheus");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
if !status.is_success() {
let body_text = resp.text().await?;
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text),
});
}
Ok(resp.text().await?)
}
pub async fn postgres_org_prometheus_get(
&self,
organization_id: &str,
) -> Result<String, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/prometheus");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
if !status.is_success() {
let body_text = resp.text().await?;
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text),
});
}
Ok(resp.text().await?)
}
pub async fn postgres_instance_restore(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresServiceRestoreRequest,
) -> Result<ApiResponse<PostgresService>, Error> {
let path =
format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/restoredService");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn postgres_service_patch_state(
&self,
organization_id: &str,
postgres_id: &str,
body: &PostgresServiceSetState,
) -> Result<ApiResponse<PostgresService>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/state");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn postgres_instance_metrics_get(
&self,
organization_id: &str,
postgres_id: &str,
from_date: &str,
to_date: &str,
bucket_size_seconds: Option<i64>,
) -> Result<ApiResponse<PostgresMetrics>, Error> {
let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/metrics");
let mut req = self.request(reqwest::Method::GET, &path);
req = req.query(&[("from_date", from_date), ("to_date", to_date)]);
if let Some(v) = bucket_size_seconds {
req = req.query(&[("bucket_size_seconds", v)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn slow_query_patterns_get_list(
&self,
organization_id: &str,
postgres_id: &str,
from_date: &str,
to_date: &str,
db_name: Option<&str>,
db_user: Option<&str>,
db_operation: Option<&str>,
app: Option<&str>,
sort_by: Option<&str>,
sort_order: Option<&str>,
limit: Option<i64>,
offset: Option<i64>,
) -> Result<ApiResponse<Vec<PostgresSlowQueryPattern>>, Error> {
let path =
format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/slowQueryPatterns");
let mut req = self.request(reqwest::Method::GET, &path);
req = req.query(&[("from_date", from_date), ("to_date", to_date)]);
if let Some(v) = db_name {
req = req.query(&[("db_name", v)]);
}
if let Some(v) = db_user {
req = req.query(&[("db_user", v)]);
}
if let Some(v) = db_operation {
req = req.query(&[("db_operation", v)]);
}
if let Some(v) = app {
req = req.query(&[("app", v)]);
}
if let Some(v) = sort_by {
req = req.query(&[("sort_by", v)]);
}
if let Some(v) = sort_order {
req = req.query(&[("sort_order", v)]);
}
if let Some(v) = limit {
req = req.query(&[("limit", v)]);
}
if let Some(v) = offset {
req = req.query(&[("offset", v)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn slow_query_pattern_get(
&self,
organization_id: &str,
postgres_id: &str,
query_id: &str,
db_name: &str,
db_user: &str,
db_operation: &str,
app: Option<&str>,
timestamp: Option<&str>,
) -> Result<ApiResponse<PostgresSlowQueryPatternDetail>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/postgres/{postgres_id}/slowQueryPatterns/{query_id}"
);
let mut req = self.request(reqwest::Method::GET, &path);
req = req.query(&[
("db_name", db_name),
("db_user", db_user),
("db_operation", db_operation),
]);
if let Some(v) = app {
req = req.query(&[("app", v)]);
}
if let Some(v) = timestamp {
req = req.query(&[("timestamp", v)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
#[deprecated]
#[allow(deprecated)]
pub async fn organization_private_endpoint_config_get_list(
&self,
organization_id: &str,
cloud_provider: &str,
region_id: &str,
) -> Result<ApiResponse<OrganizationCloudRegionPrivateEndpointConfig>, Error> {
let path = format!("/v1/organizations/{organization_id}/privateEndpointConfig");
let mut req = self.request(reqwest::Method::GET, &path);
req = req.query(&[("cloud_provider", cloud_provider)]);
req = req.query(&[("region_id", region_id)]);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn organization_prometheus_get(
&self,
organization_id: &str,
filtered_metrics: Option<&str>,
) -> Result<String, Error> {
let path = format!("/v1/organizations/{organization_id}/prometheus");
let mut req = self.request(reqwest::Method::GET, &path);
if let Some(v) = filtered_metrics {
req = req.query(&[("filtered_metrics", v)]);
}
let resp = req.send().await?;
let status = resp.status();
if !status.is_success() {
let body_text = resp.text().await?;
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text),
});
}
Ok(resp.text().await?)
}
pub async fn instance_get_list(
&self,
organization_id: &str,
filters: &[&str],
) -> Result<ApiResponse<Vec<Service>>, Error> {
let path = format!("/v1/organizations/{organization_id}/services");
let mut req = self.request(reqwest::Method::GET, &path);
for f in filters {
req = req.query(&[("filter", f)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_create(
&self,
organization_id: &str,
body: &ServicePostRequest,
) -> Result<ApiResponse<ServicePostResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/services");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Service>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServicePatchRequest,
) -> Result<ApiResponse<Service>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_delete(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_bucket_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<BackupBucket>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_bucket_create(
&self,
organization_id: &str,
service_id: &str,
body: &BackupBucketPostRequest,
) -> Result<ApiResponse<BackupBucket>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_bucket_update(
&self,
organization_id: &str,
service_id: &str,
body: &BackupBucketPatchRequest,
) -> Result<ApiResponse<BackupBucket>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_bucket_delete(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_configuration_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<BackupConfiguration>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/backupConfiguration"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_configuration_update(
&self,
organization_id: &str,
service_id: &str,
body: &BackupConfigurationPatchRequest,
) -> Result<ApiResponse<BackupConfiguration>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/backupConfiguration"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_get_list(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<Backup>>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/backups");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn backup_get(
&self,
organization_id: &str,
service_id: &str,
backup_id: &str,
) -> Result<ApiResponse<Backup>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/backups/{backup_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_get_list(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickPipe>>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/clickpipes");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_create(
&self,
organization_id: &str,
service_id: &str,
body: &ClickPipePostRequest,
) -> Result<ApiResponse<ClickPipe>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/clickpipes");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_get(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
) -> Result<ApiResponse<ClickPipe>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_update(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
body: &ClickPipePatchRequest,
) -> Result<ApiResponse<ClickPipe>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_delete(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_scaling_update(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
body: &ClickPipeScalingPatchRequest,
) -> Result<ApiResponse<ClickPipe>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/scaling"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_settings_get(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
) -> Result<ApiResponse<ClickPipeSettingsResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/settings"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_settings_update(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
body: &ClickPipeSettingsPutRequest,
) -> Result<ApiResponse<ClickPipeSettingsResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/settings"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_state_update(
&self,
organization_id: &str,
service_id: &str,
click_pipe_id: &str,
body: &ClickPipeStatePatchRequest,
) -> Result<ApiResponse<ClickPipe>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/state"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_cdc_scaling_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<ClickPipesCdcScaling>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesCdcScaling"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_cdc_scaling_update(
&self,
organization_id: &str,
service_id: &str,
body: &ClickPipesCdcScalingPatchRequest,
) -> Result<ApiResponse<ClickPipesCdcScaling>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesCdcScaling"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_reverse_private_endpoint_get_list(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ReversePrivateEndpoint>>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_reverse_private_endpoint_create(
&self,
organization_id: &str,
service_id: &str,
body: &CreateReversePrivateEndpoint,
) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_reverse_private_endpoint_get(
&self,
organization_id: &str,
service_id: &str,
reverse_private_endpoint_id: &str,
) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_reverse_private_endpoint_delete(
&self,
organization_id: &str,
service_id: &str,
reverse_private_endpoint_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_reverse_private_endpoint_update(
&self,
organization_id: &str,
service_id: &str,
reverse_private_endpoint_id: &str,
body: &UpdateReversePrivateEndpoint,
) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
);
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_pipe_schema_discovery(
&self,
organization_id: &str,
service_id: &str,
body: &ClickPipeSchemaDiscoveryRequest,
) -> Result<ApiResponse<ClickPipeSchemaDiscoveryResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickpipes/schemaDiscovery"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_alerts(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackAlertResponse>>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_alert(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackCreateAlertRequest,
) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_alert(
&self,
organization_id: &str,
service_id: &str,
click_stack_alert_id: &str,
) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_alert(
&self,
organization_id: &str,
service_id: &str,
click_stack_alert_id: &str,
body: &ClickStackUpdateAlertRequest,
) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_alert(
&self,
organization_id: &str,
service_id: &str,
click_stack_alert_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_saved_searches(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackSavedSearch>>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_saved_search(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackSavedSearchInput,
) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_saved_search(
&self,
organization_id: &str,
service_id: &str,
click_stack_saved_search_id: &str,
) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_saved_search(
&self,
organization_id: &str,
service_id: &str,
click_stack_saved_search_id: &str,
body: &ClickStackSavedSearchInput,
) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_saved_search(
&self,
organization_id: &str,
service_id: &str,
click_stack_saved_search_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_dashboards(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackDashboardResponse>>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_dashboard(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackCreateDashboardRequest,
) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_dashboard(
&self,
organization_id: &str,
service_id: &str,
click_stack_dashboard_id: &str,
) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_dashboard(
&self,
organization_id: &str,
service_id: &str,
click_stack_dashboard_id: &str,
body: &ClickStackUpdateDashboardRequest,
) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_dashboard(
&self,
organization_id: &str,
service_id: &str,
click_stack_dashboard_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_sources(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackSourceResponse>>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_source(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackSource,
) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_source(
&self,
organization_id: &str,
service_id: &str,
click_stack_source_id: &str,
) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_source(
&self,
organization_id: &str,
service_id: &str,
click_stack_source_id: &str,
body: &ClickStackSource,
) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_source(
&self,
organization_id: &str,
service_id: &str,
click_stack_source_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_connections(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackConnection>>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_connection(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackCreateConnectionRequest,
) -> Result<ApiResponse<ClickStackConnection>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_connection(
&self,
organization_id: &str,
service_id: &str,
click_stack_connection_id: &str,
) -> Result<ApiResponse<ClickStackConnection>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_connection(
&self,
organization_id: &str,
service_id: &str,
click_stack_connection_id: &str,
body: &ClickStackUpdateConnectionRequest,
) -> Result<ApiResponse<ClickStackConnection>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_connection(
&self,
organization_id: &str,
service_id: &str,
click_stack_connection_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_roles(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackRole>>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_role(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackCreateRoleRequest,
) -> Result<ApiResponse<ClickStackRole>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_get_role(
&self,
organization_id: &str,
service_id: &str,
click_stack_role_id: &str,
) -> Result<ApiResponse<ClickStackRole>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_role(
&self,
organization_id: &str,
service_id: &str,
click_stack_role_id: &str,
body: &ClickStackUpdateRoleRequest,
) -> Result<ApiResponse<ClickStackRole>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_role(
&self,
organization_id: &str,
service_id: &str,
click_stack_role_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_list_webhooks(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<Vec<ClickStackWebhook>>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_create_webhook(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackWebhookInput,
) -> Result<ApiResponse<ClickStackWebhook>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_update_webhook(
&self,
organization_id: &str,
service_id: &str,
click_stack_webhook_id: &str,
body: &ClickStackWebhookInput,
) -> Result<ApiResponse<ClickStackWebhook>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks/{click_stack_webhook_id}"
);
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_delete_webhook(
&self,
organization_id: &str,
service_id: &str,
click_stack_webhook_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks/{click_stack_webhook_id}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn click_stack_validate_dashboard(
&self,
organization_id: &str,
service_id: &str,
body: &ClickStackCreateDashboardRequest,
) -> Result<ApiResponse<ClickStackValidateDashboardResponse>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/validate"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_password_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServicePasswordPatchRequest,
) -> Result<ApiResponse<ServicePasswordPatchResponse>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/password");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_private_endpoint_create(
&self,
organization_id: &str,
service_id: &str,
body: &ServicPrivateEndpointePostRequest,
) -> Result<ApiResponse<InstancePrivateEndpoint>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/privateEndpoint");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_private_endpoint_config_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<PrivateEndpointConfig>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/privateEndpointConfig"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_prometheus_get(
&self,
organization_id: &str,
service_id: &str,
filtered_metrics: Option<&str>,
) -> Result<String, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/prometheus");
let mut req = self.request(reqwest::Method::GET, &path);
if let Some(v) = filtered_metrics {
req = req.query(&[("filtered_metrics", v)]);
}
let resp = req.send().await?;
let status = resp.status();
if !status.is_success() {
let body_text = resp.text().await?;
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text),
});
}
Ok(resp.text().await?)
}
pub async fn instance_replica_scaling_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServiceReplicaScalingPatchRequest,
) -> Result<ApiResponse<ServiceScalingPatchResponse>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/replicaScaling");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
#[deprecated]
#[allow(deprecated)]
pub async fn instance_scaling_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServiceScalingPatchRequest,
) -> Result<ApiResponse<Service>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/scaling");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn scaling_schedule_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<ScalingSchedule>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn scaling_schedule_upsert(
&self,
organization_id: &str,
service_id: &str,
body: &ScalingSchedulePostRequest,
) -> Result<ApiResponse<ScalingSchedule>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn scaling_schedule_delete(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn upgrade_window_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<UpgradeWindow>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn upgrade_window_update(
&self,
organization_id: &str,
service_id: &str,
body: &UpgradeWindowPutRequest,
) -> Result<ApiResponse<UpgradeWindow>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
let mut req = self.request(reqwest::Method::PUT, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn upgrade_window_delete(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_query_endpoint_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<ServiceQueryAPIEndpoint>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_query_endpoint_delete(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_query_endpoint_upsert(
&self,
organization_id: &str,
service_id: &str,
body: &InstanceServiceQueryApiEndpointsPostRequest,
) -> Result<ApiResponse<ServiceQueryAPIEndpoint>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
);
let mut req = self.request(reqwest::Method::POST, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn instance_state_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServiceStatePatchRequest,
) -> Result<ApiResponse<Service>, Error> {
let path = format!("/v1/organizations/{organization_id}/services/{service_id}/state");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn usage_cost_get(
&self,
organization_id: &str,
from_date: &str,
to_date: &str,
filters: &[&str],
) -> Result<ApiResponse<UsageCost>, Error> {
let path = format!("/v1/organizations/{organization_id}/usageCost");
let mut req = self.request(reqwest::Method::GET, &path);
req = req.query(&[("from_date", from_date)]);
req = req.query(&[("to_date", to_date)]);
for f in filters {
req = req.query(&[("filter", f)]);
}
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn service_clickhouse_settings_list_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<ServiceClickhouseSettingsList>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings");
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn service_clickhouse_settings_update(
&self,
organization_id: &str,
service_id: &str,
body: &ServiceClickhouseSettingsPatchRequest,
) -> Result<ApiResponse<ServiceClickhouseSettingsPatchResponse>, Error> {
let path =
format!("/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings");
let mut req = self.request(reqwest::Method::PATCH, &path);
req = req.json(body);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn service_clickhouse_settings_schema_get(
&self,
organization_id: &str,
service_id: &str,
) -> Result<ApiResponse<ServiceClickhouseSettingsSchema>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/schema"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn service_clickhouse_setting_get(
&self,
organization_id: &str,
service_id: &str,
setting_name: &str,
) -> Result<ApiResponse<ServiceClickhouseSetting>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/{setting_name}"
);
let req = self.request(reqwest::Method::GET, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
pub async fn service_clickhouse_setting_delete(
&self,
organization_id: &str,
service_id: &str,
setting_name: &str,
) -> Result<ApiResponse<serde_json::Value>, Error> {
let path = format!(
"/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/{setting_name}"
);
let req = self.request(reqwest::Method::DELETE, &path);
let resp = req.send().await?;
let status = resp.status();
let body_text = resp.text().await?;
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
.ok()
.and_then(|r| r.error)
.unwrap_or(body_text.clone()),
});
}
Ok(serde_json::from_str(&body_text)?)
}
}
#[cfg(test)]
mod tests {
use super::derive_query_host;
#[test]
fn derive_query_host_prod() {
assert_eq!(
derive_query_host("https://api.clickhouse.cloud").as_deref(),
Some("https://queries.clickhouse.cloud")
);
}
#[test]
fn derive_query_host_staging() {
assert_eq!(
derive_query_host("https://api.control-plane.clickhouse-staging.com").as_deref(),
Some("https://queries.clickhouse-staging.com")
);
}
#[test]
fn derive_query_host_dev() {
assert_eq!(
derive_query_host("https://api.control-plane.clickhouse-dev.com").as_deref(),
Some("https://queries.clickhouse-dev.com")
);
}
#[test]
fn derive_query_host_plain_api_prefix_without_control_plane() {
assert_eq!(
derive_query_host("https://api.clickhouse-staging.com").as_deref(),
Some("https://queries.clickhouse-staging.com")
);
}
#[test]
fn derive_query_host_non_api_host_is_none() {
assert_eq!(derive_query_host("http://127.0.0.1:8123"), None);
assert_eq!(derive_query_host("https://example.com"), None);
}
#[test]
fn derive_query_host_invalid_url_is_none() {
assert_eq!(derive_query_host("not a url"), None);
}
#[test]
fn derive_query_host_preserves_non_default_port() {
assert_eq!(
derive_query_host("https://api.mycorp.example.com:8443").as_deref(),
Some("https://queries.mycorp.example.com:8443")
);
assert_eq!(
derive_query_host("https://api.clickhouse.cloud:443").as_deref(),
Some("https://queries.clickhouse.cloud")
);
}
}