1use crate::error::Error;
6use crate::models::*;
7
8#[derive(Debug, Clone)]
10enum Auth {
11 Basic { key_id: String, key_secret: String },
12 Bearer { token: String },
13}
14
15enum QueryAuth<'a> {
18 Basic {
19 key_id: &'a str,
20 key_secret: &'a str,
21 },
22 Bearer {
23 token: &'a str,
24 },
25}
26
27#[derive(Debug, Clone)]
31pub struct Client {
32 http: reqwest::Client,
33 base_url: String,
34 auth: Auth,
35 query_host: Option<String>,
37}
38
39fn derive_query_host(base_url: &str) -> Option<String> {
52 let parsed = url::Url::parse(base_url).ok()?;
53 let rest = parsed.host_str()?.strip_prefix("api.")?;
54 let rest = rest.strip_prefix("control-plane.").unwrap_or(rest);
55 let port = parsed.port().map(|p| format!(":{p}")).unwrap_or_default();
56 Some(format!("{}://queries.{}{}", parsed.scheme(), rest, port))
57}
58
59impl Client {
60 pub fn new(key_id: impl Into<String>, key_secret: impl Into<String>) -> Self {
62 Self::with_base_url("https://api.clickhouse.cloud", key_id, key_secret)
63 }
64
65 pub fn with_base_url(
67 base_url: impl Into<String>,
68 key_id: impl Into<String>,
69 key_secret: impl Into<String>,
70 ) -> Self {
71 Self {
72 http: reqwest::Client::new(),
73 base_url: base_url.into().trim_end_matches('/').to_string(),
74 auth: Auth::Basic {
75 key_id: key_id.into(),
76 key_secret: key_secret.into(),
77 },
78 query_host: None,
79 }
80 }
81
82 pub fn with_bearer_token(base_url: impl Into<String>, token: impl Into<String>) -> Self {
84 Self {
85 http: reqwest::Client::new(),
86 base_url: base_url.into().trim_end_matches('/').to_string(),
87 auth: Auth::Bearer {
88 token: token.into(),
89 },
90 query_host: None,
91 }
92 }
93
94 pub fn with_http_client(
99 http: reqwest::Client,
100 base_url: impl Into<String>,
101 key_id: impl Into<String>,
102 key_secret: impl Into<String>,
103 ) -> Self {
104 Self {
105 http,
106 base_url: base_url.into().trim_end_matches('/').to_string(),
107 auth: Auth::Basic {
108 key_id: key_id.into(),
109 key_secret: key_secret.into(),
110 },
111 query_host: None,
112 }
113 }
114
115 pub fn with_http_client_bearer(
120 http: reqwest::Client,
121 base_url: impl Into<String>,
122 token: impl Into<String>,
123 ) -> Self {
124 Self {
125 http,
126 base_url: base_url.into().trim_end_matches('/').to_string(),
127 auth: Auth::Bearer {
128 token: token.into(),
129 },
130 query_host: None,
131 }
132 }
133
134 pub fn set_bearer_token(&mut self, token: impl Into<String>) -> Result<(), Error> {
139 match &mut self.auth {
140 Auth::Bearer { token: t } => {
141 *t = token.into();
142 Ok(())
143 }
144 Auth::Basic { .. } => Err(Error::AuthMismatch(
145 "set_bearer_token called on a Basic-auth client".into(),
146 )),
147 }
148 }
149
150 pub fn with_query_host(mut self, host: impl Into<String>) -> Self {
158 self.query_host = Some(host.into().trim_end_matches('/').to_string());
159 self
160 }
161
162 fn resolved_query_host(&self) -> String {
165 if let Some(host) = &self.query_host {
166 return host.clone();
167 }
168 if let Ok(host) = std::env::var("CLICKHOUSE_CLOUD_QUERY_HOST") {
169 return host;
170 }
171 derive_query_host(&self.base_url)
172 .unwrap_or_else(|| "https://queries.clickhouse.cloud".to_string())
173 }
174
175 fn request(&self, method: reqwest::Method, path: &str) -> reqwest::RequestBuilder {
176 let builder = self
177 .http
178 .request(method, format!("{}{}", self.base_url, path));
179 match &self.auth {
180 Auth::Basic { key_id, key_secret } => builder.basic_auth(key_id, Some(key_secret)),
181 Auth::Bearer { token } => builder.bearer_auth(token),
182 }
183 }
184
185 #[allow(clippy::too_many_arguments)]
200 pub async fn run_query(
201 &self,
202 service_id: &str,
203 key_id: &str,
204 key_secret: &str,
205 sql: &str,
206 database: Option<&str>,
207 format: &str,
208 wake_service: bool,
209 ) -> Result<reqwest::Response, Error> {
210 self.run_query_with(
211 QueryAuth::Basic { key_id, key_secret },
212 service_id,
213 sql,
214 database,
215 format,
216 wake_service,
217 )
218 .await
219 }
220
221 pub async fn run_query_bearer(
234 &self,
235 service_id: &str,
236 sql: &str,
237 database: Option<&str>,
238 format: &str,
239 wake_service: bool,
240 ) -> Result<reqwest::Response, Error> {
241 let token = match &self.auth {
242 Auth::Bearer { token } => token,
243 Auth::Basic { .. } => {
244 return Err(Error::AuthMismatch(
245 "run_query_bearer called on a Basic-auth client".into(),
246 ));
247 }
248 };
249 self.run_query_with(
250 QueryAuth::Bearer { token },
251 service_id,
252 sql,
253 database,
254 format,
255 wake_service,
256 )
257 .await
258 }
259
260 async fn run_query_with(
261 &self,
262 auth: QueryAuth<'_>,
263 service_id: &str,
264 sql: &str,
265 database: Option<&str>,
266 format: &str,
267 wake_service: bool,
268 ) -> Result<reqwest::Response, Error> {
269 #[derive(serde::Serialize)]
270 #[serde(rename_all = "camelCase")]
271 struct RunQueryBody<'a> {
272 run_id: String,
273 sql: &'a str,
274 #[serde(skip_serializing_if = "Option::is_none")]
275 database: Option<&'a str>,
276 }
277
278 let url = format!(
279 "{}/service/{}/run",
280 self.resolved_query_host().trim_end_matches('/'),
281 service_id,
282 );
283
284 let body = RunQueryBody {
285 run_id: uuid::Uuid::new_v4().to_string(),
286 sql,
287 database,
288 };
289
290 let request = self
291 .http
292 .post(url)
293 .query(&[("format", format)])
294 .header("content-type", "text/plain;charset=UTF-8")
295 .header("x-service-type", "clickhouse");
296 let request = if wake_service {
300 request.header("wake-service", "true")
301 } else {
302 request
303 };
304 let request = match auth {
308 QueryAuth::Basic { key_id, key_secret } => request
309 .basic_auth(key_id, Some(key_secret))
310 .header("auth-provider", "custom"),
311 QueryAuth::Bearer { token } => request.bearer_auth(token),
312 };
313
314 let response = request.json(&body).send().await?;
315
316 let status = response.status();
317 if status.as_u16() == 206 {
322 let body_text = response.text().await.unwrap_or_default();
323 #[derive(serde::Deserialize)]
324 struct StateBody {
325 data: Option<String>,
326 }
327 let data = serde_json::from_str::<StateBody>(&body_text)
328 .ok()
329 .and_then(|b| b.data);
330 return Err(match data.as_deref() {
331 Some("Confirm wake service") => Error::ServiceIdle,
332 Some("Service is stopped") => Error::ServiceStopped,
333 _ => Error::Api {
334 status: 206,
335 message: body_text,
336 },
337 });
338 }
339 if !status.is_success() {
340 let body_text = response.text().await.unwrap_or_default();
341 return Err(Error::Api {
342 status: status.as_u16(),
343 message: if body_text.is_empty() {
344 format!("Query API returned {status}")
345 } else {
346 body_text
347 },
348 });
349 }
350
351 Ok(response)
352 }
353
354 pub async fn organization_get_list(&self) -> Result<ApiResponse<Vec<Organization>>, Error> {
356 let path = "/v1/organizations".to_string();
357 let req = self.request(reqwest::Method::GET, &path);
358 let resp = req.send().await?;
359 let status = resp.status();
360 let body_text = resp.text().await?;
361 if !status.is_success() {
362 return Err(Error::Api {
363 status: status.as_u16(),
364 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
365 .ok()
366 .and_then(|r| r.error)
367 .unwrap_or(body_text.clone()),
368 });
369 }
370 Ok(serde_json::from_str(&body_text)?)
371 }
372
373 pub async fn organization_get(
375 &self,
376 organization_id: &str,
377 ) -> Result<ApiResponse<Organization>, Error> {
378 let path = format!("/v1/organizations/{organization_id}");
379 let req = self.request(reqwest::Method::GET, &path);
380 let resp = req.send().await?;
381 let status = resp.status();
382 let body_text = resp.text().await?;
383 if !status.is_success() {
384 return Err(Error::Api {
385 status: status.as_u16(),
386 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
387 .ok()
388 .and_then(|r| r.error)
389 .unwrap_or(body_text.clone()),
390 });
391 }
392 Ok(serde_json::from_str(&body_text)?)
393 }
394
395 pub async fn organization_quotas_get_list(
397 &self,
398 organization_id: &str,
399 ) -> Result<ApiResponse<Vec<OrganizationQuota>>, Error> {
400 let path = format!("/v1/organizations/{organization_id}/quotas");
401 let req = self.request(reqwest::Method::GET, &path);
402 let resp = req.send().await?;
403 let status = resp.status();
404 let body_text = resp.text().await?;
405 if !status.is_success() {
406 return Err(Error::Api {
407 status: status.as_u16(),
408 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
409 .ok()
410 .and_then(|r| r.error)
411 .unwrap_or(body_text.clone()),
412 });
413 }
414 Ok(serde_json::from_str(&body_text)?)
415 }
416
417 pub async fn organization_quota_get(
419 &self,
420 organization_id: &str,
421 quota_code: &str,
422 ) -> Result<ApiResponse<OrganizationQuota>, Error> {
423 let path = format!("/v1/organizations/{organization_id}/quotas/{quota_code}");
424 let req = self.request(reqwest::Method::GET, &path);
425 let resp = req.send().await?;
426 let status = resp.status();
427 let body_text = resp.text().await?;
428 if !status.is_success() {
429 return Err(Error::Api {
430 status: status.as_u16(),
431 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
432 .ok()
433 .and_then(|r| r.error)
434 .unwrap_or(body_text.clone()),
435 });
436 }
437 Ok(serde_json::from_str(&body_text)?)
438 }
439
440 pub async fn organization_update(
442 &self,
443 organization_id: &str,
444 body: &OrganizationPatchRequest,
445 ) -> Result<ApiResponse<Organization>, Error> {
446 let path = format!("/v1/organizations/{organization_id}");
447 let mut req = self.request(reqwest::Method::PATCH, &path);
448 req = req.json(body);
449 let resp = req.send().await?;
450 let status = resp.status();
451 let body_text = resp.text().await?;
452 if !status.is_success() {
453 return Err(Error::Api {
454 status: status.as_u16(),
455 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
456 .ok()
457 .and_then(|r| r.error)
458 .unwrap_or(body_text.clone()),
459 });
460 }
461 Ok(serde_json::from_str(&body_text)?)
462 }
463
464 pub async fn activity_get_list(
466 &self,
467 organization_id: &str,
468 from_date: Option<&str>,
469 to_date: Option<&str>,
470 ) -> Result<ApiResponse<Vec<Activity>>, Error> {
471 let path = format!("/v1/organizations/{organization_id}/activities");
472 let mut req = self.request(reqwest::Method::GET, &path);
473 if let Some(v) = from_date {
474 req = req.query(&[("from_date", v)]);
475 }
476 if let Some(v) = to_date {
477 req = req.query(&[("to_date", v)]);
478 }
479 let resp = req.send().await?;
480 let status = resp.status();
481 let body_text = resp.text().await?;
482 if !status.is_success() {
483 return Err(Error::Api {
484 status: status.as_u16(),
485 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
486 .ok()
487 .and_then(|r| r.error)
488 .unwrap_or(body_text.clone()),
489 });
490 }
491 Ok(serde_json::from_str(&body_text)?)
492 }
493
494 pub async fn activity_get(
496 &self,
497 organization_id: &str,
498 activity_id: &str,
499 ) -> Result<ApiResponse<Activity>, Error> {
500 let path = format!("/v1/organizations/{organization_id}/activities/{activity_id}");
501 let req = self.request(reqwest::Method::GET, &path);
502 let resp = req.send().await?;
503 let status = resp.status();
504 let body_text = resp.text().await?;
505 if !status.is_success() {
506 return Err(Error::Api {
507 status: status.as_u16(),
508 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
509 .ok()
510 .and_then(|r| r.error)
511 .unwrap_or(body_text.clone()),
512 });
513 }
514 Ok(serde_json::from_str(&body_text)?)
515 }
516
517 pub async fn organization_byoc_infrastructure_create(
519 &self,
520 organization_id: &str,
521 body: &ByocInfrastructurePostRequest,
522 ) -> Result<ApiResponse<ByocConfig>, Error> {
523 let path = format!("/v1/organizations/{organization_id}/byocInfrastructure");
524 let mut req = self.request(reqwest::Method::POST, &path);
525 req = req.json(body);
526 let resp = req.send().await?;
527 let status = resp.status();
528 let body_text = resp.text().await?;
529 if !status.is_success() {
530 return Err(Error::Api {
531 status: status.as_u16(),
532 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
533 .ok()
534 .and_then(|r| r.error)
535 .unwrap_or(body_text.clone()),
536 });
537 }
538 Ok(serde_json::from_str(&body_text)?)
539 }
540
541 pub async fn organization_byoc_infrastructure_delete(
543 &self,
544 organization_id: &str,
545 byoc_infrastructure_id: &str,
546 ) -> Result<ApiResponse<serde_json::Value>, Error> {
547 let path = format!(
548 "/v1/organizations/{organization_id}/byocInfrastructure/{byoc_infrastructure_id}"
549 );
550 let req = self.request(reqwest::Method::DELETE, &path);
551 let resp = req.send().await?;
552 let status = resp.status();
553 let body_text = resp.text().await?;
554 if !status.is_success() {
555 return Err(Error::Api {
556 status: status.as_u16(),
557 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
558 .ok()
559 .and_then(|r| r.error)
560 .unwrap_or(body_text.clone()),
561 });
562 }
563 Ok(serde_json::from_str(&body_text)?)
564 }
565
566 pub async fn organization_byoc_infrastructure_update(
568 &self,
569 organization_id: &str,
570 byoc_infrastructure_id: &str,
571 body: &ByocInfrastructurePatchRequest,
572 ) -> Result<ApiResponse<ByocConfig>, Error> {
573 let path = format!(
574 "/v1/organizations/{organization_id}/byocInfrastructure/{byoc_infrastructure_id}"
575 );
576 let mut req = self.request(reqwest::Method::PATCH, &path);
577 req = req.json(body);
578 let resp = req.send().await?;
579 let status = resp.status();
580 let body_text = resp.text().await?;
581 if !status.is_success() {
582 return Err(Error::Api {
583 status: status.as_u16(),
584 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
585 .ok()
586 .and_then(|r| r.error)
587 .unwrap_or(body_text.clone()),
588 });
589 }
590 Ok(serde_json::from_str(&body_text)?)
591 }
592
593 pub async fn invitation_get_list(
595 &self,
596 organization_id: &str,
597 ) -> Result<ApiResponse<Vec<Invitation>>, Error> {
598 let path = format!("/v1/organizations/{organization_id}/invitations");
599 let req = self.request(reqwest::Method::GET, &path);
600 let resp = req.send().await?;
601 let status = resp.status();
602 let body_text = resp.text().await?;
603 if !status.is_success() {
604 return Err(Error::Api {
605 status: status.as_u16(),
606 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
607 .ok()
608 .and_then(|r| r.error)
609 .unwrap_or(body_text.clone()),
610 });
611 }
612 Ok(serde_json::from_str(&body_text)?)
613 }
614
615 pub async fn invitation_create(
617 &self,
618 organization_id: &str,
619 body: &InvitationPostRequest,
620 ) -> Result<ApiResponse<Invitation>, Error> {
621 let path = format!("/v1/organizations/{organization_id}/invitations");
622 let mut req = self.request(reqwest::Method::POST, &path);
623 req = req.json(body);
624 let resp = req.send().await?;
625 let status = resp.status();
626 let body_text = resp.text().await?;
627 if !status.is_success() {
628 return Err(Error::Api {
629 status: status.as_u16(),
630 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
631 .ok()
632 .and_then(|r| r.error)
633 .unwrap_or(body_text.clone()),
634 });
635 }
636 Ok(serde_json::from_str(&body_text)?)
637 }
638
639 pub async fn invitation_get(
641 &self,
642 organization_id: &str,
643 invitation_id: &str,
644 ) -> Result<ApiResponse<Invitation>, Error> {
645 let path = format!("/v1/organizations/{organization_id}/invitations/{invitation_id}");
646 let req = self.request(reqwest::Method::GET, &path);
647 let resp = req.send().await?;
648 let status = resp.status();
649 let body_text = resp.text().await?;
650 if !status.is_success() {
651 return Err(Error::Api {
652 status: status.as_u16(),
653 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
654 .ok()
655 .and_then(|r| r.error)
656 .unwrap_or(body_text.clone()),
657 });
658 }
659 Ok(serde_json::from_str(&body_text)?)
660 }
661
662 pub async fn invitation_delete(
664 &self,
665 organization_id: &str,
666 invitation_id: &str,
667 ) -> Result<ApiResponse<serde_json::Value>, Error> {
668 let path = format!("/v1/organizations/{organization_id}/invitations/{invitation_id}");
669 let req = self.request(reqwest::Method::DELETE, &path);
670 let resp = req.send().await?;
671 let status = resp.status();
672 let body_text = resp.text().await?;
673 if !status.is_success() {
674 return Err(Error::Api {
675 status: status.as_u16(),
676 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
677 .ok()
678 .and_then(|r| r.error)
679 .unwrap_or(body_text.clone()),
680 });
681 }
682 Ok(serde_json::from_str(&body_text)?)
683 }
684
685 pub async fn openapi_key_get_list(
687 &self,
688 organization_id: &str,
689 ) -> Result<ApiResponse<Vec<ApiKey>>, Error> {
690 let path = format!("/v1/organizations/{organization_id}/keys");
691 let req = self.request(reqwest::Method::GET, &path);
692 let resp = req.send().await?;
693 let status = resp.status();
694 let body_text = resp.text().await?;
695 if !status.is_success() {
696 return Err(Error::Api {
697 status: status.as_u16(),
698 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
699 .ok()
700 .and_then(|r| r.error)
701 .unwrap_or(body_text.clone()),
702 });
703 }
704 Ok(serde_json::from_str(&body_text)?)
705 }
706
707 pub async fn openapi_key_create(
709 &self,
710 organization_id: &str,
711 body: &ApiKeyPostRequest,
712 ) -> Result<ApiResponse<ApiKeyPostResponse>, Error> {
713 let path = format!("/v1/organizations/{organization_id}/keys");
714 let mut req = self.request(reqwest::Method::POST, &path);
715 req = req.json(body);
716 let resp = req.send().await?;
717 let status = resp.status();
718 let body_text = resp.text().await?;
719 if !status.is_success() {
720 return Err(Error::Api {
721 status: status.as_u16(),
722 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
723 .ok()
724 .and_then(|r| r.error)
725 .unwrap_or(body_text.clone()),
726 });
727 }
728 Ok(serde_json::from_str(&body_text)?)
729 }
730
731 pub async fn openapi_key_get(
733 &self,
734 organization_id: &str,
735 key_id: &str,
736 ) -> Result<ApiResponse<ApiKey>, Error> {
737 let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
738 let req = self.request(reqwest::Method::GET, &path);
739 let resp = req.send().await?;
740 let status = resp.status();
741 let body_text = resp.text().await?;
742 if !status.is_success() {
743 return Err(Error::Api {
744 status: status.as_u16(),
745 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
746 .ok()
747 .and_then(|r| r.error)
748 .unwrap_or(body_text.clone()),
749 });
750 }
751 Ok(serde_json::from_str(&body_text)?)
752 }
753
754 pub async fn openapi_key_update(
756 &self,
757 organization_id: &str,
758 key_id: &str,
759 body: &ApiKeyPatchRequest,
760 ) -> Result<ApiResponse<ApiKey>, Error> {
761 let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
762 let mut req = self.request(reqwest::Method::PATCH, &path);
763 req = req.json(body);
764 let resp = req.send().await?;
765 let status = resp.status();
766 let body_text = resp.text().await?;
767 if !status.is_success() {
768 return Err(Error::Api {
769 status: status.as_u16(),
770 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
771 .ok()
772 .and_then(|r| r.error)
773 .unwrap_or(body_text.clone()),
774 });
775 }
776 Ok(serde_json::from_str(&body_text)?)
777 }
778
779 pub async fn openapi_key_delete(
781 &self,
782 organization_id: &str,
783 key_id: &str,
784 ) -> Result<ApiResponse<serde_json::Value>, Error> {
785 let path = format!("/v1/organizations/{organization_id}/keys/{key_id}");
786 let req = self.request(reqwest::Method::DELETE, &path);
787 let resp = req.send().await?;
788 let status = resp.status();
789 let body_text = resp.text().await?;
790 if !status.is_success() {
791 return Err(Error::Api {
792 status: status.as_u16(),
793 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
794 .ok()
795 .and_then(|r| r.error)
796 .unwrap_or(body_text.clone()),
797 });
798 }
799 Ok(serde_json::from_str(&body_text)?)
800 }
801
802 pub async fn member_get_list(
804 &self,
805 organization_id: &str,
806 ) -> Result<ApiResponse<Vec<Member>>, Error> {
807 let path = format!("/v1/organizations/{organization_id}/members");
808 let req = self.request(reqwest::Method::GET, &path);
809 let resp = req.send().await?;
810 let status = resp.status();
811 let body_text = resp.text().await?;
812 if !status.is_success() {
813 return Err(Error::Api {
814 status: status.as_u16(),
815 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
816 .ok()
817 .and_then(|r| r.error)
818 .unwrap_or(body_text.clone()),
819 });
820 }
821 Ok(serde_json::from_str(&body_text)?)
822 }
823
824 pub async fn member_get(
826 &self,
827 organization_id: &str,
828 user_id: &str,
829 ) -> Result<ApiResponse<Member>, Error> {
830 let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
831 let req = self.request(reqwest::Method::GET, &path);
832 let resp = req.send().await?;
833 let status = resp.status();
834 let body_text = resp.text().await?;
835 if !status.is_success() {
836 return Err(Error::Api {
837 status: status.as_u16(),
838 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
839 .ok()
840 .and_then(|r| r.error)
841 .unwrap_or(body_text.clone()),
842 });
843 }
844 Ok(serde_json::from_str(&body_text)?)
845 }
846
847 pub async fn member_update(
849 &self,
850 organization_id: &str,
851 user_id: &str,
852 body: &MemberPatchRequest,
853 ) -> Result<ApiResponse<Member>, Error> {
854 let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
855 let mut req = self.request(reqwest::Method::PATCH, &path);
856 req = req.json(body);
857 let resp = req.send().await?;
858 let status = resp.status();
859 let body_text = resp.text().await?;
860 if !status.is_success() {
861 return Err(Error::Api {
862 status: status.as_u16(),
863 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
864 .ok()
865 .and_then(|r| r.error)
866 .unwrap_or(body_text.clone()),
867 });
868 }
869 Ok(serde_json::from_str(&body_text)?)
870 }
871
872 pub async fn member_delete(
874 &self,
875 organization_id: &str,
876 user_id: &str,
877 ) -> Result<ApiResponse<serde_json::Value>, Error> {
878 let path = format!("/v1/organizations/{organization_id}/members/{user_id}");
879 let req = self.request(reqwest::Method::DELETE, &path);
880 let resp = req.send().await?;
881 let status = resp.status();
882 let body_text = resp.text().await?;
883 if !status.is_success() {
884 return Err(Error::Api {
885 status: status.as_u16(),
886 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
887 .ok()
888 .and_then(|r| r.error)
889 .unwrap_or(body_text.clone()),
890 });
891 }
892 Ok(serde_json::from_str(&body_text)?)
893 }
894
895 pub async fn organization_roles_get_list(
897 &self,
898 organization_id: &str,
899 ) -> Result<ApiResponse<Vec<RBACRole>>, Error> {
900 let path = format!("/v1/organizations/{organization_id}/roles");
901 let req = self.request(reqwest::Method::GET, &path);
902 let resp = req.send().await?;
903 let status = resp.status();
904 let body_text = resp.text().await?;
905 if !status.is_success() {
906 return Err(Error::Api {
907 status: status.as_u16(),
908 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
909 .ok()
910 .and_then(|r| r.error)
911 .unwrap_or(body_text.clone()),
912 });
913 }
914 Ok(serde_json::from_str(&body_text)?)
915 }
916
917 pub async fn organization_role_post(
919 &self,
920 organization_id: &str,
921 body: &RoleCreateRequest,
922 ) -> Result<ApiResponse<RBACRole>, Error> {
923 let path = format!("/v1/organizations/{organization_id}/roles");
924 let mut req = self.request(reqwest::Method::POST, &path);
925 req = req.json(body);
926 let resp = req.send().await?;
927 let status = resp.status();
928 let body_text = resp.text().await?;
929 if !status.is_success() {
930 return Err(Error::Api {
931 status: status.as_u16(),
932 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
933 .ok()
934 .and_then(|r| r.error)
935 .unwrap_or(body_text.clone()),
936 });
937 }
938 Ok(serde_json::from_str(&body_text)?)
939 }
940
941 pub async fn organization_role_get(
943 &self,
944 organization_id: &str,
945 role_id: &str,
946 ) -> Result<ApiResponse<RBACRole>, Error> {
947 let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
948 let req = self.request(reqwest::Method::GET, &path);
949 let resp = req.send().await?;
950 let status = resp.status();
951 let body_text = resp.text().await?;
952 if !status.is_success() {
953 return Err(Error::Api {
954 status: status.as_u16(),
955 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
956 .ok()
957 .and_then(|r| r.error)
958 .unwrap_or(body_text.clone()),
959 });
960 }
961 Ok(serde_json::from_str(&body_text)?)
962 }
963
964 pub async fn organization_role_patch(
966 &self,
967 organization_id: &str,
968 role_id: &str,
969 body: &RoleUpdateRequest,
970 ) -> Result<ApiResponse<RBACRole>, Error> {
971 let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
972 let mut req = self.request(reqwest::Method::PATCH, &path);
973 req = req.json(body);
974 let resp = req.send().await?;
975 let status = resp.status();
976 let body_text = resp.text().await?;
977 if !status.is_success() {
978 return Err(Error::Api {
979 status: status.as_u16(),
980 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
981 .ok()
982 .and_then(|r| r.error)
983 .unwrap_or(body_text.clone()),
984 });
985 }
986 Ok(serde_json::from_str(&body_text)?)
987 }
988
989 pub async fn organization_role_delete(
991 &self,
992 organization_id: &str,
993 role_id: &str,
994 ) -> Result<ApiResponse<serde_json::Value>, Error> {
995 let path = format!("/v1/organizations/{organization_id}/roles/{role_id}");
996 let req = self.request(reqwest::Method::DELETE, &path);
997 let resp = req.send().await?;
998 let status = resp.status();
999 let body_text = resp.text().await?;
1000 if !status.is_success() {
1001 return Err(Error::Api {
1002 status: status.as_u16(),
1003 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1004 .ok()
1005 .and_then(|r| r.error)
1006 .unwrap_or(body_text.clone()),
1007 });
1008 }
1009 Ok(serde_json::from_str(&body_text)?)
1010 }
1011
1012 pub async fn postgres_service_create(
1014 &self,
1015 organization_id: &str,
1016 body: &PostgresServicePostRequest,
1017 ) -> Result<ApiResponse<PostgresService>, Error> {
1018 let path = format!("/v1/organizations/{organization_id}/postgres");
1019 let mut req = self.request(reqwest::Method::POST, &path);
1020 req = req.json(body);
1021 let resp = req.send().await?;
1022 let status = resp.status();
1023 let body_text = resp.text().await?;
1024 if !status.is_success() {
1025 return Err(Error::Api {
1026 status: status.as_u16(),
1027 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1028 .ok()
1029 .and_then(|r| r.error)
1030 .unwrap_or(body_text.clone()),
1031 });
1032 }
1033 Ok(serde_json::from_str(&body_text)?)
1034 }
1035
1036 pub async fn postgres_service_get_list(
1038 &self,
1039 organization_id: &str,
1040 ) -> Result<ApiResponse<Vec<PostgresServiceListItem>>, Error> {
1041 let path = format!("/v1/organizations/{organization_id}/postgres");
1042 let req = self.request(reqwest::Method::GET, &path);
1043 let resp = req.send().await?;
1044 let status = resp.status();
1045 let body_text = resp.text().await?;
1046 if !status.is_success() {
1047 return Err(Error::Api {
1048 status: status.as_u16(),
1049 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1050 .ok()
1051 .and_then(|r| r.error)
1052 .unwrap_or(body_text.clone()),
1053 });
1054 }
1055 Ok(serde_json::from_str(&body_text)?)
1056 }
1057
1058 pub async fn postgres_service_get(
1060 &self,
1061 organization_id: &str,
1062 postgres_id: &str,
1063 ) -> Result<ApiResponse<PostgresService>, Error> {
1064 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
1065 let req = self.request(reqwest::Method::GET, &path);
1066 let resp = req.send().await?;
1067 let status = resp.status();
1068 let body_text = resp.text().await?;
1069 if !status.is_success() {
1070 return Err(Error::Api {
1071 status: status.as_u16(),
1072 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1073 .ok()
1074 .and_then(|r| r.error)
1075 .unwrap_or(body_text.clone()),
1076 });
1077 }
1078 Ok(serde_json::from_str(&body_text)?)
1079 }
1080
1081 pub async fn postgres_service_delete(
1083 &self,
1084 organization_id: &str,
1085 postgres_id: &str,
1086 ) -> Result<ApiResponse<serde_json::Value>, Error> {
1087 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
1088 let req = self.request(reqwest::Method::DELETE, &path);
1089 let resp = req.send().await?;
1090 let status = resp.status();
1091 let body_text = resp.text().await?;
1092 if !status.is_success() {
1093 return Err(Error::Api {
1094 status: status.as_u16(),
1095 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1096 .ok()
1097 .and_then(|r| r.error)
1098 .unwrap_or(body_text.clone()),
1099 });
1100 }
1101 Ok(serde_json::from_str(&body_text)?)
1102 }
1103
1104 pub async fn postgres_service_patch(
1106 &self,
1107 organization_id: &str,
1108 postgres_id: &str,
1109 body: &PostgresServicePatchRequest,
1110 ) -> Result<ApiResponse<PostgresService>, Error> {
1111 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}");
1112 let mut req = self.request(reqwest::Method::PATCH, &path);
1113 req = req.json(body);
1114 let resp = req.send().await?;
1115 let status = resp.status();
1116 let body_text = resp.text().await?;
1117 if !status.is_success() {
1118 return Err(Error::Api {
1119 status: status.as_u16(),
1120 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1121 .ok()
1122 .and_then(|r| r.error)
1123 .unwrap_or(body_text.clone()),
1124 });
1125 }
1126 Ok(serde_json::from_str(&body_text)?)
1127 }
1128
1129 pub async fn postgres_service_certs_get(
1131 &self,
1132 organization_id: &str,
1133 postgres_id: &str,
1134 ) -> Result<String, Error> {
1135 let path =
1136 format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/caCertificates");
1137 let req = self.request(reqwest::Method::GET, &path);
1138 let resp = req.send().await?;
1139 let status = resp.status();
1140 let body_text = resp.text().await?;
1141 if !status.is_success() {
1142 return Err(Error::Api {
1143 status: status.as_u16(),
1144 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1145 .ok()
1146 .and_then(|r| r.error)
1147 .unwrap_or(body_text.clone()),
1148 });
1149 }
1150 Ok(body_text)
1151 }
1152
1153 pub async fn postgres_instance_config_get(
1155 &self,
1156 organization_id: &str,
1157 postgres_id: &str,
1158 ) -> Result<ApiResponse<PostgresInstanceConfigResponse>, Error> {
1159 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
1160 let req = self.request(reqwest::Method::GET, &path);
1161 let resp = req.send().await?;
1162 let status = resp.status();
1163 let body_text = resp.text().await?;
1164 if !status.is_success() {
1165 return Err(Error::Api {
1166 status: status.as_u16(),
1167 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1168 .ok()
1169 .and_then(|r| r.error)
1170 .unwrap_or(body_text.clone()),
1171 });
1172 }
1173 Ok(serde_json::from_str(&body_text)?)
1174 }
1175
1176 pub async fn postgres_instance_config_post(
1178 &self,
1179 organization_id: &str,
1180 postgres_id: &str,
1181 body: &PostgresInstanceConfig,
1182 ) -> Result<ApiResponse<PostgresInstanceUpdateConfigResponse>, Error> {
1183 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
1184 let mut req = self.request(reqwest::Method::POST, &path);
1185 req = req.json(body);
1186 let resp = req.send().await?;
1187 let status = resp.status();
1188 let body_text = resp.text().await?;
1189 if !status.is_success() {
1190 return Err(Error::Api {
1191 status: status.as_u16(),
1192 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1193 .ok()
1194 .and_then(|r| r.error)
1195 .unwrap_or(body_text.clone()),
1196 });
1197 }
1198 Ok(serde_json::from_str(&body_text)?)
1199 }
1200
1201 pub async fn postgres_instance_config_patch(
1203 &self,
1204 organization_id: &str,
1205 postgres_id: &str,
1206 body: &PostgresInstanceConfig,
1207 ) -> Result<ApiResponse<PostgresInstanceUpdateConfigResponse>, Error> {
1208 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/config");
1209 let mut req = self.request(reqwest::Method::PATCH, &path);
1210 req = req.json(body);
1211 let resp = req.send().await?;
1212 let status = resp.status();
1213 let body_text = resp.text().await?;
1214 if !status.is_success() {
1215 return Err(Error::Api {
1216 status: status.as_u16(),
1217 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1218 .ok()
1219 .and_then(|r| r.error)
1220 .unwrap_or(body_text.clone()),
1221 });
1222 }
1223 Ok(serde_json::from_str(&body_text)?)
1224 }
1225
1226 pub async fn postgres_service_set_password(
1228 &self,
1229 organization_id: &str,
1230 postgres_id: &str,
1231 body: &PostgresServiceSetPassword,
1232 ) -> Result<ApiResponse<PostgresServicePasswordResource>, Error> {
1233 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/password");
1234 let mut req = self.request(reqwest::Method::PATCH, &path);
1235 req = req.json(body);
1236 let resp = req.send().await?;
1237 let status = resp.status();
1238 let body_text = resp.text().await?;
1239 if !status.is_success() {
1240 return Err(Error::Api {
1241 status: status.as_u16(),
1242 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1243 .ok()
1244 .and_then(|r| r.error)
1245 .unwrap_or(body_text.clone()),
1246 });
1247 }
1248 Ok(serde_json::from_str(&body_text)?)
1249 }
1250
1251 pub async fn postgres_instance_create_read_replica(
1253 &self,
1254 organization_id: &str,
1255 postgres_id: &str,
1256 body: &PostgresServiceReadReplicaRequest,
1257 ) -> Result<ApiResponse<PostgresService>, Error> {
1258 let path =
1259 format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/readReplica");
1260 let mut req = self.request(reqwest::Method::POST, &path);
1261 req = req.json(body);
1262 let resp = req.send().await?;
1263 let status = resp.status();
1264 let body_text = resp.text().await?;
1265 if !status.is_success() {
1266 return Err(Error::Api {
1267 status: status.as_u16(),
1268 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1269 .ok()
1270 .and_then(|r| r.error)
1271 .unwrap_or(body_text.clone()),
1272 });
1273 }
1274 Ok(serde_json::from_str(&body_text)?)
1275 }
1276
1277 pub async fn postgres_instance_prometheus_get(
1279 &self,
1280 organization_id: &str,
1281 postgres_id: &str,
1282 ) -> Result<String, Error> {
1283 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/prometheus");
1284 let req = self.request(reqwest::Method::GET, &path);
1285 let resp = req.send().await?;
1286 let status = resp.status();
1287 if !status.is_success() {
1288 let body_text = resp.text().await?;
1289 return Err(Error::Api {
1290 status: status.as_u16(),
1291 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1292 .ok()
1293 .and_then(|r| r.error)
1294 .unwrap_or(body_text),
1295 });
1296 }
1297 Ok(resp.text().await?)
1298 }
1299
1300 pub async fn postgres_org_prometheus_get(
1302 &self,
1303 organization_id: &str,
1304 ) -> Result<String, Error> {
1305 let path = format!("/v1/organizations/{organization_id}/postgres/prometheus");
1306 let req = self.request(reqwest::Method::GET, &path);
1307 let resp = req.send().await?;
1308 let status = resp.status();
1309 if !status.is_success() {
1310 let body_text = resp.text().await?;
1311 return Err(Error::Api {
1312 status: status.as_u16(),
1313 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1314 .ok()
1315 .and_then(|r| r.error)
1316 .unwrap_or(body_text),
1317 });
1318 }
1319 Ok(resp.text().await?)
1320 }
1321
1322 pub async fn postgres_instance_restore(
1324 &self,
1325 organization_id: &str,
1326 postgres_id: &str,
1327 body: &PostgresServiceRestoreRequest,
1328 ) -> Result<ApiResponse<PostgresService>, Error> {
1329 let path =
1330 format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/restoredService");
1331 let mut req = self.request(reqwest::Method::POST, &path);
1332 req = req.json(body);
1333 let resp = req.send().await?;
1334 let status = resp.status();
1335 let body_text = resp.text().await?;
1336 if !status.is_success() {
1337 return Err(Error::Api {
1338 status: status.as_u16(),
1339 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1340 .ok()
1341 .and_then(|r| r.error)
1342 .unwrap_or(body_text.clone()),
1343 });
1344 }
1345 Ok(serde_json::from_str(&body_text)?)
1346 }
1347
1348 pub async fn postgres_service_patch_state(
1350 &self,
1351 organization_id: &str,
1352 postgres_id: &str,
1353 body: &PostgresServiceSetState,
1354 ) -> Result<ApiResponse<PostgresService>, Error> {
1355 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/state");
1356 let mut req = self.request(reqwest::Method::PATCH, &path);
1357 req = req.json(body);
1358 let resp = req.send().await?;
1359 let status = resp.status();
1360 let body_text = resp.text().await?;
1361 if !status.is_success() {
1362 return Err(Error::Api {
1363 status: status.as_u16(),
1364 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1365 .ok()
1366 .and_then(|r| r.error)
1367 .unwrap_or(body_text.clone()),
1368 });
1369 }
1370 Ok(serde_json::from_str(&body_text)?)
1371 }
1372
1373 #[allow(clippy::too_many_arguments)]
1375 pub async fn postgres_instance_metrics_get(
1376 &self,
1377 organization_id: &str,
1378 postgres_id: &str,
1379 from_date: &str,
1380 to_date: &str,
1381 bucket_size_seconds: Option<i64>,
1382 ) -> Result<ApiResponse<PostgresMetrics>, Error> {
1383 let path = format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/metrics");
1384 let mut req = self.request(reqwest::Method::GET, &path);
1385 req = req.query(&[("from_date", from_date), ("to_date", to_date)]);
1386 if let Some(v) = bucket_size_seconds {
1387 req = req.query(&[("bucket_size_seconds", v)]);
1388 }
1389 let resp = req.send().await?;
1390 let status = resp.status();
1391 let body_text = resp.text().await?;
1392 if !status.is_success() {
1393 return Err(Error::Api {
1394 status: status.as_u16(),
1395 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1396 .ok()
1397 .and_then(|r| r.error)
1398 .unwrap_or(body_text.clone()),
1399 });
1400 }
1401 Ok(serde_json::from_str(&body_text)?)
1402 }
1403
1404 #[allow(clippy::too_many_arguments)]
1406 pub async fn slow_query_patterns_get_list(
1407 &self,
1408 organization_id: &str,
1409 postgres_id: &str,
1410 from_date: &str,
1411 to_date: &str,
1412 db_name: Option<&str>,
1413 db_user: Option<&str>,
1414 db_operation: Option<&str>,
1415 app: Option<&str>,
1416 sort_by: Option<&str>,
1417 sort_order: Option<&str>,
1418 limit: Option<i64>,
1419 offset: Option<i64>,
1420 ) -> Result<ApiResponse<Vec<PostgresSlowQueryPattern>>, Error> {
1421 let path =
1422 format!("/v1/organizations/{organization_id}/postgres/{postgres_id}/slowQueryPatterns");
1423 let mut req = self.request(reqwest::Method::GET, &path);
1424 req = req.query(&[("from_date", from_date), ("to_date", to_date)]);
1425 if let Some(v) = db_name {
1426 req = req.query(&[("db_name", v)]);
1427 }
1428 if let Some(v) = db_user {
1429 req = req.query(&[("db_user", v)]);
1430 }
1431 if let Some(v) = db_operation {
1432 req = req.query(&[("db_operation", v)]);
1433 }
1434 if let Some(v) = app {
1435 req = req.query(&[("app", v)]);
1436 }
1437 if let Some(v) = sort_by {
1438 req = req.query(&[("sort_by", v)]);
1439 }
1440 if let Some(v) = sort_order {
1441 req = req.query(&[("sort_order", v)]);
1442 }
1443 if let Some(v) = limit {
1444 req = req.query(&[("limit", v)]);
1445 }
1446 if let Some(v) = offset {
1447 req = req.query(&[("offset", v)]);
1448 }
1449 let resp = req.send().await?;
1450 let status = resp.status();
1451 let body_text = resp.text().await?;
1452 if !status.is_success() {
1453 return Err(Error::Api {
1454 status: status.as_u16(),
1455 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1456 .ok()
1457 .and_then(|r| r.error)
1458 .unwrap_or(body_text.clone()),
1459 });
1460 }
1461 Ok(serde_json::from_str(&body_text)?)
1462 }
1463
1464 #[allow(clippy::too_many_arguments)]
1466 pub async fn slow_query_pattern_get(
1467 &self,
1468 organization_id: &str,
1469 postgres_id: &str,
1470 query_id: &str,
1471 db_name: &str,
1472 db_user: &str,
1473 db_operation: &str,
1474 app: Option<&str>,
1475 timestamp: Option<&str>,
1476 ) -> Result<ApiResponse<PostgresSlowQueryPatternDetail>, Error> {
1477 let path = format!(
1478 "/v1/organizations/{organization_id}/postgres/{postgres_id}/slowQueryPatterns/{query_id}"
1479 );
1480 let mut req = self.request(reqwest::Method::GET, &path);
1481 req = req.query(&[
1482 ("db_name", db_name),
1483 ("db_user", db_user),
1484 ("db_operation", db_operation),
1485 ]);
1486 if let Some(v) = app {
1487 req = req.query(&[("app", v)]);
1488 }
1489 if let Some(v) = timestamp {
1490 req = req.query(&[("timestamp", v)]);
1491 }
1492 let resp = req.send().await?;
1493 let status = resp.status();
1494 let body_text = resp.text().await?;
1495 if !status.is_success() {
1496 return Err(Error::Api {
1497 status: status.as_u16(),
1498 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1499 .ok()
1500 .and_then(|r| r.error)
1501 .unwrap_or(body_text.clone()),
1502 });
1503 }
1504 Ok(serde_json::from_str(&body_text)?)
1505 }
1506
1507 #[deprecated]
1509 #[allow(deprecated)]
1510 pub async fn organization_private_endpoint_config_get_list(
1511 &self,
1512 organization_id: &str,
1513 cloud_provider: &str,
1514 region_id: &str,
1515 ) -> Result<ApiResponse<OrganizationCloudRegionPrivateEndpointConfig>, Error> {
1516 let path = format!("/v1/organizations/{organization_id}/privateEndpointConfig");
1517 let mut req = self.request(reqwest::Method::GET, &path);
1518 req = req.query(&[("cloud_provider", cloud_provider)]);
1519 req = req.query(&[("region_id", region_id)]);
1520 let resp = req.send().await?;
1521 let status = resp.status();
1522 let body_text = resp.text().await?;
1523 if !status.is_success() {
1524 return Err(Error::Api {
1525 status: status.as_u16(),
1526 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1527 .ok()
1528 .and_then(|r| r.error)
1529 .unwrap_or(body_text.clone()),
1530 });
1531 }
1532 Ok(serde_json::from_str(&body_text)?)
1533 }
1534
1535 pub async fn organization_prometheus_get(
1537 &self,
1538 organization_id: &str,
1539 filtered_metrics: Option<&str>,
1540 ) -> Result<String, Error> {
1541 let path = format!("/v1/organizations/{organization_id}/prometheus");
1542 let mut req = self.request(reqwest::Method::GET, &path);
1543 if let Some(v) = filtered_metrics {
1544 req = req.query(&[("filtered_metrics", v)]);
1545 }
1546 let resp = req.send().await?;
1547 let status = resp.status();
1548 if !status.is_success() {
1549 let body_text = resp.text().await?;
1550 return Err(Error::Api {
1551 status: status.as_u16(),
1552 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1553 .ok()
1554 .and_then(|r| r.error)
1555 .unwrap_or(body_text),
1556 });
1557 }
1558 Ok(resp.text().await?)
1559 }
1560
1561 pub async fn instance_get_list(
1563 &self,
1564 organization_id: &str,
1565 filters: &[&str],
1566 ) -> Result<ApiResponse<Vec<Service>>, Error> {
1567 let path = format!("/v1/organizations/{organization_id}/services");
1568 let mut req = self.request(reqwest::Method::GET, &path);
1569 for f in filters {
1570 req = req.query(&[("filter", f)]);
1571 }
1572 let resp = req.send().await?;
1573 let status = resp.status();
1574 let body_text = resp.text().await?;
1575 if !status.is_success() {
1576 return Err(Error::Api {
1577 status: status.as_u16(),
1578 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1579 .ok()
1580 .and_then(|r| r.error)
1581 .unwrap_or(body_text.clone()),
1582 });
1583 }
1584 Ok(serde_json::from_str(&body_text)?)
1585 }
1586
1587 pub async fn instance_create(
1589 &self,
1590 organization_id: &str,
1591 body: &ServicePostRequest,
1592 ) -> Result<ApiResponse<ServicePostResponse>, Error> {
1593 let path = format!("/v1/organizations/{organization_id}/services");
1594 let mut req = self.request(reqwest::Method::POST, &path);
1595 req = req.json(body);
1596 let resp = req.send().await?;
1597 let status = resp.status();
1598 let body_text = resp.text().await?;
1599 if !status.is_success() {
1600 return Err(Error::Api {
1601 status: status.as_u16(),
1602 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1603 .ok()
1604 .and_then(|r| r.error)
1605 .unwrap_or(body_text.clone()),
1606 });
1607 }
1608 Ok(serde_json::from_str(&body_text)?)
1609 }
1610
1611 pub async fn instance_get(
1613 &self,
1614 organization_id: &str,
1615 service_id: &str,
1616 ) -> Result<ApiResponse<Service>, Error> {
1617 let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
1618 let req = self.request(reqwest::Method::GET, &path);
1619 let resp = req.send().await?;
1620 let status = resp.status();
1621 let body_text = resp.text().await?;
1622 if !status.is_success() {
1623 return Err(Error::Api {
1624 status: status.as_u16(),
1625 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1626 .ok()
1627 .and_then(|r| r.error)
1628 .unwrap_or(body_text.clone()),
1629 });
1630 }
1631 Ok(serde_json::from_str(&body_text)?)
1632 }
1633
1634 pub async fn instance_update(
1636 &self,
1637 organization_id: &str,
1638 service_id: &str,
1639 body: &ServicePatchRequest,
1640 ) -> Result<ApiResponse<Service>, Error> {
1641 let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
1642 let mut req = self.request(reqwest::Method::PATCH, &path);
1643 req = req.json(body);
1644 let resp = req.send().await?;
1645 let status = resp.status();
1646 let body_text = resp.text().await?;
1647 if !status.is_success() {
1648 return Err(Error::Api {
1649 status: status.as_u16(),
1650 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1651 .ok()
1652 .and_then(|r| r.error)
1653 .unwrap_or(body_text.clone()),
1654 });
1655 }
1656 Ok(serde_json::from_str(&body_text)?)
1657 }
1658
1659 pub async fn instance_delete(
1661 &self,
1662 organization_id: &str,
1663 service_id: &str,
1664 ) -> Result<ApiResponse<serde_json::Value>, Error> {
1665 let path = format!("/v1/organizations/{organization_id}/services/{service_id}");
1666 let req = self.request(reqwest::Method::DELETE, &path);
1667 let resp = req.send().await?;
1668 let status = resp.status();
1669 let body_text = resp.text().await?;
1670 if !status.is_success() {
1671 return Err(Error::Api {
1672 status: status.as_u16(),
1673 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1674 .ok()
1675 .and_then(|r| r.error)
1676 .unwrap_or(body_text.clone()),
1677 });
1678 }
1679 Ok(serde_json::from_str(&body_text)?)
1680 }
1681
1682 pub async fn backup_bucket_get(
1684 &self,
1685 organization_id: &str,
1686 service_id: &str,
1687 ) -> Result<ApiResponse<BackupBucket>, Error> {
1688 let path =
1689 format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
1690 let req = self.request(reqwest::Method::GET, &path);
1691 let resp = req.send().await?;
1692 let status = resp.status();
1693 let body_text = resp.text().await?;
1694 if !status.is_success() {
1695 return Err(Error::Api {
1696 status: status.as_u16(),
1697 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1698 .ok()
1699 .and_then(|r| r.error)
1700 .unwrap_or(body_text.clone()),
1701 });
1702 }
1703 Ok(serde_json::from_str(&body_text)?)
1704 }
1705
1706 pub async fn backup_bucket_create(
1708 &self,
1709 organization_id: &str,
1710 service_id: &str,
1711 body: &BackupBucketPostRequest,
1712 ) -> Result<ApiResponse<BackupBucket>, Error> {
1713 let path =
1714 format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
1715 let mut req = self.request(reqwest::Method::POST, &path);
1716 req = req.json(body);
1717 let resp = req.send().await?;
1718 let status = resp.status();
1719 let body_text = resp.text().await?;
1720 if !status.is_success() {
1721 return Err(Error::Api {
1722 status: status.as_u16(),
1723 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1724 .ok()
1725 .and_then(|r| r.error)
1726 .unwrap_or(body_text.clone()),
1727 });
1728 }
1729 Ok(serde_json::from_str(&body_text)?)
1730 }
1731
1732 pub async fn backup_bucket_update(
1734 &self,
1735 organization_id: &str,
1736 service_id: &str,
1737 body: &BackupBucketPatchRequest,
1738 ) -> Result<ApiResponse<BackupBucket>, Error> {
1739 let path =
1740 format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
1741 let mut req = self.request(reqwest::Method::PATCH, &path);
1742 req = req.json(body);
1743 let resp = req.send().await?;
1744 let status = resp.status();
1745 let body_text = resp.text().await?;
1746 if !status.is_success() {
1747 return Err(Error::Api {
1748 status: status.as_u16(),
1749 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1750 .ok()
1751 .and_then(|r| r.error)
1752 .unwrap_or(body_text.clone()),
1753 });
1754 }
1755 Ok(serde_json::from_str(&body_text)?)
1756 }
1757
1758 pub async fn backup_bucket_delete(
1760 &self,
1761 organization_id: &str,
1762 service_id: &str,
1763 ) -> Result<ApiResponse<serde_json::Value>, Error> {
1764 let path =
1765 format!("/v1/organizations/{organization_id}/services/{service_id}/backupBucket");
1766 let req = self.request(reqwest::Method::DELETE, &path);
1767 let resp = req.send().await?;
1768 let status = resp.status();
1769 let body_text = resp.text().await?;
1770 if !status.is_success() {
1771 return Err(Error::Api {
1772 status: status.as_u16(),
1773 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1774 .ok()
1775 .and_then(|r| r.error)
1776 .unwrap_or(body_text.clone()),
1777 });
1778 }
1779 Ok(serde_json::from_str(&body_text)?)
1780 }
1781
1782 pub async fn backup_configuration_get(
1784 &self,
1785 organization_id: &str,
1786 service_id: &str,
1787 ) -> Result<ApiResponse<BackupConfiguration>, Error> {
1788 let path = format!(
1789 "/v1/organizations/{organization_id}/services/{service_id}/backupConfiguration"
1790 );
1791 let req = self.request(reqwest::Method::GET, &path);
1792 let resp = req.send().await?;
1793 let status = resp.status();
1794 let body_text = resp.text().await?;
1795 if !status.is_success() {
1796 return Err(Error::Api {
1797 status: status.as_u16(),
1798 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1799 .ok()
1800 .and_then(|r| r.error)
1801 .unwrap_or(body_text.clone()),
1802 });
1803 }
1804 Ok(serde_json::from_str(&body_text)?)
1805 }
1806
1807 pub async fn backup_configuration_update(
1809 &self,
1810 organization_id: &str,
1811 service_id: &str,
1812 body: &BackupConfigurationPatchRequest,
1813 ) -> Result<ApiResponse<BackupConfiguration>, Error> {
1814 let path = format!(
1815 "/v1/organizations/{organization_id}/services/{service_id}/backupConfiguration"
1816 );
1817 let mut req = self.request(reqwest::Method::PATCH, &path);
1818 req = req.json(body);
1819 let resp = req.send().await?;
1820 let status = resp.status();
1821 let body_text = resp.text().await?;
1822 if !status.is_success() {
1823 return Err(Error::Api {
1824 status: status.as_u16(),
1825 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1826 .ok()
1827 .and_then(|r| r.error)
1828 .unwrap_or(body_text.clone()),
1829 });
1830 }
1831 Ok(serde_json::from_str(&body_text)?)
1832 }
1833
1834 pub async fn backup_get_list(
1836 &self,
1837 organization_id: &str,
1838 service_id: &str,
1839 ) -> Result<ApiResponse<Vec<Backup>>, Error> {
1840 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/backups");
1841 let req = self.request(reqwest::Method::GET, &path);
1842 let resp = req.send().await?;
1843 let status = resp.status();
1844 let body_text = resp.text().await?;
1845 if !status.is_success() {
1846 return Err(Error::Api {
1847 status: status.as_u16(),
1848 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1849 .ok()
1850 .and_then(|r| r.error)
1851 .unwrap_or(body_text.clone()),
1852 });
1853 }
1854 Ok(serde_json::from_str(&body_text)?)
1855 }
1856
1857 pub async fn backup_get(
1859 &self,
1860 organization_id: &str,
1861 service_id: &str,
1862 backup_id: &str,
1863 ) -> Result<ApiResponse<Backup>, Error> {
1864 let path = format!(
1865 "/v1/organizations/{organization_id}/services/{service_id}/backups/{backup_id}"
1866 );
1867 let req = self.request(reqwest::Method::GET, &path);
1868 let resp = req.send().await?;
1869 let status = resp.status();
1870 let body_text = resp.text().await?;
1871 if !status.is_success() {
1872 return Err(Error::Api {
1873 status: status.as_u16(),
1874 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1875 .ok()
1876 .and_then(|r| r.error)
1877 .unwrap_or(body_text.clone()),
1878 });
1879 }
1880 Ok(serde_json::from_str(&body_text)?)
1881 }
1882
1883 pub async fn click_pipe_get_list(
1885 &self,
1886 organization_id: &str,
1887 service_id: &str,
1888 ) -> Result<ApiResponse<Vec<ClickPipe>>, Error> {
1889 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/clickpipes");
1890 let req = self.request(reqwest::Method::GET, &path);
1891 let resp = req.send().await?;
1892 let status = resp.status();
1893 let body_text = resp.text().await?;
1894 if !status.is_success() {
1895 return Err(Error::Api {
1896 status: status.as_u16(),
1897 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1898 .ok()
1899 .and_then(|r| r.error)
1900 .unwrap_or(body_text.clone()),
1901 });
1902 }
1903 Ok(serde_json::from_str(&body_text)?)
1904 }
1905
1906 pub async fn click_pipe_create(
1908 &self,
1909 organization_id: &str,
1910 service_id: &str,
1911 body: &ClickPipePostRequest,
1912 ) -> Result<ApiResponse<ClickPipe>, Error> {
1913 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/clickpipes");
1914 let mut req = self.request(reqwest::Method::POST, &path);
1915 req = req.json(body);
1916 let resp = req.send().await?;
1917 let status = resp.status();
1918 let body_text = resp.text().await?;
1919 if !status.is_success() {
1920 return Err(Error::Api {
1921 status: status.as_u16(),
1922 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1923 .ok()
1924 .and_then(|r| r.error)
1925 .unwrap_or(body_text.clone()),
1926 });
1927 }
1928 Ok(serde_json::from_str(&body_text)?)
1929 }
1930
1931 pub async fn click_pipe_get(
1933 &self,
1934 organization_id: &str,
1935 service_id: &str,
1936 click_pipe_id: &str,
1937 ) -> Result<ApiResponse<ClickPipe>, Error> {
1938 let path = format!(
1939 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
1940 );
1941 let req = self.request(reqwest::Method::GET, &path);
1942 let resp = req.send().await?;
1943 let status = resp.status();
1944 let body_text = resp.text().await?;
1945 if !status.is_success() {
1946 return Err(Error::Api {
1947 status: status.as_u16(),
1948 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1949 .ok()
1950 .and_then(|r| r.error)
1951 .unwrap_or(body_text.clone()),
1952 });
1953 }
1954 Ok(serde_json::from_str(&body_text)?)
1955 }
1956
1957 pub async fn click_pipe_update(
1959 &self,
1960 organization_id: &str,
1961 service_id: &str,
1962 click_pipe_id: &str,
1963 body: &ClickPipePatchRequest,
1964 ) -> Result<ApiResponse<ClickPipe>, Error> {
1965 let path = format!(
1966 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
1967 );
1968 let mut req = self.request(reqwest::Method::PATCH, &path);
1969 req = req.json(body);
1970 let resp = req.send().await?;
1971 let status = resp.status();
1972 let body_text = resp.text().await?;
1973 if !status.is_success() {
1974 return Err(Error::Api {
1975 status: status.as_u16(),
1976 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
1977 .ok()
1978 .and_then(|r| r.error)
1979 .unwrap_or(body_text.clone()),
1980 });
1981 }
1982 Ok(serde_json::from_str(&body_text)?)
1983 }
1984
1985 pub async fn click_pipe_delete(
1987 &self,
1988 organization_id: &str,
1989 service_id: &str,
1990 click_pipe_id: &str,
1991 ) -> Result<ApiResponse<serde_json::Value>, Error> {
1992 let path = format!(
1993 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}"
1994 );
1995 let req = self.request(reqwest::Method::DELETE, &path);
1996 let resp = req.send().await?;
1997 let status = resp.status();
1998 let body_text = resp.text().await?;
1999 if !status.is_success() {
2000 return Err(Error::Api {
2001 status: status.as_u16(),
2002 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2003 .ok()
2004 .and_then(|r| r.error)
2005 .unwrap_or(body_text.clone()),
2006 });
2007 }
2008 Ok(serde_json::from_str(&body_text)?)
2009 }
2010
2011 pub async fn click_pipe_scaling_update(
2013 &self,
2014 organization_id: &str,
2015 service_id: &str,
2016 click_pipe_id: &str,
2017 body: &ClickPipeScalingPatchRequest,
2018 ) -> Result<ApiResponse<ClickPipe>, Error> {
2019 let path = format!(
2020 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/scaling"
2021 );
2022 let mut req = self.request(reqwest::Method::PATCH, &path);
2023 req = req.json(body);
2024 let resp = req.send().await?;
2025 let status = resp.status();
2026 let body_text = resp.text().await?;
2027 if !status.is_success() {
2028 return Err(Error::Api {
2029 status: status.as_u16(),
2030 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2031 .ok()
2032 .and_then(|r| r.error)
2033 .unwrap_or(body_text.clone()),
2034 });
2035 }
2036 Ok(serde_json::from_str(&body_text)?)
2037 }
2038
2039 pub async fn click_pipe_settings_get(
2041 &self,
2042 organization_id: &str,
2043 service_id: &str,
2044 click_pipe_id: &str,
2045 ) -> Result<ApiResponse<ClickPipeSettingsResponse>, Error> {
2046 let path = format!(
2047 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/settings"
2048 );
2049 let req = self.request(reqwest::Method::GET, &path);
2050 let resp = req.send().await?;
2051 let status = resp.status();
2052 let body_text = resp.text().await?;
2053 if !status.is_success() {
2054 return Err(Error::Api {
2055 status: status.as_u16(),
2056 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2057 .ok()
2058 .and_then(|r| r.error)
2059 .unwrap_or(body_text.clone()),
2060 });
2061 }
2062 Ok(serde_json::from_str(&body_text)?)
2063 }
2064
2065 pub async fn click_pipe_settings_update(
2067 &self,
2068 organization_id: &str,
2069 service_id: &str,
2070 click_pipe_id: &str,
2071 body: &ClickPipeSettingsPutRequest,
2072 ) -> Result<ApiResponse<ClickPipeSettingsResponse>, Error> {
2073 let path = format!(
2074 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/settings"
2075 );
2076 let mut req = self.request(reqwest::Method::PUT, &path);
2077 req = req.json(body);
2078 let resp = req.send().await?;
2079 let status = resp.status();
2080 let body_text = resp.text().await?;
2081 if !status.is_success() {
2082 return Err(Error::Api {
2083 status: status.as_u16(),
2084 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2085 .ok()
2086 .and_then(|r| r.error)
2087 .unwrap_or(body_text.clone()),
2088 });
2089 }
2090 Ok(serde_json::from_str(&body_text)?)
2091 }
2092
2093 pub async fn click_pipe_state_update(
2095 &self,
2096 organization_id: &str,
2097 service_id: &str,
2098 click_pipe_id: &str,
2099 body: &ClickPipeStatePatchRequest,
2100 ) -> Result<ApiResponse<ClickPipe>, Error> {
2101 let path = format!(
2102 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/{click_pipe_id}/state"
2103 );
2104 let mut req = self.request(reqwest::Method::PATCH, &path);
2105 req = req.json(body);
2106 let resp = req.send().await?;
2107 let status = resp.status();
2108 let body_text = resp.text().await?;
2109 if !status.is_success() {
2110 return Err(Error::Api {
2111 status: status.as_u16(),
2112 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2113 .ok()
2114 .and_then(|r| r.error)
2115 .unwrap_or(body_text.clone()),
2116 });
2117 }
2118 Ok(serde_json::from_str(&body_text)?)
2119 }
2120
2121 pub async fn click_pipe_cdc_scaling_get(
2123 &self,
2124 organization_id: &str,
2125 service_id: &str,
2126 ) -> Result<ApiResponse<ClickPipesCdcScaling>, Error> {
2127 let path = format!(
2128 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesCdcScaling"
2129 );
2130 let req = self.request(reqwest::Method::GET, &path);
2131 let resp = req.send().await?;
2132 let status = resp.status();
2133 let body_text = resp.text().await?;
2134 if !status.is_success() {
2135 return Err(Error::Api {
2136 status: status.as_u16(),
2137 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2138 .ok()
2139 .and_then(|r| r.error)
2140 .unwrap_or(body_text.clone()),
2141 });
2142 }
2143 Ok(serde_json::from_str(&body_text)?)
2144 }
2145
2146 pub async fn click_pipe_cdc_scaling_update(
2148 &self,
2149 organization_id: &str,
2150 service_id: &str,
2151 body: &ClickPipesCdcScalingPatchRequest,
2152 ) -> Result<ApiResponse<ClickPipesCdcScaling>, Error> {
2153 let path = format!(
2154 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesCdcScaling"
2155 );
2156 let mut req = self.request(reqwest::Method::PATCH, &path);
2157 req = req.json(body);
2158 let resp = req.send().await?;
2159 let status = resp.status();
2160 let body_text = resp.text().await?;
2161 if !status.is_success() {
2162 return Err(Error::Api {
2163 status: status.as_u16(),
2164 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2165 .ok()
2166 .and_then(|r| r.error)
2167 .unwrap_or(body_text.clone()),
2168 });
2169 }
2170 Ok(serde_json::from_str(&body_text)?)
2171 }
2172
2173 pub async fn click_pipe_reverse_private_endpoint_get_list(
2175 &self,
2176 organization_id: &str,
2177 service_id: &str,
2178 ) -> Result<ApiResponse<Vec<ReversePrivateEndpoint>>, Error> {
2179 let path = format!(
2180 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints"
2181 );
2182 let req = self.request(reqwest::Method::GET, &path);
2183 let resp = req.send().await?;
2184 let status = resp.status();
2185 let body_text = resp.text().await?;
2186 if !status.is_success() {
2187 return Err(Error::Api {
2188 status: status.as_u16(),
2189 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2190 .ok()
2191 .and_then(|r| r.error)
2192 .unwrap_or(body_text.clone()),
2193 });
2194 }
2195 Ok(serde_json::from_str(&body_text)?)
2196 }
2197
2198 pub async fn click_pipe_reverse_private_endpoint_create(
2200 &self,
2201 organization_id: &str,
2202 service_id: &str,
2203 body: &CreateReversePrivateEndpoint,
2204 ) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
2205 let path = format!(
2206 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints"
2207 );
2208 let mut req = self.request(reqwest::Method::POST, &path);
2209 req = req.json(body);
2210 let resp = req.send().await?;
2211 let status = resp.status();
2212 let body_text = resp.text().await?;
2213 if !status.is_success() {
2214 return Err(Error::Api {
2215 status: status.as_u16(),
2216 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2217 .ok()
2218 .and_then(|r| r.error)
2219 .unwrap_or(body_text.clone()),
2220 });
2221 }
2222 Ok(serde_json::from_str(&body_text)?)
2223 }
2224
2225 pub async fn click_pipe_reverse_private_endpoint_get(
2227 &self,
2228 organization_id: &str,
2229 service_id: &str,
2230 reverse_private_endpoint_id: &str,
2231 ) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
2232 let path = format!(
2233 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
2234 );
2235 let req = self.request(reqwest::Method::GET, &path);
2236 let resp = req.send().await?;
2237 let status = resp.status();
2238 let body_text = resp.text().await?;
2239 if !status.is_success() {
2240 return Err(Error::Api {
2241 status: status.as_u16(),
2242 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2243 .ok()
2244 .and_then(|r| r.error)
2245 .unwrap_or(body_text.clone()),
2246 });
2247 }
2248 Ok(serde_json::from_str(&body_text)?)
2249 }
2250
2251 pub async fn click_pipe_reverse_private_endpoint_delete(
2253 &self,
2254 organization_id: &str,
2255 service_id: &str,
2256 reverse_private_endpoint_id: &str,
2257 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2258 let path = format!(
2259 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
2260 );
2261 let req = self.request(reqwest::Method::DELETE, &path);
2262 let resp = req.send().await?;
2263 let status = resp.status();
2264 let body_text = resp.text().await?;
2265 if !status.is_success() {
2266 return Err(Error::Api {
2267 status: status.as_u16(),
2268 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2269 .ok()
2270 .and_then(|r| r.error)
2271 .unwrap_or(body_text.clone()),
2272 });
2273 }
2274 Ok(serde_json::from_str(&body_text)?)
2275 }
2276
2277 pub async fn click_pipe_reverse_private_endpoint_update(
2279 &self,
2280 organization_id: &str,
2281 service_id: &str,
2282 reverse_private_endpoint_id: &str,
2283 body: &UpdateReversePrivateEndpoint,
2284 ) -> Result<ApiResponse<ReversePrivateEndpoint>, Error> {
2285 let path = format!(
2286 "/v1/organizations/{organization_id}/services/{service_id}/clickpipesReversePrivateEndpoints/{reverse_private_endpoint_id}"
2287 );
2288 let mut req = self.request(reqwest::Method::PATCH, &path);
2289 req = req.json(body);
2290 let resp = req.send().await?;
2291 let status = resp.status();
2292 let body_text = resp.text().await?;
2293 if !status.is_success() {
2294 return Err(Error::Api {
2295 status: status.as_u16(),
2296 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2297 .ok()
2298 .and_then(|r| r.error)
2299 .unwrap_or(body_text.clone()),
2300 });
2301 }
2302 Ok(serde_json::from_str(&body_text)?)
2303 }
2304
2305 pub async fn click_pipe_schema_discovery(
2307 &self,
2308 organization_id: &str,
2309 service_id: &str,
2310 body: &ClickPipeSchemaDiscoveryRequest,
2311 ) -> Result<ApiResponse<ClickPipeSchemaDiscoveryResponse>, Error> {
2312 let path = format!(
2313 "/v1/organizations/{organization_id}/services/{service_id}/clickpipes/schemaDiscovery"
2314 );
2315 let mut req = self.request(reqwest::Method::POST, &path);
2316 req = req.json(body);
2317 let resp = req.send().await?;
2318 let status = resp.status();
2319 let body_text = resp.text().await?;
2320 if !status.is_success() {
2321 return Err(Error::Api {
2322 status: status.as_u16(),
2323 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2324 .ok()
2325 .and_then(|r| r.error)
2326 .unwrap_or(body_text.clone()),
2327 });
2328 }
2329 Ok(serde_json::from_str(&body_text)?)
2330 }
2331
2332 pub async fn click_stack_list_alerts(
2334 &self,
2335 organization_id: &str,
2336 service_id: &str,
2337 ) -> Result<ApiResponse<Vec<ClickStackAlertResponse>>, Error> {
2338 let path =
2339 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts");
2340 let req = self.request(reqwest::Method::GET, &path);
2341 let resp = req.send().await?;
2342 let status = resp.status();
2343 let body_text = resp.text().await?;
2344 if !status.is_success() {
2345 return Err(Error::Api {
2346 status: status.as_u16(),
2347 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2348 .ok()
2349 .and_then(|r| r.error)
2350 .unwrap_or(body_text.clone()),
2351 });
2352 }
2353 Ok(serde_json::from_str(&body_text)?)
2354 }
2355
2356 pub async fn click_stack_create_alert(
2358 &self,
2359 organization_id: &str,
2360 service_id: &str,
2361 body: &ClickStackCreateAlertRequest,
2362 ) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
2363 let path =
2364 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts");
2365 let mut req = self.request(reqwest::Method::POST, &path);
2366 req = req.json(body);
2367 let resp = req.send().await?;
2368 let status = resp.status();
2369 let body_text = resp.text().await?;
2370 if !status.is_success() {
2371 return Err(Error::Api {
2372 status: status.as_u16(),
2373 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2374 .ok()
2375 .and_then(|r| r.error)
2376 .unwrap_or(body_text.clone()),
2377 });
2378 }
2379 Ok(serde_json::from_str(&body_text)?)
2380 }
2381
2382 pub async fn click_stack_get_alert(
2384 &self,
2385 organization_id: &str,
2386 service_id: &str,
2387 click_stack_alert_id: &str,
2388 ) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
2389 let path = format!(
2390 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
2391 );
2392 let req = self.request(reqwest::Method::GET, &path);
2393 let resp = req.send().await?;
2394 let status = resp.status();
2395 let body_text = resp.text().await?;
2396 if !status.is_success() {
2397 return Err(Error::Api {
2398 status: status.as_u16(),
2399 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2400 .ok()
2401 .and_then(|r| r.error)
2402 .unwrap_or(body_text.clone()),
2403 });
2404 }
2405 Ok(serde_json::from_str(&body_text)?)
2406 }
2407
2408 pub async fn click_stack_update_alert(
2410 &self,
2411 organization_id: &str,
2412 service_id: &str,
2413 click_stack_alert_id: &str,
2414 body: &ClickStackUpdateAlertRequest,
2415 ) -> Result<ApiResponse<ClickStackAlertResponse>, Error> {
2416 let path = format!(
2417 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
2418 );
2419 let mut req = self.request(reqwest::Method::PUT, &path);
2420 req = req.json(body);
2421 let resp = req.send().await?;
2422 let status = resp.status();
2423 let body_text = resp.text().await?;
2424 if !status.is_success() {
2425 return Err(Error::Api {
2426 status: status.as_u16(),
2427 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2428 .ok()
2429 .and_then(|r| r.error)
2430 .unwrap_or(body_text.clone()),
2431 });
2432 }
2433 Ok(serde_json::from_str(&body_text)?)
2434 }
2435
2436 pub async fn click_stack_delete_alert(
2438 &self,
2439 organization_id: &str,
2440 service_id: &str,
2441 click_stack_alert_id: &str,
2442 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2443 let path = format!(
2444 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/alerts/{click_stack_alert_id}"
2445 );
2446 let req = self.request(reqwest::Method::DELETE, &path);
2447 let resp = req.send().await?;
2448 let status = resp.status();
2449 let body_text = resp.text().await?;
2450 if !status.is_success() {
2451 return Err(Error::Api {
2452 status: status.as_u16(),
2453 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2454 .ok()
2455 .and_then(|r| r.error)
2456 .unwrap_or(body_text.clone()),
2457 });
2458 }
2459 Ok(serde_json::from_str(&body_text)?)
2460 }
2461
2462 pub async fn click_stack_list_saved_searches(
2464 &self,
2465 organization_id: &str,
2466 service_id: &str,
2467 ) -> Result<ApiResponse<Vec<ClickStackSavedSearch>>, Error> {
2468 let path = format!(
2469 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches"
2470 );
2471 let req = self.request(reqwest::Method::GET, &path);
2472 let resp = req.send().await?;
2473 let status = resp.status();
2474 let body_text = resp.text().await?;
2475 if !status.is_success() {
2476 return Err(Error::Api {
2477 status: status.as_u16(),
2478 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2479 .ok()
2480 .and_then(|r| r.error)
2481 .unwrap_or(body_text.clone()),
2482 });
2483 }
2484 Ok(serde_json::from_str(&body_text)?)
2485 }
2486
2487 pub async fn click_stack_create_saved_search(
2489 &self,
2490 organization_id: &str,
2491 service_id: &str,
2492 body: &ClickStackSavedSearchInput,
2493 ) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
2494 let path = format!(
2495 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches"
2496 );
2497 let mut req = self.request(reqwest::Method::POST, &path);
2498 req = req.json(body);
2499 let resp = req.send().await?;
2500 let status = resp.status();
2501 let body_text = resp.text().await?;
2502 if !status.is_success() {
2503 return Err(Error::Api {
2504 status: status.as_u16(),
2505 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2506 .ok()
2507 .and_then(|r| r.error)
2508 .unwrap_or(body_text.clone()),
2509 });
2510 }
2511 Ok(serde_json::from_str(&body_text)?)
2512 }
2513
2514 pub async fn click_stack_get_saved_search(
2516 &self,
2517 organization_id: &str,
2518 service_id: &str,
2519 click_stack_saved_search_id: &str,
2520 ) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
2521 let path = format!(
2522 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
2523 );
2524 let req = self.request(reqwest::Method::GET, &path);
2525 let resp = req.send().await?;
2526 let status = resp.status();
2527 let body_text = resp.text().await?;
2528 if !status.is_success() {
2529 return Err(Error::Api {
2530 status: status.as_u16(),
2531 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2532 .ok()
2533 .and_then(|r| r.error)
2534 .unwrap_or(body_text.clone()),
2535 });
2536 }
2537 Ok(serde_json::from_str(&body_text)?)
2538 }
2539
2540 pub async fn click_stack_update_saved_search(
2542 &self,
2543 organization_id: &str,
2544 service_id: &str,
2545 click_stack_saved_search_id: &str,
2546 body: &ClickStackSavedSearchInput,
2547 ) -> Result<ApiResponse<ClickStackSavedSearch>, Error> {
2548 let path = format!(
2549 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
2550 );
2551 let mut req = self.request(reqwest::Method::PUT, &path);
2552 req = req.json(body);
2553 let resp = req.send().await?;
2554 let status = resp.status();
2555 let body_text = resp.text().await?;
2556 if !status.is_success() {
2557 return Err(Error::Api {
2558 status: status.as_u16(),
2559 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2560 .ok()
2561 .and_then(|r| r.error)
2562 .unwrap_or(body_text.clone()),
2563 });
2564 }
2565 Ok(serde_json::from_str(&body_text)?)
2566 }
2567
2568 pub async fn click_stack_delete_saved_search(
2570 &self,
2571 organization_id: &str,
2572 service_id: &str,
2573 click_stack_saved_search_id: &str,
2574 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2575 let path = format!(
2576 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/saved-searches/{click_stack_saved_search_id}"
2577 );
2578 let req = self.request(reqwest::Method::DELETE, &path);
2579 let resp = req.send().await?;
2580 let status = resp.status();
2581 let body_text = resp.text().await?;
2582 if !status.is_success() {
2583 return Err(Error::Api {
2584 status: status.as_u16(),
2585 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2586 .ok()
2587 .and_then(|r| r.error)
2588 .unwrap_or(body_text.clone()),
2589 });
2590 }
2591 Ok(serde_json::from_str(&body_text)?)
2592 }
2593
2594 pub async fn click_stack_list_dashboards(
2596 &self,
2597 organization_id: &str,
2598 service_id: &str,
2599 ) -> Result<ApiResponse<Vec<ClickStackDashboardResponse>>, Error> {
2600 let path = format!(
2601 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards"
2602 );
2603 let req = self.request(reqwest::Method::GET, &path);
2604 let resp = req.send().await?;
2605 let status = resp.status();
2606 let body_text = resp.text().await?;
2607 if !status.is_success() {
2608 return Err(Error::Api {
2609 status: status.as_u16(),
2610 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2611 .ok()
2612 .and_then(|r| r.error)
2613 .unwrap_or(body_text.clone()),
2614 });
2615 }
2616 Ok(serde_json::from_str(&body_text)?)
2617 }
2618
2619 pub async fn click_stack_create_dashboard(
2621 &self,
2622 organization_id: &str,
2623 service_id: &str,
2624 body: &ClickStackCreateDashboardRequest,
2625 ) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
2626 let path = format!(
2627 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards"
2628 );
2629 let mut req = self.request(reqwest::Method::POST, &path);
2630 req = req.json(body);
2631 let resp = req.send().await?;
2632 let status = resp.status();
2633 let body_text = resp.text().await?;
2634 if !status.is_success() {
2635 return Err(Error::Api {
2636 status: status.as_u16(),
2637 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2638 .ok()
2639 .and_then(|r| r.error)
2640 .unwrap_or(body_text.clone()),
2641 });
2642 }
2643 Ok(serde_json::from_str(&body_text)?)
2644 }
2645
2646 pub async fn click_stack_get_dashboard(
2648 &self,
2649 organization_id: &str,
2650 service_id: &str,
2651 click_stack_dashboard_id: &str,
2652 ) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
2653 let path = format!(
2654 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
2655 );
2656 let req = self.request(reqwest::Method::GET, &path);
2657 let resp = req.send().await?;
2658 let status = resp.status();
2659 let body_text = resp.text().await?;
2660 if !status.is_success() {
2661 return Err(Error::Api {
2662 status: status.as_u16(),
2663 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2664 .ok()
2665 .and_then(|r| r.error)
2666 .unwrap_or(body_text.clone()),
2667 });
2668 }
2669 Ok(serde_json::from_str(&body_text)?)
2670 }
2671
2672 pub async fn click_stack_update_dashboard(
2674 &self,
2675 organization_id: &str,
2676 service_id: &str,
2677 click_stack_dashboard_id: &str,
2678 body: &ClickStackUpdateDashboardRequest,
2679 ) -> Result<ApiResponse<ClickStackDashboardResponse>, Error> {
2680 let path = format!(
2681 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
2682 );
2683 let mut req = self.request(reqwest::Method::PUT, &path);
2684 req = req.json(body);
2685 let resp = req.send().await?;
2686 let status = resp.status();
2687 let body_text = resp.text().await?;
2688 if !status.is_success() {
2689 return Err(Error::Api {
2690 status: status.as_u16(),
2691 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2692 .ok()
2693 .and_then(|r| r.error)
2694 .unwrap_or(body_text.clone()),
2695 });
2696 }
2697 Ok(serde_json::from_str(&body_text)?)
2698 }
2699
2700 pub async fn click_stack_delete_dashboard(
2702 &self,
2703 organization_id: &str,
2704 service_id: &str,
2705 click_stack_dashboard_id: &str,
2706 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2707 let path = format!(
2708 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/{click_stack_dashboard_id}"
2709 );
2710 let req = self.request(reqwest::Method::DELETE, &path);
2711 let resp = req.send().await?;
2712 let status = resp.status();
2713 let body_text = resp.text().await?;
2714 if !status.is_success() {
2715 return Err(Error::Api {
2716 status: status.as_u16(),
2717 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2718 .ok()
2719 .and_then(|r| r.error)
2720 .unwrap_or(body_text.clone()),
2721 });
2722 }
2723 Ok(serde_json::from_str(&body_text)?)
2724 }
2725
2726 pub async fn click_stack_list_sources(
2728 &self,
2729 organization_id: &str,
2730 service_id: &str,
2731 ) -> Result<ApiResponse<Vec<ClickStackSourceResponse>>, Error> {
2732 let path =
2733 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources");
2734 let req = self.request(reqwest::Method::GET, &path);
2735 let resp = req.send().await?;
2736 let status = resp.status();
2737 let body_text = resp.text().await?;
2738 if !status.is_success() {
2739 return Err(Error::Api {
2740 status: status.as_u16(),
2741 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2742 .ok()
2743 .and_then(|r| r.error)
2744 .unwrap_or(body_text.clone()),
2745 });
2746 }
2747 Ok(serde_json::from_str(&body_text)?)
2748 }
2749
2750 pub async fn click_stack_create_source(
2752 &self,
2753 organization_id: &str,
2754 service_id: &str,
2755 body: &ClickStackSource,
2756 ) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
2757 let path =
2758 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources");
2759 let mut req = self.request(reqwest::Method::POST, &path);
2760 req = req.json(body);
2761 let resp = req.send().await?;
2762 let status = resp.status();
2763 let body_text = resp.text().await?;
2764 if !status.is_success() {
2765 return Err(Error::Api {
2766 status: status.as_u16(),
2767 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2768 .ok()
2769 .and_then(|r| r.error)
2770 .unwrap_or(body_text.clone()),
2771 });
2772 }
2773 Ok(serde_json::from_str(&body_text)?)
2774 }
2775
2776 pub async fn click_stack_get_source(
2778 &self,
2779 organization_id: &str,
2780 service_id: &str,
2781 click_stack_source_id: &str,
2782 ) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
2783 let path = format!(
2784 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
2785 );
2786 let req = self.request(reqwest::Method::GET, &path);
2787 let resp = req.send().await?;
2788 let status = resp.status();
2789 let body_text = resp.text().await?;
2790 if !status.is_success() {
2791 return Err(Error::Api {
2792 status: status.as_u16(),
2793 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2794 .ok()
2795 .and_then(|r| r.error)
2796 .unwrap_or(body_text.clone()),
2797 });
2798 }
2799 Ok(serde_json::from_str(&body_text)?)
2800 }
2801
2802 pub async fn click_stack_update_source(
2804 &self,
2805 organization_id: &str,
2806 service_id: &str,
2807 click_stack_source_id: &str,
2808 body: &ClickStackSource,
2809 ) -> Result<ApiResponse<ClickStackSourceResponse>, Error> {
2810 let path = format!(
2811 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
2812 );
2813 let mut req = self.request(reqwest::Method::PUT, &path);
2814 req = req.json(body);
2815 let resp = req.send().await?;
2816 let status = resp.status();
2817 let body_text = resp.text().await?;
2818 if !status.is_success() {
2819 return Err(Error::Api {
2820 status: status.as_u16(),
2821 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2822 .ok()
2823 .and_then(|r| r.error)
2824 .unwrap_or(body_text.clone()),
2825 });
2826 }
2827 Ok(serde_json::from_str(&body_text)?)
2828 }
2829
2830 pub async fn click_stack_delete_source(
2832 &self,
2833 organization_id: &str,
2834 service_id: &str,
2835 click_stack_source_id: &str,
2836 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2837 let path = format!(
2838 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/sources/{click_stack_source_id}"
2839 );
2840 let req = self.request(reqwest::Method::DELETE, &path);
2841 let resp = req.send().await?;
2842 let status = resp.status();
2843 let body_text = resp.text().await?;
2844 if !status.is_success() {
2845 return Err(Error::Api {
2846 status: status.as_u16(),
2847 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2848 .ok()
2849 .and_then(|r| r.error)
2850 .unwrap_or(body_text.clone()),
2851 });
2852 }
2853 Ok(serde_json::from_str(&body_text)?)
2854 }
2855
2856 pub async fn click_stack_list_connections(
2858 &self,
2859 organization_id: &str,
2860 service_id: &str,
2861 ) -> Result<ApiResponse<Vec<ClickStackConnection>>, Error> {
2862 let path = format!(
2863 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections"
2864 );
2865 let req = self.request(reqwest::Method::GET, &path);
2866 let resp = req.send().await?;
2867 let status = resp.status();
2868 let body_text = resp.text().await?;
2869 if !status.is_success() {
2870 return Err(Error::Api {
2871 status: status.as_u16(),
2872 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2873 .ok()
2874 .and_then(|r| r.error)
2875 .unwrap_or(body_text.clone()),
2876 });
2877 }
2878 Ok(serde_json::from_str(&body_text)?)
2879 }
2880
2881 pub async fn click_stack_create_connection(
2883 &self,
2884 organization_id: &str,
2885 service_id: &str,
2886 body: &ClickStackCreateConnectionRequest,
2887 ) -> Result<ApiResponse<ClickStackConnection>, Error> {
2888 let path = format!(
2889 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections"
2890 );
2891 let mut req = self.request(reqwest::Method::POST, &path);
2892 req = req.json(body);
2893 let resp = req.send().await?;
2894 let status = resp.status();
2895 let body_text = resp.text().await?;
2896 if !status.is_success() {
2897 return Err(Error::Api {
2898 status: status.as_u16(),
2899 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2900 .ok()
2901 .and_then(|r| r.error)
2902 .unwrap_or(body_text.clone()),
2903 });
2904 }
2905 Ok(serde_json::from_str(&body_text)?)
2906 }
2907
2908 pub async fn click_stack_get_connection(
2910 &self,
2911 organization_id: &str,
2912 service_id: &str,
2913 click_stack_connection_id: &str,
2914 ) -> Result<ApiResponse<ClickStackConnection>, Error> {
2915 let path = format!(
2916 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
2917 );
2918 let req = self.request(reqwest::Method::GET, &path);
2919 let resp = req.send().await?;
2920 let status = resp.status();
2921 let body_text = resp.text().await?;
2922 if !status.is_success() {
2923 return Err(Error::Api {
2924 status: status.as_u16(),
2925 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2926 .ok()
2927 .and_then(|r| r.error)
2928 .unwrap_or(body_text.clone()),
2929 });
2930 }
2931 Ok(serde_json::from_str(&body_text)?)
2932 }
2933
2934 pub async fn click_stack_update_connection(
2936 &self,
2937 organization_id: &str,
2938 service_id: &str,
2939 click_stack_connection_id: &str,
2940 body: &ClickStackUpdateConnectionRequest,
2941 ) -> Result<ApiResponse<ClickStackConnection>, Error> {
2942 let path = format!(
2943 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
2944 );
2945 let mut req = self.request(reqwest::Method::PUT, &path);
2946 req = req.json(body);
2947 let resp = req.send().await?;
2948 let status = resp.status();
2949 let body_text = resp.text().await?;
2950 if !status.is_success() {
2951 return Err(Error::Api {
2952 status: status.as_u16(),
2953 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2954 .ok()
2955 .and_then(|r| r.error)
2956 .unwrap_or(body_text.clone()),
2957 });
2958 }
2959 Ok(serde_json::from_str(&body_text)?)
2960 }
2961
2962 pub async fn click_stack_delete_connection(
2964 &self,
2965 organization_id: &str,
2966 service_id: &str,
2967 click_stack_connection_id: &str,
2968 ) -> Result<ApiResponse<serde_json::Value>, Error> {
2969 let path = format!(
2970 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/connections/{click_stack_connection_id}"
2971 );
2972 let req = self.request(reqwest::Method::DELETE, &path);
2973 let resp = req.send().await?;
2974 let status = resp.status();
2975 let body_text = resp.text().await?;
2976 if !status.is_success() {
2977 return Err(Error::Api {
2978 status: status.as_u16(),
2979 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
2980 .ok()
2981 .and_then(|r| r.error)
2982 .unwrap_or(body_text.clone()),
2983 });
2984 }
2985 Ok(serde_json::from_str(&body_text)?)
2986 }
2987
2988 pub async fn click_stack_list_roles(
2990 &self,
2991 organization_id: &str,
2992 service_id: &str,
2993 ) -> Result<ApiResponse<Vec<ClickStackRole>>, Error> {
2994 let path =
2995 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles");
2996 let req = self.request(reqwest::Method::GET, &path);
2997 let resp = req.send().await?;
2998 let status = resp.status();
2999 let body_text = resp.text().await?;
3000 if !status.is_success() {
3001 return Err(Error::Api {
3002 status: status.as_u16(),
3003 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3004 .ok()
3005 .and_then(|r| r.error)
3006 .unwrap_or(body_text.clone()),
3007 });
3008 }
3009 Ok(serde_json::from_str(&body_text)?)
3010 }
3011
3012 pub async fn click_stack_create_role(
3014 &self,
3015 organization_id: &str,
3016 service_id: &str,
3017 body: &ClickStackCreateRoleRequest,
3018 ) -> Result<ApiResponse<ClickStackRole>, Error> {
3019 let path =
3020 format!("/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles");
3021 let mut req = self.request(reqwest::Method::POST, &path);
3022 req = req.json(body);
3023 let resp = req.send().await?;
3024 let status = resp.status();
3025 let body_text = resp.text().await?;
3026 if !status.is_success() {
3027 return Err(Error::Api {
3028 status: status.as_u16(),
3029 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3030 .ok()
3031 .and_then(|r| r.error)
3032 .unwrap_or(body_text.clone()),
3033 });
3034 }
3035 Ok(serde_json::from_str(&body_text)?)
3036 }
3037
3038 pub async fn click_stack_get_role(
3040 &self,
3041 organization_id: &str,
3042 service_id: &str,
3043 click_stack_role_id: &str,
3044 ) -> Result<ApiResponse<ClickStackRole>, Error> {
3045 let path = format!(
3046 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
3047 );
3048 let req = self.request(reqwest::Method::GET, &path);
3049 let resp = req.send().await?;
3050 let status = resp.status();
3051 let body_text = resp.text().await?;
3052 if !status.is_success() {
3053 return Err(Error::Api {
3054 status: status.as_u16(),
3055 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3056 .ok()
3057 .and_then(|r| r.error)
3058 .unwrap_or(body_text.clone()),
3059 });
3060 }
3061 Ok(serde_json::from_str(&body_text)?)
3062 }
3063
3064 pub async fn click_stack_update_role(
3066 &self,
3067 organization_id: &str,
3068 service_id: &str,
3069 click_stack_role_id: &str,
3070 body: &ClickStackUpdateRoleRequest,
3071 ) -> Result<ApiResponse<ClickStackRole>, Error> {
3072 let path = format!(
3073 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
3074 );
3075 let mut req = self.request(reqwest::Method::PUT, &path);
3076 req = req.json(body);
3077 let resp = req.send().await?;
3078 let status = resp.status();
3079 let body_text = resp.text().await?;
3080 if !status.is_success() {
3081 return Err(Error::Api {
3082 status: status.as_u16(),
3083 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3084 .ok()
3085 .and_then(|r| r.error)
3086 .unwrap_or(body_text.clone()),
3087 });
3088 }
3089 Ok(serde_json::from_str(&body_text)?)
3090 }
3091
3092 pub async fn click_stack_delete_role(
3094 &self,
3095 organization_id: &str,
3096 service_id: &str,
3097 click_stack_role_id: &str,
3098 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3099 let path = format!(
3100 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/roles/{click_stack_role_id}"
3101 );
3102 let req = self.request(reqwest::Method::DELETE, &path);
3103 let resp = req.send().await?;
3104 let status = resp.status();
3105 let body_text = resp.text().await?;
3106 if !status.is_success() {
3107 return Err(Error::Api {
3108 status: status.as_u16(),
3109 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3110 .ok()
3111 .and_then(|r| r.error)
3112 .unwrap_or(body_text.clone()),
3113 });
3114 }
3115 Ok(serde_json::from_str(&body_text)?)
3116 }
3117
3118 pub async fn click_stack_list_webhooks(
3120 &self,
3121 organization_id: &str,
3122 service_id: &str,
3123 ) -> Result<ApiResponse<Vec<ClickStackWebhook>>, Error> {
3124 let path = format!(
3125 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks"
3126 );
3127 let req = self.request(reqwest::Method::GET, &path);
3128 let resp = req.send().await?;
3129 let status = resp.status();
3130 let body_text = resp.text().await?;
3131 if !status.is_success() {
3132 return Err(Error::Api {
3133 status: status.as_u16(),
3134 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3135 .ok()
3136 .and_then(|r| r.error)
3137 .unwrap_or(body_text.clone()),
3138 });
3139 }
3140 Ok(serde_json::from_str(&body_text)?)
3141 }
3142
3143 pub async fn click_stack_create_webhook(
3145 &self,
3146 organization_id: &str,
3147 service_id: &str,
3148 body: &ClickStackWebhookInput,
3149 ) -> Result<ApiResponse<ClickStackWebhook>, Error> {
3150 let path = format!(
3151 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks"
3152 );
3153 let mut req = self.request(reqwest::Method::POST, &path);
3154 req = req.json(body);
3155 let resp = req.send().await?;
3156 let status = resp.status();
3157 let body_text = resp.text().await?;
3158 if !status.is_success() {
3159 return Err(Error::Api {
3160 status: status.as_u16(),
3161 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3162 .ok()
3163 .and_then(|r| r.error)
3164 .unwrap_or(body_text.clone()),
3165 });
3166 }
3167 Ok(serde_json::from_str(&body_text)?)
3168 }
3169
3170 pub async fn click_stack_update_webhook(
3172 &self,
3173 organization_id: &str,
3174 service_id: &str,
3175 click_stack_webhook_id: &str,
3176 body: &ClickStackWebhookInput,
3177 ) -> Result<ApiResponse<ClickStackWebhook>, Error> {
3178 let path = format!(
3179 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks/{click_stack_webhook_id}"
3180 );
3181 let mut req = self.request(reqwest::Method::PUT, &path);
3182 req = req.json(body);
3183 let resp = req.send().await?;
3184 let status = resp.status();
3185 let body_text = resp.text().await?;
3186 if !status.is_success() {
3187 return Err(Error::Api {
3188 status: status.as_u16(),
3189 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3190 .ok()
3191 .and_then(|r| r.error)
3192 .unwrap_or(body_text.clone()),
3193 });
3194 }
3195 Ok(serde_json::from_str(&body_text)?)
3196 }
3197
3198 pub async fn click_stack_delete_webhook(
3200 &self,
3201 organization_id: &str,
3202 service_id: &str,
3203 click_stack_webhook_id: &str,
3204 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3205 let path = format!(
3206 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/webhooks/{click_stack_webhook_id}"
3207 );
3208 let req = self.request(reqwest::Method::DELETE, &path);
3209 let resp = req.send().await?;
3210 let status = resp.status();
3211 let body_text = resp.text().await?;
3212 if !status.is_success() {
3213 return Err(Error::Api {
3214 status: status.as_u16(),
3215 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3216 .ok()
3217 .and_then(|r| r.error)
3218 .unwrap_or(body_text.clone()),
3219 });
3220 }
3221 Ok(serde_json::from_str(&body_text)?)
3222 }
3223
3224 pub async fn click_stack_validate_dashboard(
3226 &self,
3227 organization_id: &str,
3228 service_id: &str,
3229 body: &ClickStackCreateDashboardRequest,
3230 ) -> Result<ApiResponse<ClickStackValidateDashboardResponse>, Error> {
3231 let path = format!(
3232 "/v1/organizations/{organization_id}/services/{service_id}/clickstack/dashboards/validate"
3233 );
3234 let mut req = self.request(reqwest::Method::POST, &path);
3235 req = req.json(body);
3236 let resp = req.send().await?;
3237 let status = resp.status();
3238 let body_text = resp.text().await?;
3239 if !status.is_success() {
3240 return Err(Error::Api {
3241 status: status.as_u16(),
3242 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3243 .ok()
3244 .and_then(|r| r.error)
3245 .unwrap_or(body_text.clone()),
3246 });
3247 }
3248 Ok(serde_json::from_str(&body_text)?)
3249 }
3250
3251 pub async fn instance_password_update(
3253 &self,
3254 organization_id: &str,
3255 service_id: &str,
3256 body: &ServicePasswordPatchRequest,
3257 ) -> Result<ApiResponse<ServicePasswordPatchResponse>, Error> {
3258 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/password");
3259 let mut req = self.request(reqwest::Method::PATCH, &path);
3260 req = req.json(body);
3261 let resp = req.send().await?;
3262 let status = resp.status();
3263 let body_text = resp.text().await?;
3264 if !status.is_success() {
3265 return Err(Error::Api {
3266 status: status.as_u16(),
3267 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3268 .ok()
3269 .and_then(|r| r.error)
3270 .unwrap_or(body_text.clone()),
3271 });
3272 }
3273 Ok(serde_json::from_str(&body_text)?)
3274 }
3275
3276 pub async fn instance_private_endpoint_create(
3278 &self,
3279 organization_id: &str,
3280 service_id: &str,
3281 body: &ServicPrivateEndpointePostRequest,
3282 ) -> Result<ApiResponse<InstancePrivateEndpoint>, Error> {
3283 let path =
3284 format!("/v1/organizations/{organization_id}/services/{service_id}/privateEndpoint");
3285 let mut req = self.request(reqwest::Method::POST, &path);
3286 req = req.json(body);
3287 let resp = req.send().await?;
3288 let status = resp.status();
3289 let body_text = resp.text().await?;
3290 if !status.is_success() {
3291 return Err(Error::Api {
3292 status: status.as_u16(),
3293 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3294 .ok()
3295 .and_then(|r| r.error)
3296 .unwrap_or(body_text.clone()),
3297 });
3298 }
3299 Ok(serde_json::from_str(&body_text)?)
3300 }
3301
3302 pub async fn instance_private_endpoint_config_get(
3304 &self,
3305 organization_id: &str,
3306 service_id: &str,
3307 ) -> Result<ApiResponse<PrivateEndpointConfig>, Error> {
3308 let path = format!(
3309 "/v1/organizations/{organization_id}/services/{service_id}/privateEndpointConfig"
3310 );
3311 let req = self.request(reqwest::Method::GET, &path);
3312 let resp = req.send().await?;
3313 let status = resp.status();
3314 let body_text = resp.text().await?;
3315 if !status.is_success() {
3316 return Err(Error::Api {
3317 status: status.as_u16(),
3318 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3319 .ok()
3320 .and_then(|r| r.error)
3321 .unwrap_or(body_text.clone()),
3322 });
3323 }
3324 Ok(serde_json::from_str(&body_text)?)
3325 }
3326
3327 pub async fn instance_prometheus_get(
3329 &self,
3330 organization_id: &str,
3331 service_id: &str,
3332 filtered_metrics: Option<&str>,
3333 ) -> Result<String, Error> {
3334 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/prometheus");
3335 let mut req = self.request(reqwest::Method::GET, &path);
3336 if let Some(v) = filtered_metrics {
3337 req = req.query(&[("filtered_metrics", v)]);
3338 }
3339 let resp = req.send().await?;
3340 let status = resp.status();
3341 if !status.is_success() {
3342 let body_text = resp.text().await?;
3343 return Err(Error::Api {
3344 status: status.as_u16(),
3345 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3346 .ok()
3347 .and_then(|r| r.error)
3348 .unwrap_or(body_text),
3349 });
3350 }
3351 Ok(resp.text().await?)
3352 }
3353
3354 pub async fn instance_replica_scaling_update(
3356 &self,
3357 organization_id: &str,
3358 service_id: &str,
3359 body: &ServiceReplicaScalingPatchRequest,
3360 ) -> Result<ApiResponse<ServiceScalingPatchResponse>, Error> {
3361 let path =
3362 format!("/v1/organizations/{organization_id}/services/{service_id}/replicaScaling");
3363 let mut req = self.request(reqwest::Method::PATCH, &path);
3364 req = req.json(body);
3365 let resp = req.send().await?;
3366 let status = resp.status();
3367 let body_text = resp.text().await?;
3368 if !status.is_success() {
3369 return Err(Error::Api {
3370 status: status.as_u16(),
3371 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3372 .ok()
3373 .and_then(|r| r.error)
3374 .unwrap_or(body_text.clone()),
3375 });
3376 }
3377 Ok(serde_json::from_str(&body_text)?)
3378 }
3379
3380 #[deprecated]
3382 #[allow(deprecated)]
3383 pub async fn instance_scaling_update(
3384 &self,
3385 organization_id: &str,
3386 service_id: &str,
3387 body: &ServiceScalingPatchRequest,
3388 ) -> Result<ApiResponse<Service>, Error> {
3389 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/scaling");
3390 let mut req = self.request(reqwest::Method::PATCH, &path);
3391 req = req.json(body);
3392 let resp = req.send().await?;
3393 let status = resp.status();
3394 let body_text = resp.text().await?;
3395 if !status.is_success() {
3396 return Err(Error::Api {
3397 status: status.as_u16(),
3398 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3399 .ok()
3400 .and_then(|r| r.error)
3401 .unwrap_or(body_text.clone()),
3402 });
3403 }
3404 Ok(serde_json::from_str(&body_text)?)
3405 }
3406
3407 pub async fn scaling_schedule_get(
3409 &self,
3410 organization_id: &str,
3411 service_id: &str,
3412 ) -> Result<ApiResponse<ScalingSchedule>, Error> {
3413 let path =
3414 format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
3415 let req = self.request(reqwest::Method::GET, &path);
3416 let resp = req.send().await?;
3417 let status = resp.status();
3418 let body_text = resp.text().await?;
3419 if !status.is_success() {
3420 return Err(Error::Api {
3421 status: status.as_u16(),
3422 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3423 .ok()
3424 .and_then(|r| r.error)
3425 .unwrap_or(body_text.clone()),
3426 });
3427 }
3428 Ok(serde_json::from_str(&body_text)?)
3429 }
3430
3431 pub async fn scaling_schedule_upsert(
3433 &self,
3434 organization_id: &str,
3435 service_id: &str,
3436 body: &ScalingSchedulePostRequest,
3437 ) -> Result<ApiResponse<ScalingSchedule>, Error> {
3438 let path =
3439 format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
3440 let mut req = self.request(reqwest::Method::POST, &path);
3441 req = req.json(body);
3442 let resp = req.send().await?;
3443 let status = resp.status();
3444 let body_text = resp.text().await?;
3445 if !status.is_success() {
3446 return Err(Error::Api {
3447 status: status.as_u16(),
3448 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3449 .ok()
3450 .and_then(|r| r.error)
3451 .unwrap_or(body_text.clone()),
3452 });
3453 }
3454 Ok(serde_json::from_str(&body_text)?)
3455 }
3456
3457 pub async fn scaling_schedule_delete(
3459 &self,
3460 organization_id: &str,
3461 service_id: &str,
3462 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3463 let path =
3464 format!("/v1/organizations/{organization_id}/services/{service_id}/scalingSchedule");
3465 let req = self.request(reqwest::Method::DELETE, &path);
3466 let resp = req.send().await?;
3467 let status = resp.status();
3468 let body_text = resp.text().await?;
3469 if !status.is_success() {
3470 return Err(Error::Api {
3471 status: status.as_u16(),
3472 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3473 .ok()
3474 .and_then(|r| r.error)
3475 .unwrap_or(body_text.clone()),
3476 });
3477 }
3478 Ok(serde_json::from_str(&body_text)?)
3479 }
3480
3481 pub async fn upgrade_window_get(
3483 &self,
3484 organization_id: &str,
3485 service_id: &str,
3486 ) -> Result<ApiResponse<UpgradeWindow>, Error> {
3487 let path =
3488 format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
3489 let req = self.request(reqwest::Method::GET, &path);
3490 let resp = req.send().await?;
3491 let status = resp.status();
3492 let body_text = resp.text().await?;
3493 if !status.is_success() {
3494 return Err(Error::Api {
3495 status: status.as_u16(),
3496 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3497 .ok()
3498 .and_then(|r| r.error)
3499 .unwrap_or(body_text.clone()),
3500 });
3501 }
3502 Ok(serde_json::from_str(&body_text)?)
3503 }
3504
3505 pub async fn upgrade_window_update(
3507 &self,
3508 organization_id: &str,
3509 service_id: &str,
3510 body: &UpgradeWindowPutRequest,
3511 ) -> Result<ApiResponse<UpgradeWindow>, Error> {
3512 let path =
3513 format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
3514 let mut req = self.request(reqwest::Method::PUT, &path);
3515 req = req.json(body);
3516 let resp = req.send().await?;
3517 let status = resp.status();
3518 let body_text = resp.text().await?;
3519 if !status.is_success() {
3520 return Err(Error::Api {
3521 status: status.as_u16(),
3522 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3523 .ok()
3524 .and_then(|r| r.error)
3525 .unwrap_or(body_text.clone()),
3526 });
3527 }
3528 Ok(serde_json::from_str(&body_text)?)
3529 }
3530
3531 pub async fn upgrade_window_delete(
3533 &self,
3534 organization_id: &str,
3535 service_id: &str,
3536 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3537 let path =
3538 format!("/v1/organizations/{organization_id}/services/{service_id}/upgradeWindow");
3539 let req = self.request(reqwest::Method::DELETE, &path);
3540 let resp = req.send().await?;
3541 let status = resp.status();
3542 let body_text = resp.text().await?;
3543 if !status.is_success() {
3544 return Err(Error::Api {
3545 status: status.as_u16(),
3546 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3547 .ok()
3548 .and_then(|r| r.error)
3549 .unwrap_or(body_text.clone()),
3550 });
3551 }
3552 Ok(serde_json::from_str(&body_text)?)
3553 }
3554
3555 pub async fn instance_query_endpoint_get(
3557 &self,
3558 organization_id: &str,
3559 service_id: &str,
3560 ) -> Result<ApiResponse<ServiceQueryAPIEndpoint>, Error> {
3561 let path = format!(
3562 "/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
3563 );
3564 let req = self.request(reqwest::Method::GET, &path);
3565 let resp = req.send().await?;
3566 let status = resp.status();
3567 let body_text = resp.text().await?;
3568 if !status.is_success() {
3569 return Err(Error::Api {
3570 status: status.as_u16(),
3571 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3572 .ok()
3573 .and_then(|r| r.error)
3574 .unwrap_or(body_text.clone()),
3575 });
3576 }
3577 Ok(serde_json::from_str(&body_text)?)
3578 }
3579
3580 pub async fn instance_query_endpoint_delete(
3582 &self,
3583 organization_id: &str,
3584 service_id: &str,
3585 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3586 let path = format!(
3587 "/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
3588 );
3589 let req = self.request(reqwest::Method::DELETE, &path);
3590 let resp = req.send().await?;
3591 let status = resp.status();
3592 let body_text = resp.text().await?;
3593 if !status.is_success() {
3594 return Err(Error::Api {
3595 status: status.as_u16(),
3596 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3597 .ok()
3598 .and_then(|r| r.error)
3599 .unwrap_or(body_text.clone()),
3600 });
3601 }
3602 Ok(serde_json::from_str(&body_text)?)
3603 }
3604
3605 pub async fn instance_query_endpoint_upsert(
3607 &self,
3608 organization_id: &str,
3609 service_id: &str,
3610 body: &InstanceServiceQueryApiEndpointsPostRequest,
3611 ) -> Result<ApiResponse<ServiceQueryAPIEndpoint>, Error> {
3612 let path = format!(
3613 "/v1/organizations/{organization_id}/services/{service_id}/serviceQueryEndpoint"
3614 );
3615 let mut req = self.request(reqwest::Method::POST, &path);
3616 req = req.json(body);
3617 let resp = req.send().await?;
3618 let status = resp.status();
3619 let body_text = resp.text().await?;
3620 if !status.is_success() {
3621 return Err(Error::Api {
3622 status: status.as_u16(),
3623 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3624 .ok()
3625 .and_then(|r| r.error)
3626 .unwrap_or(body_text.clone()),
3627 });
3628 }
3629 Ok(serde_json::from_str(&body_text)?)
3630 }
3631
3632 pub async fn instance_state_update(
3634 &self,
3635 organization_id: &str,
3636 service_id: &str,
3637 body: &ServiceStatePatchRequest,
3638 ) -> Result<ApiResponse<Service>, Error> {
3639 let path = format!("/v1/organizations/{organization_id}/services/{service_id}/state");
3640 let mut req = self.request(reqwest::Method::PATCH, &path);
3641 req = req.json(body);
3642 let resp = req.send().await?;
3643 let status = resp.status();
3644 let body_text = resp.text().await?;
3645 if !status.is_success() {
3646 return Err(Error::Api {
3647 status: status.as_u16(),
3648 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3649 .ok()
3650 .and_then(|r| r.error)
3651 .unwrap_or(body_text.clone()),
3652 });
3653 }
3654 Ok(serde_json::from_str(&body_text)?)
3655 }
3656
3657 pub async fn usage_cost_get(
3659 &self,
3660 organization_id: &str,
3661 from_date: &str,
3662 to_date: &str,
3663 filters: &[&str],
3664 ) -> Result<ApiResponse<UsageCost>, Error> {
3665 let path = format!("/v1/organizations/{organization_id}/usageCost");
3666 let mut req = self.request(reqwest::Method::GET, &path);
3667 req = req.query(&[("from_date", from_date)]);
3668 req = req.query(&[("to_date", to_date)]);
3669 for f in filters {
3670 req = req.query(&[("filter", f)]);
3671 }
3672 let resp = req.send().await?;
3673 let status = resp.status();
3674 let body_text = resp.text().await?;
3675 if !status.is_success() {
3676 return Err(Error::Api {
3677 status: status.as_u16(),
3678 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3679 .ok()
3680 .and_then(|r| r.error)
3681 .unwrap_or(body_text.clone()),
3682 });
3683 }
3684 Ok(serde_json::from_str(&body_text)?)
3685 }
3686
3687 pub async fn service_clickhouse_settings_list_get(
3689 &self,
3690 organization_id: &str,
3691 service_id: &str,
3692 ) -> Result<ApiResponse<ServiceClickhouseSettingsList>, Error> {
3693 let path =
3694 format!("/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings");
3695 let req = self.request(reqwest::Method::GET, &path);
3696 let resp = req.send().await?;
3697 let status = resp.status();
3698 let body_text = resp.text().await?;
3699 if !status.is_success() {
3700 return Err(Error::Api {
3701 status: status.as_u16(),
3702 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3703 .ok()
3704 .and_then(|r| r.error)
3705 .unwrap_or(body_text.clone()),
3706 });
3707 }
3708 Ok(serde_json::from_str(&body_text)?)
3709 }
3710
3711 pub async fn service_clickhouse_settings_update(
3713 &self,
3714 organization_id: &str,
3715 service_id: &str,
3716 body: &ServiceClickhouseSettingsPatchRequest,
3717 ) -> Result<ApiResponse<ServiceClickhouseSettingsPatchResponse>, Error> {
3718 let path =
3719 format!("/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings");
3720 let mut req = self.request(reqwest::Method::PATCH, &path);
3721 req = req.json(body);
3722 let resp = req.send().await?;
3723 let status = resp.status();
3724 let body_text = resp.text().await?;
3725 if !status.is_success() {
3726 return Err(Error::Api {
3727 status: status.as_u16(),
3728 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3729 .ok()
3730 .and_then(|r| r.error)
3731 .unwrap_or(body_text.clone()),
3732 });
3733 }
3734 Ok(serde_json::from_str(&body_text)?)
3735 }
3736
3737 pub async fn service_clickhouse_settings_schema_get(
3739 &self,
3740 organization_id: &str,
3741 service_id: &str,
3742 ) -> Result<ApiResponse<ServiceClickhouseSettingsSchema>, Error> {
3743 let path = format!(
3744 "/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/schema"
3745 );
3746 let req = self.request(reqwest::Method::GET, &path);
3747 let resp = req.send().await?;
3748 let status = resp.status();
3749 let body_text = resp.text().await?;
3750 if !status.is_success() {
3751 return Err(Error::Api {
3752 status: status.as_u16(),
3753 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3754 .ok()
3755 .and_then(|r| r.error)
3756 .unwrap_or(body_text.clone()),
3757 });
3758 }
3759 Ok(serde_json::from_str(&body_text)?)
3760 }
3761
3762 pub async fn service_clickhouse_setting_get(
3764 &self,
3765 organization_id: &str,
3766 service_id: &str,
3767 setting_name: &str,
3768 ) -> Result<ApiResponse<ServiceClickhouseSetting>, Error> {
3769 let path = format!(
3770 "/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/{setting_name}"
3771 );
3772 let req = self.request(reqwest::Method::GET, &path);
3773 let resp = req.send().await?;
3774 let status = resp.status();
3775 let body_text = resp.text().await?;
3776 if !status.is_success() {
3777 return Err(Error::Api {
3778 status: status.as_u16(),
3779 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3780 .ok()
3781 .and_then(|r| r.error)
3782 .unwrap_or(body_text.clone()),
3783 });
3784 }
3785 Ok(serde_json::from_str(&body_text)?)
3786 }
3787
3788 pub async fn service_clickhouse_setting_delete(
3790 &self,
3791 organization_id: &str,
3792 service_id: &str,
3793 setting_name: &str,
3794 ) -> Result<ApiResponse<serde_json::Value>, Error> {
3795 let path = format!(
3796 "/v1/organizations/{organization_id}/services/{service_id}/clickhouseSettings/{setting_name}"
3797 );
3798 let req = self.request(reqwest::Method::DELETE, &path);
3799 let resp = req.send().await?;
3800 let status = resp.status();
3801 let body_text = resp.text().await?;
3802 if !status.is_success() {
3803 return Err(Error::Api {
3804 status: status.as_u16(),
3805 message: serde_json::from_str::<ApiResponse<serde_json::Value>>(&body_text)
3806 .ok()
3807 .and_then(|r| r.error)
3808 .unwrap_or(body_text.clone()),
3809 });
3810 }
3811 Ok(serde_json::from_str(&body_text)?)
3812 }
3813}
3814
3815#[cfg(test)]
3816mod tests {
3817 use super::derive_query_host;
3818
3819 #[test]
3820 fn derive_query_host_prod() {
3821 assert_eq!(
3822 derive_query_host("https://api.clickhouse.cloud").as_deref(),
3823 Some("https://queries.clickhouse.cloud")
3824 );
3825 }
3826
3827 #[test]
3828 fn derive_query_host_staging() {
3829 assert_eq!(
3830 derive_query_host("https://api.control-plane.clickhouse-staging.com").as_deref(),
3831 Some("https://queries.clickhouse-staging.com")
3832 );
3833 }
3834
3835 #[test]
3836 fn derive_query_host_dev() {
3837 assert_eq!(
3838 derive_query_host("https://api.control-plane.clickhouse-dev.com").as_deref(),
3839 Some("https://queries.clickhouse-dev.com")
3840 );
3841 }
3842
3843 #[test]
3844 fn derive_query_host_plain_api_prefix_without_control_plane() {
3845 assert_eq!(
3846 derive_query_host("https://api.clickhouse-staging.com").as_deref(),
3847 Some("https://queries.clickhouse-staging.com")
3848 );
3849 }
3850
3851 #[test]
3852 fn derive_query_host_non_api_host_is_none() {
3853 assert_eq!(derive_query_host("http://127.0.0.1:8123"), None);
3854 assert_eq!(derive_query_host("https://example.com"), None);
3855 }
3856
3857 #[test]
3858 fn derive_query_host_invalid_url_is_none() {
3859 assert_eq!(derive_query_host("not a url"), None);
3860 }
3861
3862 #[test]
3863 fn derive_query_host_preserves_non_default_port() {
3864 assert_eq!(
3865 derive_query_host("https://api.mycorp.example.com:8443").as_deref(),
3866 Some("https://queries.mycorp.example.com:8443")
3867 );
3868 assert_eq!(
3871 derive_query_host("https://api.clickhouse.cloud:443").as_deref(),
3872 Some("https://queries.clickhouse.cloud")
3873 );
3874 }
3875}