From 6f4b5861c3977cec7fddb0e4356b165d338d0fa6 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Sun, 26 Nov 2023 11:22:40 +0800 Subject: [PATCH 1/6] Avoid generating needless lifetimes --- progenitor-impl/src/method.rs | 34 +++++++++++++------ .../tests/output/buildomat-positional.out | 18 ++++------ .../tests/output/nexus-positional.out | 30 +++++++--------- .../output/propolis-server-positional.out | 8 ++--- .../tests/output/test_freeform_response.out | 4 +-- 5 files changed, 48 insertions(+), 46 deletions(-) diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index 9b219e0e..b3844cf9 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -662,16 +662,30 @@ impl Generator { body, } = self.method_sig_body(method, quote! { self })?; - let method_impl = quote! { - #[doc = #doc_comment] - pub async fn #operation_id #bounds ( - &'a self, - #(#params),* - ) -> Result< - ResponseValue<#success_type>, - Error<#error_type>, - > { - #body + let method_impl = if params.is_empty() { + quote! { + #[doc = #doc_comment] + pub async fn #operation_id ( + &self, + ) -> Result< + ResponseValue<#success_type>, + Error<#error_type>, + > { + #body + } + } + } else { + quote! { + #[doc = #doc_comment] + pub async fn #operation_id #bounds ( + &'a self, + #(#params),* + ) -> Result< + ResponseValue<#success_type>, + Error<#error_type>, + > { + #body + } } }; diff --git a/progenitor-impl/tests/output/buildomat-positional.out b/progenitor-impl/tests/output/buildomat-positional.out index 1713415c..8bd5d054 100644 --- a/progenitor-impl/tests/output/buildomat-positional.out +++ b/progenitor-impl/tests/output/buildomat-positional.out @@ -312,7 +312,7 @@ impl Client { impl Client { ///Sends a `POST` request to `/v1/control/hold` - pub async fn control_hold<'a>(&'a self) -> Result, Error<()>> { + pub async fn control_hold(&self) -> Result, Error<()>> { let url = format!("{}/v1/control/hold", self.baseurl,); let request = self .client @@ -331,7 +331,7 @@ impl Client { } ///Sends a `POST` request to `/v1/control/resume` - pub async fn control_resume<'a>(&'a self) -> Result, Error<()>> { + pub async fn control_resume(&self) -> Result, Error<()>> { let url = format!("{}/v1/control/resume", self.baseurl,); let request = self.client.post(url).build()?; let result = self.client.execute(request).await; @@ -369,7 +369,7 @@ impl Client { } ///Sends a `GET` request to `/v1/tasks` - pub async fn tasks_get<'a>(&'a self) -> Result>, Error<()>> { + pub async fn tasks_get(&self) -> Result>, Error<()>> { let url = format!("{}/v1/tasks", self.baseurl,); let request = self .client @@ -514,7 +514,7 @@ impl Client { } ///Sends a `GET` request to `/v1/whoami` - pub async fn whoami<'a>(&'a self) -> Result, Error<()>> { + pub async fn whoami(&self) -> Result, Error<()>> { let url = format!("{}/v1/whoami", self.baseurl,); let request = self .client @@ -579,9 +579,7 @@ impl Client { } ///Sends a `GET` request to `/v1/worker/ping` - pub async fn worker_ping<'a>( - &'a self, - ) -> Result, Error<()>> { + pub async fn worker_ping(&self) -> Result, Error<()>> { let url = format!("{}/v1/worker/ping", self.baseurl,); let request = self .client @@ -692,9 +690,7 @@ impl Client { } ///Sends a `GET` request to `/v1/workers` - pub async fn workers_list<'a>( - &'a self, - ) -> Result, Error<()>> { + pub async fn workers_list(&self) -> Result, Error<()>> { let url = format!("{}/v1/workers", self.baseurl,); let request = self .client @@ -713,7 +709,7 @@ impl Client { } ///Sends a `POST` request to `/v1/workers/recycle` - pub async fn workers_recycle<'a>(&'a self) -> Result, Error<()>> { + pub async fn workers_recycle(&self) -> Result, Error<()>> { let url = format!("{}/v1/workers/recycle", self.baseurl,); let request = self.client.post(url).build()?; let result = self.client.execute(request).await; diff --git a/progenitor-impl/tests/output/nexus-positional.out b/progenitor-impl/tests/output/nexus-positional.out index 60652844..0a94285e 100644 --- a/progenitor-impl/tests/output/nexus-positional.out +++ b/progenitor-impl/tests/output/nexus-positional.out @@ -6630,7 +6630,7 @@ impl Client { } ///Sends a `POST` request to `/logout` - pub async fn logout<'a>(&'a self) -> Result, Error> { + pub async fn logout(&self) -> Result, Error> { let url = format!("{}/logout", self.baseurl,); let request = self .client @@ -10806,8 +10806,8 @@ impl Client { ///Fetch the current silo's IAM policy /// ///Sends a `GET` request to `/policy` - pub async fn policy_view<'a>( - &'a self, + pub async fn policy_view( + &self, ) -> Result, Error> { let url = format!("{}/policy", self.baseurl,); let request = self @@ -10992,9 +10992,7 @@ impl Client { ///Fetch the user associated with the current session /// ///Sends a `GET` request to `/session/me` - pub async fn session_me<'a>( - &'a self, - ) -> Result, Error> { + pub async fn session_me(&self) -> Result, Error> { let url = format!("{}/session/me", self.baseurl,); let request = self .client @@ -12733,8 +12731,8 @@ impl Client { ///Fetch the IP pool used for Oxide services /// ///Sends a `GET` request to `/system/ip-pools-service` - pub async fn ip_pool_service_view<'a>( - &'a self, + pub async fn ip_pool_service_view( + &self, ) -> Result, Error> { let url = format!("{}/system/ip-pools-service", self.baseurl,); let request = self @@ -12985,8 +12983,8 @@ impl Client { ///Fetch the top-level IAM policy /// ///Sends a `GET` request to `/system/policy` - pub async fn system_policy_view<'a>( - &'a self, + pub async fn system_policy_view( + &self, ) -> Result, Error> { let url = format!("{}/system/policy", self.baseurl,); let request = self @@ -16161,9 +16159,7 @@ impl Client { ///Refresh update data /// ///Sends a `POST` request to `/v1/system/update/refresh` - pub async fn system_update_refresh<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_refresh(&self) -> Result, Error> { let url = format!("{}/v1/system/update/refresh", self.baseurl,); let request = self .client @@ -16223,9 +16219,7 @@ impl Client { ///If there is no update in progress, do nothing. /// ///Sends a `POST` request to `/v1/system/update/stop` - pub async fn system_update_stop<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_stop(&self) -> Result, Error> { let url = format!("{}/v1/system/update/stop", self.baseurl,); let request = self .client @@ -16419,8 +16413,8 @@ impl Client { ///View system version and update status /// ///Sends a `GET` request to `/v1/system/update/version` - pub async fn system_version<'a>( - &'a self, + pub async fn system_version( + &self, ) -> Result, Error> { let url = format!("{}/v1/system/update/version", self.baseurl,); let request = self diff --git a/progenitor-impl/tests/output/propolis-server-positional.out b/progenitor-impl/tests/output/propolis-server-positional.out index 0a69540f..cc394fe7 100644 --- a/progenitor-impl/tests/output/propolis-server-positional.out +++ b/progenitor-impl/tests/output/propolis-server-positional.out @@ -668,8 +668,8 @@ impl Client { impl Client { ///Sends a `GET` request to `/instance` - pub async fn instance_get<'a>( - &'a self, + pub async fn instance_get( + &self, ) -> Result, Error> { let url = format!("{}/instance", self.baseurl,); let request = self @@ -789,8 +789,8 @@ impl Client { } ///Sends a `GET` request to `/instance/serial` - pub async fn instance_serial<'a>( - &'a self, + pub async fn instance_serial( + &self, ) -> Result, Error> { let url = format!("{}/instance/serial", self.baseurl,); let request = self diff --git a/progenitor-impl/tests/output/test_freeform_response.out b/progenitor-impl/tests/output/test_freeform_response.out index ba64d543..e235bb1d 100644 --- a/progenitor-impl/tests/output/test_freeform_response.out +++ b/progenitor-impl/tests/output/test_freeform_response.out @@ -85,9 +85,7 @@ impl Client { impl Client { ///Sends a `GET` request to `/` - pub async fn freeform_response<'a>( - &'a self, - ) -> Result, Error> { + pub async fn freeform_response(&self) -> Result, Error> { let url = format!("{}/", self.baseurl,); let request = self.client.get(url).build()?; let result = self.client.execute(request).await; From 8d405f8754639fbc1d3a420fc42a93d979feddd9 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 9 Oct 2025 10:30:42 -0700 Subject: [PATCH 2/6] update fixtures --- .../tests/output/src/buildomat_positional.rs | 20 +++++-------- .../tests/output/src/nexus_positional.rs | 30 ++++++++----------- .../tests/output/src/nexus_with_timeout.rs | 30 ++++++++----------- .../output/src/propolis_server_positional.rs | 8 ++--- .../output/src/test_freeform_response.rs | 4 +-- 5 files changed, 37 insertions(+), 55 deletions(-) diff --git a/progenitor-impl/tests/output/src/buildomat_positional.rs b/progenitor-impl/tests/output/src/buildomat_positional.rs index ac3479f6..8d1da734 100644 --- a/progenitor-impl/tests/output/src/buildomat_positional.rs +++ b/progenitor-impl/tests/output/src/buildomat_positional.rs @@ -1023,7 +1023,7 @@ impl ClientHooks<()> for &Client {} #[allow(clippy::all)] impl Client { ///Sends a `POST` request to `/v1/control/hold` - pub async fn control_hold<'a>(&'a self) -> Result, Error<()>> { + pub async fn control_hold(&self) -> Result, Error<()>> { let url = format!("{}/v1/control/hold", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -1054,7 +1054,7 @@ impl Client { } ///Sends a `POST` request to `/v1/control/resume` - pub async fn control_resume<'a>(&'a self) -> Result, Error<()>> { + pub async fn control_resume(&self) -> Result, Error<()>> { let url = format!("{}/v1/control/resume", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -1115,8 +1115,8 @@ impl Client { } ///Sends a `GET` request to `/v1/tasks` - pub async fn tasks_get<'a>( - &'a self, + pub async fn tasks_get( + &self, ) -> Result>, Error<()>> { let url = format!("{}/v1/tasks", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -1328,7 +1328,7 @@ impl Client { } ///Sends a `GET` request to `/v1/whoami` - pub async fn whoami<'a>(&'a self) -> Result, Error<()>> { + pub async fn whoami(&self) -> Result, Error<()>> { let url = format!("{}/v1/whoami", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -1429,9 +1429,7 @@ impl Client { } ///Sends a `GET` request to `/v1/worker/ping` - pub async fn worker_ping<'a>( - &'a self, - ) -> Result, Error<()>> { + pub async fn worker_ping(&self) -> Result, Error<()>> { let url = format!("{}/v1/worker/ping", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -1614,9 +1612,7 @@ impl Client { } ///Sends a `GET` request to `/v1/workers` - pub async fn workers_list<'a>( - &'a self, - ) -> Result, Error<()>> { + pub async fn workers_list(&self) -> Result, Error<()>> { let url = format!("{}/v1/workers", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -1647,7 +1643,7 @@ impl Client { } ///Sends a `POST` request to `/v1/workers/recycle` - pub async fn workers_recycle<'a>(&'a self) -> Result, Error<()>> { + pub async fn workers_recycle(&self) -> Result, Error<()>> { let url = format!("{}/v1/workers/recycle", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( diff --git a/progenitor-impl/tests/output/src/nexus_positional.rs b/progenitor-impl/tests/output/src/nexus_positional.rs index 829ee854..35973da2 100644 --- a/progenitor-impl/tests/output/src/nexus_positional.rs +++ b/progenitor-impl/tests/output/src/nexus_positional.rs @@ -15015,7 +15015,7 @@ impl Client { } ///Sends a `POST` request to `/logout` - pub async fn logout<'a>(&'a self) -> Result, Error> { + pub async fn logout(&self) -> Result, Error> { let url = format!("{}/logout", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -19830,8 +19830,8 @@ impl Client { ///Fetch the current silo's IAM policy /// ///Sends a `GET` request to `/policy` - pub async fn policy_view<'a>( - &'a self, + pub async fn policy_view( + &self, ) -> Result, Error> { let url = format!("{}/policy", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -20053,9 +20053,7 @@ impl Client { ///Fetch the user associated with the current session /// ///Sends a `GET` request to `/session/me` - pub async fn session_me<'a>( - &'a self, - ) -> Result, Error> { + pub async fn session_me(&self) -> Result, Error> { let url = format!("{}/session/me", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -22029,8 +22027,8 @@ impl Client { ///Fetch the IP pool used for Oxide services /// ///Sends a `GET` request to `/system/ip-pools-service` - pub async fn ip_pool_service_view<'a>( - &'a self, + pub async fn ip_pool_service_view( + &self, ) -> Result, Error> { let url = format!("{}/system/ip-pools-service", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -22322,8 +22320,8 @@ impl Client { ///Fetch the top-level IAM policy /// ///Sends a `GET` request to `/system/policy` - pub async fn system_policy_view<'a>( - &'a self, + pub async fn system_policy_view( + &self, ) -> Result, Error> { let url = format!("{}/system/policy", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -25892,9 +25890,7 @@ impl Client { ///Refresh update data /// ///Sends a `POST` request to `/v1/system/update/refresh` - pub async fn system_update_refresh<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_refresh(&self) -> Result, Error> { let url = format!("{}/v1/system/update/refresh", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -25978,9 +25974,7 @@ impl Client { ///If there is no update in progress, do nothing. /// ///Sends a `POST` request to `/v1/system/update/stop` - pub async fn system_update_stop<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_stop(&self) -> Result, Error> { let url = format!("{}/v1/system/update/stop", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -26208,8 +26202,8 @@ impl Client { ///View system version and update status /// ///Sends a `GET` request to `/v1/system/update/version` - pub async fn system_version<'a>( - &'a self, + pub async fn system_version( + &self, ) -> Result, Error> { let url = format!("{}/v1/system/update/version", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); diff --git a/progenitor-impl/tests/output/src/nexus_with_timeout.rs b/progenitor-impl/tests/output/src/nexus_with_timeout.rs index 0bea2f16..de7f31a4 100644 --- a/progenitor-impl/tests/output/src/nexus_with_timeout.rs +++ b/progenitor-impl/tests/output/src/nexus_with_timeout.rs @@ -15015,7 +15015,7 @@ impl Client { } ///Sends a `POST` request to `/logout` - pub async fn logout<'a>(&'a self) -> Result, Error> { + pub async fn logout(&self) -> Result, Error> { let url = format!("{}/logout", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -19830,8 +19830,8 @@ impl Client { ///Fetch the current silo's IAM policy /// ///Sends a `GET` request to `/policy` - pub async fn policy_view<'a>( - &'a self, + pub async fn policy_view( + &self, ) -> Result, Error> { let url = format!("{}/policy", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -20053,9 +20053,7 @@ impl Client { ///Fetch the user associated with the current session /// ///Sends a `GET` request to `/session/me` - pub async fn session_me<'a>( - &'a self, - ) -> Result, Error> { + pub async fn session_me(&self) -> Result, Error> { let url = format!("{}/session/me", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -22029,8 +22027,8 @@ impl Client { ///Fetch the IP pool used for Oxide services /// ///Sends a `GET` request to `/system/ip-pools-service` - pub async fn ip_pool_service_view<'a>( - &'a self, + pub async fn ip_pool_service_view( + &self, ) -> Result, Error> { let url = format!("{}/system/ip-pools-service", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -22322,8 +22320,8 @@ impl Client { ///Fetch the top-level IAM policy /// ///Sends a `GET` request to `/system/policy` - pub async fn system_policy_view<'a>( - &'a self, + pub async fn system_policy_view( + &self, ) -> Result, Error> { let url = format!("{}/system/policy", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -25892,9 +25890,7 @@ impl Client { ///Refresh update data /// ///Sends a `POST` request to `/v1/system/update/refresh` - pub async fn system_update_refresh<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_refresh(&self) -> Result, Error> { let url = format!("{}/v1/system/update/refresh", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -25978,9 +25974,7 @@ impl Client { ///If there is no update in progress, do nothing. /// ///Sends a `POST` request to `/v1/system/update/stop` - pub async fn system_update_stop<'a>( - &'a self, - ) -> Result, Error> { + pub async fn system_update_stop(&self) -> Result, Error> { let url = format!("{}/v1/system/update/stop", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( @@ -26208,8 +26202,8 @@ impl Client { ///View system version and update status /// ///Sends a `GET` request to `/v1/system/update/version` - pub async fn system_version<'a>( - &'a self, + pub async fn system_version( + &self, ) -> Result, Error> { let url = format!("{}/v1/system/update/version", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); diff --git a/progenitor-impl/tests/output/src/propolis_server_positional.rs b/progenitor-impl/tests/output/src/propolis_server_positional.rs index 2836091c..a6fc7ab9 100644 --- a/progenitor-impl/tests/output/src/propolis_server_positional.rs +++ b/progenitor-impl/tests/output/src/propolis_server_positional.rs @@ -1562,8 +1562,8 @@ impl ClientHooks<()> for &Client {} #[allow(clippy::all)] impl Client { ///Sends a `GET` request to `/instance` - pub async fn instance_get<'a>( - &'a self, + pub async fn instance_get( + &self, ) -> Result, Error> { let url = format!("{}/instance", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); @@ -1731,8 +1731,8 @@ impl Client { } ///Sends a `GET` request to `/instance/serial` - pub async fn instance_serial<'a>( - &'a self, + pub async fn instance_serial( + &self, ) -> Result, Error> { let url = format!("{}/instance/serial", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); diff --git a/progenitor-impl/tests/output/src/test_freeform_response.rs b/progenitor-impl/tests/output/src/test_freeform_response.rs index 3fac53b2..65cfd07d 100644 --- a/progenitor-impl/tests/output/src/test_freeform_response.rs +++ b/progenitor-impl/tests/output/src/test_freeform_response.rs @@ -100,9 +100,7 @@ impl ClientHooks<()> for &Client {} #[allow(clippy::all)] impl Client { ///Sends a `GET` request to `/` - pub async fn freeform_response<'a>( - &'a self, - ) -> Result, Error> { + pub async fn freeform_response(&self) -> Result, Error> { let url = format!("{}/", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( From fdfd142701e988ba10edffd523352dc07bfea144 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 9 Oct 2025 10:32:11 -0700 Subject: [PATCH 3/6] remove moved files --- .../tests/output/buildomat-positional.out | 726 - .../tests/output/nexus-positional.out | 16445 ---------------- .../output/propolis-server-positional.out | 880 - .../tests/output/test_freeform_response.out | 102 - 4 files changed, 18153 deletions(-) delete mode 100644 progenitor-impl/tests/output/buildomat-positional.out delete mode 100644 progenitor-impl/tests/output/nexus-positional.out delete mode 100644 progenitor-impl/tests/output/propolis-server-positional.out delete mode 100644 progenitor-impl/tests/output/test_freeform_response.out diff --git a/progenitor-impl/tests/output/buildomat-positional.out b/progenitor-impl/tests/output/buildomat-positional.out deleted file mode 100644 index 8bd5d054..00000000 --- a/progenitor-impl/tests/output/buildomat-positional.out +++ /dev/null @@ -1,726 +0,0 @@ -#[allow(unused_imports)] -use progenitor_client::{encode_path, RequestBuilderExt}; -pub use progenitor_client::{ByteStream, Error, ResponseValue}; -#[allow(unused_imports)] -use reqwest::header::{HeaderMap, HeaderValue}; -pub mod types { - use serde::{Deserialize, Serialize}; - #[allow(unused_imports)] - use std::convert::TryFrom; - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Task { - pub id: String, - pub name: String, - pub output_rules: Vec, - pub script: String, - pub state: String, - } - - impl From<&Task> for Task { - fn from(value: &Task) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TaskEvent { - pub payload: String, - pub seq: u32, - pub stream: String, - pub time: chrono::DateTime, - } - - impl From<&TaskEvent> for TaskEvent { - fn from(value: &TaskEvent) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TaskOutput { - pub id: String, - pub path: String, - pub size: u64, - } - - impl From<&TaskOutput> for TaskOutput { - fn from(value: &TaskOutput) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TaskSubmit { - pub name: String, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub output_rules: Vec, - pub script: String, - } - - impl From<&TaskSubmit> for TaskSubmit { - fn from(value: &TaskSubmit) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TaskSubmitResult { - pub id: String, - } - - impl From<&TaskSubmitResult> for TaskSubmitResult { - fn from(value: &TaskSubmitResult) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UploadedChunk { - pub id: String, - } - - impl From<&UploadedChunk> for UploadedChunk { - fn from(value: &UploadedChunk) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserCreate { - pub name: String, - } - - impl From<&UserCreate> for UserCreate { - fn from(value: &UserCreate) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserCreateResult { - pub id: String, - pub name: String, - pub token: String, - } - - impl From<&UserCreateResult> for UserCreateResult { - fn from(value: &UserCreateResult) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WhoamiResult { - pub id: String, - pub name: String, - } - - impl From<&WhoamiResult> for WhoamiResult { - fn from(value: &WhoamiResult) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Worker { - pub deleted: bool, - pub id: String, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub instance_id: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub lastping: Option>, - pub recycle: bool, - pub tasks: Vec, - } - - impl From<&Worker> for Worker { - fn from(value: &Worker) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerAddOutput { - pub chunks: Vec, - pub path: String, - pub size: i64, - } - - impl From<&WorkerAddOutput> for WorkerAddOutput { - fn from(value: &WorkerAddOutput) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerAppendTask { - pub payload: String, - pub stream: String, - pub time: chrono::DateTime, - } - - impl From<&WorkerAppendTask> for WorkerAppendTask { - fn from(value: &WorkerAppendTask) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerBootstrap { - pub bootstrap: String, - pub token: String, - } - - impl From<&WorkerBootstrap> for WorkerBootstrap { - fn from(value: &WorkerBootstrap) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerBootstrapResult { - pub id: String, - } - - impl From<&WorkerBootstrapResult> for WorkerBootstrapResult { - fn from(value: &WorkerBootstrapResult) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerCompleteTask { - pub failed: bool, - } - - impl From<&WorkerCompleteTask> for WorkerCompleteTask { - fn from(value: &WorkerCompleteTask) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerPingResult { - pub poweroff: bool, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub task: Option, - } - - impl From<&WorkerPingResult> for WorkerPingResult { - fn from(value: &WorkerPingResult) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerPingTask { - pub id: String, - pub output_rules: Vec, - pub script: String, - } - - impl From<&WorkerPingTask> for WorkerPingTask { - fn from(value: &WorkerPingTask) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkerTask { - pub id: String, - pub name: String, - pub owner: String, - } - - impl From<&WorkerTask> for WorkerTask { - fn from(value: &WorkerTask) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct WorkersResult { - pub workers: Vec, - } - - impl From<&WorkersResult> for WorkersResult { - fn from(value: &WorkersResult) -> Self { - value.clone() - } - } -} - -#[derive(Clone, Debug)] -///Client for Buildomat -/// -///Version: 1.0 -pub struct Client { - pub(crate) baseurl: String, - pub(crate) client: reqwest::Client, -} - -impl Client { - /// Create a new client. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new(baseurl: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] - let client = { - let dur = std::time::Duration::from_secs(15); - reqwest::ClientBuilder::new() - .connect_timeout(dur) - .timeout(dur) - }; - #[cfg(target_arch = "wasm32")] - let client = reqwest::ClientBuilder::new(); - Self::new_with_client(baseurl, client.build().unwrap()) - } - - /// Construct a new client with an existing `reqwest::Client`, - /// allowing more control over its configuration. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { - Self { - baseurl: baseurl.to_string(), - client, - } - } - - /// Get the base URL to which requests are made. - pub fn baseurl(&self) -> &String { - &self.baseurl - } - - /// Get the internal `reqwest::Client` used to make requests. - pub fn client(&self) -> &reqwest::Client { - &self.client - } - - /// Get the version of this API. - /// - /// This string is pulled directly from the source OpenAPI - /// document and may be in any format the API selects. - pub fn api_version(&self) -> &'static str { - "1.0" - } -} - -impl Client { - ///Sends a `POST` request to `/v1/control/hold` - pub async fn control_hold(&self) -> Result, Error<()>> { - let url = format!("{}/v1/control/hold", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/control/resume` - pub async fn control_resume(&self) -> Result, Error<()>> { - let url = format!("{}/v1/control/resume", self.baseurl,); - let request = self.client.post(url).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/task/{task}` - pub async fn task_get<'a>( - &'a self, - task: &'a str, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/task/{}", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/tasks` - pub async fn tasks_get(&self) -> Result>, Error<()>> { - let url = format!("{}/v1/tasks", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/tasks` - pub async fn task_submit<'a>( - &'a self, - body: &'a types::TaskSubmit, - ) -> Result, Error<()>> { - let url = format!("{}/v1/tasks", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/tasks/{task}/events` - pub async fn task_events_get<'a>( - &'a self, - task: &'a str, - minseq: Option, - ) -> Result>, Error<()>> { - let url = format!( - "{}/v1/tasks/{}/events", - self.baseurl, - encode_path(&task.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &minseq { - query.push(("minseq", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/tasks/{task}/outputs` - pub async fn task_outputs_get<'a>( - &'a self, - task: &'a str, - ) -> Result>, Error<()>> { - let url = format!( - "{}/v1/tasks/{}/outputs", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/tasks/{task}/outputs/{output}` - pub async fn task_output_download<'a>( - &'a self, - task: &'a str, - output: &'a str, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/tasks/{}/outputs/{}", - self.baseurl, - encode_path(&task.to_string()), - encode_path(&output.to_string()), - ); - let request = self.client.get(url).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/users` - pub async fn user_create<'a>( - &'a self, - body: &'a types::UserCreate, - ) -> Result, Error<()>> { - let url = format!("{}/v1/users", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/whoami` - pub async fn whoami(&self) -> Result, Error<()>> { - let url = format!("{}/v1/whoami", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `PUT` request to `/v1/whoami/name` - pub async fn whoami_put_name<'a>( - &'a self, - body: String, - ) -> Result, Error<()>> { - let url = format!("{}/v1/whoami/name", self.baseurl,); - let request = self - .client - .put(url) - .header( - reqwest::header::CONTENT_TYPE, - reqwest::header::HeaderValue::from_static("text/plain"), - ) - .body(body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/worker/bootstrap` - pub async fn worker_bootstrap<'a>( - &'a self, - body: &'a types::WorkerBootstrap, - ) -> Result, Error<()>> { - let url = format!("{}/v1/worker/bootstrap", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/worker/ping` - pub async fn worker_ping(&self) -> Result, Error<()>> { - let url = format!("{}/v1/worker/ping", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/worker/task/{task}/append` - pub async fn worker_task_append<'a>( - &'a self, - task: &'a str, - body: &'a types::WorkerAppendTask, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/worker/task/{}/append", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self.client.post(url).json(&body).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/worker/task/{task}/chunk` - pub async fn worker_task_upload_chunk<'a, B: Into>( - &'a self, - task: &'a str, - body: B, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/worker/task/{}/chunk", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .header( - reqwest::header::CONTENT_TYPE, - reqwest::header::HeaderValue::from_static("application/octet-stream"), - ) - .body(body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/worker/task/{task}/complete` - pub async fn worker_task_complete<'a>( - &'a self, - task: &'a str, - body: &'a types::WorkerCompleteTask, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/worker/task/{}/complete", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self.client.post(url).json(&body).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/worker/task/{task}/output` - pub async fn worker_task_add_output<'a>( - &'a self, - task: &'a str, - body: &'a types::WorkerAddOutput, - ) -> Result, Error<()>> { - let url = format!( - "{}/v1/worker/task/{}/output", - self.baseurl, - encode_path(&task.to_string()), - ); - let request = self.client.post(url).json(&body).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/v1/workers` - pub async fn workers_list(&self) -> Result, Error<()>> { - let url = format!("{}/v1/workers", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/v1/workers/recycle` - pub async fn workers_recycle(&self) -> Result, Error<()>> { - let url = format!("{}/v1/workers/recycle", self.baseurl,); - let request = self.client.post(url).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => Ok(ResponseValue::empty(response)), - _ => Err(Error::UnexpectedResponse(response)), - } - } -} - -pub mod prelude { - pub use super::Client; -} diff --git a/progenitor-impl/tests/output/nexus-positional.out b/progenitor-impl/tests/output/nexus-positional.out deleted file mode 100644 index 0a94285e..00000000 --- a/progenitor-impl/tests/output/nexus-positional.out +++ /dev/null @@ -1,16445 +0,0 @@ -#[allow(unused_imports)] -use progenitor_client::{encode_path, RequestBuilderExt}; -pub use progenitor_client::{ByteStream, Error, ResponseValue}; -#[allow(unused_imports)] -use reqwest::header::{HeaderMap, HeaderValue}; -pub mod types { - use serde::{Deserialize, Serialize}; - #[allow(unused_imports)] - use std::convert::TryFrom; - ///Describes properties that should uniquely identify a Gimlet. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Baseboard { - pub part: String, - pub revision: i64, - pub serial: String, - } - - impl From<&Baseboard> for Baseboard { - fn from(value: &Baseboard) -> Self { - value.clone() - } - } - - ///A type storing a range over `T`. - /// - ///This type supports ranges similar to the `RangeTo`, `Range` and - /// `RangeFrom` types in the standard library. Those cover `(..end)`, - /// `(start..end)`, and `(start..)` respectively. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum BinRangedouble { - ///A range unbounded below and exclusively above, `..end`. - #[serde(rename = "range_to")] - RangeTo { end: f64 }, - ///A range bounded inclusively below and exclusively above, - /// `start..end`. - #[serde(rename = "range")] - Range { end: f64, start: f64 }, - ///A range bounded inclusively below and unbounded above, `start..`. - #[serde(rename = "range_from")] - RangeFrom { start: f64 }, - } - - impl From<&BinRangedouble> for BinRangedouble { - fn from(value: &BinRangedouble) -> Self { - value.clone() - } - } - - ///A type storing a range over `T`. - /// - ///This type supports ranges similar to the `RangeTo`, `Range` and - /// `RangeFrom` types in the standard library. Those cover `(..end)`, - /// `(start..end)`, and `(start..)` respectively. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum BinRangeint64 { - ///A range unbounded below and exclusively above, `..end`. - #[serde(rename = "range_to")] - RangeTo { end: i64 }, - ///A range bounded inclusively below and exclusively above, - /// `start..end`. - #[serde(rename = "range")] - Range { end: i64, start: i64 }, - ///A range bounded inclusively below and unbounded above, `start..`. - #[serde(rename = "range_from")] - RangeFrom { start: i64 }, - } - - impl From<&BinRangeint64> for BinRangeint64 { - fn from(value: &BinRangeint64) -> Self { - value.clone() - } - } - - ///Type storing bin edges and a count of samples within it. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Bindouble { - ///The total count of samples in this bin. - pub count: u64, - ///The range of the support covered by this bin. - pub range: BinRangedouble, - } - - impl From<&Bindouble> for Bindouble { - fn from(value: &Bindouble) -> Self { - value.clone() - } - } - - ///Type storing bin edges and a count of samples within it. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Binint64 { - ///The total count of samples in this bin. - pub count: u64, - ///The range of the support covered by this bin. - pub range: BinRangeint64, - } - - impl From<&Binint64> for Binint64 { - fn from(value: &Binint64) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Serialize)] - pub struct BlockSize(i64); - impl std::ops::Deref for BlockSize { - type Target = i64; - fn deref(&self) -> &i64 { - &self.0 - } - } - - impl From for i64 { - fn from(value: BlockSize) -> Self { - value.0 - } - } - - impl From<&BlockSize> for BlockSize { - fn from(value: &BlockSize) -> Self { - value.clone() - } - } - - impl std::convert::TryFrom for BlockSize { - type Error = &'static str; - fn try_from(value: i64) -> Result { - if ![512_i64, 2048_i64, 4096_i64].contains(&value) { - Err("invalid value") - } else { - Ok(Self(value)) - } - } - } - - impl<'de> serde::Deserialize<'de> for BlockSize { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - Self::try_from(::deserialize(deserializer)?) - .map_err(|e| ::custom(e.to_string())) - } - } - - ///A count of bytes, typically used either for memory or storage capacity - /// - ///The maximum supported byte count is [`i64::MAX`]. This makes it - /// somewhat inconvenient to define constructors: a u32 constructor can be - /// infallible, but an i64 constructor can fail (if the value is negative) - /// and a u64 constructor can fail (if the value is larger than i64::MAX). - /// We provide all of these for consumers' convenience. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ByteCount(pub u64); - impl std::ops::Deref for ByteCount { - type Target = u64; - fn deref(&self) -> &u64 { - &self.0 - } - } - - impl From for u64 { - fn from(value: ByteCount) -> Self { - value.0 - } - } - - impl From<&ByteCount> for ByteCount { - fn from(value: &ByteCount) -> Self { - value.clone() - } - } - - impl From for ByteCount { - fn from(value: u64) -> Self { - Self(value) - } - } - - impl std::str::FromStr for ByteCount { - type Err = ::Err; - fn from_str(value: &str) -> Result { - Ok(Self(value.parse()?)) - } - } - - impl std::convert::TryFrom<&str> for ByteCount { - type Error = ::Err; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for ByteCount { - type Error = ::Err; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for ByteCount { - type Error = ::Err; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl ToString for ByteCount { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - ///Client view of a [`Certificate`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Certificate { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - pub service: ServiceUsingCertificate, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Certificate> for Certificate { - fn from(value: &Certificate) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`Certificate`](crate::external_api::views::Certificate) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct CertificateCreate { - ///PEM file containing public certificate chain - pub cert: Vec, - pub description: String, - ///PEM file containing private key - pub key: Vec, - pub name: Name, - ///The service using this certificate - pub service: ServiceUsingCertificate, - } - - impl From<&CertificateCreate> for CertificateCreate { - fn from(value: &CertificateCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct CertificateResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&CertificateResultsPage> for CertificateResultsPage { - fn from(value: &CertificateResultsPage) -> Self { - value.clone() - } - } - - ///Identity-related metadata that's included in "asset" public API objects - /// (which generally have no name or description) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ComponentUpdate { - pub component_type: UpdateableComponentType, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub version: SemverVersion, - } - - impl From<&ComponentUpdate> for ComponentUpdate { - fn from(value: &ComponentUpdate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ComponentUpdateResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&ComponentUpdateResultsPage> for ComponentUpdateResultsPage { - fn from(value: &ComponentUpdateResultsPage) -> Self { - value.clone() - } - } - - ///A cumulative or counter data type. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Cumulativedouble { - pub start_time: chrono::DateTime, - pub value: f64, - } - - impl From<&Cumulativedouble> for Cumulativedouble { - fn from(value: &Cumulativedouble) -> Self { - value.clone() - } - } - - ///A cumulative or counter data type. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Cumulativeint64 { - pub start_time: chrono::DateTime, - pub value: i64, - } - - impl From<&Cumulativeint64> for Cumulativeint64 { - fn from(value: &Cumulativeint64) -> Self { - value.clone() - } - } - - ///A `Datum` is a single sampled data point from a metric. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "datum")] - pub enum Datum { - #[serde(rename = "bool")] - Bool(bool), - #[serde(rename = "i64")] - I64(i64), - #[serde(rename = "f64")] - F64(f64), - #[serde(rename = "string")] - String(String), - #[serde(rename = "bytes")] - Bytes(Vec), - #[serde(rename = "cumulative_i64")] - CumulativeI64(Cumulativeint64), - #[serde(rename = "cumulative_f64")] - CumulativeF64(Cumulativedouble), - #[serde(rename = "histogram_i64")] - HistogramI64(Histogramint64), - #[serde(rename = "histogram_f64")] - HistogramF64(Histogramdouble), - } - - impl From<&Datum> for Datum { - fn from(value: &Datum) -> Self { - value.clone() - } - } - - impl From for Datum { - fn from(value: bool) -> Self { - Self::Bool(value) - } - } - - impl From for Datum { - fn from(value: i64) -> Self { - Self::I64(value) - } - } - - impl From for Datum { - fn from(value: f64) -> Self { - Self::F64(value) - } - } - - impl From> for Datum { - fn from(value: Vec) -> Self { - Self::Bytes(value) - } - } - - impl From for Datum { - fn from(value: Cumulativeint64) -> Self { - Self::CumulativeI64(value) - } - } - - impl From for Datum { - fn from(value: Cumulativedouble) -> Self { - Self::CumulativeF64(value) - } - } - - impl From for Datum { - fn from(value: Histogramint64) -> Self { - Self::HistogramI64(value) - } - } - - impl From for Datum { - fn from(value: Histogramdouble) -> Self { - Self::HistogramF64(value) - } - } - - ///The type of an individual datum of a metric. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum DatumType { - #[serde(rename = "bool")] - Bool, - #[serde(rename = "i64")] - I64, - #[serde(rename = "f64")] - F64, - #[serde(rename = "string")] - String, - #[serde(rename = "bytes")] - Bytes, - #[serde(rename = "cumulative_i64")] - CumulativeI64, - #[serde(rename = "cumulative_f64")] - CumulativeF64, - #[serde(rename = "histogram_i64")] - HistogramI64, - #[serde(rename = "histogram_f64")] - HistogramF64, - } - - impl From<&DatumType> for DatumType { - fn from(value: &DatumType) -> Self { - value.clone() - } - } - - impl ToString for DatumType { - fn to_string(&self) -> String { - match *self { - Self::Bool => "bool".to_string(), - Self::I64 => "i64".to_string(), - Self::F64 => "f64".to_string(), - Self::String => "string".to_string(), - Self::Bytes => "bytes".to_string(), - Self::CumulativeI64 => "cumulative_i64".to_string(), - Self::CumulativeF64 => "cumulative_f64".to_string(), - Self::HistogramI64 => "histogram_i64".to_string(), - Self::HistogramF64 => "histogram_f64".to_string(), - } - } - } - - impl std::str::FromStr for DatumType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "bool" => Ok(Self::Bool), - "i64" => Ok(Self::I64), - "f64" => Ok(Self::F64), - "string" => Ok(Self::String), - "bytes" => Ok(Self::Bytes), - "cumulative_i64" => Ok(Self::CumulativeI64), - "cumulative_f64" => Ok(Self::CumulativeF64), - "histogram_i64" => Ok(Self::HistogramI64), - "histogram_f64" => Ok(Self::HistogramF64), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for DatumType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for DatumType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for DatumType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DerEncodedKeyPair { - ///request signing private key (base64 encoded der file) - pub private_key: String, - ///request signing public certificate (base64 encoded der file) - pub public_cert: String, - } - - impl From<&DerEncodedKeyPair> for DerEncodedKeyPair { - fn from(value: &DerEncodedKeyPair) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DeviceAccessTokenRequest { - pub client_id: uuid::Uuid, - pub device_code: String, - pub grant_type: String, - } - - impl From<&DeviceAccessTokenRequest> for DeviceAccessTokenRequest { - fn from(value: &DeviceAccessTokenRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DeviceAuthRequest { - pub client_id: uuid::Uuid, - } - - impl From<&DeviceAuthRequest> for DeviceAuthRequest { - fn from(value: &DeviceAuthRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DeviceAuthVerify { - pub user_code: String, - } - - impl From<&DeviceAuthVerify> for DeviceAuthVerify { - fn from(value: &DeviceAuthVerify) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "value")] - pub enum Digest { - #[serde(rename = "sha256")] - Sha256(String), - } - - impl From<&Digest> for Digest { - fn from(value: &Digest) -> Self { - value.clone() - } - } - - ///Client view of a [`Disk`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Disk { - pub block_size: ByteCount, - ///human-readable free-form text about a resource - pub description: String, - pub device_path: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub image_id: Option, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - pub project_id: uuid::Uuid, - pub size: ByteCount, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub snapshot_id: Option, - pub state: DiskState, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Disk> for Disk { - fn from(value: &Disk) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`Disk`](omicron_common::api::external::Disk) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskCreate { - pub description: String, - ///initial source for this disk - pub disk_source: DiskSource, - pub name: Name, - ///total size of the Disk in bytes - pub size: ByteCount, - } - - impl From<&DiskCreate> for DiskCreate { - fn from(value: &DiskCreate) -> Self { - value.clone() - } - } - - ///TODO-v1: Delete this Parameters for the - /// [`Disk`](omicron_common::api::external::Disk) to be attached or detached - /// to an instance - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskIdentifier { - pub name: Name, - } - - impl From<&DiskIdentifier> for DiskIdentifier { - fn from(value: &DiskIdentifier) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum DiskMetricName { - #[serde(rename = "activated")] - Activated, - #[serde(rename = "flush")] - Flush, - #[serde(rename = "read")] - Read, - #[serde(rename = "read_bytes")] - ReadBytes, - #[serde(rename = "write")] - Write, - #[serde(rename = "write_bytes")] - WriteBytes, - } - - impl From<&DiskMetricName> for DiskMetricName { - fn from(value: &DiskMetricName) -> Self { - value.clone() - } - } - - impl ToString for DiskMetricName { - fn to_string(&self) -> String { - match *self { - Self::Activated => "activated".to_string(), - Self::Flush => "flush".to_string(), - Self::Read => "read".to_string(), - Self::ReadBytes => "read_bytes".to_string(), - Self::Write => "write".to_string(), - Self::WriteBytes => "write_bytes".to_string(), - } - } - } - - impl std::str::FromStr for DiskMetricName { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "activated" => Ok(Self::Activated), - "flush" => Ok(Self::Flush), - "read" => Ok(Self::Read), - "read_bytes" => Ok(Self::ReadBytes), - "write" => Ok(Self::Write), - "write_bytes" => Ok(Self::WriteBytes), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for DiskMetricName { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for DiskMetricName { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for DiskMetricName { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskPath { - pub disk: NameOrId, - } - - impl From<&DiskPath> for DiskPath { - fn from(value: &DiskPath) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&DiskResultsPage> for DiskResultsPage { - fn from(value: &DiskResultsPage) -> Self { - value.clone() - } - } - - ///Different sources for a disk - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum DiskSource { - ///Create a blank disk - #[serde(rename = "blank")] - Blank { - ///size of blocks for this Disk. valid values are: 512, 2048, or - /// 4096 - block_size: BlockSize, - }, - ///Create a disk from a disk snapshot - #[serde(rename = "snapshot")] - Snapshot { snapshot_id: uuid::Uuid }, - ///Create a disk from a project image - #[serde(rename = "image")] - Image { image_id: uuid::Uuid }, - ///Create a disk from a global image - #[serde(rename = "global_image")] - GlobalImage { image_id: uuid::Uuid }, - } - - impl From<&DiskSource> for DiskSource { - fn from(value: &DiskSource) -> Self { - value.clone() - } - } - - ///State of a Disk (primarily: attached or not) - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "state", content = "instance")] - pub enum DiskState { - #[serde(rename = "creating")] - Creating, - #[serde(rename = "detached")] - Detached, - ///Disk is being attached to the given Instance - #[serde(rename = "attaching")] - Attaching(uuid::Uuid), - ///Disk is attached to the given Instance - #[serde(rename = "attached")] - Attached(uuid::Uuid), - ///Disk is being detached from the given Instance - #[serde(rename = "detaching")] - Detaching(uuid::Uuid), - #[serde(rename = "destroyed")] - Destroyed, - #[serde(rename = "faulted")] - Faulted, - } - - impl From<&DiskState> for DiskState { - fn from(value: &DiskState) -> Self { - value.clone() - } - } - - ///OS image distribution - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Distribution { - ///The name of the distribution (e.g. "alpine" or "ubuntu") - pub name: Name, - ///The version of the distribution (e.g. "3.10" or "18.04") - pub version: String, - } - - impl From<&Distribution> for Distribution { - fn from(value: &Distribution) -> Self { - value.clone() - } - } - - ///Error information from a response. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Error { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub error_code: Option, - pub message: String, - pub request_id: String, - } - - impl From<&Error> for Error { - fn from(value: &Error) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ExternalIp { - pub ip: std::net::IpAddr, - pub kind: IpKind, - } - - impl From<&ExternalIp> for ExternalIp { - fn from(value: &ExternalIp) -> Self { - value.clone() - } - } - - ///Parameters for creating an external IP address for instances. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum ExternalIpCreate { - ///An IP address providing both inbound and outbound access. The - /// address is automatically-assigned from the provided IP Pool, or all - /// available pools if not specified. - #[serde(rename = "ephemeral")] - Ephemeral { - #[serde(default, skip_serializing_if = "Option::is_none")] - pool_name: Option, - }, - } - - impl From<&ExternalIpCreate> for ExternalIpCreate { - fn from(value: &ExternalIpCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ExternalIpResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&ExternalIpResultsPage> for ExternalIpResultsPage { - fn from(value: &ExternalIpResultsPage) -> Self { - value.clone() - } - } - - ///The name and type information for a field of a timeseries schema. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct FieldSchema { - pub name: String, - pub source: FieldSource, - pub ty: FieldType, - } - - impl From<&FieldSchema> for FieldSchema { - fn from(value: &FieldSchema) -> Self { - value.clone() - } - } - - ///The source from which a field is derived, the target or metric. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum FieldSource { - #[serde(rename = "target")] - Target, - #[serde(rename = "metric")] - Metric, - } - - impl From<&FieldSource> for FieldSource { - fn from(value: &FieldSource) -> Self { - value.clone() - } - } - - impl ToString for FieldSource { - fn to_string(&self) -> String { - match *self { - Self::Target => "target".to_string(), - Self::Metric => "metric".to_string(), - } - } - } - - impl std::str::FromStr for FieldSource { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "target" => Ok(Self::Target), - "metric" => Ok(Self::Metric), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for FieldSource { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for FieldSource { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for FieldSource { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///The `FieldType` identifies the data type of a target or metric field. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum FieldType { - #[serde(rename = "string")] - String, - #[serde(rename = "i64")] - I64, - #[serde(rename = "ip_addr")] - IpAddr, - #[serde(rename = "uuid")] - Uuid, - #[serde(rename = "bool")] - Bool, - } - - impl From<&FieldType> for FieldType { - fn from(value: &FieldType) -> Self { - value.clone() - } - } - - impl ToString for FieldType { - fn to_string(&self) -> String { - match *self { - Self::String => "string".to_string(), - Self::I64 => "i64".to_string(), - Self::IpAddr => "ip_addr".to_string(), - Self::Uuid => "uuid".to_string(), - Self::Bool => "bool".to_string(), - } - } - } - - impl std::str::FromStr for FieldType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "string" => Ok(Self::String), - "i64" => Ok(Self::I64), - "ip_addr" => Ok(Self::IpAddr), - "uuid" => Ok(Self::Uuid), - "bool" => Ok(Self::Bool), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for FieldType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for FieldType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for FieldType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum FleetRole { - #[serde(rename = "admin")] - Admin, - #[serde(rename = "collaborator")] - Collaborator, - #[serde(rename = "viewer")] - Viewer, - } - - impl From<&FleetRole> for FleetRole { - fn from(value: &FleetRole) -> Self { - value.clone() - } - } - - impl ToString for FleetRole { - fn to_string(&self) -> String { - match *self { - Self::Admin => "admin".to_string(), - Self::Collaborator => "collaborator".to_string(), - Self::Viewer => "viewer".to_string(), - } - } - } - - impl std::str::FromStr for FleetRole { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "admin" => Ok(Self::Admin), - "collaborator" => Ok(Self::Collaborator), - "viewer" => Ok(Self::Viewer), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for FleetRole { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for FleetRole { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for FleetRole { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`Policy`], which describes how this resource may be - /// accessed - /// - ///Note that the Policy only describes access granted explicitly for this - /// resource. The policies of parent resources can also cause a user to - /// have access to this resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct FleetRolePolicy { - ///Roles directly assigned on this resource - pub role_assignments: Vec, - } - - impl From<&FleetRolePolicy> for FleetRolePolicy { - fn from(value: &FleetRolePolicy) -> Self { - value.clone() - } - } - - ///Describes the assignment of a particular role on a particular resource - /// to a particular identity (user, group, etc.) - /// - ///The resource is not part of this structure. Rather, [`RoleAssignment`]s - /// are put into a [`Policy`] and that Policy is applied to a particular - /// resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct FleetRoleRoleAssignment { - pub identity_id: uuid::Uuid, - pub identity_type: IdentityType, - pub role_name: FleetRole, - } - - impl From<&FleetRoleRoleAssignment> for FleetRoleRoleAssignment { - fn from(value: &FleetRoleRoleAssignment) -> Self { - value.clone() - } - } - - ///Client view of global Images - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct GlobalImage { - ///size of blocks in bytes - pub block_size: ByteCount, - ///human-readable free-form text about a resource - pub description: String, - ///Hash of the image contents, if applicable - #[serde(default, skip_serializing_if = "Option::is_none")] - pub digest: Option, - ///Image distribution - pub distribution: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///total size in bytes - pub size: ByteCount, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///URL source of this image, if any - #[serde(default, skip_serializing_if = "Option::is_none")] - pub url: Option, - ///Image version - pub version: String, - } - - impl From<&GlobalImage> for GlobalImage { - fn from(value: &GlobalImage) -> Self { - value.clone() - } - } - - ///Create-time parameters for an - /// [`GlobalImage`](crate::external_api::views::GlobalImage) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct GlobalImageCreate { - ///block size in bytes - pub block_size: BlockSize, - pub description: String, - ///OS image distribution - pub distribution: Distribution, - pub name: Name, - ///The source of the image's contents. - pub source: ImageSource, - } - - impl From<&GlobalImageCreate> for GlobalImageCreate { - fn from(value: &GlobalImageCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct GlobalImageResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&GlobalImageResultsPage> for GlobalImageResultsPage { - fn from(value: &GlobalImageResultsPage) -> Self { - value.clone() - } - } - - ///Client view of a [`Group`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Group { - ///Human-readable name that can identify the group - pub display_name: String, - pub id: uuid::Uuid, - ///Uuid of the silo to which this group belongs - pub silo_id: uuid::Uuid, - } - - impl From<&Group> for Group { - fn from(value: &Group) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct GroupResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&GroupResultsPage> for GroupResultsPage { - fn from(value: &GroupResultsPage) -> Self { - value.clone() - } - } - - ///A simple type for managing a histogram metric. - /// - ///A histogram maintains the count of any number of samples, over a set of - /// bins. Bins are specified on construction via their _left_ edges, - /// inclusive. There can't be any "gaps" in the bins, and an additional bin - /// may be added to the left, right, or both so that the bins extend to the - /// entire range of the support. - /// - ///Note that any gaps, unsorted bins, or non-finite values will result in - /// an error. - /// - ///Example ------- ```rust use oximeter::histogram::{BinRange, Histogram}; - /// - ///let edges = [0i64, 10, 20]; let mut hist = - /// Histogram::new(&edges).unwrap(); assert_eq!(hist.n_bins(), 4); // One - /// additional bin for the range (20..) assert_eq!(hist.n_samples(), 0); - /// hist.sample(4); hist.sample(100); assert_eq!(hist.n_samples(), 2); - /// - ///let data = hist.iter().collect::>(); assert_eq!(data[0].range, - /// BinRange::range(i64::MIN, 0)); // An additional bin for `..0` - /// assert_eq!(data[0].count, 0); // Nothing is in this bin - /// - ///assert_eq!(data[1].range, BinRange::range(0, 10)); // The range `0..10` - /// assert_eq!(data[1].count, 1); // 4 is sampled into this bin ``` - /// - ///Notes ----- - /// - ///Histograms may be constructed either from their left bin edges, or from - /// a sequence of ranges. In either case, the left-most bin may be converted - /// upon construction. In particular, if the left-most value is not equal to - /// the minimum of the support, a new bin will be added from the minimum to - /// that provided value. If the left-most value _is_ the support's minimum, - /// because the provided bin was unbounded below, such as `(..0)`, then that - /// bin will be converted into one bounded below, `(MIN..0)` in this case. - /// - ///The short of this is that, most of the time, it shouldn't matter. If one - /// specifies the extremes of the support as their bins, be aware that the - /// left-most may be converted from a `BinRange::RangeTo` into a - /// `BinRange::Range`. In other words, the first bin of a histogram is - /// _always_ a `Bin::Range` or a `Bin::RangeFrom` after construction. In - /// fact, every bin is one of those variants, the `BinRange::RangeTo` is - /// only provided as a convenience during construction. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Histogramdouble { - pub bins: Vec, - pub n_samples: u64, - pub start_time: chrono::DateTime, - } - - impl From<&Histogramdouble> for Histogramdouble { - fn from(value: &Histogramdouble) -> Self { - value.clone() - } - } - - ///A simple type for managing a histogram metric. - /// - ///A histogram maintains the count of any number of samples, over a set of - /// bins. Bins are specified on construction via their _left_ edges, - /// inclusive. There can't be any "gaps" in the bins, and an additional bin - /// may be added to the left, right, or both so that the bins extend to the - /// entire range of the support. - /// - ///Note that any gaps, unsorted bins, or non-finite values will result in - /// an error. - /// - ///Example ------- ```rust use oximeter::histogram::{BinRange, Histogram}; - /// - ///let edges = [0i64, 10, 20]; let mut hist = - /// Histogram::new(&edges).unwrap(); assert_eq!(hist.n_bins(), 4); // One - /// additional bin for the range (20..) assert_eq!(hist.n_samples(), 0); - /// hist.sample(4); hist.sample(100); assert_eq!(hist.n_samples(), 2); - /// - ///let data = hist.iter().collect::>(); assert_eq!(data[0].range, - /// BinRange::range(i64::MIN, 0)); // An additional bin for `..0` - /// assert_eq!(data[0].count, 0); // Nothing is in this bin - /// - ///assert_eq!(data[1].range, BinRange::range(0, 10)); // The range `0..10` - /// assert_eq!(data[1].count, 1); // 4 is sampled into this bin ``` - /// - ///Notes ----- - /// - ///Histograms may be constructed either from their left bin edges, or from - /// a sequence of ranges. In either case, the left-most bin may be converted - /// upon construction. In particular, if the left-most value is not equal to - /// the minimum of the support, a new bin will be added from the minimum to - /// that provided value. If the left-most value _is_ the support's minimum, - /// because the provided bin was unbounded below, such as `(..0)`, then that - /// bin will be converted into one bounded below, `(MIN..0)` in this case. - /// - ///The short of this is that, most of the time, it shouldn't matter. If one - /// specifies the extremes of the support as their bins, be aware that the - /// left-most may be converted from a `BinRange::RangeTo` into a - /// `BinRange::Range`. In other words, the first bin of a histogram is - /// _always_ a `Bin::Range` or a `Bin::RangeFrom` after construction. In - /// fact, every bin is one of those variants, the `BinRange::RangeTo` is - /// only provided as a convenience during construction. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Histogramint64 { - pub bins: Vec, - pub n_samples: u64, - pub start_time: chrono::DateTime, - } - - impl From<&Histogramint64> for Histogramint64 { - fn from(value: &Histogramint64) -> Self { - value.clone() - } - } - - ///Supported set of sort modes for scanning by id only. - /// - ///Currently, we only support scanning in ascending order. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum IdSortMode { - ///sort in increasing order of "id" - #[serde(rename = "id_ascending")] - IdAscending, - } - - impl From<&IdSortMode> for IdSortMode { - fn from(value: &IdSortMode) -> Self { - value.clone() - } - } - - impl ToString for IdSortMode { - fn to_string(&self) -> String { - match *self { - Self::IdAscending => "id_ascending".to_string(), - } - } - } - - impl std::str::FromStr for IdSortMode { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "id_ascending" => Ok(Self::IdAscending), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for IdSortMode { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for IdSortMode { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for IdSortMode { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of an [`IdentityProvider`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IdentityProvider { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///Identity provider type - pub provider_type: IdentityProviderType, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&IdentityProvider> for IdentityProvider { - fn from(value: &IdentityProvider) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IdentityProviderResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&IdentityProviderResultsPage> for IdentityProviderResultsPage { - fn from(value: &IdentityProviderResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum IdentityProviderType { - ///SAML identity provider - #[serde(rename = "saml")] - Saml, - } - - impl From<&IdentityProviderType> for IdentityProviderType { - fn from(value: &IdentityProviderType) -> Self { - value.clone() - } - } - - impl ToString for IdentityProviderType { - fn to_string(&self) -> String { - match *self { - Self::Saml => "saml".to_string(), - } - } - } - - impl std::str::FromStr for IdentityProviderType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "saml" => Ok(Self::Saml), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for IdentityProviderType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for IdentityProviderType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for IdentityProviderType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Describes what kind of identity is described by an id - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum IdentityType { - #[serde(rename = "silo_user")] - SiloUser, - #[serde(rename = "silo_group")] - SiloGroup, - } - - impl From<&IdentityType> for IdentityType { - fn from(value: &IdentityType) -> Self { - value.clone() - } - } - - impl ToString for IdentityType { - fn to_string(&self) -> String { - match *self { - Self::SiloUser => "silo_user".to_string(), - Self::SiloGroup => "silo_group".to_string(), - } - } - } - - impl std::str::FromStr for IdentityType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "silo_user" => Ok(Self::SiloUser), - "silo_group" => Ok(Self::SiloGroup), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for IdentityType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for IdentityType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for IdentityType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum IdpMetadataSource { - #[serde(rename = "url")] - Url { url: String }, - #[serde(rename = "base64_encoded_xml")] - Base64EncodedXml { data: String }, - } - - impl From<&IdpMetadataSource> for IdpMetadataSource { - fn from(value: &IdpMetadataSource) -> Self { - value.clone() - } - } - - ///Client view of project Images - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Image { - ///size of blocks in bytes - pub block_size: ByteCount, - ///human-readable free-form text about a resource - pub description: String, - ///Hash of the image contents, if applicable - #[serde(default, skip_serializing_if = "Option::is_none")] - pub digest: Option, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///The project the disk belongs to - pub project_id: uuid::Uuid, - ///total size in bytes - pub size: ByteCount, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///URL source of this image, if any - #[serde(default, skip_serializing_if = "Option::is_none")] - pub url: Option, - ///Version of this, if any - #[serde(default, skip_serializing_if = "Option::is_none")] - pub version: Option, - } - - impl From<&Image> for Image { - fn from(value: &Image) -> Self { - value.clone() - } - } - - ///Create-time parameters for an - /// [`Image`](crate::external_api::views::Image) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ImageCreate { - ///block size in bytes - pub block_size: BlockSize, - pub description: String, - pub name: Name, - ///The source of the image's contents. - pub source: ImageSource, - } - - impl From<&ImageCreate> for ImageCreate { - fn from(value: &ImageCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ImageResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&ImageResultsPage> for ImageResultsPage { - fn from(value: &ImageResultsPage) -> Self { - value.clone() - } - } - - ///The source of the underlying image. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum ImageSource { - #[serde(rename = "url")] - Url { url: String }, - #[serde(rename = "snapshot")] - Snapshot { id: uuid::Uuid }, - #[serde(rename = "you_can_boot_anything_as_long_as_its_alpine")] - YouCanBootAnythingAsLongAsItsAlpine, - } - - impl From<&ImageSource> for ImageSource { - fn from(value: &ImageSource) -> Self { - value.clone() - } - } - - ///Client view of an [`Instance`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Instance { - ///human-readable free-form text about a resource - pub description: String, - ///RFC1035-compliant hostname for the Instance. - pub hostname: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///memory allocated for this Instance - pub memory: ByteCount, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///number of CPUs allocated for this Instance - pub ncpus: InstanceCpuCount, - ///id for the project containing this Instance - pub project_id: uuid::Uuid, - pub run_state: InstanceState, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub time_run_state_updated: chrono::DateTime, - } - - impl From<&Instance> for Instance { - fn from(value: &Instance) -> Self { - value.clone() - } - } - - ///The number of CPUs in an Instance - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceCpuCount(pub u16); - impl std::ops::Deref for InstanceCpuCount { - type Target = u16; - fn deref(&self) -> &u16 { - &self.0 - } - } - - impl From for u16 { - fn from(value: InstanceCpuCount) -> Self { - value.0 - } - } - - impl From<&InstanceCpuCount> for InstanceCpuCount { - fn from(value: &InstanceCpuCount) -> Self { - value.clone() - } - } - - impl From for InstanceCpuCount { - fn from(value: u16) -> Self { - Self(value) - } - } - - impl std::str::FromStr for InstanceCpuCount { - type Err = ::Err; - fn from_str(value: &str) -> Result { - Ok(Self(value.parse()?)) - } - } - - impl std::convert::TryFrom<&str> for InstanceCpuCount { - type Error = ::Err; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for InstanceCpuCount { - type Error = ::Err; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for InstanceCpuCount { - type Error = ::Err; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl ToString for InstanceCpuCount { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - ///Create-time parameters for an - /// [`Instance`](omicron_common::api::external::Instance) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceCreate { - pub description: String, - ///The disks to be created or attached for this instance. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub disks: Vec, - ///The external IP addresses provided to this instance. - /// - ///By default, all instances have outbound connectivity, but no inbound - /// connectivity. These external addresses can be used to provide a - /// fixed, known IP address for making inbound connections to the - /// instance. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub external_ips: Vec, - pub hostname: String, - pub memory: ByteCount, - pub name: Name, - pub ncpus: InstanceCpuCount, - ///The network interfaces to be created for this instance. - #[serde(default = "defaults::instance_create_network_interfaces")] - pub network_interfaces: InstanceNetworkInterfaceAttachment, - ///Should this instance be started upon creation; true by default. - #[serde(default = "defaults::default_bool::")] - pub start: bool, - ///User data for instance initialization systems (such as cloud-init). - /// Must be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and - /// / characters with padding). Maximum 32 KiB unencoded data. - #[serde(default)] - pub user_data: String, - } - - impl From<&InstanceCreate> for InstanceCreate { - fn from(value: &InstanceCreate) -> Self { - value.clone() - } - } - - ///Describe the instance's disks at creation time - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum InstanceDiskAttachment { - ///During instance creation, create and attach disks - #[serde(rename = "create")] - Create { - description: String, - ///initial source for this disk - disk_source: DiskSource, - name: Name, - ///total size of the Disk in bytes - size: ByteCount, - }, - ///During instance creation, attach this disk - #[serde(rename = "attach")] - Attach { - ///A disk name to attach - name: Name, - }, - } - - impl From<&InstanceDiskAttachment> for InstanceDiskAttachment { - fn from(value: &InstanceDiskAttachment) -> Self { - value.clone() - } - } - - ///Migration parameters for an - /// [`Instance`](omicron_common::api::external::Instance) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceMigrate { - pub dst_sled_id: uuid::Uuid, - } - - impl From<&InstanceMigrate> for InstanceMigrate { - fn from(value: &InstanceMigrate) -> Self { - value.clone() - } - } - - ///Describes an attachment of a `NetworkInterface` to an `Instance`, at the - /// time the instance is created. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "params")] - pub enum InstanceNetworkInterfaceAttachment { - ///Create one or more `NetworkInterface`s for the `Instance`. - /// - ///If more than one interface is provided, then the first will be - /// designated the primary interface for the instance. - #[serde(rename = "create")] - Create(Vec), - #[serde(rename = "default")] - Default, - #[serde(rename = "none")] - None, - } - - impl From<&InstanceNetworkInterfaceAttachment> for InstanceNetworkInterfaceAttachment { - fn from(value: &InstanceNetworkInterfaceAttachment) -> Self { - value.clone() - } - } - - impl From> for InstanceNetworkInterfaceAttachment { - fn from(value: Vec) -> Self { - Self::Create(value) - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&InstanceResultsPage> for InstanceResultsPage { - fn from(value: &InstanceResultsPage) -> Self { - value.clone() - } - } - - ///Contents of an Instance's serial console buffer. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceSerialConsoleData { - ///The bytes starting from the requested offset up to either the end of - /// the buffer or the request's `max_bytes`. Provided as a u8 array - /// rather than a string, as it may not be UTF-8. - pub data: Vec, - ///The absolute offset since boot (suitable for use as `byte_offset` in - /// a subsequent request) of the last byte returned in `data`. - pub last_byte_offset: u64, - } - - impl From<&InstanceSerialConsoleData> for InstanceSerialConsoleData { - fn from(value: &InstanceSerialConsoleData) -> Self { - value.clone() - } - } - - ///Running state of an Instance (primarily: booted or stopped) - /// - ///This typically reflects whether it's starting, running, stopping, or - /// stopped, but also includes states related to the Instance's lifecycle - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum InstanceState { - ///The instance is being created. - #[serde(rename = "creating")] - Creating, - ///The instance is currently starting up. - #[serde(rename = "starting")] - Starting, - ///The instance is currently running. - #[serde(rename = "running")] - Running, - ///The instance has been requested to stop and a transition to - /// "Stopped" is imminent. - #[serde(rename = "stopping")] - Stopping, - ///The instance is currently stopped. - #[serde(rename = "stopped")] - Stopped, - ///The instance is in the process of rebooting - it will remain in the - /// "rebooting" state until the VM is starting once more. - #[serde(rename = "rebooting")] - Rebooting, - ///The instance is in the process of migrating - it will remain in the - /// "migrating" state until the migration process is complete and the - /// destination propolis is ready to continue execution. - #[serde(rename = "migrating")] - Migrating, - ///The instance is attempting to recover from a failure. - #[serde(rename = "repairing")] - Repairing, - ///The instance has encountered a failure. - #[serde(rename = "failed")] - Failed, - ///The instance has been deleted. - #[serde(rename = "destroyed")] - Destroyed, - } - - impl From<&InstanceState> for InstanceState { - fn from(value: &InstanceState) -> Self { - value.clone() - } - } - - impl ToString for InstanceState { - fn to_string(&self) -> String { - match *self { - Self::Creating => "creating".to_string(), - Self::Starting => "starting".to_string(), - Self::Running => "running".to_string(), - Self::Stopping => "stopping".to_string(), - Self::Stopped => "stopped".to_string(), - Self::Rebooting => "rebooting".to_string(), - Self::Migrating => "migrating".to_string(), - Self::Repairing => "repairing".to_string(), - Self::Failed => "failed".to_string(), - Self::Destroyed => "destroyed".to_string(), - } - } - } - - impl std::str::FromStr for InstanceState { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "creating" => Ok(Self::Creating), - "starting" => Ok(Self::Starting), - "running" => Ok(Self::Running), - "stopping" => Ok(Self::Stopping), - "stopped" => Ok(Self::Stopped), - "rebooting" => Ok(Self::Rebooting), - "migrating" => Ok(Self::Migrating), - "repairing" => Ok(Self::Repairing), - "failed" => Ok(Self::Failed), - "destroyed" => Ok(Self::Destroyed), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for InstanceState { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for InstanceState { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for InstanceState { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///The kind of an external IP address for an instance - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum IpKind { - #[serde(rename = "ephemeral")] - Ephemeral, - #[serde(rename = "floating")] - Floating, - } - - impl From<&IpKind> for IpKind { - fn from(value: &IpKind) -> Self { - value.clone() - } - } - - impl ToString for IpKind { - fn to_string(&self) -> String { - match *self { - Self::Ephemeral => "ephemeral".to_string(), - Self::Floating => "floating".to_string(), - } - } - } - - impl std::str::FromStr for IpKind { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "ephemeral" => Ok(Self::Ephemeral), - "floating" => Ok(Self::Floating), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for IpKind { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for IpKind { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for IpKind { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(untagged)] - pub enum IpNet { - V4(Ipv4Net), - V6(Ipv6Net), - } - - impl From<&IpNet> for IpNet { - fn from(value: &IpNet) -> Self { - value.clone() - } - } - - impl std::str::FromStr for IpNet { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if let Ok(v) = value.parse() { - Ok(Self::V4(v)) - } else if let Ok(v) = value.parse() { - Ok(Self::V6(v)) - } else { - Err("string conversion failed for all variants") - } - } - } - - impl std::convert::TryFrom<&str> for IpNet { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for IpNet { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for IpNet { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl ToString for IpNet { - fn to_string(&self) -> String { - match self { - Self::V4(x) => x.to_string(), - Self::V6(x) => x.to_string(), - } - } - } - - impl From for IpNet { - fn from(value: Ipv4Net) -> Self { - Self::V4(value) - } - } - - impl From for IpNet { - fn from(value: Ipv6Net) -> Self { - Self::V6(value) - } - } - - ///Identity-related metadata that's included in nearly all public API - /// objects - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPool { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&IpPool> for IpPool { - fn from(value: &IpPool) -> Self { - value.clone() - } - } - - ///Create-time parameters for an IP Pool. - /// - ///See [`IpPool`](crate::external_api::views::IpPool) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPoolCreate { - pub description: String, - pub name: Name, - } - - impl From<&IpPoolCreate> for IpPoolCreate { - fn from(value: &IpPoolCreate) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPoolRange { - pub id: uuid::Uuid, - pub range: IpRange, - pub time_created: chrono::DateTime, - } - - impl From<&IpPoolRange> for IpPoolRange { - fn from(value: &IpPoolRange) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPoolRangeResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&IpPoolRangeResultsPage> for IpPoolRangeResultsPage { - fn from(value: &IpPoolRangeResultsPage) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPoolResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&IpPoolResultsPage> for IpPoolResultsPage { - fn from(value: &IpPoolResultsPage) -> Self { - value.clone() - } - } - - ///Parameters for updating an IP Pool - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct IpPoolUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&IpPoolUpdate> for IpPoolUpdate { - fn from(value: &IpPoolUpdate) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(untagged)] - pub enum IpRange { - V4(Ipv4Range), - V6(Ipv6Range), - } - - impl From<&IpRange> for IpRange { - fn from(value: &IpRange) -> Self { - value.clone() - } - } - - impl From for IpRange { - fn from(value: Ipv4Range) -> Self { - Self::V4(value) - } - } - - impl From for IpRange { - fn from(value: Ipv6Range) -> Self { - Self::V6(value) - } - } - - ///An IPv4 subnet, including prefix and subnet mask - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct Ipv4Net(String); - impl std::ops::Deref for Ipv4Net { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: Ipv4Net) -> Self { - value.0 - } - } - - impl From<&Ipv4Net> for Ipv4Net { - fn from(value: &Ipv4Net) -> Self { - value.clone() - } - } - - impl std::str::FromStr for Ipv4Net { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if regress::Regex::new( - "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.\ - ){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/\ - ([8-9]|1[0-9]|2[0-9]|3[0-2])$", - ) - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \ - \"^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.\ - ){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/\ - ([8-9]|1[0-9]|2[0-9]|3[0-2])$\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for Ipv4Net { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for Ipv4Net { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for Ipv4Net { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for Ipv4Net { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///A non-decreasing IPv4 address range, inclusive of both ends. - /// - ///The first address must be less than or equal to the last address. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Ipv4Range { - pub first: std::net::Ipv4Addr, - pub last: std::net::Ipv4Addr, - } - - impl From<&Ipv4Range> for Ipv4Range { - fn from(value: &Ipv4Range) -> Self { - value.clone() - } - } - - ///An IPv6 subnet, including prefix and subnet mask - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct Ipv6Net(String); - impl std::ops::Deref for Ipv6Net { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: Ipv6Net) -> Self { - value.0 - } - } - - impl From<&Ipv6Net> for Ipv6Net { - fn from(value: &Ipv6Net) -> Self { - value.clone() - } - } - - impl std::str::FromStr for Ipv6Net { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if regress::Regex::new( - "^([fF][dD])[0-9a-fA-F]{2}:(([0-9a-fA-F]{1,4}:){6}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,\ - 4}:){1,6}:)\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$", - ) - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \ - \"^([fF][dD])[0-9a-fA-F]{2}:(([0-9a-fA-F]{1,4}:){6}[0-9a-fA-F]{1,\ - 4}|([0-9a-fA-F]{1,4}:){1,6}:)\\/\ - ([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for Ipv6Net { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for Ipv6Net { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for Ipv6Net { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for Ipv6Net { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///A non-decreasing IPv6 address range, inclusive of both ends. - /// - ///The first address must be less than or equal to the last address. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Ipv6Range { - pub first: std::net::Ipv6Addr, - pub last: std::net::Ipv6Addr, - } - - impl From<&Ipv6Range> for Ipv6Range { - fn from(value: &Ipv6Range) -> Self { - value.clone() - } - } - - ///An inclusive-inclusive range of IP ports. The second port may be omitted - /// to represent a single port - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct L4PortRange(String); - impl std::ops::Deref for L4PortRange { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: L4PortRange) -> Self { - value.0 - } - } - - impl From<&L4PortRange> for L4PortRange { - fn from(value: &L4PortRange) -> Self { - value.clone() - } - } - - impl std::str::FromStr for L4PortRange { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 11usize { - return Err("longer than 11 characters"); - } - if value.len() < 1usize { - return Err("shorter than 1 characters"); - } - if regress::Regex::new("^[0-9]{1,5}(-[0-9]{1,5})?$") - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \"^[0-9]{1,5}(-[0-9]{1,5})?$\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for L4PortRange { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for L4PortRange { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for L4PortRange { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for L4PortRange { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///A Media Access Control address, in EUI-48 format - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct MacAddr(String); - impl std::ops::Deref for MacAddr { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: MacAddr) -> Self { - value.0 - } - } - - impl From<&MacAddr> for MacAddr { - fn from(value: &MacAddr) -> Self { - value.clone() - } - } - - impl std::str::FromStr for MacAddr { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 17usize { - return Err("longer than 17 characters"); - } - if value.len() < 17usize { - return Err("shorter than 17 characters"); - } - if regress::Regex::new("^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$") - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for MacAddr { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for MacAddr { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for MacAddr { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for MacAddr { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///A `Measurement` is a timestamped datum from a single metric - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Measurement { - pub datum: Datum, - pub timestamp: chrono::DateTime, - } - - impl From<&Measurement> for Measurement { - fn from(value: &Measurement) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct MeasurementResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&MeasurementResultsPage> for MeasurementResultsPage { - fn from(value: &MeasurementResultsPage) -> Self { - value.clone() - } - } - - ///Names must begin with a lower case ASCII letter, be composed exclusively - /// of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end - /// with a '-'. Names cannot be a UUID though they may contain a UUID. - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct Name(String); - impl std::ops::Deref for Name { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: Name) -> Self { - value.0 - } - } - - impl From<&Name> for Name { - fn from(value: &Name) -> Self { - value.clone() - } - } - - impl std::str::FromStr for Name { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 63usize { - return Err("longer than 63 characters"); - } - if regress :: Regex :: new ("^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$") . unwrap () . find (value) . is_none () { return Err ("doesn't match pattern \"^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$\"") ; } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for Name { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for Name { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for Name { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for Name { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(untagged)] - pub enum NameOrId { - Id(uuid::Uuid), - Name(Name), - } - - impl From<&NameOrId> for NameOrId { - fn from(value: &NameOrId) -> Self { - value.clone() - } - } - - impl std::str::FromStr for NameOrId { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if let Ok(v) = value.parse() { - Ok(Self::Id(v)) - } else if let Ok(v) = value.parse() { - Ok(Self::Name(v)) - } else { - Err("string conversion failed for all variants") - } - } - } - - impl std::convert::TryFrom<&str> for NameOrId { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for NameOrId { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for NameOrId { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl ToString for NameOrId { - fn to_string(&self) -> String { - match self { - Self::Id(x) => x.to_string(), - Self::Name(x) => x.to_string(), - } - } - } - - impl From for NameOrId { - fn from(value: uuid::Uuid) -> Self { - Self::Id(value) - } - } - - impl From for NameOrId { - fn from(value: Name) -> Self { - Self::Name(value) - } - } - - ///Supported set of sort modes for scanning by name or id - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum NameOrIdSortMode { - ///sort in increasing order of "name" - #[serde(rename = "name_ascending")] - NameAscending, - ///sort in decreasing order of "name" - #[serde(rename = "name_descending")] - NameDescending, - ///sort in increasing order of "id" - #[serde(rename = "id_ascending")] - IdAscending, - } - - impl From<&NameOrIdSortMode> for NameOrIdSortMode { - fn from(value: &NameOrIdSortMode) -> Self { - value.clone() - } - } - - impl ToString for NameOrIdSortMode { - fn to_string(&self) -> String { - match *self { - Self::NameAscending => "name_ascending".to_string(), - Self::NameDescending => "name_descending".to_string(), - Self::IdAscending => "id_ascending".to_string(), - } - } - } - - impl std::str::FromStr for NameOrIdSortMode { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "name_ascending" => Ok(Self::NameAscending), - "name_descending" => Ok(Self::NameDescending), - "id_ascending" => Ok(Self::IdAscending), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for NameOrIdSortMode { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for NameOrIdSortMode { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for NameOrIdSortMode { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Supported set of sort modes for scanning by name only - /// - ///Currently, we only support scanning in ascending order. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum NameSortMode { - ///sort in increasing order of "name" - #[serde(rename = "name_ascending")] - NameAscending, - } - - impl From<&NameSortMode> for NameSortMode { - fn from(value: &NameSortMode) -> Self { - value.clone() - } - } - - impl ToString for NameSortMode { - fn to_string(&self) -> String { - match *self { - Self::NameAscending => "name_ascending".to_string(), - } - } - } - - impl std::str::FromStr for NameSortMode { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "name_ascending" => Ok(Self::NameAscending), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for NameSortMode { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for NameSortMode { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for NameSortMode { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///A `NetworkInterface` represents a virtual network interface device. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterface { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///The Instance to which the interface belongs. - pub instance_id: uuid::Uuid, - ///The IP address assigned to this interface. - pub ip: std::net::IpAddr, - ///The MAC address assigned to this interface. - pub mac: MacAddr, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///True if this interface is the primary for the instance to which it's - /// attached. - pub primary: bool, - ///The subnet to which the interface belongs. - pub subnet_id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///The VPC to which the interface belongs. - pub vpc_id: uuid::Uuid, - } - - impl From<&NetworkInterface> for NetworkInterface { - fn from(value: &NetworkInterface) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`NetworkInterface`](omicron_common::api::external::NetworkInterface) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterfaceCreate { - pub description: String, - ///The IP address for the interface. One will be auto-assigned if not - /// provided. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ip: Option, - pub name: Name, - ///The VPC Subnet in which to create the interface. - pub subnet_name: Name, - ///The VPC in which to create the interface. - pub vpc_name: Name, - } - - impl From<&NetworkInterfaceCreate> for NetworkInterfaceCreate { - fn from(value: &NetworkInterfaceCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterfaceResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&NetworkInterfaceResultsPage> for NetworkInterfaceResultsPage { - fn from(value: &NetworkInterfaceResultsPage) -> Self { - value.clone() - } - } - - ///Parameters for updating a - /// [`NetworkInterface`](omicron_common::api::external::NetworkInterface). - /// - ///Note that modifying IP addresses for an interface is not yet supported, - /// a new interface must be created instead. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterfaceUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - ///Make a secondary interface the instance's primary interface. - /// - ///If applied to a secondary interface, that interface will become the - /// primary on the next reboot of the instance. Note that this may have - /// implications for routing between instances, as the new primary - /// interface will be on a distinct subnet from the previous primary - /// interface. - /// - ///Note that this can only be used to select a new primary interface - /// for an instance. Requests to change the primary interface into a - /// secondary will return an error. - #[serde(default)] - pub primary: bool, - } - - impl From<&NetworkInterfaceUpdate> for NetworkInterfaceUpdate { - fn from(value: &NetworkInterfaceUpdate) -> Self { - value.clone() - } - } - - ///Unique name for a saga [`Node`] - /// - ///Each node requires a string name that's unique within its DAG. The name - /// is used to identify its output. Nodes that depend on a given node - /// (either directly or indirectly) can access the node's output using its - /// name. - #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct NodeName(pub String); - impl std::ops::Deref for NodeName { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: NodeName) -> Self { - value.0 - } - } - - impl From<&NodeName> for NodeName { - fn from(value: &NodeName) -> Self { - value.clone() - } - } - - impl From for NodeName { - fn from(value: String) -> Self { - Self(value) - } - } - - impl std::str::FromStr for NodeName { - type Err = std::convert::Infallible; - fn from_str(value: &str) -> Result { - Ok(Self(value.to_string())) - } - } - - impl ToString for NodeName { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - ///Client view of an [`Organization`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Organization { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Organization> for Organization { - fn from(value: &Organization) -> Self { - value.clone() - } - } - - ///Create-time parameters for an - /// [`Organization`](crate::external_api::views::Organization) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct OrganizationCreate { - pub description: String, - pub name: Name, - } - - impl From<&OrganizationCreate> for OrganizationCreate { - fn from(value: &OrganizationCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct OrganizationResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&OrganizationResultsPage> for OrganizationResultsPage { - fn from(value: &OrganizationResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum OrganizationRole { - #[serde(rename = "admin")] - Admin, - #[serde(rename = "collaborator")] - Collaborator, - #[serde(rename = "viewer")] - Viewer, - } - - impl From<&OrganizationRole> for OrganizationRole { - fn from(value: &OrganizationRole) -> Self { - value.clone() - } - } - - impl ToString for OrganizationRole { - fn to_string(&self) -> String { - match *self { - Self::Admin => "admin".to_string(), - Self::Collaborator => "collaborator".to_string(), - Self::Viewer => "viewer".to_string(), - } - } - } - - impl std::str::FromStr for OrganizationRole { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "admin" => Ok(Self::Admin), - "collaborator" => Ok(Self::Collaborator), - "viewer" => Ok(Self::Viewer), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for OrganizationRole { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for OrganizationRole { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for OrganizationRole { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`Policy`], which describes how this resource may be - /// accessed - /// - ///Note that the Policy only describes access granted explicitly for this - /// resource. The policies of parent resources can also cause a user to - /// have access to this resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct OrganizationRolePolicy { - ///Roles directly assigned on this resource - pub role_assignments: Vec, - } - - impl From<&OrganizationRolePolicy> for OrganizationRolePolicy { - fn from(value: &OrganizationRolePolicy) -> Self { - value.clone() - } - } - - ///Describes the assignment of a particular role on a particular resource - /// to a particular identity (user, group, etc.) - /// - ///The resource is not part of this structure. Rather, [`RoleAssignment`]s - /// are put into a [`Policy`] and that Policy is applied to a particular - /// resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct OrganizationRoleRoleAssignment { - pub identity_id: uuid::Uuid, - pub identity_type: IdentityType, - pub role_name: OrganizationRole, - } - - impl From<&OrganizationRoleRoleAssignment> for OrganizationRoleRoleAssignment { - fn from(value: &OrganizationRoleRoleAssignment) -> Self { - value.clone() - } - } - - ///Updateable properties of an - /// [`Organization`](crate::external_api::views::Organization) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct OrganizationUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&OrganizationUpdate> for OrganizationUpdate { - fn from(value: &OrganizationUpdate) -> Self { - value.clone() - } - } - - ///Passwords may be subject to additional constraints. - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct Password(String); - impl std::ops::Deref for Password { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: Password) -> Self { - value.0 - } - } - - impl From<&Password> for Password { - fn from(value: &Password) -> Self { - value.clone() - } - } - - impl std::str::FromStr for Password { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 512usize { - return Err("longer than 512 characters"); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for Password { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for Password { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for Password { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for Password { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///Client view of a [`PhysicalDisk`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct PhysicalDisk { - pub disk_type: PhysicalDiskType, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - pub model: String, - pub serial: String, - ///The sled to which this disk is attached, if any. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub sled_id: Option, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub vendor: String, - } - - impl From<&PhysicalDisk> for PhysicalDisk { - fn from(value: &PhysicalDisk) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct PhysicalDiskResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&PhysicalDiskResultsPage> for PhysicalDiskResultsPage { - fn from(value: &PhysicalDiskResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum PhysicalDiskType { - #[serde(rename = "internal")] - Internal, - #[serde(rename = "external")] - External, - } - - impl From<&PhysicalDiskType> for PhysicalDiskType { - fn from(value: &PhysicalDiskType) -> Self { - value.clone() - } - } - - impl ToString for PhysicalDiskType { - fn to_string(&self) -> String { - match *self { - Self::Internal => "internal".to_string(), - Self::External => "external".to_string(), - } - } - } - - impl std::str::FromStr for PhysicalDiskType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "internal" => Ok(Self::Internal), - "external" => Ok(Self::External), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for PhysicalDiskType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for PhysicalDiskType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for PhysicalDiskType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`Project`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Project { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - pub organization_id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Project> for Project { - fn from(value: &Project) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`Project`](crate::external_api::views::Project) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ProjectCreate { - pub description: String, - pub name: Name, - } - - impl From<&ProjectCreate> for ProjectCreate { - fn from(value: &ProjectCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ProjectResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&ProjectResultsPage> for ProjectResultsPage { - fn from(value: &ProjectResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum ProjectRole { - #[serde(rename = "admin")] - Admin, - #[serde(rename = "collaborator")] - Collaborator, - #[serde(rename = "viewer")] - Viewer, - } - - impl From<&ProjectRole> for ProjectRole { - fn from(value: &ProjectRole) -> Self { - value.clone() - } - } - - impl ToString for ProjectRole { - fn to_string(&self) -> String { - match *self { - Self::Admin => "admin".to_string(), - Self::Collaborator => "collaborator".to_string(), - Self::Viewer => "viewer".to_string(), - } - } - } - - impl std::str::FromStr for ProjectRole { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "admin" => Ok(Self::Admin), - "collaborator" => Ok(Self::Collaborator), - "viewer" => Ok(Self::Viewer), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for ProjectRole { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for ProjectRole { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for ProjectRole { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`Policy`], which describes how this resource may be - /// accessed - /// - ///Note that the Policy only describes access granted explicitly for this - /// resource. The policies of parent resources can also cause a user to - /// have access to this resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ProjectRolePolicy { - ///Roles directly assigned on this resource - pub role_assignments: Vec, - } - - impl From<&ProjectRolePolicy> for ProjectRolePolicy { - fn from(value: &ProjectRolePolicy) -> Self { - value.clone() - } - } - - ///Describes the assignment of a particular role on a particular resource - /// to a particular identity (user, group, etc.) - /// - ///The resource is not part of this structure. Rather, [`RoleAssignment`]s - /// are put into a [`Policy`] and that Policy is applied to a particular - /// resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ProjectRoleRoleAssignment { - pub identity_id: uuid::Uuid, - pub identity_type: IdentityType, - pub role_name: ProjectRole, - } - - impl From<&ProjectRoleRoleAssignment> for ProjectRoleRoleAssignment { - fn from(value: &ProjectRoleRoleAssignment) -> Self { - value.clone() - } - } - - ///Updateable properties of a - /// [`Project`](crate::external_api::views::Project) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct ProjectUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&ProjectUpdate> for ProjectUpdate { - fn from(value: &ProjectUpdate) -> Self { - value.clone() - } - } - - ///Client view of an [`Rack`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Rack { - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Rack> for Rack { - fn from(value: &Rack) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RackResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&RackResultsPage> for RackResultsPage { - fn from(value: &RackResultsPage) -> Self { - value.clone() - } - } - - ///Client view of a [`Role`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Role { - pub description: String, - pub name: RoleName, - } - - impl From<&Role> for Role { - fn from(value: &Role) -> Self { - value.clone() - } - } - - ///Role names consist of two string components separated by dot ("."). - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct RoleName(String); - impl std::ops::Deref for RoleName { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: RoleName) -> Self { - value.0 - } - } - - impl From<&RoleName> for RoleName { - fn from(value: &RoleName) -> Self { - value.clone() - } - } - - impl std::str::FromStr for RoleName { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 63usize { - return Err("longer than 63 characters"); - } - if regress::Regex::new("[a-z-]+\\.[a-z-]+") - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \"[a-z-]+\\.[a-z-]+\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for RoleName { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for RoleName { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for RoleName { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for RoleName { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RoleResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&RoleResultsPage> for RoleResultsPage { - fn from(value: &RoleResultsPage) -> Self { - value.clone() - } - } - - ///A `RouteDestination` is used to match traffic with a routing rule, on - /// the destination of that traffic. - /// - ///When traffic is to be sent to a destination that is within a given - /// `RouteDestination`, the corresponding [`RouterRoute`] applies, and - /// traffic will be forward to the [`RouteTarget`] for that rule. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "value")] - pub enum RouteDestination { - ///Route applies to traffic destined for a specific IP address - #[serde(rename = "ip")] - Ip(std::net::IpAddr), - ///Route applies to traffic destined for a specific IP subnet - #[serde(rename = "ip_net")] - IpNet(IpNet), - ///Route applies to traffic destined for the given VPC. - #[serde(rename = "vpc")] - Vpc(Name), - ///Route applies to traffic - #[serde(rename = "subnet")] - Subnet(Name), - } - - impl From<&RouteDestination> for RouteDestination { - fn from(value: &RouteDestination) -> Self { - value.clone() - } - } - - impl From for RouteDestination { - fn from(value: std::net::IpAddr) -> Self { - Self::Ip(value) - } - } - - impl From for RouteDestination { - fn from(value: IpNet) -> Self { - Self::IpNet(value) - } - } - - ///A `RouteTarget` describes the possible locations that traffic matching a - /// route destination can be sent. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "value")] - pub enum RouteTarget { - ///Forward traffic to a particular IP address. - #[serde(rename = "ip")] - Ip(std::net::IpAddr), - ///Forward traffic to a VPC - #[serde(rename = "vpc")] - Vpc(Name), - ///Forward traffic to a VPC Subnet - #[serde(rename = "subnet")] - Subnet(Name), - ///Forward traffic to a specific instance - #[serde(rename = "instance")] - Instance(Name), - ///Forward traffic to an internet gateway - #[serde(rename = "internet_gateway")] - InternetGateway(Name), - } - - impl From<&RouteTarget> for RouteTarget { - fn from(value: &RouteTarget) -> Self { - value.clone() - } - } - - impl From for RouteTarget { - fn from(value: std::net::IpAddr) -> Self { - Self::Ip(value) - } - } - - ///A route defines a rule that governs where traffic should be sent based - /// on its destination. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RouterRoute { - ///human-readable free-form text about a resource - pub description: String, - pub destination: RouteDestination, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///Describes the kind of router. Set at creation. `read-only` - pub kind: RouterRouteKind, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - pub target: RouteTarget, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///The VPC Router to which the route belongs. - pub vpc_router_id: uuid::Uuid, - } - - impl From<&RouterRoute> for RouterRoute { - fn from(value: &RouterRoute) -> Self { - value.clone() - } - } - - ///Create-time parameters for a [`RouterRoute`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RouterRouteCreateParams { - pub description: String, - pub destination: RouteDestination, - pub name: Name, - pub target: RouteTarget, - } - - impl From<&RouterRouteCreateParams> for RouterRouteCreateParams { - fn from(value: &RouterRouteCreateParams) -> Self { - value.clone() - } - } - - ///The classification of a [`RouterRoute`] as defined by the system. The - /// kind determines certain attributes such as if the route is modifiable - /// and describes how or where the route was created. - /// - ///See [RFD-21](https://rfd.shared.oxide.computer/rfd/0021#concept-router) for more context - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum RouterRouteKind { - ///Determines the default destination of traffic, such as whether it - /// goes to the internet or not. - /// - ///`Destination: An Internet Gateway` `Modifiable: true` - #[serde(rename = "default")] - Default, - ///Automatically added for each VPC Subnet in the VPC - /// - ///`Destination: A VPC Subnet` `Modifiable: false` - #[serde(rename = "vpc_subnet")] - VpcSubnet, - ///Automatically added when VPC peering is established - /// - ///`Destination: A different VPC` `Modifiable: false` - #[serde(rename = "vpc_peering")] - VpcPeering, - ///Created by a user See [`RouteTarget`] - /// - ///`Destination: User defined` `Modifiable: true` - #[serde(rename = "custom")] - Custom, - } - - impl From<&RouterRouteKind> for RouterRouteKind { - fn from(value: &RouterRouteKind) -> Self { - value.clone() - } - } - - impl ToString for RouterRouteKind { - fn to_string(&self) -> String { - match *self { - Self::Default => "default".to_string(), - Self::VpcSubnet => "vpc_subnet".to_string(), - Self::VpcPeering => "vpc_peering".to_string(), - Self::Custom => "custom".to_string(), - } - } - } - - impl std::str::FromStr for RouterRouteKind { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "default" => Ok(Self::Default), - "vpc_subnet" => Ok(Self::VpcSubnet), - "vpc_peering" => Ok(Self::VpcPeering), - "custom" => Ok(Self::Custom), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for RouterRouteKind { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for RouterRouteKind { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for RouterRouteKind { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RouterRouteResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&RouterRouteResultsPage> for RouterRouteResultsPage { - fn from(value: &RouterRouteResultsPage) -> Self { - value.clone() - } - } - - ///Updateable properties of a [`RouterRoute`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct RouterRouteUpdateParams { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - pub destination: RouteDestination, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - pub target: RouteTarget, - } - - impl From<&RouterRouteUpdateParams> for RouterRouteUpdateParams { - fn from(value: &RouterRouteUpdateParams) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Saga { - pub id: uuid::Uuid, - pub state: SagaState, - } - - impl From<&Saga> for Saga { - fn from(value: &Saga) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "error")] - pub enum SagaErrorInfo { - #[serde(rename = "action_failed")] - ActionFailed { source_error: serde_json::Value }, - #[serde(rename = "deserialize_failed")] - DeserializeFailed { message: String }, - #[serde(rename = "injected_error")] - InjectedError, - #[serde(rename = "serialize_failed")] - SerializeFailed { message: String }, - #[serde(rename = "subsaga_create_failed")] - SubsagaCreateFailed { message: String }, - } - - impl From<&SagaErrorInfo> for SagaErrorInfo { - fn from(value: &SagaErrorInfo) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SagaResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SagaResultsPage> for SagaResultsPage { - fn from(value: &SagaResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "state")] - pub enum SagaState { - #[serde(rename = "running")] - Running, - #[serde(rename = "succeeded")] - Succeeded, - #[serde(rename = "failed")] - Failed { - error_info: SagaErrorInfo, - error_node_name: NodeName, - }, - } - - impl From<&SagaState> for SagaState { - fn from(value: &SagaState) -> Self { - value.clone() - } - } - - ///Identity-related metadata that's included in nearly all public API - /// objects - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SamlIdentityProvider { - ///service provider endpoint where the response will be sent - pub acs_url: String, - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///idp's entity id - pub idp_entity_id: String, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///optional request signing public certificate (base64 encoded der - /// file) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub public_cert: Option, - ///service provider endpoint where the idp should send log out requests - pub slo_url: String, - ///sp's client id - pub sp_client_id: String, - ///customer's technical contact for saml configuration - pub technical_contact_email: String, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&SamlIdentityProvider> for SamlIdentityProvider { - fn from(value: &SamlIdentityProvider) -> Self { - value.clone() - } - } - - ///Create-time identity-related parameters - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SamlIdentityProviderCreate { - ///service provider endpoint where the response will be sent - pub acs_url: String, - pub description: String, - ///If set, SAML attributes with this name will be considered to denote - /// a user's group membership, where the attribute value(s) should be a - /// comma-separated list of group names. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub group_attribute_name: Option, - ///idp's entity id - pub idp_entity_id: String, - ///the source of an identity provider metadata descriptor - pub idp_metadata_source: IdpMetadataSource, - pub name: Name, - ///optional request signing key pair - #[serde(default, skip_serializing_if = "Option::is_none")] - pub signing_keypair: Option, - ///service provider endpoint where the idp should send log out requests - pub slo_url: String, - ///sp's client id - pub sp_client_id: String, - ///customer's technical contact for saml configuration - pub technical_contact_email: String, - } - - impl From<&SamlIdentityProviderCreate> for SamlIdentityProviderCreate { - fn from(value: &SamlIdentityProviderCreate) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct SemverVersion(String); - impl std::ops::Deref for SemverVersion { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: SemverVersion) -> Self { - value.0 - } - } - - impl From<&SemverVersion> for SemverVersion { - fn from(value: &SemverVersion) -> Self { - value.clone() - } - } - - impl std::str::FromStr for SemverVersion { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if regress::Regex::new("^\\d+\\.\\d+\\.\\d+([\\-\\+].+)?$") - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \"^\\d+\\.\\d+\\.\\d+([\\-\\+].+)?$\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for SemverVersion { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for SemverVersion { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for SemverVersion { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for SemverVersion { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///The service intended to use this certificate. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum ServiceUsingCertificate { - ///This certificate is intended for access to the external API. - #[serde(rename = "external_api")] - ExternalApi, - } - - impl From<&ServiceUsingCertificate> for ServiceUsingCertificate { - fn from(value: &ServiceUsingCertificate) -> Self { - value.clone() - } - } - - impl ToString for ServiceUsingCertificate { - fn to_string(&self) -> String { - match *self { - Self::ExternalApi => "external_api".to_string(), - } - } - } - - impl std::str::FromStr for ServiceUsingCertificate { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "external_api" => Ok(Self::ExternalApi), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for ServiceUsingCertificate { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for ServiceUsingCertificate { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for ServiceUsingCertificate { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a ['Silo'] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Silo { - ///human-readable free-form text about a resource - pub description: String, - ///A silo where discoverable is false can be retrieved only by its id - - /// it will not be part of the "list all silos" output. - pub discoverable: bool, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///How users and groups are managed in this Silo - pub identity_mode: SiloIdentityMode, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Silo> for Silo { - fn from(value: &Silo) -> Self { - value.clone() - } - } - - ///Create-time parameters for a [`Silo`](crate::external_api::views::Silo) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SiloCreate { - ///If set, this group will be created during Silo creation and granted - /// the "Silo Admin" role. Identity providers can assert that users - /// belong to this group and those users can log in and further - /// initialize the Silo. - /// - ///Note that if configuring a SAML based identity provider, - /// group_attribute_name must be set for users to be considered part of - /// a group. See [`SamlIdentityProviderCreate`] for more information. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub admin_group_name: Option, - pub description: String, - pub discoverable: bool, - pub identity_mode: SiloIdentityMode, - pub name: Name, - } - - impl From<&SiloCreate> for SiloCreate { - fn from(value: &SiloCreate) -> Self { - value.clone() - } - } - - ///Describes how identities are managed and users are authenticated in this - /// Silo - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum SiloIdentityMode { - ///Users are authenticated with SAML using an external authentication - /// provider. The system updates information about users and groups - /// only during successful authentication (i.e,. "JIT provisioning" of - /// users and groups). - #[serde(rename = "saml_jit")] - SamlJit, - ///The system is the source of truth about users. There is no linkage - /// to an external authentication provider or identity provider. - #[serde(rename = "local_only")] - LocalOnly, - } - - impl From<&SiloIdentityMode> for SiloIdentityMode { - fn from(value: &SiloIdentityMode) -> Self { - value.clone() - } - } - - impl ToString for SiloIdentityMode { - fn to_string(&self) -> String { - match *self { - Self::SamlJit => "saml_jit".to_string(), - Self::LocalOnly => "local_only".to_string(), - } - } - } - - impl std::str::FromStr for SiloIdentityMode { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "saml_jit" => Ok(Self::SamlJit), - "local_only" => Ok(Self::LocalOnly), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for SiloIdentityMode { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for SiloIdentityMode { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for SiloIdentityMode { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SiloResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SiloResultsPage> for SiloResultsPage { - fn from(value: &SiloResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum SiloRole { - #[serde(rename = "admin")] - Admin, - #[serde(rename = "collaborator")] - Collaborator, - #[serde(rename = "viewer")] - Viewer, - } - - impl From<&SiloRole> for SiloRole { - fn from(value: &SiloRole) -> Self { - value.clone() - } - } - - impl ToString for SiloRole { - fn to_string(&self) -> String { - match *self { - Self::Admin => "admin".to_string(), - Self::Collaborator => "collaborator".to_string(), - Self::Viewer => "viewer".to_string(), - } - } - } - - impl std::str::FromStr for SiloRole { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "admin" => Ok(Self::Admin), - "collaborator" => Ok(Self::Collaborator), - "viewer" => Ok(Self::Viewer), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for SiloRole { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for SiloRole { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for SiloRole { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`Policy`], which describes how this resource may be - /// accessed - /// - ///Note that the Policy only describes access granted explicitly for this - /// resource. The policies of parent resources can also cause a user to - /// have access to this resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SiloRolePolicy { - ///Roles directly assigned on this resource - pub role_assignments: Vec, - } - - impl From<&SiloRolePolicy> for SiloRolePolicy { - fn from(value: &SiloRolePolicy) -> Self { - value.clone() - } - } - - ///Describes the assignment of a particular role on a particular resource - /// to a particular identity (user, group, etc.) - /// - ///The resource is not part of this structure. Rather, [`RoleAssignment`]s - /// are put into a [`Policy`] and that Policy is applied to a particular - /// resource. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SiloRoleRoleAssignment { - pub identity_id: uuid::Uuid, - pub identity_type: IdentityType, - pub role_name: SiloRole, - } - - impl From<&SiloRoleRoleAssignment> for SiloRoleRoleAssignment { - fn from(value: &SiloRoleRoleAssignment) -> Self { - value.clone() - } - } - - ///Client view of a [`Sled`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Sled { - pub baseboard: Baseboard, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - pub service_address: String, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Sled> for Sled { - fn from(value: &Sled) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SledResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SledResultsPage> for SledResultsPage { - fn from(value: &SledResultsPage) -> Self { - value.clone() - } - } - - ///Client view of a Snapshot - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Snapshot { - ///human-readable free-form text about a resource - pub description: String, - pub disk_id: uuid::Uuid, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - pub project_id: uuid::Uuid, - pub size: ByteCount, - pub state: SnapshotState, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Snapshot> for Snapshot { - fn from(value: &Snapshot) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`Snapshot`](crate::external_api::views::Snapshot) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SnapshotCreate { - pub description: String, - ///The name of the disk to be snapshotted - pub disk: Name, - pub name: Name, - } - - impl From<&SnapshotCreate> for SnapshotCreate { - fn from(value: &SnapshotCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SnapshotResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SnapshotResultsPage> for SnapshotResultsPage { - fn from(value: &SnapshotResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum SnapshotState { - #[serde(rename = "creating")] - Creating, - #[serde(rename = "ready")] - Ready, - #[serde(rename = "faulted")] - Faulted, - #[serde(rename = "destroyed")] - Destroyed, - } - - impl From<&SnapshotState> for SnapshotState { - fn from(value: &SnapshotState) -> Self { - value.clone() - } - } - - impl ToString for SnapshotState { - fn to_string(&self) -> String { - match *self { - Self::Creating => "creating".to_string(), - Self::Ready => "ready".to_string(), - Self::Faulted => "faulted".to_string(), - Self::Destroyed => "destroyed".to_string(), - } - } - } - - impl std::str::FromStr for SnapshotState { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "creating" => Ok(Self::Creating), - "ready" => Ok(Self::Ready), - "faulted" => Ok(Self::Faulted), - "destroyed" => Ok(Self::Destroyed), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for SnapshotState { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for SnapshotState { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for SnapshotState { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SpoofLoginBody { - pub username: String, - } - - impl From<&SpoofLoginBody> for SpoofLoginBody { - fn from(value: &SpoofLoginBody) -> Self { - value.clone() - } - } - - ///Client view of a [`SshKey`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SshKey { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///SSH public key, e.g., `"ssh-ed25519 AAAAC3NzaC..."` - pub public_key: String, - ///The user to whom this key belongs - pub silo_user_id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&SshKey> for SshKey { - fn from(value: &SshKey) -> Self { - value.clone() - } - } - - ///Create-time parameters for an - /// [`SshKey`](crate::external_api::views::SshKey) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SshKeyCreate { - pub description: String, - pub name: Name, - ///SSH public key, e.g., `"ssh-ed25519 AAAAC3NzaC..."` - pub public_key: String, - } - - impl From<&SshKeyCreate> for SshKeyCreate { - fn from(value: &SshKeyCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SshKeyResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SshKeyResultsPage> for SshKeyResultsPage { - fn from(value: &SshKeyResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum SystemMetricName { - #[serde(rename = "virtual_disk_space_provisioned")] - VirtualDiskSpaceProvisioned, - #[serde(rename = "cpus_provisioned")] - CpusProvisioned, - #[serde(rename = "ram_provisioned")] - RamProvisioned, - } - - impl From<&SystemMetricName> for SystemMetricName { - fn from(value: &SystemMetricName) -> Self { - value.clone() - } - } - - impl ToString for SystemMetricName { - fn to_string(&self) -> String { - match *self { - Self::VirtualDiskSpaceProvisioned => "virtual_disk_space_provisioned".to_string(), - Self::CpusProvisioned => "cpus_provisioned".to_string(), - Self::RamProvisioned => "ram_provisioned".to_string(), - } - } - } - - impl std::str::FromStr for SystemMetricName { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "virtual_disk_space_provisioned" => Ok(Self::VirtualDiskSpaceProvisioned), - "cpus_provisioned" => Ok(Self::CpusProvisioned), - "ram_provisioned" => Ok(Self::RamProvisioned), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for SystemMetricName { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for SystemMetricName { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for SystemMetricName { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Identity-related metadata that's included in "asset" public API objects - /// (which generally have no name or description) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SystemUpdate { - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub version: SemverVersion, - } - - impl From<&SystemUpdate> for SystemUpdate { - fn from(value: &SystemUpdate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SystemUpdateResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&SystemUpdateResultsPage> for SystemUpdateResultsPage { - fn from(value: &SystemUpdateResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SystemUpdateStart { - pub version: SemverVersion, - } - - impl From<&SystemUpdateStart> for SystemUpdateStart { - fn from(value: &SystemUpdateStart) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct SystemVersion { - pub status: UpdateStatus, - pub version_range: VersionRange, - } - - impl From<&SystemVersion> for SystemVersion { - fn from(value: &SystemVersion) -> Self { - value.clone() - } - } - - ///Names are constructed by concatenating the target and metric names with - /// ':'. Target and metric names must be lowercase alphanumeric characters - /// with '_' separating words. - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct TimeseriesName(String); - impl std::ops::Deref for TimeseriesName { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: TimeseriesName) -> Self { - value.0 - } - } - - impl From<&TimeseriesName> for TimeseriesName { - fn from(value: &TimeseriesName) -> Self { - value.clone() - } - } - - impl std::str::FromStr for TimeseriesName { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if regress::Regex::new( - "(([a-z]+[a-z0-9]*)(_([a-z0-9]+))*):(([a-z]+[a-z0-9]*)(_([a-z0-9]+))*)", - ) - .unwrap() - .find(value) - .is_none() - { - return Err("doesn't match pattern \ - \"(([a-z]+[a-z0-9]*)(_([a-z0-9]+))*):(([a-z]+[a-z0-9]*\ - )(_([a-z0-9]+))*)\""); - } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for TimeseriesName { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for TimeseriesName { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for TimeseriesName { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for TimeseriesName { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///The schema for a timeseries. - /// - ///This includes the name of the timeseries, as well as the datum type of - /// its metric and the schema for each field. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TimeseriesSchema { - pub created: chrono::DateTime, - pub datum_type: DatumType, - pub field_schema: Vec, - pub timeseries_name: TimeseriesName, - } - - impl From<&TimeseriesSchema> for TimeseriesSchema { - fn from(value: &TimeseriesSchema) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct TimeseriesSchemaResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&TimeseriesSchemaResultsPage> for TimeseriesSchemaResultsPage { - fn from(value: &TimeseriesSchemaResultsPage) -> Self { - value.clone() - } - } - - ///Identity-related metadata that's included in "asset" public API objects - /// (which generally have no name or description) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UpdateDeployment { - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - pub status: UpdateStatus, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub version: SemverVersion, - } - - impl From<&UpdateDeployment> for UpdateDeployment { - fn from(value: &UpdateDeployment) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UpdateDeploymentResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&UpdateDeploymentResultsPage> for UpdateDeploymentResultsPage { - fn from(value: &UpdateDeploymentResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - #[serde(tag = "status")] - pub enum UpdateStatus { - #[serde(rename = "updating")] - Updating, - #[serde(rename = "steady")] - Steady, - } - - impl From<&UpdateStatus> for UpdateStatus { - fn from(value: &UpdateStatus) -> Self { - value.clone() - } - } - - impl ToString for UpdateStatus { - fn to_string(&self) -> String { - match *self { - Self::Updating => "updating".to_string(), - Self::Steady => "steady".to_string(), - } - } - } - - impl std::str::FromStr for UpdateStatus { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "updating" => Ok(Self::Updating), - "steady" => Ok(Self::Steady), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for UpdateStatus { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for UpdateStatus { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for UpdateStatus { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Identity-related metadata that's included in "asset" public API objects - /// (which generally have no name or description) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UpdateableComponent { - pub component_type: UpdateableComponentType, - pub device_id: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - pub status: UpdateStatus, - pub system_version: SemverVersion, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - pub version: SemverVersion, - } - - impl From<&UpdateableComponent> for UpdateableComponent { - fn from(value: &UpdateableComponent) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UpdateableComponentResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&UpdateableComponentResultsPage> for UpdateableComponentResultsPage { - fn from(value: &UpdateableComponentResultsPage) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum UpdateableComponentType { - #[serde(rename = "bootloader_for_rot")] - BootloaderForRot, - #[serde(rename = "bootloader_for_sp")] - BootloaderForSp, - #[serde(rename = "bootloader_for_host_proc")] - BootloaderForHostProc, - #[serde(rename = "hubris_for_psc_rot")] - HubrisForPscRot, - #[serde(rename = "hubris_for_psc_sp")] - HubrisForPscSp, - #[serde(rename = "hubris_for_sidecar_rot")] - HubrisForSidecarRot, - #[serde(rename = "hubris_for_sidecar_sp")] - HubrisForSidecarSp, - #[serde(rename = "hubris_for_gimlet_rot")] - HubrisForGimletRot, - #[serde(rename = "hubris_for_gimlet_sp")] - HubrisForGimletSp, - #[serde(rename = "helios_host_phase1")] - HeliosHostPhase1, - #[serde(rename = "helios_host_phase2")] - HeliosHostPhase2, - #[serde(rename = "host_omicron")] - HostOmicron, - } - - impl From<&UpdateableComponentType> for UpdateableComponentType { - fn from(value: &UpdateableComponentType) -> Self { - value.clone() - } - } - - impl ToString for UpdateableComponentType { - fn to_string(&self) -> String { - match *self { - Self::BootloaderForRot => "bootloader_for_rot".to_string(), - Self::BootloaderForSp => "bootloader_for_sp".to_string(), - Self::BootloaderForHostProc => "bootloader_for_host_proc".to_string(), - Self::HubrisForPscRot => "hubris_for_psc_rot".to_string(), - Self::HubrisForPscSp => "hubris_for_psc_sp".to_string(), - Self::HubrisForSidecarRot => "hubris_for_sidecar_rot".to_string(), - Self::HubrisForSidecarSp => "hubris_for_sidecar_sp".to_string(), - Self::HubrisForGimletRot => "hubris_for_gimlet_rot".to_string(), - Self::HubrisForGimletSp => "hubris_for_gimlet_sp".to_string(), - Self::HeliosHostPhase1 => "helios_host_phase1".to_string(), - Self::HeliosHostPhase2 => "helios_host_phase2".to_string(), - Self::HostOmicron => "host_omicron".to_string(), - } - } - } - - impl std::str::FromStr for UpdateableComponentType { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "bootloader_for_rot" => Ok(Self::BootloaderForRot), - "bootloader_for_sp" => Ok(Self::BootloaderForSp), - "bootloader_for_host_proc" => Ok(Self::BootloaderForHostProc), - "hubris_for_psc_rot" => Ok(Self::HubrisForPscRot), - "hubris_for_psc_sp" => Ok(Self::HubrisForPscSp), - "hubris_for_sidecar_rot" => Ok(Self::HubrisForSidecarRot), - "hubris_for_sidecar_sp" => Ok(Self::HubrisForSidecarSp), - "hubris_for_gimlet_rot" => Ok(Self::HubrisForGimletRot), - "hubris_for_gimlet_sp" => Ok(Self::HubrisForGimletSp), - "helios_host_phase1" => Ok(Self::HeliosHostPhase1), - "helios_host_phase2" => Ok(Self::HeliosHostPhase2), - "host_omicron" => Ok(Self::HostOmicron), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for UpdateableComponentType { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for UpdateableComponentType { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for UpdateableComponentType { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Client view of a [`User`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct User { - ///Human-readable name that can identify the user - pub display_name: String, - pub id: uuid::Uuid, - ///Uuid of the silo to which this user belongs - pub silo_id: uuid::Uuid, - } - - impl From<&User> for User { - fn from(value: &User) -> Self { - value.clone() - } - } - - ///Client view of a [`UserBuiltin`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserBuiltin { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&UserBuiltin> for UserBuiltin { - fn from(value: &UserBuiltin) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserBuiltinResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&UserBuiltinResultsPage> for UserBuiltinResultsPage { - fn from(value: &UserBuiltinResultsPage) -> Self { - value.clone() - } - } - - ///Create-time parameters for a [`User`](crate::external_api::views::User) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserCreate { - ///username used to log in - pub external_id: UserId, - ///password used to log in - pub password: UserPassword, - } - - impl From<&UserCreate> for UserCreate { - fn from(value: &UserCreate) -> Self { - value.clone() - } - } - - ///Names must begin with a lower case ASCII letter, be composed exclusively - /// of lowercase ASCII, uppercase ASCII, numbers, and '-', and may not end - /// with a '-'. Names cannot be a UUID though they may contain a UUID. - #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub struct UserId(String); - impl std::ops::Deref for UserId { - type Target = String; - fn deref(&self) -> &String { - &self.0 - } - } - - impl From for String { - fn from(value: UserId) -> Self { - value.0 - } - } - - impl From<&UserId> for UserId { - fn from(value: &UserId) -> Self { - value.clone() - } - } - - impl std::str::FromStr for UserId { - type Err = &'static str; - fn from_str(value: &str) -> Result { - if value.len() > 63usize { - return Err("longer than 63 characters"); - } - if regress :: Regex :: new ("^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$") . unwrap () . find (value) . is_none () { return Err ("doesn't match pattern \"^(?![0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)^[a-z][a-z0-9-]*[a-zA-Z0-9]$\"") ; } - Ok(Self(value.to_string())) - } - } - - impl std::convert::TryFrom<&str> for UserId { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for UserId { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for UserId { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl<'de> serde::Deserialize<'de> for UserId { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - String::deserialize(deserializer)? - .parse() - .map_err(|e: &'static str| ::custom(e.to_string())) - } - } - - ///Parameters for setting a user's password - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "user_password_value", content = "details")] - pub enum UserPassword { - ///Sets the user's password to the provided value - #[serde(rename = "password")] - Password(Password), - #[serde(rename = "invalid_password")] - InvalidPassword, - } - - impl From<&UserPassword> for UserPassword { - fn from(value: &UserPassword) -> Self { - value.clone() - } - } - - impl From for UserPassword { - fn from(value: Password) -> Self { - Self::Password(value) - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UserResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&UserResultsPage> for UserResultsPage { - fn from(value: &UserResultsPage) -> Self { - value.clone() - } - } - - ///Credentials for local user login - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct UsernamePasswordCredentials { - pub password: Password, - pub username: UserId, - } - - impl From<&UsernamePasswordCredentials> for UsernamePasswordCredentials { - fn from(value: &UsernamePasswordCredentials) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VersionRange { - pub high: SemverVersion, - pub low: SemverVersion, - } - - impl From<&VersionRange> for VersionRange { - fn from(value: &VersionRange) -> Self { - value.clone() - } - } - - ///Client view of a [`Vpc`] - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Vpc { - ///human-readable free-form text about a resource - pub description: String, - ///The name used for the VPC in DNS. - pub dns_name: Name, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///The unique local IPv6 address range for subnets in this VPC - pub ipv6_prefix: Ipv6Net, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///id for the project containing this VPC - pub project_id: uuid::Uuid, - ///id for the system router where subnet default routes are registered - pub system_router_id: uuid::Uuid, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - } - - impl From<&Vpc> for Vpc { - fn from(value: &Vpc) -> Self { - value.clone() - } - } - - ///Create-time parameters for a [`Vpc`](crate::external_api::views::Vpc) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcCreate { - pub description: String, - pub dns_name: Name, - ///The IPv6 prefix for this VPC. - /// - ///All IPv6 subnets created from this VPC must be taken from this - /// range, which sould be a Unique Local Address in the range - /// `fd00::/48`. The default VPC Subnet will have the first `/64` range - /// from this prefix. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ipv6_prefix: Option, - pub name: Name, - } - - impl From<&VpcCreate> for VpcCreate { - fn from(value: &VpcCreate) -> Self { - value.clone() - } - } - - ///A single rule in a VPC firewall - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcFirewallRule { - ///whether traffic matching the rule should be allowed or dropped - pub action: VpcFirewallRuleAction, - ///human-readable free-form text about a resource - pub description: String, - ///whether this rule is for incoming or outgoing traffic - pub direction: VpcFirewallRuleDirection, - ///reductions on the scope of the rule - pub filters: VpcFirewallRuleFilter, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///the relative priority of this rule - pub priority: u16, - ///whether this rule is in effect - pub status: VpcFirewallRuleStatus, - ///list of sets of instances that the rule applies to - pub targets: Vec, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///the VPC to which this rule belongs - pub vpc_id: uuid::Uuid, - } - - impl From<&VpcFirewallRule> for VpcFirewallRule { - fn from(value: &VpcFirewallRule) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum VpcFirewallRuleAction { - #[serde(rename = "allow")] - Allow, - #[serde(rename = "deny")] - Deny, - } - - impl From<&VpcFirewallRuleAction> for VpcFirewallRuleAction { - fn from(value: &VpcFirewallRuleAction) -> Self { - value.clone() - } - } - - impl ToString for VpcFirewallRuleAction { - fn to_string(&self) -> String { - match *self { - Self::Allow => "allow".to_string(), - Self::Deny => "deny".to_string(), - } - } - } - - impl std::str::FromStr for VpcFirewallRuleAction { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "allow" => Ok(Self::Allow), - "deny" => Ok(Self::Deny), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for VpcFirewallRuleAction { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for VpcFirewallRuleAction { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for VpcFirewallRuleAction { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum VpcFirewallRuleDirection { - #[serde(rename = "inbound")] - Inbound, - #[serde(rename = "outbound")] - Outbound, - } - - impl From<&VpcFirewallRuleDirection> for VpcFirewallRuleDirection { - fn from(value: &VpcFirewallRuleDirection) -> Self { - value.clone() - } - } - - impl ToString for VpcFirewallRuleDirection { - fn to_string(&self) -> String { - match *self { - Self::Inbound => "inbound".to_string(), - Self::Outbound => "outbound".to_string(), - } - } - } - - impl std::str::FromStr for VpcFirewallRuleDirection { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "inbound" => Ok(Self::Inbound), - "outbound" => Ok(Self::Outbound), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for VpcFirewallRuleDirection { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for VpcFirewallRuleDirection { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for VpcFirewallRuleDirection { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///Filter for a firewall rule. A given packet must match every field that - /// is present for the rule to apply to it. A packet matches a field if any - /// entry in that field matches the packet. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcFirewallRuleFilter { - ///If present, the sources (if incoming) or destinations (if outgoing) - /// this rule applies to. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub hosts: Option>, - ///If present, the destination ports this rule applies to. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ports: Option>, - ///If present, the networking protocols this rule applies to. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub protocols: Option>, - } - - impl From<&VpcFirewallRuleFilter> for VpcFirewallRuleFilter { - fn from(value: &VpcFirewallRuleFilter) -> Self { - value.clone() - } - } - - ///The `VpcFirewallRuleHostFilter` is used to filter traffic on the basis - /// of its source or destination host. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "value")] - pub enum VpcFirewallRuleHostFilter { - ///The rule applies to traffic from/to all instances in the VPC - #[serde(rename = "vpc")] - Vpc(Name), - ///The rule applies to traffic from/to all instances in the VPC Subnet - #[serde(rename = "subnet")] - Subnet(Name), - ///The rule applies to traffic from/to this specific instance - #[serde(rename = "instance")] - Instance(Name), - ///The rule applies to traffic from/to a specific IP address - #[serde(rename = "ip")] - Ip(std::net::IpAddr), - ///The rule applies to traffic from/to a specific IP subnet - #[serde(rename = "ip_net")] - IpNet(IpNet), - } - - impl From<&VpcFirewallRuleHostFilter> for VpcFirewallRuleHostFilter { - fn from(value: &VpcFirewallRuleHostFilter) -> Self { - value.clone() - } - } - - impl From for VpcFirewallRuleHostFilter { - fn from(value: std::net::IpAddr) -> Self { - Self::Ip(value) - } - } - - impl From for VpcFirewallRuleHostFilter { - fn from(value: IpNet) -> Self { - Self::IpNet(value) - } - } - - ///The protocols that may be specified in a firewall rule's filter - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum VpcFirewallRuleProtocol { - #[serde(rename = "TCP")] - Tcp, - #[serde(rename = "UDP")] - Udp, - #[serde(rename = "ICMP")] - Icmp, - } - - impl From<&VpcFirewallRuleProtocol> for VpcFirewallRuleProtocol { - fn from(value: &VpcFirewallRuleProtocol) -> Self { - value.clone() - } - } - - impl ToString for VpcFirewallRuleProtocol { - fn to_string(&self) -> String { - match *self { - Self::Tcp => "TCP".to_string(), - Self::Udp => "UDP".to_string(), - Self::Icmp => "ICMP".to_string(), - } - } - } - - impl std::str::FromStr for VpcFirewallRuleProtocol { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "TCP" => Ok(Self::Tcp), - "UDP" => Ok(Self::Udp), - "ICMP" => Ok(Self::Icmp), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for VpcFirewallRuleProtocol { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for VpcFirewallRuleProtocol { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for VpcFirewallRuleProtocol { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum VpcFirewallRuleStatus { - #[serde(rename = "disabled")] - Disabled, - #[serde(rename = "enabled")] - Enabled, - } - - impl From<&VpcFirewallRuleStatus> for VpcFirewallRuleStatus { - fn from(value: &VpcFirewallRuleStatus) -> Self { - value.clone() - } - } - - impl ToString for VpcFirewallRuleStatus { - fn to_string(&self) -> String { - match *self { - Self::Disabled => "disabled".to_string(), - Self::Enabled => "enabled".to_string(), - } - } - } - - impl std::str::FromStr for VpcFirewallRuleStatus { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "disabled" => Ok(Self::Disabled), - "enabled" => Ok(Self::Enabled), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for VpcFirewallRuleStatus { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for VpcFirewallRuleStatus { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for VpcFirewallRuleStatus { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///A `VpcFirewallRuleTarget` is used to specify the set of [`Instance`]s to - /// which a firewall rule applies. - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type", content = "value")] - pub enum VpcFirewallRuleTarget { - ///The rule applies to all instances in the VPC - #[serde(rename = "vpc")] - Vpc(Name), - ///The rule applies to all instances in the VPC Subnet - #[serde(rename = "subnet")] - Subnet(Name), - ///The rule applies to this specific instance - #[serde(rename = "instance")] - Instance(Name), - ///The rule applies to a specific IP address - #[serde(rename = "ip")] - Ip(std::net::IpAddr), - ///The rule applies to a specific IP subnet - #[serde(rename = "ip_net")] - IpNet(IpNet), - } - - impl From<&VpcFirewallRuleTarget> for VpcFirewallRuleTarget { - fn from(value: &VpcFirewallRuleTarget) -> Self { - value.clone() - } - } - - impl From for VpcFirewallRuleTarget { - fn from(value: std::net::IpAddr) -> Self { - Self::Ip(value) - } - } - - impl From for VpcFirewallRuleTarget { - fn from(value: IpNet) -> Self { - Self::IpNet(value) - } - } - - ///A single rule in a VPC firewall - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcFirewallRuleUpdate { - ///whether traffic matching the rule should be allowed or dropped - pub action: VpcFirewallRuleAction, - ///human-readable free-form text about a resource - pub description: String, - ///whether this rule is for incoming or outgoing traffic - pub direction: VpcFirewallRuleDirection, - ///reductions on the scope of the rule - pub filters: VpcFirewallRuleFilter, - ///name of the rule, unique to this VPC - pub name: Name, - ///the relative priority of this rule - pub priority: u16, - ///whether this rule is in effect - pub status: VpcFirewallRuleStatus, - ///list of sets of instances that the rule applies to - pub targets: Vec, - } - - impl From<&VpcFirewallRuleUpdate> for VpcFirewallRuleUpdate { - fn from(value: &VpcFirewallRuleUpdate) -> Self { - value.clone() - } - } - - ///Updateable properties of a `Vpc`'s firewall Note that VpcFirewallRules - /// are implicitly created along with a Vpc, so there is no explicit - /// creation. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcFirewallRuleUpdateParams { - pub rules: Vec, - } - - impl From<&VpcFirewallRuleUpdateParams> for VpcFirewallRuleUpdateParams { - fn from(value: &VpcFirewallRuleUpdateParams) -> Self { - value.clone() - } - } - - ///Collection of a Vpc's firewall rules - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcFirewallRules { - pub rules: Vec, - } - - impl From<&VpcFirewallRules> for VpcFirewallRules { - fn from(value: &VpcFirewallRules) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&VpcResultsPage> for VpcResultsPage { - fn from(value: &VpcResultsPage) -> Self { - value.clone() - } - } - - ///A VPC router defines a series of rules that indicate where traffic - /// should be sent depending on its destination. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcRouter { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - pub kind: VpcRouterKind, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///The VPC to which the router belongs. - pub vpc_id: uuid::Uuid, - } - - impl From<&VpcRouter> for VpcRouter { - fn from(value: &VpcRouter) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`VpcRouter`](crate::external_api::views::VpcRouter) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcRouterCreate { - pub description: String, - pub name: Name, - } - - impl From<&VpcRouterCreate> for VpcRouterCreate { - fn from(value: &VpcRouterCreate) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum VpcRouterKind { - #[serde(rename = "system")] - System, - #[serde(rename = "custom")] - Custom, - } - - impl From<&VpcRouterKind> for VpcRouterKind { - fn from(value: &VpcRouterKind) -> Self { - value.clone() - } - } - - impl ToString for VpcRouterKind { - fn to_string(&self) -> String { - match *self { - Self::System => "system".to_string(), - Self::Custom => "custom".to_string(), - } - } - } - - impl std::str::FromStr for VpcRouterKind { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "system" => Ok(Self::System), - "custom" => Ok(Self::Custom), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for VpcRouterKind { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for VpcRouterKind { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for VpcRouterKind { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcRouterResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&VpcRouterResultsPage> for VpcRouterResultsPage { - fn from(value: &VpcRouterResultsPage) -> Self { - value.clone() - } - } - - ///Updateable properties of a - /// [`VpcRouter`](crate::external_api::views::VpcRouter) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcRouterUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&VpcRouterUpdate> for VpcRouterUpdate { - fn from(value: &VpcRouterUpdate) -> Self { - value.clone() - } - } - - ///A VPC subnet represents a logical grouping for instances that allows - /// network traffic between them, within a IPv4 subnetwork or optionall an - /// IPv6 subnetwork. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcSubnet { - ///human-readable free-form text about a resource - pub description: String, - ///unique, immutable, system-controlled identifier for each resource - pub id: uuid::Uuid, - ///The IPv4 subnet CIDR block. - pub ipv4_block: Ipv4Net, - ///The IPv6 subnet CIDR block. - pub ipv6_block: Ipv6Net, - ///unique, mutable, user-controlled identifier for each resource - pub name: Name, - ///timestamp when this resource was created - pub time_created: chrono::DateTime, - ///timestamp when this resource was last modified - pub time_modified: chrono::DateTime, - ///The VPC to which the subnet belongs. - pub vpc_id: uuid::Uuid, - } - - impl From<&VpcSubnet> for VpcSubnet { - fn from(value: &VpcSubnet) -> Self { - value.clone() - } - } - - ///Create-time parameters for a - /// [`VpcSubnet`](crate::external_api::views::VpcSubnet) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcSubnetCreate { - pub description: String, - ///The IPv4 address range for this subnet. - /// - ///It must be allocated from an RFC 1918 private address range, and - /// must not overlap with any other existing subnet in the VPC. - pub ipv4_block: Ipv4Net, - ///The IPv6 address range for this subnet. - /// - ///It must be allocated from the RFC 4193 Unique Local Address range, - /// with the prefix equal to the parent VPC's prefix. A random `/64` - /// block will be assigned if one is not provided. It must not overlap - /// with any existing subnet in the VPC. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ipv6_block: Option, - pub name: Name, - } - - impl From<&VpcSubnetCreate> for VpcSubnetCreate { - fn from(value: &VpcSubnetCreate) -> Self { - value.clone() - } - } - - ///A single page of results - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcSubnetResultsPage { - ///list of items on this page of results - pub items: Vec, - ///token used to fetch the next page of results (if any) - #[serde(default, skip_serializing_if = "Option::is_none")] - pub next_page: Option, - } - - impl From<&VpcSubnetResultsPage> for VpcSubnetResultsPage { - fn from(value: &VpcSubnetResultsPage) -> Self { - value.clone() - } - } - - ///Updateable properties of a - /// [`VpcSubnet`](crate::external_api::views::VpcSubnet) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcSubnetUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&VpcSubnetUpdate> for VpcSubnetUpdate { - fn from(value: &VpcSubnetUpdate) -> Self { - value.clone() - } - } - - ///Updateable properties of a [`Vpc`](crate::external_api::views::Vpc) - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct VpcUpdate { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub description: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub dns_name: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub name: Option, - } - - impl From<&VpcUpdate> for VpcUpdate { - fn from(value: &VpcUpdate) -> Self { - value.clone() - } - } - - pub mod defaults { - pub(super) fn default_bool() -> bool { - V - } - - pub(super) fn instance_create_network_interfaces( - ) -> super::InstanceNetworkInterfaceAttachment { - super::InstanceNetworkInterfaceAttachment::Default - } - } -} - -#[derive(Clone, Debug)] -///Client for Oxide Region API -/// -///API for interacting with the Oxide control plane -/// -///Version: 0.0.1 -pub struct Client { - pub(crate) baseurl: String, - pub(crate) client: reqwest::Client, -} - -impl Client { - /// Create a new client. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new(baseurl: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] - let client = { - let dur = std::time::Duration::from_secs(15); - reqwest::ClientBuilder::new() - .connect_timeout(dur) - .timeout(dur) - }; - #[cfg(target_arch = "wasm32")] - let client = reqwest::ClientBuilder::new(); - Self::new_with_client(baseurl, client.build().unwrap()) - } - - /// Construct a new client with an existing `reqwest::Client`, - /// allowing more control over its configuration. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { - Self { - baseurl: baseurl.to_string(), - client, - } - } - - /// Get the base URL to which requests are made. - pub fn baseurl(&self) -> &String { - &self.baseurl - } - - /// Get the internal `reqwest::Client` used to make requests. - pub fn client(&self) -> &reqwest::Client { - &self.client - } - - /// Get the version of this API. - /// - /// This string is pulled directly from the source OpenAPI - /// document and may be in any format the API selects. - pub fn api_version(&self) -> &'static str { - "0.0.1" - } -} - -impl Client { - ///Fetch a disk by id - /// - ///Use `GET /v1/disks/{disk}` instead - /// - ///Sends a `GET` request to `/by-id/disks/{id}` - pub async fn disk_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/disks/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an image by id - /// - ///Sends a `GET` request to `/by-id/images/{id}` - pub async fn image_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/images/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an instance by id - /// - ///Sends a `GET` request to `/by-id/instances/{id}` - pub async fn instance_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/instances/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a network interface by id - /// - ///Sends a `GET` request to `/by-id/network-interfaces/{id}` - pub async fn instance_network_interface_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/network-interfaces/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an organization by id - /// - ///Use `GET /v1/organizations/{organization}` instead - /// - ///Sends a `GET` request to `/by-id/organizations/{id}` - pub async fn organization_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/organizations/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a project by id - /// - ///Use `GET /v1/projects/{project}` instead - /// - ///Sends a `GET` request to `/by-id/projects/{id}` - pub async fn project_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/projects/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a snapshot by id - /// - ///Sends a `GET` request to `/by-id/snapshots/{id}` - pub async fn snapshot_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/snapshots/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a route by id - /// - ///Sends a `GET` request to `/by-id/vpc-router-routes/{id}` - pub async fn vpc_router_route_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/vpc-router-routes/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Get a router by id - /// - ///Sends a `GET` request to `/by-id/vpc-routers/{id}` - pub async fn vpc_router_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/vpc-routers/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a subnet by id - /// - ///Sends a `GET` request to `/by-id/vpc-subnets/{id}` - pub async fn vpc_subnet_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/vpc-subnets/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a VPC - /// - ///Sends a `GET` request to `/by-id/vpcs/{id}` - pub async fn vpc_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/by-id/vpcs/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Start an OAuth 2.0 Device Authorization Grant - /// - ///This endpoint is designed to be accessed from an *unauthenticated* API - /// client. It generates and records a `device_code` and `user_code` which - /// must be verified and confirmed prior to a token being granted. - /// - ///Sends a `POST` request to `/device/auth` - pub async fn device_auth_request<'a>( - &'a self, - body: &'a types::DeviceAuthRequest, - ) -> Result, Error> { - let url = format!("{}/device/auth", self.baseurl,); - let request = self.client.post(url).form_urlencoded(&body)?.build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - _ => Err(Error::ErrorResponse(ResponseValue::stream(response))), - } - } - - ///Confirm an OAuth 2.0 Device Authorization Grant - /// - ///This endpoint is designed to be accessed by the user agent (browser), - /// not the client requesting the token. So we do not actually return the - /// token here; it will be returned in response to the poll on - /// `/device/token`. - /// - ///Sends a `POST` request to `/device/confirm` - pub async fn device_auth_confirm<'a>( - &'a self, - body: &'a types::DeviceAuthVerify, - ) -> Result, Error> { - let url = format!("{}/device/confirm", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Request a device access token - /// - ///This endpoint should be polled by the client until the user code is - /// verified and the grant is confirmed. - /// - ///Sends a `POST` request to `/device/token` - pub async fn device_access_token<'a>( - &'a self, - body: &'a types::DeviceAccessTokenRequest, - ) -> Result, Error> { - let url = format!("{}/device/token", self.baseurl,); - let request = self.client.post(url).form_urlencoded(&body)?.build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - _ => Err(Error::ErrorResponse(ResponseValue::stream(response))), - } - } - - ///List groups - /// - ///Sends a `GET` request to `/groups` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn group_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/groups", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List groups as a Stream - /// - ///Sends repeated `GET` requests to `/groups` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn group_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.group_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.group_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Sends a `POST` request to `/login` - pub async fn login_spoof<'a>( - &'a self, - body: &'a types::SpoofLoginBody, - ) -> Result, Error> { - let url = format!("{}/login", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Authenticate a user (i.e., log in) via username and password - /// - ///Sends a `POST` request to `/login/{silo_name}/local` - pub async fn login_local<'a>( - &'a self, - silo_name: &'a types::Name, - body: &'a types::UsernamePasswordCredentials, - ) -> Result, Error> { - let url = format!( - "{}/login/{}/local", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self.client.post(url).json(&body).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Prompt user login - /// - ///Either display a page asking a user for their credentials, or redirect - /// them to their identity provider. - /// - ///Sends a `GET` request to `/login/{silo_name}/saml/{provider_name}` - pub async fn login_saml_begin<'a>( - &'a self, - silo_name: &'a types::Name, - provider_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/login/{}/saml/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&provider_name.to_string()), - ); - let request = self.client.get(url).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Authenticate a user (i.e., log in) via SAML - /// - ///Sends a `POST` request to `/login/{silo_name}/saml/{provider_name}` - pub async fn login_saml<'a, B: Into>( - &'a self, - silo_name: &'a types::Name, - provider_name: &'a types::Name, - body: B, - ) -> Result, Error> { - let url = format!( - "{}/login/{}/saml/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&provider_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::CONTENT_TYPE, - reqwest::header::HeaderValue::from_static("application/octet-stream"), - ) - .body(body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `POST` request to `/logout` - pub async fn logout(&self) -> Result, Error> { - let url = format!("{}/logout", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List organizations - /// - ///Use `GET /v1/organizations` instead - /// - ///Sends a `GET` request to `/organizations` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn organization_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/organizations", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List organizations as a Stream - /// - ///Use `GET /v1/organizations` instead - /// - ///Sends repeated `GET` requests to `/organizations` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn organization_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.organization_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.organization_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an organization - /// - ///Use `POST /v1/organizations` instead - /// - ///Sends a `POST` request to `/organizations` - pub async fn organization_create<'a>( - &'a self, - body: &'a types::OrganizationCreate, - ) -> Result, Error> { - let url = format!("{}/organizations", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an organization - /// - ///Use `GET /v1/organizations/{organization}` instead - /// - ///Sends a `GET` request to `/organizations/{organization_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - pub async fn organization_view<'a>( - &'a self, - organization_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update an organization - /// - ///Use `PUT /v1/organizations/{organization}` instead - /// - ///Sends a `PUT` request to `/organizations/{organization_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `body` - pub async fn organization_update<'a>( - &'a self, - organization_name: &'a types::Name, - body: &'a types::OrganizationUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an organization - /// - ///Use `DELETE /v1/organizations/{organization}` instead - /// - ///Sends a `DELETE` request to `/organizations/{organization_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - pub async fn organization_delete<'a>( - &'a self, - organization_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an organization's IAM policy - /// - ///Use `GET /v1/organizations/{organization}/policy` instead - /// - ///Sends a `GET` request to `/organizations/{organization_name}/policy` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - pub async fn organization_policy_view<'a>( - &'a self, - organization_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/policy", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update an organization's IAM policy - /// - ///Use `PUT /v1/organizations/{organization}/policy` instead - /// - ///Sends a `PUT` request to `/organizations/{organization_name}/policy` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `body` - pub async fn organization_policy_update<'a>( - &'a self, - organization_name: &'a types::Name, - body: &'a types::OrganizationRolePolicy, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/policy", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List projects - /// - ///Use `GET /v1/projects` instead - /// - ///Sends a `GET` request to `/organizations/{organization_name}/projects` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn project_list<'a>( - &'a self, - organization_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List projects as a Stream - /// - ///Use `GET /v1/projects` instead - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects` until there are no more - /// results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn project_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.project_list(organization_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.project_list(organization_name, None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a project - /// - ///Use `POST /v1/projects` instead - /// - ///Sends a `POST` request to `/organizations/{organization_name}/projects` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `body` - pub async fn project_create<'a>( - &'a self, - organization_name: &'a types::Name, - body: &'a types::ProjectCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects", - self.baseurl, - encode_path(&organization_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a project - /// - ///Use `GET /v1/projects/{project}` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - pub async fn project_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a project - /// - ///Use `PUT /v1/projects/{project}` instead - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn project_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::ProjectUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a project - /// - ///Use `DELETE /v1/projects/{project}` instead - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - pub async fn project_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List disks - /// - ///Use `GET /v1/disks` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/disks` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn disk_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/disks", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List disks as a Stream - /// - ///Use `GET /v1/disks` instead - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/disks` until - /// there are no more results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn disk_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.disk_list(organization_name, project_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.disk_list( - organization_name, - project_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Use `POST /v1/disks` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/disks` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn disk_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::DiskCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/disks", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a disk - /// - ///Use `GET /v1/disks/{disk}` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/disks/ - /// {disk_name}` - pub async fn disk_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - disk_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/disks/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&disk_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Use `DELETE /v1/disks/{disk}` instead - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/disks/ - /// {disk_name}` - pub async fn disk_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - disk_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/disks/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&disk_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch disk metrics - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/disks/ - /// {disk_name}/metrics/{metric_name}` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `disk_name` - /// - `metric_name` - /// - `end_time`: An exclusive end time of metrics. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `start_time`: An inclusive start time of metrics. - pub async fn disk_metrics_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - disk_name: &'a types::Name, - metric_name: types::DiskMetricName, - end_time: Option<&'a chrono::DateTime>, - limit: Option, - page_token: Option<&'a str>, - start_time: Option<&'a chrono::DateTime>, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/disks/{}/metrics/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&disk_name.to_string()), - encode_path(&metric_name.to_string()), - ); - let mut query = Vec::with_capacity(4usize); - if let Some(v) = &end_time { - query.push(("end_time", v.to_string())); - } - - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &start_time { - query.push(("start_time", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch disk metrics as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/disks/ - /// {disk_name}/metrics/{metric_name}` until there are no more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `disk_name` - /// - `metric_name` - /// - `end_time`: An exclusive end time of metrics. - /// - `limit`: Maximum number of items returned by a single call - /// - `start_time`: An inclusive start time of metrics. - pub fn disk_metrics_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - disk_name: &'a types::Name, - metric_name: types::DiskMetricName, - end_time: Option<&'a chrono::DateTime>, - limit: Option, - start_time: Option<&'a chrono::DateTime>, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.disk_metrics_list( - organization_name, - project_name, - disk_name, - metric_name, - end_time, - limit, - None, - start_time, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.disk_metrics_list( - organization_name, - project_name, - disk_name, - metric_name, - None, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List images - /// - ///List images in a project. The images are returned sorted by creation - /// date, with the most recent images appearing first. - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/images` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn image_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/images", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List images as a Stream - /// - ///List images in a project. The images are returned sorted by creation - /// date, with the most recent images appearing first. - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/images` - /// until there are no more results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn image_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.image_list(organization_name, project_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.image_list( - organization_name, - project_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an image - /// - ///Create a new image in a project. - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/images` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn image_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::ImageCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/images", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an image - /// - ///Fetch the details for a specific image in a project. - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/images/ - /// {image_name}` - pub async fn image_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - image_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/images/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&image_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an image - /// - ///Permanently delete an image from a project. This operation cannot be - /// undone. Any instances in the project using the image will continue to - /// run, however new instances can not be created with this image. - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/images/ - /// {image_name}` - pub async fn image_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - image_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/images/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&image_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List instances - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn instance_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List instances as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/instances` - /// until there are no more results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn instance_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.instance_list(organization_name, project_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.instance_list( - organization_name, - project_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an instance - /// - ///Use `POST /v1/instances` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn instance_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::InstanceCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an instance - /// - ///Use `GET /v1/instances/{instance}` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}` - pub async fn instance_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an instance - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}` - pub async fn instance_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List an instance's disks - /// - ///Use `GET /v1/instances/{instance}/disks` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/disks` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `instance_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn instance_disk_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/disks", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List an instance's disks as a Stream - /// - ///Use `GET /v1/instances/{instance}/disks` instead - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/disks` until there are no more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `instance_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn instance_disk_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.instance_disk_list( - organization_name, - project_name, - instance_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.instance_disk_list( - organization_name, - project_name, - instance_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Attach a disk to an instance - /// - ///Use `POST /v1/instances/{instance}/disks/attach` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/disks/attach` - pub async fn instance_disk_attach<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - body: &'a types::DiskIdentifier, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/disks/attach", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Detach a disk from an instance - /// - ///Use `POST /v1/disks/{disk}/detach` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/disks/detach` - pub async fn instance_disk_detach<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - body: &'a types::DiskIdentifier, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/disks/detach", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List external IP addresses - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/external-ips` - pub async fn instance_external_ip_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/external-ips", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Migrate an instance - /// - ///Use `POST /v1/instances/{instance}/migrate` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/migrate` - pub async fn instance_migrate<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - body: &'a types::InstanceMigrate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/migrate", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List network interfaces - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `instance_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn instance_network_interface_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/network-interfaces", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List network interfaces as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces` until there are no more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `instance_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn instance_network_interface_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.instance_network_interface_list( - organization_name, - project_name, - instance_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.instance_network_interface_list( - organization_name, - project_name, - instance_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a network interface - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces` - pub async fn instance_network_interface_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - body: &'a types::NetworkInterfaceCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/network-interfaces", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a network interface - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces/{interface_name}` - pub async fn instance_network_interface_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - interface_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/network-interfaces/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - encode_path(&interface_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a network interface - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces/{interface_name}` - pub async fn instance_network_interface_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - interface_name: &'a types::Name, - body: &'a types::NetworkInterfaceUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/network-interfaces/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - encode_path(&interface_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a network interface - /// - ///Note that the primary interface for an instance cannot be deleted if - /// there are any secondary interfaces. A new primary interface must be - /// designated first. The primary interface can be deleted if there are no - /// secondary interfaces. - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/network-interfaces/{interface_name}` - pub async fn instance_network_interface_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - interface_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/network-interfaces/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - encode_path(&interface_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Reboot an instance - /// - ///Use `POST /v1/instances/{instance}/reboot` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/reboot` - pub async fn instance_reboot<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/reboot", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an instance's serial console - /// - ///Use `GET /v1/instances/{instance}/serial-console` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/serial-console` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `instance_name` - /// - `from_start`: Character index in the serial buffer from which to read, - /// counting the bytes output since instance start. If this is not - /// provided, `most_recent` must be provided, and if this *is* provided, - /// `most_recent` must *not* be provided. - /// - `max_bytes`: Maximum number of bytes of buffered serial console - /// contents to return. If the requested range runs to the end of the - /// available buffer, the data returned will be shorter than `max_bytes`. - /// - `most_recent`: Character index in the serial buffer from which to - /// read, counting *backward* from the most recently buffered data - /// retrieved from the instance. (See note on `from_start` about mutual - /// exclusivity) - pub async fn instance_serial_console<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - from_start: Option, - max_bytes: Option, - most_recent: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/serial-console", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &from_start { - query.push(("from_start", v.to_string())); - } - - if let Some(v) = &max_bytes { - query.push(("max_bytes", v.to_string())); - } - - if let Some(v) = &most_recent { - query.push(("most_recent", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Connect to an instance's serial console - /// - ///Use `GET /v1/instances/{instance}/serial-console/stream` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/serial-console/stream` - pub async fn instance_serial_console_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/serial-console/stream", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .get(url) - .header(reqwest::header::CONNECTION, "Upgrade") - .header(reqwest::header::UPGRADE, "websocket") - .header(reqwest::header::SEC_WEBSOCKET_VERSION, "13") - .header( - reqwest::header::SEC_WEBSOCKET_KEY, - base64::Engine::encode( - &base64::engine::general_purpose::STANDARD, - rand::random::<[u8; 16]>(), - ), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 101u16 => ResponseValue::upgrade(response).await, - 200..=299 => ResponseValue::upgrade(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Boot an instance - /// - ///Use `POST /v1/instances/{instance}/start` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/start` - pub async fn instance_start<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/start", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Halt an instance - /// - ///Use `POST /v1/instances/{instance}/stop` instead - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/instances/ - /// {instance_name}/stop` - pub async fn instance_stop<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - instance_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/instances/{}/stop", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&instance_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a project's IAM policy - /// - ///Use `GET /v1/projects/{project}/policy` instead - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/policy` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - pub async fn project_policy_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/policy", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a project's IAM policy - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/policy` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn project_policy_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::ProjectRolePolicy, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/policy", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List snapshots - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/snapshots` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn snapshot_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/snapshots", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List snapshots as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/snapshots` - /// until there are no more results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn snapshot_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.snapshot_list(organization_name, project_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.snapshot_list( - organization_name, - project_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a snapshot - /// - ///Creates a point-in-time snapshot from a disk. - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/snapshots` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn snapshot_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::SnapshotCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/snapshots", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a snapshot - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/snapshots/ - /// {snapshot_name}` - pub async fn snapshot_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - snapshot_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/snapshots/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&snapshot_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a snapshot - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/snapshots/ - /// {snapshot_name}` - pub async fn snapshot_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - snapshot_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/snapshots/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&snapshot_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List VPCs - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn vpc_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List VPCs as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs` until - /// there are no more results. - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn vpc_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.vpc_list(organization_name, project_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.vpc_list( - organization_name, - project_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a VPC - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs` - /// - ///Arguments: - /// - `organization_name`: The organization's unique name. - /// - `project_name`: The project's unique name within the organization. - /// - `body` - pub async fn vpc_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - body: &'a types::VpcCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a VPC - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}` - pub async fn vpc_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a VPC - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}` - pub async fn vpc_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - body: &'a types::VpcUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a VPC - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}` - pub async fn vpc_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List firewall rules - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/firewall/rules` - pub async fn vpc_firewall_rules_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/firewall/rules", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Replace firewall rules - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/firewall/rules` - pub async fn vpc_firewall_rules_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - body: &'a types::VpcFirewallRuleUpdateParams, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/firewall/rules", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List routers - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn vpc_router_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List routers as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers` until there are no more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn vpc_router_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.vpc_router_list( - organization_name, - project_name, - vpc_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.vpc_router_list( - organization_name, - project_name, - vpc_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a router - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers` - pub async fn vpc_router_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - body: &'a types::VpcRouterCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Get a router - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}` - pub async fn vpc_router_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a router - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}` - pub async fn vpc_router_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - body: &'a types::VpcRouterUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a router - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}` - pub async fn vpc_router_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List routes - /// - ///List the routes associated with a router in a particular VPC. - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `router_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn vpc_router_route_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}/routes", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List routes as a Stream - /// - ///List the routes associated with a router in a particular VPC. - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes` until there are no more - /// results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `router_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn vpc_router_route_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.vpc_router_route_list( - organization_name, - project_name, - vpc_name, - router_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.vpc_router_route_list( - organization_name, - project_name, - vpc_name, - router_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a router - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes` - pub async fn vpc_router_route_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - body: &'a types::RouterRouteCreateParams, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}/routes", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a route - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes/{route_name}` - pub async fn vpc_router_route_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - route_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}/routes/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - encode_path(&route_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a route - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes/{route_name}` - pub async fn vpc_router_route_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - route_name: &'a types::Name, - body: &'a types::RouterRouteUpdateParams, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}/routes/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - encode_path(&route_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a route - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/routers/{router_name}/routes/{route_name}` - pub async fn vpc_router_route_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - router_name: &'a types::Name, - route_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/routers/{}/routes/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&router_name.to_string()), - encode_path(&route_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List subnets - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn vpc_subnet_list<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List subnets as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets` until there are no more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn vpc_subnet_list_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.vpc_subnet_list( - organization_name, - project_name, - vpc_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.vpc_subnet_list( - organization_name, - project_name, - vpc_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a subnet - /// - ///Sends a `POST` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets` - pub async fn vpc_subnet_create<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - body: &'a types::VpcSubnetCreate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a subnet - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets/{subnet_name}` - pub async fn vpc_subnet_view<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - subnet_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&subnet_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a subnet - /// - ///Sends a `PUT` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets/{subnet_name}` - pub async fn vpc_subnet_update<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - subnet_name: &'a types::Name, - body: &'a types::VpcSubnetUpdate, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&subnet_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a subnet - /// - ///Sends a `DELETE` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets/{subnet_name}` - pub async fn vpc_subnet_delete<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - subnet_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets/{}", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&subnet_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List network interfaces - /// - ///Sends a `GET` request to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets/{subnet_name}/network-interfaces` - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `subnet_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn vpc_subnet_list_network_interfaces<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - subnet_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/organizations/{}/projects/{}/vpcs/{}/subnets/{}/network-interfaces", - self.baseurl, - encode_path(&organization_name.to_string()), - encode_path(&project_name.to_string()), - encode_path(&vpc_name.to_string()), - encode_path(&subnet_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List network interfaces as a Stream - /// - ///Sends repeated `GET` requests to - /// `/organizations/{organization_name}/projects/{project_name}/vpcs/ - /// {vpc_name}/subnets/{subnet_name}/network-interfaces` until there are no - /// more results. - /// - ///Arguments: - /// - `organization_name` - /// - `project_name` - /// - `vpc_name` - /// - `subnet_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn vpc_subnet_list_network_interfaces_stream<'a>( - &'a self, - organization_name: &'a types::Name, - project_name: &'a types::Name, - vpc_name: &'a types::Name, - subnet_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.vpc_subnet_list_network_interfaces( - organization_name, - project_name, - vpc_name, - subnet_name, - limit, - None, - sort_by, - ) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.vpc_subnet_list_network_interfaces( - organization_name, - project_name, - vpc_name, - subnet_name, - None, - state.as_deref(), - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch the current silo's IAM policy - /// - ///Sends a `GET` request to `/policy` - pub async fn policy_view( - &self, - ) -> Result, Error> { - let url = format!("{}/policy", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update the current silo's IAM policy - /// - ///Sends a `PUT` request to `/policy` - pub async fn policy_update<'a>( - &'a self, - body: &'a types::SiloRolePolicy, - ) -> Result, Error> { - let url = format!("{}/policy", self.baseurl,); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List built-in roles - /// - ///Sends a `GET` request to `/roles` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - pub async fn role_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - ) -> Result, Error> { - let url = format!("{}/roles", self.baseurl,); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List built-in roles as a Stream - /// - ///Sends repeated `GET` requests to `/roles` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - pub fn role_list_stream<'a>( - &'a self, - limit: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.role_list(limit, None) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.role_list(None, state.as_deref()) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a built-in role - /// - ///Sends a `GET` request to `/roles/{role_name}` - /// - ///Arguments: - /// - `role_name`: The built-in role's unique name. - pub async fn role_view<'a>( - &'a self, - role_name: &'a str, - ) -> Result, Error> { - let url = format!( - "{}/roles/{}", - self.baseurl, - encode_path(&role_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch the user associated with the current session - /// - ///Sends a `GET` request to `/session/me` - pub async fn session_me(&self) -> Result, Error> { - let url = format!("{}/session/me", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch the silo groups the current user belongs to - /// - ///Sends a `GET` request to `/session/me/groups` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn session_me_groups<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/session/me/groups", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch the silo groups the current user belongs to as a Stream - /// - ///Sends repeated `GET` requests to `/session/me/groups` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn session_me_groups_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.session_me_groups(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.session_me_groups(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List SSH public keys - /// - ///Lists SSH public keys for the currently authenticated user. - /// - ///Sends a `GET` request to `/session/me/sshkeys` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn session_sshkey_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/session/me/sshkeys", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List SSH public keys as a Stream - /// - ///Lists SSH public keys for the currently authenticated user. - /// - ///Sends repeated `GET` requests to `/session/me/sshkeys` until there are - /// no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn session_sshkey_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.session_sshkey_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.session_sshkey_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an SSH public key - /// - ///Create an SSH public key for the currently authenticated user. - /// - ///Sends a `POST` request to `/session/me/sshkeys` - pub async fn session_sshkey_create<'a>( - &'a self, - body: &'a types::SshKeyCreate, - ) -> Result, Error> { - let url = format!("{}/session/me/sshkeys", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an SSH public key - /// - ///Fetch an SSH public key associated with the currently authenticated - /// user. - /// - ///Sends a `GET` request to `/session/me/sshkeys/{ssh_key_name}` - pub async fn session_sshkey_view<'a>( - &'a self, - ssh_key_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/session/me/sshkeys/{}", - self.baseurl, - encode_path(&ssh_key_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an SSH public key - /// - ///Delete an SSH public key associated with the currently authenticated - /// user. - /// - ///Sends a `DELETE` request to `/session/me/sshkeys/{ssh_key_name}` - pub async fn session_sshkey_delete<'a>( - &'a self, - ssh_key_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/session/me/sshkeys/{}", - self.baseurl, - encode_path(&ssh_key_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a system-wide image by id - /// - ///Sends a `GET` request to `/system/by-id/images/{id}` - pub async fn system_image_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/by-id/images/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an IP pool by id - /// - ///Sends a `GET` request to `/system/by-id/ip-pools/{id}` - pub async fn ip_pool_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/by-id/ip-pools/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a silo by id - /// - ///Sends a `GET` request to `/system/by-id/silos/{id}` - pub async fn silo_view_by_id<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/by-id/silos/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List system-wide certificates - /// - ///Returns a list of all the system-wide certificates. System-wide - /// certificates are returned sorted by creation date, with the most recent - /// certificates appearing first. - /// - ///Sends a `GET` request to `/system/certificates` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn certificate_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/certificates", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List system-wide certificates as a Stream - /// - ///Returns a list of all the system-wide certificates. System-wide - /// certificates are returned sorted by creation date, with the most recent - /// certificates appearing first. - /// - ///Sends repeated `GET` requests to `/system/certificates` until there are - /// no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn certificate_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.certificate_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.certificate_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a new system-wide x.509 certificate - /// - ///This certificate is automatically used by the Oxide Control plane to - /// serve external connections. - /// - ///Sends a `POST` request to `/system/certificates` - pub async fn certificate_create<'a>( - &'a self, - body: &'a types::CertificateCreate, - ) -> Result, Error> { - let url = format!("{}/system/certificates", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a certificate - /// - ///Returns the details of a specific certificate - /// - ///Sends a `GET` request to `/system/certificates/{certificate}` - pub async fn certificate_view<'a>( - &'a self, - certificate: &'a types::NameOrId, - ) -> Result, Error> { - let url = format!( - "{}/system/certificates/{}", - self.baseurl, - encode_path(&certificate.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a certificate - /// - ///Permanently delete a certificate. This operation cannot be undone. - /// - ///Sends a `DELETE` request to `/system/certificates/{certificate}` - pub async fn certificate_delete<'a>( - &'a self, - certificate: &'a types::NameOrId, - ) -> Result, Error> { - let url = format!( - "{}/system/certificates/{}", - self.baseurl, - encode_path(&certificate.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List physical disks - /// - ///Sends a `GET` request to `/system/hardware/disks` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn physical_disk_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/hardware/disks", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List physical disks as a Stream - /// - ///Sends repeated `GET` requests to `/system/hardware/disks` until there - /// are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn physical_disk_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.physical_disk_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.physical_disk_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List racks - /// - ///Sends a `GET` request to `/system/hardware/racks` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn rack_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/hardware/racks", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List racks as a Stream - /// - ///Sends repeated `GET` requests to `/system/hardware/racks` until there - /// are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn rack_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.rack_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.rack_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a rack - /// - ///Sends a `GET` request to `/system/hardware/racks/{rack_id}` - /// - ///Arguments: - /// - `rack_id`: The rack's unique ID. - pub async fn rack_view<'a>( - &'a self, - rack_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/hardware/racks/{}", - self.baseurl, - encode_path(&rack_id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List sleds - /// - ///Sends a `GET` request to `/system/hardware/sleds` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn sled_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/hardware/sleds", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List sleds as a Stream - /// - ///Sends repeated `GET` requests to `/system/hardware/sleds` until there - /// are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn sled_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.sled_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.sled_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a sled - /// - ///Sends a `GET` request to `/system/hardware/sleds/{sled_id}` - /// - ///Arguments: - /// - `sled_id`: The sled's unique ID. - pub async fn sled_view<'a>( - &'a self, - sled_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/hardware/sleds/{}", - self.baseurl, - encode_path(&sled_id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List physical disks attached to sleds - /// - ///Sends a `GET` request to `/system/hardware/sleds/{sled_id}/disks` - /// - ///Arguments: - /// - `sled_id`: The sled's unique ID. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn sled_physical_disk_list<'a>( - &'a self, - sled_id: &'a uuid::Uuid, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/system/hardware/sleds/{}/disks", - self.baseurl, - encode_path(&sled_id.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List physical disks attached to sleds as a Stream - /// - ///Sends repeated `GET` requests to - /// `/system/hardware/sleds/{sled_id}/disks` until there are no more - /// results. - /// - ///Arguments: - /// - `sled_id`: The sled's unique ID. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn sled_physical_disk_list_stream<'a>( - &'a self, - sled_id: &'a uuid::Uuid, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.sled_physical_disk_list(sled_id, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.sled_physical_disk_list(sled_id, None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List system-wide images - /// - ///Returns a list of all the system-wide images. System-wide images are - /// returned sorted by creation date, with the most recent images appearing - /// first. - /// - ///Sends a `GET` request to `/system/images` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn system_image_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/images", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List system-wide images as a Stream - /// - ///Returns a list of all the system-wide images. System-wide images are - /// returned sorted by creation date, with the most recent images appearing - /// first. - /// - ///Sends repeated `GET` requests to `/system/images` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn system_image_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.system_image_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.system_image_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a system-wide image - /// - ///Create a new system-wide image. This image can then be used by any user - /// in any silo as a base for instances. - /// - ///Sends a `POST` request to `/system/images` - pub async fn system_image_create<'a>( - &'a self, - body: &'a types::GlobalImageCreate, - ) -> Result, Error> { - let url = format!("{}/system/images", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a system-wide image - /// - ///Returns the details of a specific system-wide image. - /// - ///Sends a `GET` request to `/system/images/{image_name}` - pub async fn system_image_view<'a>( - &'a self, - image_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/images/{}", - self.baseurl, - encode_path(&image_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a system-wide image - /// - ///Permanently delete a system-wide image. This operation cannot be undone. - /// Any instances using the system-wide image will continue to run, however - /// new instances can not be created with this image. - /// - ///Sends a `DELETE` request to `/system/images/{image_name}` - pub async fn system_image_delete<'a>( - &'a self, - image_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/images/{}", - self.baseurl, - encode_path(&image_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List IP pools - /// - ///Sends a `GET` request to `/system/ip-pools` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn ip_pool_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List IP pools as a Stream - /// - ///Sends repeated `GET` requests to `/system/ip-pools` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn ip_pool_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.ip_pool_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.ip_pool_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an IP pool - /// - ///Sends a `POST` request to `/system/ip-pools` - pub async fn ip_pool_create<'a>( - &'a self, - body: &'a types::IpPoolCreate, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an IP pool - /// - ///Sends a `GET` request to `/system/ip-pools/{pool_name}` - pub async fn ip_pool_view<'a>( - &'a self, - pool_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update an IP Pool - /// - ///Sends a `PUT` request to `/system/ip-pools/{pool_name}` - pub async fn ip_pool_update<'a>( - &'a self, - pool_name: &'a types::Name, - body: &'a types::IpPoolUpdate, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an IP Pool - /// - ///Sends a `DELETE` request to `/system/ip-pools/{pool_name}` - pub async fn ip_pool_delete<'a>( - &'a self, - pool_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List ranges for an IP pool - /// - ///Ranges are ordered by their first address. - /// - ///Sends a `GET` request to `/system/ip-pools/{pool_name}/ranges` - /// - ///Arguments: - /// - `pool_name` - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - pub async fn ip_pool_range_list<'a>( - &'a self, - pool_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}/ranges", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List ranges for an IP pool as a Stream - /// - ///Ranges are ordered by their first address. - /// - ///Sends repeated `GET` requests to `/system/ip-pools/{pool_name}/ranges` - /// until there are no more results. - /// - ///Arguments: - /// - `pool_name` - /// - `limit`: Maximum number of items returned by a single call - pub fn ip_pool_range_list_stream<'a>( - &'a self, - pool_name: &'a types::Name, - limit: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.ip_pool_range_list(pool_name, limit, None) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.ip_pool_range_list(pool_name, None, state.as_deref()) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Add a range to an IP pool - /// - ///Sends a `POST` request to `/system/ip-pools/{pool_name}/ranges/add` - pub async fn ip_pool_range_add<'a>( - &'a self, - pool_name: &'a types::Name, - body: &'a types::IpRange, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}/ranges/add", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Remove a range from an IP pool - /// - ///Sends a `POST` request to `/system/ip-pools/{pool_name}/ranges/remove` - pub async fn ip_pool_range_remove<'a>( - &'a self, - pool_name: &'a types::Name, - body: &'a types::IpRange, - ) -> Result, Error> { - let url = format!( - "{}/system/ip-pools/{}/ranges/remove", - self.baseurl, - encode_path(&pool_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch the IP pool used for Oxide services - /// - ///Sends a `GET` request to `/system/ip-pools-service` - pub async fn ip_pool_service_view( - &self, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools-service", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List ranges for the IP pool used for Oxide services - /// - ///Ranges are ordered by their first address. - /// - ///Sends a `GET` request to `/system/ip-pools-service/ranges` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - pub async fn ip_pool_service_range_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools-service/ranges", self.baseurl,); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List ranges for the IP pool used for Oxide services as a Stream - /// - ///Ranges are ordered by their first address. - /// - ///Sends repeated `GET` requests to `/system/ip-pools-service/ranges` until - /// there are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - pub fn ip_pool_service_range_list_stream<'a>( - &'a self, - limit: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.ip_pool_service_range_list(limit, None) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.ip_pool_service_range_list(None, state.as_deref()) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Add a range to an IP pool used for Oxide services - /// - ///Sends a `POST` request to `/system/ip-pools-service/ranges/add` - pub async fn ip_pool_service_range_add<'a>( - &'a self, - body: &'a types::IpRange, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools-service/ranges/add", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Remove a range from an IP pool used for Oxide services - /// - ///Sends a `POST` request to `/system/ip-pools-service/ranges/remove` - pub async fn ip_pool_service_range_remove<'a>( - &'a self, - body: &'a types::IpRange, - ) -> Result, Error> { - let url = format!("{}/system/ip-pools-service/ranges/remove", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Access metrics data - /// - ///Sends a `GET` request to `/system/metrics/{metric_name}` - /// - ///Arguments: - /// - `metric_name` - /// - `end_time`: An exclusive end time of metrics. - /// - `id`: The UUID of the container being queried - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `start_time`: An inclusive start time of metrics. - pub async fn system_metric<'a>( - &'a self, - metric_name: types::SystemMetricName, - end_time: Option<&'a chrono::DateTime>, - id: &'a uuid::Uuid, - limit: Option, - page_token: Option<&'a str>, - start_time: Option<&'a chrono::DateTime>, - ) -> Result, Error> { - let url = format!( - "{}/system/metrics/{}", - self.baseurl, - encode_path(&metric_name.to_string()), - ); - let mut query = Vec::with_capacity(5usize); - if let Some(v) = &end_time { - query.push(("end_time", v.to_string())); - } - - query.push(("id", id.to_string())); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &start_time { - query.push(("start_time", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch the top-level IAM policy - /// - ///Sends a `GET` request to `/system/policy` - pub async fn system_policy_view( - &self, - ) -> Result, Error> { - let url = format!("{}/system/policy", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update the top-level IAM policy - /// - ///Sends a `PUT` request to `/system/policy` - pub async fn system_policy_update<'a>( - &'a self, - body: &'a types::FleetRolePolicy, - ) -> Result, Error> { - let url = format!("{}/system/policy", self.baseurl,); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List sagas - /// - ///Sends a `GET` request to `/system/sagas` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn saga_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/sagas", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List sagas as a Stream - /// - ///Sends repeated `GET` requests to `/system/sagas` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn saga_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.saga_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.saga_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a saga - /// - ///Sends a `GET` request to `/system/sagas/{saga_id}` - pub async fn saga_view<'a>( - &'a self, - saga_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/sagas/{}", - self.baseurl, - encode_path(&saga_id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List silos - /// - ///Lists silos that are discoverable based on the current permissions. - /// - ///Sends a `GET` request to `/system/silos` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn silo_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/silos", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List silos as a Stream - /// - ///Lists silos that are discoverable based on the current permissions. - /// - ///Sends repeated `GET` requests to `/system/silos` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn silo_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.silo_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.silo_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a silo - /// - ///Sends a `POST` request to `/system/silos` - pub async fn silo_create<'a>( - &'a self, - body: &'a types::SiloCreate, - ) -> Result, Error> { - let url = format!("{}/system/silos", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a silo - /// - ///Fetch a silo by name. - /// - ///Sends a `GET` request to `/system/silos/{silo_name}` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - pub async fn silo_view<'a>( - &'a self, - silo_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a silo - /// - ///Delete a silo by name. - /// - ///Sends a `DELETE` request to `/system/silos/{silo_name}` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - pub async fn silo_delete<'a>( - &'a self, - silo_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List a silo's IDPs - /// - ///Sends a `GET` request to `/system/silos/{silo_name}/identity-providers` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn silo_identity_provider_list<'a>( - &'a self, - silo_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List a silo's IDPs as a Stream - /// - ///Sends repeated `GET` requests to - /// `/system/silos/{silo_name}/identity-providers` until there are no more - /// results. - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn silo_identity_provider_list_stream<'a>( - &'a self, - silo_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.silo_identity_provider_list(silo_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.silo_identity_provider_list(silo_name, None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a user - /// - ///Users can only be created in Silos with `provision_type` == `Fixed`. - /// Otherwise, Silo users are just-in-time (JIT) provisioned when a user - /// first logs in using an external Identity Provider. - /// - ///Sends a `POST` request to - /// `/system/silos/{silo_name}/identity-providers/local/users` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `body` - pub async fn local_idp_user_create<'a>( - &'a self, - silo_name: &'a types::Name, - body: &'a types::UserCreate, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers/local/users", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a user - /// - ///Sends a `DELETE` request to - /// `/system/silos/{silo_name}/identity-providers/local/users/{user_id}` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `user_id`: The user's internal id - pub async fn local_idp_user_delete<'a>( - &'a self, - silo_name: &'a types::Name, - user_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers/local/users/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&user_id.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Set or invalidate a user's password - /// - ///Passwords can only be updated for users in Silos with identity mode - /// `LocalOnly`. - /// - ///Sends a `POST` request to - /// `/system/silos/{silo_name}/identity-providers/local/users/{user_id}/ - /// set-password` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `user_id`: The user's internal id - /// - `body` - pub async fn local_idp_user_set_password<'a>( - &'a self, - silo_name: &'a types::Name, - user_id: &'a uuid::Uuid, - body: &'a types::UserPassword, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers/local/users/{}/set-password", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&user_id.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Create a SAML IDP - /// - ///Sends a `POST` request to - /// `/system/silos/{silo_name}/identity-providers/saml` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `body` - pub async fn saml_identity_provider_create<'a>( - &'a self, - silo_name: &'a types::Name, - body: &'a types::SamlIdentityProviderCreate, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers/saml", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a SAML IDP - /// - ///Sends a `GET` request to - /// `/system/silos/{silo_name}/identity-providers/saml/{provider_name}` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `provider_name`: The SAML identity provider's name - pub async fn saml_identity_provider_view<'a>( - &'a self, - silo_name: &'a types::Name, - provider_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/identity-providers/saml/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&provider_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a silo's IAM policy - /// - ///Sends a `GET` request to `/system/silos/{silo_name}/policy` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - pub async fn silo_policy_view<'a>( - &'a self, - silo_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/policy", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a silo's IAM policy - /// - ///Sends a `PUT` request to `/system/silos/{silo_name}/policy` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `body` - pub async fn silo_policy_update<'a>( - &'a self, - silo_name: &'a types::Name, - body: &'a types::SiloRolePolicy, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/policy", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List users in a silo - /// - ///Sends a `GET` request to `/system/silos/{silo_name}/users/all` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn silo_users_list<'a>( - &'a self, - silo_name: &'a types::Name, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/users/all", - self.baseurl, - encode_path(&silo_name.to_string()), - ); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List users in a silo as a Stream - /// - ///Sends repeated `GET` requests to `/system/silos/{silo_name}/users/all` - /// until there are no more results. - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn silo_users_list_stream<'a>( - &'a self, - silo_name: &'a types::Name, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.silo_users_list(silo_name, limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.silo_users_list(silo_name, None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a user - /// - ///Sends a `GET` request to `/system/silos/{silo_name}/users/id/{user_id}` - /// - ///Arguments: - /// - `silo_name`: The silo's unique name. - /// - `user_id`: The user's internal id - pub async fn silo_user_view<'a>( - &'a self, - silo_name: &'a types::Name, - user_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/system/silos/{}/users/id/{}", - self.baseurl, - encode_path(&silo_name.to_string()), - encode_path(&user_id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List built-in users - /// - ///Sends a `GET` request to `/system/user` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn system_user_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/system/user", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List built-in users as a Stream - /// - ///Sends repeated `GET` requests to `/system/user` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn system_user_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.system_user_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.system_user_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a built-in user - /// - ///Sends a `GET` request to `/system/user/{user_name}` - /// - ///Arguments: - /// - `user_name`: The built-in user's unique name. - pub async fn system_user_view<'a>( - &'a self, - user_name: &'a types::Name, - ) -> Result, Error> { - let url = format!( - "{}/system/user/{}", - self.baseurl, - encode_path(&user_name.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List timeseries schema - /// - ///Sends a `GET` request to `/timeseries/schema` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - pub async fn timeseries_schema_get<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - ) -> Result, Error> { - let url = format!("{}/timeseries/schema", self.baseurl,); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List timeseries schema as a Stream - /// - ///Sends repeated `GET` requests to `/timeseries/schema` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - pub fn timeseries_schema_get_stream<'a>( - &'a self, - limit: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.timeseries_schema_get(limit, None) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.timeseries_schema_get(None, state.as_deref()) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List users - /// - ///Sends a `GET` request to `/users` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn user_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/users", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List users as a Stream - /// - ///Sends repeated `GET` requests to `/users` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn user_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.user_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.user_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List disks - /// - ///Sends a `GET` request to `/v1/disks` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `project` - /// - `sort_by` - pub async fn disk_list_v1<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - page_token: Option<&'a str>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/disks", self.baseurl,); - let mut query = Vec::with_capacity(5usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List disks as a Stream - /// - ///Sends repeated `GET` requests to `/v1/disks` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `project` - /// - `sort_by` - pub fn disk_list_v1_stream<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.disk_list_v1(limit, organization, None, project, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.disk_list_v1(None, None, state.as_deref(), None, None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a disk - /// - ///Sends a `POST` request to `/v1/disks` - pub async fn disk_create_v1<'a>( - &'a self, - organization: Option<&'a types::NameOrId>, - project: &'a types::NameOrId, - body: &'a types::DiskCreate, - ) -> Result, Error> { - let url = format!("{}/v1/disks", self.baseurl,); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - query.push(("project", project.to_string())); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a disk - /// - ///Sends a `GET` request to `/v1/disks/{disk}` - pub async fn disk_view_v1<'a>( - &'a self, - disk: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/disks/{}", - self.baseurl, - encode_path(&disk.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a disk - /// - ///Sends a `DELETE` request to `/v1/disks/{disk}` - pub async fn disk_delete_v1<'a>( - &'a self, - disk: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/disks/{}", - self.baseurl, - encode_path(&disk.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List instances - /// - ///Sends a `GET` request to `/v1/instances` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `project` - /// - `sort_by` - pub async fn instance_list_v1<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - page_token: Option<&'a str>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/instances", self.baseurl,); - let mut query = Vec::with_capacity(5usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List instances as a Stream - /// - ///Sends repeated `GET` requests to `/v1/instances` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `project` - /// - `sort_by` - pub fn instance_list_v1_stream<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.instance_list_v1(limit, organization, None, project, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.instance_list_v1(None, None, state.as_deref(), None, None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an instance - /// - ///Sends a `POST` request to `/v1/instances` - pub async fn instance_create_v1<'a>( - &'a self, - organization: Option<&'a types::NameOrId>, - project: &'a types::NameOrId, - body: &'a types::InstanceCreate, - ) -> Result, Error> { - let url = format!("{}/v1/instances", self.baseurl,); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - query.push(("project", project.to_string())); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an instance - /// - ///Sends a `GET` request to `/v1/instances/{instance}` - pub async fn instance_view_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an instance - /// - ///Sends a `DELETE` request to `/v1/instances/{instance}` - pub async fn instance_delete_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List an instance's disks - /// - ///Sends a `GET` request to `/v1/instances/{instance}/disks` - /// - ///Arguments: - /// - `instance` - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `project` - /// - `sort_by` - pub async fn instance_disk_list_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - limit: Option, - organization: Option<&'a types::NameOrId>, - page_token: Option<&'a str>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/disks", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(5usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List an instance's disks as a Stream - /// - ///Sends repeated `GET` requests to `/v1/instances/{instance}/disks` until - /// there are no more results. - /// - ///Arguments: - /// - `instance` - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `project` - /// - `sort_by` - pub fn instance_disk_list_v1_stream<'a>( - &'a self, - instance: &'a types::NameOrId, - limit: Option, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.instance_disk_list_v1(instance, limit, organization, None, project, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.instance_disk_list_v1( - instance, - None, - None, - state.as_deref(), - None, - None, - ) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Attach a disk to an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/disks/attach` - pub async fn instance_disk_attach_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - body: &'a types::DiskPath, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/disks/attach", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Detach a disk from an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/disks/detach` - pub async fn instance_disk_detach_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - body: &'a types::DiskPath, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/disks/detach", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Migrate an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/migrate` - pub async fn instance_migrate_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - body: &'a types::InstanceMigrate, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/migrate", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Reboot an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/reboot` - pub async fn instance_reboot_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/reboot", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an instance's serial console - /// - ///Sends a `GET` request to `/v1/instances/{instance}/serial-console` - /// - ///Arguments: - /// - `instance` - /// - `from_start`: Character index in the serial buffer from which to read, - /// counting the bytes output since instance start. If this is not - /// provided, `most_recent` must be provided, and if this *is* provided, - /// `most_recent` must *not* be provided. - /// - `max_bytes`: Maximum number of bytes of buffered serial console - /// contents to return. If the requested range runs to the end of the - /// available buffer, the data returned will be shorter than `max_bytes`. - /// - `most_recent`: Character index in the serial buffer from which to - /// read, counting *backward* from the most recently buffered data - /// retrieved from the instance. (See note on `from_start` about mutual - /// exclusivity) - /// - `organization` - /// - `project` - pub async fn instance_serial_console_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - from_start: Option, - max_bytes: Option, - most_recent: Option, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/serial-console", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(5usize); - if let Some(v) = &from_start { - query.push(("from_start", v.to_string())); - } - - if let Some(v) = &max_bytes { - query.push(("max_bytes", v.to_string())); - } - - if let Some(v) = &most_recent { - query.push(("most_recent", v.to_string())); - } - - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Stream an instance's serial console - /// - ///Sends a `GET` request to - /// `/v1/instances/{instance}/serial-console/stream` - pub async fn instance_serial_console_stream_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/serial-console/stream", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .get(url) - .query(&query) - .header(reqwest::header::CONNECTION, "Upgrade") - .header(reqwest::header::UPGRADE, "websocket") - .header(reqwest::header::SEC_WEBSOCKET_VERSION, "13") - .header( - reqwest::header::SEC_WEBSOCKET_KEY, - base64::Engine::encode( - &base64::engine::general_purpose::STANDARD, - rand::random::<[u8; 16]>(), - ), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 101u16 => ResponseValue::upgrade(response).await, - 200..=299 => ResponseValue::upgrade(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Boot an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/start` - pub async fn instance_start_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/start", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Stop an instance - /// - ///Sends a `POST` request to `/v1/instances/{instance}/stop` - pub async fn instance_stop_v1<'a>( - &'a self, - instance: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - project: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/instances/{}/stop", - self.baseurl, - encode_path(&instance.to_string()), - ); - let mut query = Vec::with_capacity(2usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &project { - query.push(("project", v.to_string())); - } - - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List organizations - /// - ///Sends a `GET` request to `/v1/organizations` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn organization_list_v1<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/organizations", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List organizations as a Stream - /// - ///Sends repeated `GET` requests to `/v1/organizations` until there are no - /// more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn organization_list_v1_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.organization_list_v1(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.organization_list_v1(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create an organization - /// - ///Sends a `POST` request to `/v1/organizations` - pub async fn organization_create_v1<'a>( - &'a self, - body: &'a types::OrganizationCreate, - ) -> Result, Error> { - let url = format!("{}/v1/organizations", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an organization - /// - ///Sends a `GET` request to `/v1/organizations/{organization}` - pub async fn organization_view_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - ) -> Result, Error> { - let url = format!( - "{}/v1/organizations/{}", - self.baseurl, - encode_path(&organization.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update an organization - /// - ///Sends a `PUT` request to `/v1/organizations/{organization}` - pub async fn organization_update_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - body: &'a types::OrganizationUpdate, - ) -> Result, Error> { - let url = format!( - "{}/v1/organizations/{}", - self.baseurl, - encode_path(&organization.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete an organization - /// - ///Sends a `DELETE` request to `/v1/organizations/{organization}` - pub async fn organization_delete_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - ) -> Result, Error> { - let url = format!( - "{}/v1/organizations/{}", - self.baseurl, - encode_path(&organization.to_string()), - ); - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch an organization's IAM policy - /// - ///Sends a `GET` request to `/v1/organizations/{organization}/policy` - pub async fn organization_policy_view_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - ) -> Result, Error> { - let url = format!( - "{}/v1/organizations/{}/policy", - self.baseurl, - encode_path(&organization.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update an organization's IAM policy - /// - ///Sends a `PUT` request to `/v1/organizations/{organization}/policy` - pub async fn organization_policy_update_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - body: &'a types::OrganizationRolePolicy, - ) -> Result, Error> { - let url = format!( - "{}/v1/organizations/{}/policy", - self.baseurl, - encode_path(&organization.to_string()), - ); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List projects - /// - ///Sends a `GET` request to `/v1/projects` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn project_list_v1<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/projects", self.baseurl,); - let mut query = Vec::with_capacity(4usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List projects as a Stream - /// - ///Sends repeated `GET` requests to `/v1/projects` until there are no more - /// results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `organization` - /// - `sort_by` - pub fn project_list_v1_stream<'a>( - &'a self, - limit: Option, - organization: Option<&'a types::NameOrId>, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.project_list_v1(limit, organization, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.project_list_v1(None, None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Create a project - /// - ///Sends a `POST` request to `/v1/projects` - pub async fn project_create_v1<'a>( - &'a self, - organization: &'a types::NameOrId, - body: &'a types::ProjectCreate, - ) -> Result, Error> { - let url = format!("{}/v1/projects", self.baseurl,); - let mut query = Vec::with_capacity(1usize); - query.push(("organization", organization.to_string())); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a project - /// - ///Sends a `GET` request to `/v1/projects/{project}` - pub async fn project_view_v1<'a>( - &'a self, - project: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/projects/{}", - self.baseurl, - encode_path(&project.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a project - /// - ///Sends a `PUT` request to `/v1/projects/{project}` - pub async fn project_update_v1<'a>( - &'a self, - project: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - body: &'a types::ProjectUpdate, - ) -> Result, Error> { - let url = format!( - "{}/v1/projects/{}", - self.baseurl, - encode_path(&project.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Delete a project - /// - ///Sends a `DELETE` request to `/v1/projects/{project}` - pub async fn project_delete_v1<'a>( - &'a self, - project: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/projects/{}", - self.baseurl, - encode_path(&project.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - let request = self - .client - .delete(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Fetch a project's IAM policy - /// - ///Sends a `GET` request to `/v1/projects/{project}/policy` - pub async fn project_policy_view_v1<'a>( - &'a self, - project: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - ) -> Result, Error> { - let url = format!( - "{}/v1/projects/{}/policy", - self.baseurl, - encode_path(&project.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Update a project's IAM policy - /// - ///Sends a `PUT` request to `/v1/projects/{project}/policy` - pub async fn project_policy_update_v1<'a>( - &'a self, - project: &'a types::NameOrId, - organization: Option<&'a types::NameOrId>, - body: &'a types::ProjectRolePolicy, - ) -> Result, Error> { - let url = format!( - "{}/v1/projects/{}/policy", - self.baseurl, - encode_path(&project.to_string()), - ); - let mut query = Vec::with_capacity(1usize); - if let Some(v) = &organization { - query.push(("organization", v.to_string())); - } - - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///View version and update status of component tree - /// - ///Sends a `GET` request to `/v1/system/update/components` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn system_component_version_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/system/update/components", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///View version and update status of component tree as a Stream - /// - ///Sends repeated `GET` requests to `/v1/system/update/components` until - /// there are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn system_component_version_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.system_component_version_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.system_component_version_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///List all update deployments - /// - ///Sends a `GET` request to `/v1/system/update/deployments` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn update_deployments_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/system/update/deployments", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List all update deployments as a Stream - /// - ///Sends repeated `GET` requests to `/v1/system/update/deployments` until - /// there are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn update_deployments_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.update_deployments_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.update_deployments_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///Fetch a system update deployment - /// - ///Sends a `GET` request to `/v1/system/update/deployments/{id}` - pub async fn update_deployment_view<'a>( - &'a self, - id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/v1/system/update/deployments/{}", - self.baseurl, - encode_path(&id.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Refresh update data - /// - ///Sends a `POST` request to `/v1/system/update/refresh` - pub async fn system_update_refresh(&self) -> Result, Error> { - let url = format!("{}/v1/system/update/refresh", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Start system update - /// - ///Sends a `POST` request to `/v1/system/update/start` - pub async fn system_update_start<'a>( - &'a self, - body: &'a types::SystemUpdateStart, - ) -> Result, Error> { - let url = format!("{}/v1/system/update/start", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 202u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Stop system update - /// - ///If there is no update in progress, do nothing. - /// - ///Sends a `POST` request to `/v1/system/update/stop` - pub async fn system_update_stop(&self) -> Result, Error> { - let url = format!("{}/v1/system/update/stop", self.baseurl,); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List all updates - /// - ///Sends a `GET` request to `/v1/system/update/updates` - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `page_token`: Token returned by previous call to retrieve the - /// subsequent page - /// - `sort_by` - pub async fn system_update_list<'a>( - &'a self, - limit: Option, - page_token: Option<&'a str>, - sort_by: Option, - ) -> Result, Error> { - let url = format!("{}/v1/system/update/updates", self.baseurl,); - let mut query = Vec::with_capacity(3usize); - if let Some(v) = &limit { - query.push(("limit", v.to_string())); - } - - if let Some(v) = &page_token { - query.push(("page_token", v.to_string())); - } - - if let Some(v) = &sort_by { - query.push(("sort_by", v.to_string())); - } - - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .query(&query) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///List all updates as a Stream - /// - ///Sends repeated `GET` requests to `/v1/system/update/updates` until there - /// are no more results. - /// - ///Arguments: - /// - `limit`: Maximum number of items returned by a single call - /// - `sort_by` - pub fn system_update_list_stream<'a>( - &'a self, - limit: Option, - sort_by: Option, - ) -> impl futures::Stream>> + Unpin + '_ - { - use futures::StreamExt; - use futures::TryFutureExt; - use futures::TryStreamExt; - let final_stream_limit = limit - .clone() - .and_then(|x| std::num::NonZeroUsize::try_from(x).ok()) - .map(std::num::NonZeroUsize::get) - .unwrap_or(usize::MAX); - self.system_update_list(limit, None, sort_by) - .map_ok(move |page| { - let page = page.into_inner(); - let first = futures::stream::iter(page.items).map(Ok); - let rest = futures::stream::try_unfold(page.next_page, move |state| async move { - if state.is_none() { - Ok(None) - } else { - self.system_update_list(None, state.as_deref(), None) - .map_ok(|page| { - let page = page.into_inner(); - Some((futures::stream::iter(page.items).map(Ok), page.next_page)) - }) - .await - } - }) - .try_flatten(); - first.chain(rest) - }) - .try_flatten_stream() - .take(final_stream_limit) - .boxed() - } - - ///View system update - /// - ///Sends a `GET` request to `/v1/system/update/updates/{version}` - pub async fn system_update_view<'a>( - &'a self, - version: &'a types::SemverVersion, - ) -> Result, Error> { - let url = format!( - "{}/v1/system/update/updates/{}", - self.baseurl, - encode_path(&version.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///View system update component tree - /// - ///Sends a `GET` request to - /// `/v1/system/update/updates/{version}/components` - pub async fn system_update_components_list<'a>( - &'a self, - version: &'a types::SemverVersion, - ) -> Result, Error> { - let url = format!( - "{}/v1/system/update/updates/{}/components", - self.baseurl, - encode_path(&version.to_string()), - ); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///View system version and update status - /// - ///Sends a `GET` request to `/v1/system/update/version` - pub async fn system_version( - &self, - ) -> Result, Error> { - let url = format!("{}/v1/system/update/version", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } -} - -pub mod prelude { - pub use super::Client; -} diff --git a/progenitor-impl/tests/output/propolis-server-positional.out b/progenitor-impl/tests/output/propolis-server-positional.out deleted file mode 100644 index cc394fe7..00000000 --- a/progenitor-impl/tests/output/propolis-server-positional.out +++ /dev/null @@ -1,880 +0,0 @@ -#[allow(unused_imports)] -use progenitor_client::{encode_path, RequestBuilderExt}; -pub use progenitor_client::{ByteStream, Error, ResponseValue}; -#[allow(unused_imports)] -use reqwest::header::{HeaderMap, HeaderValue}; -pub mod types { - use serde::{Deserialize, Serialize}; - #[allow(unused_imports)] - use std::convert::TryFrom; - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct CrucibleOpts { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub cert_pem: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub control: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub flush_timeout: Option, - pub id: uuid::Uuid, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub key: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub key_pem: Option, - pub lossy: bool, - pub read_only: bool, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub root_cert_pem: Option, - pub target: Vec, - } - - impl From<&CrucibleOpts> for CrucibleOpts { - fn from(value: &CrucibleOpts) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskAttachment { - pub disk_id: uuid::Uuid, - pub generation_id: u64, - pub state: DiskAttachmentState, - } - - impl From<&DiskAttachment> for DiskAttachment { - fn from(value: &DiskAttachment) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub enum DiskAttachmentState { - Detached, - Destroyed, - Faulted, - Attached(uuid::Uuid), - } - - impl From<&DiskAttachmentState> for DiskAttachmentState { - fn from(value: &DiskAttachmentState) -> Self { - value.clone() - } - } - - impl From for DiskAttachmentState { - fn from(value: uuid::Uuid) -> Self { - Self::Attached(value) - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct DiskRequest { - pub device: String, - pub gen: u64, - pub name: String, - pub read_only: bool, - pub slot: Slot, - pub volume_construction_request: VolumeConstructionRequest, - } - - impl From<&DiskRequest> for DiskRequest { - fn from(value: &DiskRequest) -> Self { - value.clone() - } - } - - ///Error information from a response. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Error { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub error_code: Option, - pub message: String, - pub request_id: String, - } - - impl From<&Error> for Error { - fn from(value: &Error) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Instance { - pub disks: Vec, - pub nics: Vec, - pub properties: InstanceProperties, - pub state: InstanceState, - } - - impl From<&Instance> for Instance { - fn from(value: &Instance) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceEnsureRequest { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub cloud_init_bytes: Option, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub disks: Vec, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub migrate: Option, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub nics: Vec, - pub properties: InstanceProperties, - } - - impl From<&InstanceEnsureRequest> for InstanceEnsureRequest { - fn from(value: &InstanceEnsureRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceEnsureResponse { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub migrate: Option, - } - - impl From<&InstanceEnsureResponse> for InstanceEnsureResponse { - fn from(value: &InstanceEnsureResponse) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceGetResponse { - pub instance: Instance, - } - - impl From<&InstanceGetResponse> for InstanceGetResponse { - fn from(value: &InstanceGetResponse) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceMigrateInitiateRequest { - pub migration_id: uuid::Uuid, - pub src_addr: String, - pub src_uuid: uuid::Uuid, - } - - impl From<&InstanceMigrateInitiateRequest> for InstanceMigrateInitiateRequest { - fn from(value: &InstanceMigrateInitiateRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceMigrateInitiateResponse { - pub migration_id: uuid::Uuid, - } - - impl From<&InstanceMigrateInitiateResponse> for InstanceMigrateInitiateResponse { - fn from(value: &InstanceMigrateInitiateResponse) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceMigrateStatusRequest { - pub migration_id: uuid::Uuid, - } - - impl From<&InstanceMigrateStatusRequest> for InstanceMigrateStatusRequest { - fn from(value: &InstanceMigrateStatusRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceMigrateStatusResponse { - pub state: MigrationState, - } - - impl From<&InstanceMigrateStatusResponse> for InstanceMigrateStatusResponse { - fn from(value: &InstanceMigrateStatusResponse) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceProperties { - ///ID of the bootrom used to initialize this Instance. - pub bootrom_id: uuid::Uuid, - ///Free-form text description of an Instance. - pub description: String, - ///Unique identifier for this Instance. - pub id: uuid::Uuid, - ///ID of the image used to initialize this Instance. - pub image_id: uuid::Uuid, - ///Size of memory allocated to the Instance, in MiB. - pub memory: u64, - ///Human-readable name of the Instance. - pub name: String, - ///Number of vCPUs to be allocated to the Instance. - pub vcpus: u8, - } - - impl From<&InstanceProperties> for InstanceProperties { - fn from(value: &InstanceProperties) -> Self { - value.clone() - } - } - - ///Current state of an Instance. - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum InstanceState { - Creating, - Starting, - Running, - Stopping, - Stopped, - Rebooting, - Migrating, - Repairing, - Failed, - Destroyed, - } - - impl From<&InstanceState> for InstanceState { - fn from(value: &InstanceState) -> Self { - value.clone() - } - } - - impl ToString for InstanceState { - fn to_string(&self) -> String { - match *self { - Self::Creating => "Creating".to_string(), - Self::Starting => "Starting".to_string(), - Self::Running => "Running".to_string(), - Self::Stopping => "Stopping".to_string(), - Self::Stopped => "Stopped".to_string(), - Self::Rebooting => "Rebooting".to_string(), - Self::Migrating => "Migrating".to_string(), - Self::Repairing => "Repairing".to_string(), - Self::Failed => "Failed".to_string(), - Self::Destroyed => "Destroyed".to_string(), - } - } - } - - impl std::str::FromStr for InstanceState { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "Creating" => Ok(Self::Creating), - "Starting" => Ok(Self::Starting), - "Running" => Ok(Self::Running), - "Stopping" => Ok(Self::Stopping), - "Stopped" => Ok(Self::Stopped), - "Rebooting" => Ok(Self::Rebooting), - "Migrating" => Ok(Self::Migrating), - "Repairing" => Ok(Self::Repairing), - "Failed" => Ok(Self::Failed), - "Destroyed" => Ok(Self::Destroyed), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for InstanceState { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for InstanceState { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for InstanceState { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceStateMonitorRequest { - pub gen: u64, - } - - impl From<&InstanceStateMonitorRequest> for InstanceStateMonitorRequest { - fn from(value: &InstanceStateMonitorRequest) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct InstanceStateMonitorResponse { - pub gen: u64, - pub state: InstanceState, - } - - impl From<&InstanceStateMonitorResponse> for InstanceStateMonitorResponse { - fn from(value: &InstanceStateMonitorResponse) -> Self { - value.clone() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum InstanceStateRequested { - Run, - Stop, - Reboot, - MigrateStart, - } - - impl From<&InstanceStateRequested> for InstanceStateRequested { - fn from(value: &InstanceStateRequested) -> Self { - value.clone() - } - } - - impl ToString for InstanceStateRequested { - fn to_string(&self) -> String { - match *self { - Self::Run => "Run".to_string(), - Self::Stop => "Stop".to_string(), - Self::Reboot => "Reboot".to_string(), - Self::MigrateStart => "MigrateStart".to_string(), - } - } - } - - impl std::str::FromStr for InstanceStateRequested { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "Run" => Ok(Self::Run), - "Stop" => Ok(Self::Stop), - "Reboot" => Ok(Self::Reboot), - "MigrateStart" => Ok(Self::MigrateStart), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for InstanceStateRequested { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for InstanceStateRequested { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for InstanceStateRequested { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] - pub enum MigrationState { - Sync, - RamPush, - Pause, - RamPushDirty, - Device, - Arch, - Resume, - RamPull, - Finish, - Error, - } - - impl From<&MigrationState> for MigrationState { - fn from(value: &MigrationState) -> Self { - value.clone() - } - } - - impl ToString for MigrationState { - fn to_string(&self) -> String { - match *self { - Self::Sync => "Sync".to_string(), - Self::RamPush => "RamPush".to_string(), - Self::Pause => "Pause".to_string(), - Self::RamPushDirty => "RamPushDirty".to_string(), - Self::Device => "Device".to_string(), - Self::Arch => "Arch".to_string(), - Self::Resume => "Resume".to_string(), - Self::RamPull => "RamPull".to_string(), - Self::Finish => "Finish".to_string(), - Self::Error => "Error".to_string(), - } - } - } - - impl std::str::FromStr for MigrationState { - type Err = &'static str; - fn from_str(value: &str) -> Result { - match value { - "Sync" => Ok(Self::Sync), - "RamPush" => Ok(Self::RamPush), - "Pause" => Ok(Self::Pause), - "RamPushDirty" => Ok(Self::RamPushDirty), - "Device" => Ok(Self::Device), - "Arch" => Ok(Self::Arch), - "Resume" => Ok(Self::Resume), - "RamPull" => Ok(Self::RamPull), - "Finish" => Ok(Self::Finish), - "Error" => Ok(Self::Error), - _ => Err("invalid value"), - } - } - } - - impl std::convert::TryFrom<&str> for MigrationState { - type Error = &'static str; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for MigrationState { - type Error = &'static str; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for MigrationState { - type Error = &'static str; - fn try_from(value: String) -> Result { - value.parse() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterface { - pub attachment: NetworkInterfaceAttachmentState, - pub name: String, - } - - impl From<&NetworkInterface> for NetworkInterface { - fn from(value: &NetworkInterface) -> Self { - value.clone() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub enum NetworkInterfaceAttachmentState { - Detached, - Faulted, - Attached(Slot), - } - - impl From<&NetworkInterfaceAttachmentState> for NetworkInterfaceAttachmentState { - fn from(value: &NetworkInterfaceAttachmentState) -> Self { - value.clone() - } - } - - impl From for NetworkInterfaceAttachmentState { - fn from(value: Slot) -> Self { - Self::Attached(value) - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct NetworkInterfaceRequest { - pub name: String, - pub slot: Slot, - } - - impl From<&NetworkInterfaceRequest> for NetworkInterfaceRequest { - fn from(value: &NetworkInterfaceRequest) -> Self { - value.clone() - } - } - - ///A stable index which is translated by Propolis into a PCI BDF, visible - /// to the guest. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Slot(pub u8); - impl std::ops::Deref for Slot { - type Target = u8; - fn deref(&self) -> &u8 { - &self.0 - } - } - - impl From for u8 { - fn from(value: Slot) -> Self { - value.0 - } - } - - impl From<&Slot> for Slot { - fn from(value: &Slot) -> Self { - value.clone() - } - } - - impl From for Slot { - fn from(value: u8) -> Self { - Self(value) - } - } - - impl std::str::FromStr for Slot { - type Err = ::Err; - fn from_str(value: &str) -> Result { - Ok(Self(value.parse()?)) - } - } - - impl std::convert::TryFrom<&str> for Slot { - type Error = ::Err; - fn try_from(value: &str) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom<&String> for Slot { - type Error = ::Err; - fn try_from(value: &String) -> Result { - value.parse() - } - } - - impl std::convert::TryFrom for Slot { - type Error = ::Err; - fn try_from(value: String) -> Result { - value.parse() - } - } - - impl ToString for Slot { - fn to_string(&self) -> String { - self.0.to_string() - } - } - - #[derive(Clone, Debug, Deserialize, Serialize)] - #[serde(tag = "type")] - pub enum VolumeConstructionRequest { - #[serde(rename = "volume")] - Volume { - block_size: u64, - id: uuid::Uuid, - #[serde(default, skip_serializing_if = "Option::is_none")] - read_only_parent: Option>, - sub_volumes: Vec, - }, - #[serde(rename = "url")] - Url { - block_size: u64, - id: uuid::Uuid, - url: String, - }, - #[serde(rename = "region")] - Region { - block_size: u64, - gen: u64, - opts: CrucibleOpts, - }, - #[serde(rename = "file")] - File { - block_size: u64, - id: uuid::Uuid, - path: String, - }, - } - - impl From<&VolumeConstructionRequest> for VolumeConstructionRequest { - fn from(value: &VolumeConstructionRequest) -> Self { - value.clone() - } - } -} - -#[derive(Clone, Debug)] -///Client for Oxide Propolis Server API -/// -///API for interacting with the Propolis hypervisor frontend. -/// -///Version: 0.0.1 -pub struct Client { - pub(crate) baseurl: String, - pub(crate) client: reqwest::Client, -} - -impl Client { - /// Create a new client. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new(baseurl: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] - let client = { - let dur = std::time::Duration::from_secs(15); - reqwest::ClientBuilder::new() - .connect_timeout(dur) - .timeout(dur) - }; - #[cfg(target_arch = "wasm32")] - let client = reqwest::ClientBuilder::new(); - Self::new_with_client(baseurl, client.build().unwrap()) - } - - /// Construct a new client with an existing `reqwest::Client`, - /// allowing more control over its configuration. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { - Self { - baseurl: baseurl.to_string(), - client, - } - } - - /// Get the base URL to which requests are made. - pub fn baseurl(&self) -> &String { - &self.baseurl - } - - /// Get the internal `reqwest::Client` used to make requests. - pub fn client(&self) -> &reqwest::Client { - &self.client - } - - /// Get the version of this API. - /// - /// This string is pulled directly from the source OpenAPI - /// document and may be in any format the API selects. - pub fn api_version(&self) -> &'static str { - "0.0.1" - } -} - -impl Client { - ///Sends a `GET` request to `/instance` - pub async fn instance_get( - &self, - ) -> Result, Error> { - let url = format!("{}/instance", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `PUT` request to `/instance` - pub async fn instance_ensure<'a>( - &'a self, - body: &'a types::InstanceEnsureRequest, - ) -> Result, Error> { - let url = format!("{}/instance", self.baseurl,); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 201u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Issue a snapshot request to a crucible backend - /// - ///Sends a `POST` request to `/instance/disk/{id}/snapshot/{snapshot_id}` - pub async fn instance_issue_crucible_snapshot_request<'a>( - &'a self, - id: &'a uuid::Uuid, - snapshot_id: &'a uuid::Uuid, - ) -> Result, Error> { - let url = format!( - "{}/instance/disk/{}/snapshot/{}", - self.baseurl, - encode_path(&id.to_string()), - encode_path(&snapshot_id.to_string()), - ); - let request = self - .client - .post(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/instance/migrate/status` - pub async fn instance_migrate_status<'a>( - &'a self, - body: &'a types::InstanceMigrateStatusRequest, - ) -> Result, Error> { - let url = format!("{}/instance/migrate/status", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/instance/serial` - pub async fn instance_serial( - &self, - ) -> Result, Error> { - let url = format!("{}/instance/serial", self.baseurl,); - let request = self - .client - .get(url) - .header(reqwest::header::CONNECTION, "Upgrade") - .header(reqwest::header::UPGRADE, "websocket") - .header(reqwest::header::SEC_WEBSOCKET_VERSION, "13") - .header( - reqwest::header::SEC_WEBSOCKET_KEY, - base64::Engine::encode( - &base64::engine::general_purpose::STANDARD, - rand::random::<[u8; 16]>(), - ), - ) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 101u16 => ResponseValue::upgrade(response).await, - 200..=299 => ResponseValue::upgrade(response).await, - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `PUT` request to `/instance/state` - pub async fn instance_state_put<'a>( - &'a self, - body: types::InstanceStateRequested, - ) -> Result, Error> { - let url = format!("{}/instance/state", self.baseurl,); - let request = self - .client - .put(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 204u16 => Ok(ResponseValue::empty(response)), - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } - - ///Sends a `GET` request to `/instance/state-monitor` - pub async fn instance_state_monitor<'a>( - &'a self, - body: &'a types::InstanceStateMonitorRequest, - ) -> Result, Error> { - let url = format!("{}/instance/state-monitor", self.baseurl,); - let request = self - .client - .get(url) - .header( - reqwest::header::ACCEPT, - reqwest::header::HeaderValue::from_static("application/json"), - ) - .json(&body) - .build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200u16 => ResponseValue::from_response(response).await, - 400u16..=499u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - 500u16..=599u16 => Err(Error::ErrorResponse( - ResponseValue::from_response(response).await?, - )), - _ => Err(Error::UnexpectedResponse(response)), - } - } -} - -pub mod prelude { - pub use super::Client; -} diff --git a/progenitor-impl/tests/output/test_freeform_response.out b/progenitor-impl/tests/output/test_freeform_response.out deleted file mode 100644 index e235bb1d..00000000 --- a/progenitor-impl/tests/output/test_freeform_response.out +++ /dev/null @@ -1,102 +0,0 @@ -#[allow(unused_imports)] -use progenitor_client::{encode_path, RequestBuilderExt}; -pub use progenitor_client::{ByteStream, Error, ResponseValue}; -#[allow(unused_imports)] -use reqwest::header::{HeaderMap, HeaderValue}; -pub mod types { - use serde::{Deserialize, Serialize}; - #[allow(unused_imports)] - use std::convert::TryFrom; - ///Error information from a response. - #[derive(Clone, Debug, Deserialize, Serialize)] - pub struct Error { - #[serde(default, skip_serializing_if = "Option::is_none")] - pub error_code: Option, - pub message: String, - pub request_id: String, - } - - impl From<&Error> for Error { - fn from(value: &Error) -> Self { - value.clone() - } - } -} - -#[derive(Clone, Debug)] -///Client for pagination-demo -/// -///Version: 9000 -pub struct Client { - pub(crate) baseurl: String, - pub(crate) client: reqwest::Client, -} - -impl Client { - /// Create a new client. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new(baseurl: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] - let client = { - let dur = std::time::Duration::from_secs(15); - reqwest::ClientBuilder::new() - .connect_timeout(dur) - .timeout(dur) - }; - #[cfg(target_arch = "wasm32")] - let client = reqwest::ClientBuilder::new(); - Self::new_with_client(baseurl, client.build().unwrap()) - } - - /// Construct a new client with an existing `reqwest::Client`, - /// allowing more control over its configuration. - /// - /// `baseurl` is the base URL provided to the internal - /// `reqwest::Client`, and should include a scheme and hostname, - /// as well as port and a path stem if applicable. - pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { - Self { - baseurl: baseurl.to_string(), - client, - } - } - - /// Get the base URL to which requests are made. - pub fn baseurl(&self) -> &String { - &self.baseurl - } - - /// Get the internal `reqwest::Client` used to make requests. - pub fn client(&self) -> &reqwest::Client { - &self.client - } - - /// Get the version of this API. - /// - /// This string is pulled directly from the source OpenAPI - /// document and may be in any format the API selects. - pub fn api_version(&self) -> &'static str { - "9000" - } -} - -impl Client { - ///Sends a `GET` request to `/` - pub async fn freeform_response(&self) -> Result, Error> { - let url = format!("{}/", self.baseurl,); - let request = self.client.get(url).build()?; - let result = self.client.execute(request).await; - let response = result?; - match response.status().as_u16() { - 200..=299 => Ok(ResponseValue::stream(response)), - _ => Err(Error::ErrorResponse(ResponseValue::stream(response))), - } - } -} - -pub mod prelude { - pub use super::Client; -} From acfa8c082de338aa4582dc51deacfb0c3799da56 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 9 Oct 2025 11:00:56 -0700 Subject: [PATCH 4/6] rework --- progenitor-impl/src/method.rs | 63 ++++++++++--------- .../tests/output/src/buildomat_positional.rs | 5 +- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index 89f1b8b4..9ff112fc 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -555,6 +555,9 @@ impl Generator { ) -> Result { let operation_id = format_ident!("{}", method.operation_id); + let mut needs_lifetime = false; + let mut needs_body = false; + // Render each parameter as it will appear in the method signature. let params = method .params @@ -562,12 +565,15 @@ impl Generator { .map(|param| { let name = format_ident!("{}", param.name); let typ = match (¶m.typ, param.kind.is_optional()) { - (OperationParameterType::Type(type_id), false) => self - .type_space - .get_type(type_id) - .unwrap() - .parameter_ident_with_lifetime("a"), + (OperationParameterType::Type(type_id), false) => { + needs_lifetime = true; + self.type_space + .get_type(type_id) + .unwrap() + .parameter_ident_with_lifetime("a") + } (OperationParameterType::Type(type_id), true) => { + needs_lifetime = true; let t = self .type_space .get_type(type_id) @@ -577,6 +583,7 @@ impl Generator { } (OperationParameterType::RawBody, false) => match ¶m.kind { OperationParameterKind::Body(BodyContentType::OctetStream) => { + needs_body = true; quote! { B } } OperationParameterKind::Body(BodyContentType::Text(_)) => { @@ -603,6 +610,18 @@ impl Generator { quote! { <'a> } }; + let new_bounds = [ + needs_lifetime.then(|| quote! { 'a }), + needs_body.then(|| quote! { B: Into }), + ] + .into_iter() + .flatten() + .collect::>(); + let new_bounds = (!new_bounds.is_empty()).then(|| { + quote! { < #( #new_bounds ),* > } + }); + let self_bounds = needs_lifetime.then(|| quote! { 'a }); + let doc_comment = make_doc_comment(method); let MethodSigBody { @@ -611,30 +630,16 @@ impl Generator { body, } = self.method_sig_body(method, quote! { Self }, quote! { self }, has_inner)?; - let method_impl = if params.is_empty() { - quote! { - #[doc = #doc_comment] - pub async fn #operation_id ( - &self, - ) -> Result< - ResponseValue<#success_type>, - Error<#error_type>, - > { - #body - } - } - } else { - quote! { - #[doc = #doc_comment] - pub async fn #operation_id #bounds ( - &'a self, - #(#params),* - ) -> Result< - ResponseValue<#success_type>, - Error<#error_type>, - > { - #body - } + let method_impl = quote! { + #[doc = #doc_comment] + pub async fn #operation_id #new_bounds ( + & #self_bounds self, + #(#params),* + ) -> Result< + ResponseValue<#success_type>, + Error<#error_type>, + > { + #body } }; diff --git a/progenitor-impl/tests/output/src/buildomat_positional.rs b/progenitor-impl/tests/output/src/buildomat_positional.rs index 8d1da734..9cfd0b6e 100644 --- a/progenitor-impl/tests/output/src/buildomat_positional.rs +++ b/progenitor-impl/tests/output/src/buildomat_positional.rs @@ -1359,10 +1359,7 @@ impl Client { } ///Sends a `PUT` request to `/v1/whoami/name` - pub async fn whoami_put_name<'a>( - &'a self, - body: String, - ) -> Result, Error<()>> { + pub async fn whoami_put_name(&self, body: String) -> Result, Error<()>> { let url = format!("{}/v1/whoami/name", self.baseurl,); let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); header_map.append( From aaed02983a7138cfa482b56163baf40b4aff5f74 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 9 Oct 2025 11:33:35 -0700 Subject: [PATCH 5/6] cleanup --- progenitor-impl/src/method.rs | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index 9ff112fc..697efcdf 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -599,26 +599,15 @@ impl Generator { }) .collect::>(); - let raw_body_param = method.params.iter().any(|param| { - param.typ == OperationParameterType::RawBody - && param.kind == OperationParameterKind::Body(BodyContentType::OctetStream) - }); - - let bounds = if raw_body_param { - quote! { <'a, B: Into > } - } else { - quote! { <'a> } - }; - - let new_bounds = [ + let bounds = [ needs_lifetime.then(|| quote! { 'a }), needs_body.then(|| quote! { B: Into }), ] .into_iter() .flatten() .collect::>(); - let new_bounds = (!new_bounds.is_empty()).then(|| { - quote! { < #( #new_bounds ),* > } + let bounds = (!bounds.is_empty()).then(|| { + quote! { < #( #bounds ),* > } }); let self_bounds = needs_lifetime.then(|| quote! { 'a }); @@ -632,7 +621,7 @@ impl Generator { let method_impl = quote! { #[doc = #doc_comment] - pub async fn #operation_id #new_bounds ( + pub async fn #operation_id #bounds ( & #self_bounds self, #(#params),* ) -> Result< @@ -709,7 +698,7 @@ impl Generator { quote! { #[doc = #doc_comment] pub fn #stream_id #bounds ( - &'a self, + & #self_bounds self, #(#stream_params),* ) -> impl futures::Stream Date: Thu, 9 Oct 2025 11:37:16 -0700 Subject: [PATCH 6/6] a little more cleanup --- progenitor-impl/src/method.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index 697efcdf..a9dcc937 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -607,7 +607,7 @@ impl Generator { .flatten() .collect::>(); let bounds = (!bounds.is_empty()).then(|| { - quote! { < #( #bounds ),* > } + quote! { < #(#bounds),* > } }); let self_bounds = needs_lifetime.then(|| quote! { 'a });