6357 lines
237 KiB
Plaintext
6357 lines
237 KiB
Plaintext
#[allow(unused_imports)]
|
|
use progenitor_client::encode_path;
|
|
pub use progenitor_client::{ByteStream, Error, ResponseValue};
|
|
pub mod types {
|
|
use serde::{Deserialize, Serialize};
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct BlockSize(i64);
|
|
impl std::ops::Deref for BlockSize {
|
|
type Target = i64;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl std::convert::TryFrom<i64> for BlockSize {
|
|
type Error = &'static str;
|
|
fn try_from(value: i64) -> Result<Self, Self::Error> {
|
|
if ![512_i64, 2048_i64, 4096_i64].contains(&value) {
|
|
Err("invalid value")
|
|
} else {
|
|
Ok(Self(value))
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ByteCount(pub u64);
|
|
impl std::ops::Deref for ByteCount {
|
|
type Target = u64;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///The type of an individual datum of a metric.
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
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 ToString for DatumType {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
DatumType::Bool => "bool".to_string(),
|
|
DatumType::I64 => "i64".to_string(),
|
|
DatumType::F64 => "f64".to_string(),
|
|
DatumType::String => "string".to_string(),
|
|
DatumType::Bytes => "bytes".to_string(),
|
|
DatumType::CumulativeI64 => "cumulative_i64".to_string(),
|
|
DatumType::CumulativeF64 => "cumulative_f64".to_string(),
|
|
DatumType::HistogramI64 => "histogram_i64".to_string(),
|
|
DatumType::HistogramF64 => "histogram_f64".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Digest {
|
|
#[serde(rename = "type")]
|
|
pub type_: DigestType,
|
|
pub value: String,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum DigestType {
|
|
#[serde(rename = "sha256")]
|
|
Sha256,
|
|
}
|
|
|
|
impl ToString for DigestType {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
DigestType::Sha256 => "sha256".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///Client view of an [`Disk`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<uuid::Uuid>,
|
|
///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<uuid::Uuid>,
|
|
pub state: DiskState,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`Disk`](omicron_common::api::external::Disk)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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,
|
|
}
|
|
|
|
///Parameters for the [`Disk`](omicron_common::api::external::Disk) to be
|
|
/// attached or detached to an instance
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct DiskIdentifier {
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct DiskResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Disk>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Different sources for a disk
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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 },
|
|
}
|
|
|
|
///State of a Disk (primarily: attached or not)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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,
|
|
}
|
|
|
|
///Error information from a response.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Error {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub error_code: Option<String>,
|
|
pub message: String,
|
|
pub request_id: String,
|
|
}
|
|
|
|
///The name and type information for a field of a timeseries schema.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct FieldSchema {
|
|
pub name: String,
|
|
pub source: FieldSource,
|
|
pub ty: FieldType,
|
|
}
|
|
|
|
///The source from which a field is derived, the target or metric.
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum FieldSource {
|
|
#[serde(rename = "target")]
|
|
Target,
|
|
#[serde(rename = "metric")]
|
|
Metric,
|
|
}
|
|
|
|
impl ToString for FieldSource {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
FieldSource::Target => "target".to_string(),
|
|
FieldSource::Metric => "metric".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///The `FieldType` identifies the data type of a target or metric field.
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
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 ToString for FieldType {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
FieldType::String => "string".to_string(),
|
|
FieldType::I64 => "i64".to_string(),
|
|
FieldType::IpAddr => "ip_addr".to_string(),
|
|
FieldType::Uuid => "uuid".to_string(),
|
|
FieldType::Bool => "bool".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum FleetRoles {
|
|
#[serde(rename = "admin")]
|
|
Admin,
|
|
#[serde(rename = "collaborator")]
|
|
Collaborator,
|
|
#[serde(rename = "viewer")]
|
|
Viewer,
|
|
}
|
|
|
|
impl ToString for FleetRoles {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
FleetRoles::Admin => "admin".to_string(),
|
|
FleetRoles::Collaborator => "collaborator".to_string(),
|
|
FleetRoles::Viewer => "viewer".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct FleetRolesPolicy {
|
|
///Roles directly assigned on this resource
|
|
pub role_assignments: Vec<FleetRolesRoleAssignment>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct FleetRolesRoleAssignment {
|
|
pub identity_id: uuid::Uuid,
|
|
pub identity_type: IdentityType,
|
|
pub role_name: FleetRoles,
|
|
}
|
|
|
|
///Client view of global Images
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<Digest>,
|
|
///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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///URL source of this image, if any
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub url: Option<String>,
|
|
///Version of this, if any
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub version: Option<String>,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct GlobalImageResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<GlobalImage>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Supported set of sort modes for scanning by id only.
|
|
///
|
|
///Currently, we only support scanning in ascending order.
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum IdSortMode {
|
|
#[serde(rename = "id_ascending")]
|
|
IdAscending,
|
|
}
|
|
|
|
impl ToString for IdSortMode {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
IdSortMode::IdAscending => "id_ascending".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///Describes what kind of identity is described by an id
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum IdentityType {
|
|
#[serde(rename = "silo_user")]
|
|
SiloUser,
|
|
}
|
|
|
|
impl ToString for IdentityType {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
IdentityType::SiloUser => "silo_user".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///Client view of project Images
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<Digest>,
|
|
///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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///URL source of this image, if any
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub url: Option<String>,
|
|
///Version of this, if any
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub version: Option<String>,
|
|
}
|
|
|
|
///Create-time parameters for an
|
|
/// [`Image`](omicron_common::api::external::Image)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ImageResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Image>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///The source of the underlying image.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[serde(tag = "type", content = "src")]
|
|
pub enum ImageSource {
|
|
#[serde(rename = "url")]
|
|
Url(String),
|
|
#[serde(rename = "snapshot")]
|
|
Snapshot(uuid::Uuid),
|
|
}
|
|
|
|
///Client view of an [`Instance`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
pub time_run_state_updated: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///The number of CPUs in an Instance
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct InstanceCpuCount(pub u16);
|
|
impl std::ops::Deref for InstanceCpuCount {
|
|
type Target = u16;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///Create-time parameters for an
|
|
/// [`Instance`](omicron_common::api::external::Instance)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<InstanceDiskAttachment>,
|
|
pub hostname: String,
|
|
pub memory: ByteCount,
|
|
pub name: Name,
|
|
pub ncpus: InstanceCpuCount,
|
|
///The network interfaces to be created for this instance.
|
|
#[serde(default = "instance_create_network_interfaces")]
|
|
pub network_interfaces: InstanceNetworkInterfaceAttachment,
|
|
///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,
|
|
}
|
|
|
|
fn instance_create_network_interfaces() -> InstanceNetworkInterfaceAttachment {
|
|
InstanceNetworkInterfaceAttachment::Default
|
|
}
|
|
|
|
///Describe the instance's disks at creation time
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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,
|
|
},
|
|
}
|
|
|
|
///Migration parameters for an
|
|
/// [`Instance`](omicron_common::api::external::Instance)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct InstanceMigrate {
|
|
pub dst_sled_uuid: uuid::Uuid,
|
|
}
|
|
|
|
///Describes an attachment of a `NetworkInterface` to an `Instance`, at the
|
|
/// time the instance is created.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[serde(tag = "type", content = "params")]
|
|
pub enum InstanceNetworkInterfaceAttachment {
|
|
///Create one or more `NetworkInterface`s for the `Instance`
|
|
#[serde(rename = "create")]
|
|
Create(Vec<NetworkInterfaceCreate>),
|
|
#[serde(rename = "default")]
|
|
Default,
|
|
#[serde(rename = "none")]
|
|
None,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct InstanceResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Instance>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum InstanceState {
|
|
#[serde(rename = "creating")]
|
|
Creating,
|
|
#[serde(rename = "starting")]
|
|
Starting,
|
|
#[serde(rename = "running")]
|
|
Running,
|
|
#[serde(rename = "stopping")]
|
|
Stopping,
|
|
#[serde(rename = "stopped")]
|
|
Stopped,
|
|
#[serde(rename = "rebooting")]
|
|
Rebooting,
|
|
#[serde(rename = "migrating")]
|
|
Migrating,
|
|
#[serde(rename = "repairing")]
|
|
Repairing,
|
|
#[serde(rename = "failed")]
|
|
Failed,
|
|
#[serde(rename = "destroyed")]
|
|
Destroyed,
|
|
}
|
|
|
|
impl ToString for InstanceState {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
InstanceState::Creating => "creating".to_string(),
|
|
InstanceState::Starting => "starting".to_string(),
|
|
InstanceState::Running => "running".to_string(),
|
|
InstanceState::Stopping => "stopping".to_string(),
|
|
InstanceState::Stopped => "stopped".to_string(),
|
|
InstanceState::Rebooting => "rebooting".to_string(),
|
|
InstanceState::Migrating => "migrating".to_string(),
|
|
InstanceState::Repairing => "repairing".to_string(),
|
|
InstanceState::Failed => "failed".to_string(),
|
|
InstanceState::Destroyed => "destroyed".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[serde(untagged)]
|
|
pub enum IpNet {
|
|
V4(Ipv4Net),
|
|
V6(Ipv6Net),
|
|
}
|
|
|
|
///An IPv4 subnet, including prefix and subnet mask
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Ipv4Net(pub String);
|
|
impl std::ops::Deref for Ipv4Net {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///An IPv6 subnet, including prefix and subnet mask
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Ipv6Net(pub String);
|
|
impl std::ops::Deref for Ipv6Net {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///An inclusive-inclusive range of IP ports. The second port may be omitted
|
|
/// to represent a single port
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct L4PortRange(pub String);
|
|
impl std::ops::Deref for L4PortRange {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct LoginParams {
|
|
pub username: String,
|
|
}
|
|
|
|
///A Media Access Control address, in EUI-48 format
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct MacAddr(pub String);
|
|
impl std::ops::Deref for MacAddr {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///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 '-'.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Name(pub String);
|
|
impl std::ops::Deref for Name {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///Supported set of sort modes for scanning by name or id
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum NameOrIdSortMode {
|
|
#[serde(rename = "name_ascending")]
|
|
NameAscending,
|
|
#[serde(rename = "name_descending")]
|
|
NameDescending,
|
|
#[serde(rename = "id_ascending")]
|
|
IdAscending,
|
|
}
|
|
|
|
impl ToString for NameOrIdSortMode {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
NameOrIdSortMode::NameAscending => "name_ascending".to_string(),
|
|
NameOrIdSortMode::NameDescending => "name_descending".to_string(),
|
|
NameOrIdSortMode::IdAscending => "id_ascending".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///Supported set of sort modes for scanning by name only
|
|
///
|
|
///Currently, we only support scanning in ascending order.
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum NameSortMode {
|
|
#[serde(rename = "name_ascending")]
|
|
NameAscending,
|
|
}
|
|
|
|
impl ToString for NameSortMode {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
NameSortMode::NameAscending => "name_ascending".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///A `NetworkInterface` represents a virtual network interface device.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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,
|
|
///The subnet to which the interface belongs.
|
|
pub subnet_id: uuid::Uuid,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///The VPC to which the interface belongs.
|
|
pub vpc_id: uuid::Uuid,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`NetworkInterface`](omicron_common::api::external::NetworkInterface)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<std::net::IpAddr>,
|
|
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,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct NetworkInterfaceResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<NetworkInterface>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of an [`Organization`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for an
|
|
/// [`Organization`](crate::external_api::views::Organization)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct OrganizationCreate {
|
|
pub description: String,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct OrganizationResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Organization>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum OrganizationRoles {
|
|
#[serde(rename = "admin")]
|
|
Admin,
|
|
#[serde(rename = "collaborator")]
|
|
Collaborator,
|
|
}
|
|
|
|
impl ToString for OrganizationRoles {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
OrganizationRoles::Admin => "admin".to_string(),
|
|
OrganizationRoles::Collaborator => "collaborator".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct OrganizationRolesPolicy {
|
|
///Roles directly assigned on this resource
|
|
pub role_assignments: Vec<OrganizationRolesRoleAssignment>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct OrganizationRolesRoleAssignment {
|
|
pub identity_id: uuid::Uuid,
|
|
pub identity_type: IdentityType,
|
|
pub role_name: OrganizationRoles,
|
|
}
|
|
|
|
///Updateable properties of an
|
|
/// [`Organization`](crate::external_api::views::Organization)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct OrganizationUpdate {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
}
|
|
|
|
///Client view of a [`Project`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`Project`](crate::external_api::views::Project)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ProjectCreate {
|
|
pub description: String,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ProjectResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Project>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum ProjectRoles {
|
|
#[serde(rename = "admin")]
|
|
Admin,
|
|
#[serde(rename = "collaborator")]
|
|
Collaborator,
|
|
#[serde(rename = "viewer")]
|
|
Viewer,
|
|
}
|
|
|
|
impl ToString for ProjectRoles {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
ProjectRoles::Admin => "admin".to_string(),
|
|
ProjectRoles::Collaborator => "collaborator".to_string(),
|
|
ProjectRoles::Viewer => "viewer".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ProjectRolesPolicy {
|
|
///Roles directly assigned on this resource
|
|
pub role_assignments: Vec<ProjectRolesRoleAssignment>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ProjectRolesRoleAssignment {
|
|
pub identity_id: uuid::Uuid,
|
|
pub identity_type: IdentityType,
|
|
pub role_name: ProjectRoles,
|
|
}
|
|
|
|
///Updateable properties of a
|
|
/// [`Project`](crate::external_api::views::Project)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct ProjectUpdate {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
}
|
|
|
|
///Client view of an [`Rack`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Rack {
|
|
///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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RackResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Rack>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of a [`Role`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Role {
|
|
pub description: String,
|
|
pub name: RoleName,
|
|
}
|
|
|
|
///Role names consist of two string components separated by dot (".").
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RoleName(pub String);
|
|
impl std::ops::Deref for RoleName {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RoleResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Role>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
#[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),
|
|
}
|
|
|
|
///A `RouteTarget` describes the possible locations that traffic matching a
|
|
/// route destination can be sent.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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),
|
|
}
|
|
|
|
///A route defines a rule that governs where traffic should be sent based
|
|
/// on its destination.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///The VPC Router to which the route belongs.
|
|
pub vpc_router_id: uuid::Uuid,
|
|
}
|
|
|
|
///Create-time parameters for a [`RouterRoute`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RouterRouteCreateParams {
|
|
pub description: String,
|
|
pub destination: RouteDestination,
|
|
pub name: Name,
|
|
pub target: RouteTarget,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum RouterRouteKind {
|
|
#[serde(rename = "default")]
|
|
Default,
|
|
#[serde(rename = "vpc_subnet")]
|
|
VpcSubnet,
|
|
#[serde(rename = "vpc_peering")]
|
|
VpcPeering,
|
|
#[serde(rename = "custom")]
|
|
Custom,
|
|
}
|
|
|
|
impl ToString for RouterRouteKind {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
RouterRouteKind::Default => "default".to_string(),
|
|
RouterRouteKind::VpcSubnet => "vpc_subnet".to_string(),
|
|
RouterRouteKind::VpcPeering => "vpc_peering".to_string(),
|
|
RouterRouteKind::Custom => "custom".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RouterRouteResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<RouterRoute>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Updateable properties of a [`RouterRoute`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct RouterRouteUpdateParams {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
pub destination: RouteDestination,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
pub target: RouteTarget,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Saga {
|
|
pub id: uuid::Uuid,
|
|
pub state: SagaState,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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 },
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SagaResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Saga>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[serde(tag = "state")]
|
|
pub enum SagaState {
|
|
#[serde(rename = "running")]
|
|
Running,
|
|
#[serde(rename = "succeeded")]
|
|
Succeeded,
|
|
#[serde(rename = "failed")]
|
|
Failed {
|
|
error_info: SagaErrorInfo,
|
|
error_node_name: String,
|
|
},
|
|
}
|
|
|
|
///Client view of currently authed user.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SessionUser {
|
|
pub id: uuid::Uuid,
|
|
}
|
|
|
|
///Client view of a ['Silo']
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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,
|
|
///unique, mutable, user-controlled identifier for each resource
|
|
pub name: Name,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for a [`Silo`](crate::external_api::views::Silo)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SiloCreate {
|
|
pub description: String,
|
|
pub discoverable: bool,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SiloResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Silo>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum SiloRoles {
|
|
#[serde(rename = "admin")]
|
|
Admin,
|
|
#[serde(rename = "collaborator")]
|
|
Collaborator,
|
|
#[serde(rename = "viewer")]
|
|
Viewer,
|
|
}
|
|
|
|
impl ToString for SiloRoles {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
SiloRoles::Admin => "admin".to_string(),
|
|
SiloRoles::Collaborator => "collaborator".to_string(),
|
|
SiloRoles::Viewer => "viewer".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SiloRolesPolicy {
|
|
///Roles directly assigned on this resource
|
|
pub role_assignments: Vec<SiloRolesRoleAssignment>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SiloRolesRoleAssignment {
|
|
pub identity_id: uuid::Uuid,
|
|
pub identity_type: IdentityType,
|
|
pub role_name: SiloRoles,
|
|
}
|
|
|
|
///Client view of an [`Sled`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct Sled {
|
|
///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_address: String,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SledResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Sled>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of a Snapshot
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`Snapshot`](omicron_common::api::external::Snapshot)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SnapshotCreate {
|
|
pub description: String,
|
|
///The name of the disk to be snapshotted
|
|
pub disk: Name,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SnapshotResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Snapshot>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of a [`SshKey`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for an
|
|
/// [`SshKey`](crate::external_api::views::SshKey)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SshKeyCreate {
|
|
pub description: String,
|
|
pub name: Name,
|
|
///SSH public key, e.g., `"ssh-ed25519 AAAAC3NzaC..."`
|
|
pub public_key: String,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct SshKeyResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<SshKey>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Names are constructed by concatenating the target and metric names with
|
|
/// ':'. Target and metric names must be lowercase alphanumeric characters
|
|
/// with '_' separating words.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct TimeseriesName(pub String);
|
|
impl std::ops::Deref for TimeseriesName {
|
|
type Target = String;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct TimeseriesSchema {
|
|
pub created: chrono::DateTime<chrono::offset::Utc>,
|
|
pub datum_type: DatumType,
|
|
pub field_schema: Vec<FieldSchema>,
|
|
pub timeseries_name: TimeseriesName,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct TimeseriesSchemaResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<TimeseriesSchema>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of a [`User`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct User {
|
|
///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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct UserResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<User>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Client view of a [`Vpc`]
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
}
|
|
|
|
///Create-time parameters for a [`Vpc`](crate::external_api::views::Vpc)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<Ipv6Net>,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single rule in a VPC firewall
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<VpcFirewallRuleTarget>,
|
|
///timestamp when this resource was created
|
|
pub time_created: chrono::DateTime<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///the VPC to which this rule belongs
|
|
pub vpc_id: uuid::Uuid,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum VpcFirewallRuleAction {
|
|
#[serde(rename = "allow")]
|
|
Allow,
|
|
#[serde(rename = "deny")]
|
|
Deny,
|
|
}
|
|
|
|
impl ToString for VpcFirewallRuleAction {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
VpcFirewallRuleAction::Allow => "allow".to_string(),
|
|
VpcFirewallRuleAction::Deny => "deny".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum VpcFirewallRuleDirection {
|
|
#[serde(rename = "inbound")]
|
|
Inbound,
|
|
#[serde(rename = "outbound")]
|
|
Outbound,
|
|
}
|
|
|
|
impl ToString for VpcFirewallRuleDirection {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
VpcFirewallRuleDirection::Inbound => "inbound".to_string(),
|
|
VpcFirewallRuleDirection::Outbound => "outbound".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
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<Vec<VpcFirewallRuleHostFilter>>,
|
|
///If present, the destination ports this rule applies to.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub ports: Option<Vec<L4PortRange>>,
|
|
///If present, the networking protocols this rule applies to.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub protocols: Option<Vec<VpcFirewallRuleProtocol>>,
|
|
}
|
|
|
|
///The `VpcFirewallRuleHostFilter` is used to filter traffic on the basis
|
|
/// of its source or destination host.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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),
|
|
}
|
|
|
|
///The protocols that may be specified in a firewall rule's filter
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum VpcFirewallRuleProtocol {
|
|
#[serde(rename = "TCP")]
|
|
Tcp,
|
|
#[serde(rename = "UDP")]
|
|
Udp,
|
|
#[serde(rename = "ICMP")]
|
|
Icmp,
|
|
}
|
|
|
|
impl ToString for VpcFirewallRuleProtocol {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
VpcFirewallRuleProtocol::Tcp => "TCP".to_string(),
|
|
VpcFirewallRuleProtocol::Udp => "UDP".to_string(),
|
|
VpcFirewallRuleProtocol::Icmp => "ICMP".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum VpcFirewallRuleStatus {
|
|
#[serde(rename = "disabled")]
|
|
Disabled,
|
|
#[serde(rename = "enabled")]
|
|
Enabled,
|
|
}
|
|
|
|
impl ToString for VpcFirewallRuleStatus {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
VpcFirewallRuleStatus::Disabled => "disabled".to_string(),
|
|
VpcFirewallRuleStatus::Enabled => "enabled".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///A `VpcFirewallRuleTarget` is used to specify the set of [`Instance`]s to
|
|
/// which a firewall rule applies.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
#[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),
|
|
}
|
|
|
|
///A single rule in a VPC firewall
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<VpcFirewallRuleTarget>,
|
|
}
|
|
|
|
///Updateable properties of a `Vpc`'s firewall Note that VpcFirewallRules
|
|
/// are implicitly created along with a Vpc, so there is no explicit
|
|
/// creation.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcFirewallRuleUpdateParams {
|
|
pub rules: Vec<VpcFirewallRuleUpdate>,
|
|
}
|
|
|
|
///Collection of a [`Vpc`]'s firewall rules
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcFirewallRules {
|
|
pub rules: Vec<VpcFirewallRule>,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<Vpc>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///A VPC router defines a series of rules that indicate where traffic
|
|
/// should be sent depending on its destination.
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///The VPC to which the router belongs.
|
|
pub vpc_id: uuid::Uuid,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`VpcRouter`](crate::external_api::views::VpcRouter)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcRouterCreate {
|
|
pub description: String,
|
|
pub name: Name,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
|
pub enum VpcRouterKind {
|
|
#[serde(rename = "system")]
|
|
System,
|
|
#[serde(rename = "custom")]
|
|
Custom,
|
|
}
|
|
|
|
impl ToString for VpcRouterKind {
|
|
fn to_string(&self) -> String {
|
|
match *self {
|
|
VpcRouterKind::System => "system".to_string(),
|
|
VpcRouterKind::Custom => "custom".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcRouterResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<VpcRouter>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Updateable properties of a
|
|
/// [`VpcRouter`](crate::external_api::views::VpcRouter)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcRouterUpdate {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
}
|
|
|
|
///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(Serialize, Deserialize, Debug, Clone)]
|
|
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<chrono::offset::Utc>,
|
|
///timestamp when this resource was last modified
|
|
pub time_modified: chrono::DateTime<chrono::offset::Utc>,
|
|
///The VPC to which the subnet belongs.
|
|
pub vpc_id: uuid::Uuid,
|
|
}
|
|
|
|
///Create-time parameters for a
|
|
/// [`VpcSubnet`](crate::external_api::views::VpcSubnet)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
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<Ipv6Net>,
|
|
pub name: Name,
|
|
}
|
|
|
|
///A single page of results
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcSubnetResultsPage {
|
|
///list of items on this page of results
|
|
pub items: Vec<VpcSubnet>,
|
|
///token used to fetch the next page of results (if any)
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub next_page: Option<String>,
|
|
}
|
|
|
|
///Updateable properties of a
|
|
/// [`VpcSubnet`](crate::external_api::views::VpcSubnet)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcSubnetUpdate {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
}
|
|
|
|
///Updateable properties of a [`Vpc`](crate::external_api::views::Vpc)
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub struct VpcUpdate {
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub description: Option<String>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub dns_name: Option<Name>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub name: Option<Name>,
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Client {
|
|
pub(crate) baseurl: String,
|
|
pub(crate) client: reqwest::Client,
|
|
}
|
|
|
|
impl Client {
|
|
pub fn new(baseurl: &str) -> Self {
|
|
let dur = std::time::Duration::from_secs(15);
|
|
let client = reqwest::ClientBuilder::new()
|
|
.connect_timeout(dur)
|
|
.timeout(dur)
|
|
.build()
|
|
.unwrap();
|
|
Self::new_with_client(baseurl, client)
|
|
}
|
|
|
|
pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self {
|
|
Self {
|
|
baseurl: baseurl.to_string(),
|
|
client,
|
|
}
|
|
}
|
|
|
|
pub fn baseurl(&self) -> &String {
|
|
&self.baseurl
|
|
}
|
|
|
|
pub fn client(&self) -> &reqwest::Client {
|
|
&self.client
|
|
}
|
|
}
|
|
|
|
impl Client {
|
|
///List racks in the system
|
|
///
|
|
///Sends a `GET` request to `/hardware/racks`
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `page_token`: Token returned by previous call to retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn hardware_racks_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> Result<ResponseValue<types::RackResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/hardware/racks", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 in the system as a Stream
|
|
///
|
|
///Sends repeated `GET` requests to `/hardware/racks` until there are no
|
|
/// more results.
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `sort_by`
|
|
pub fn hardware_racks_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Rack, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.hardware_racks_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.hardware_racks_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch information about a particular rack
|
|
///
|
|
///Sends a `GET` request to `/hardware/racks/{rack_id}`
|
|
///
|
|
///Arguments:
|
|
/// - `rack_id`: The rack's unique ID.
|
|
pub async fn hardware_racks_get_rack<'a>(
|
|
&'a self,
|
|
rack_id: &'a uuid::Uuid,
|
|
) -> Result<ResponseValue<types::Rack>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/hardware/racks/{}",
|
|
self.baseurl,
|
|
encode_path(&rack_id.to_string()),
|
|
);
|
|
let request = self.client.get(url).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 in the system
|
|
///
|
|
///Sends a `GET` request to `/hardware/sleds`
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `page_token`: Token returned by previous call to retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn hardware_sleds_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> Result<ResponseValue<types::SledResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/hardware/sleds", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 in the system as a Stream
|
|
///
|
|
///Sends repeated `GET` requests to `/hardware/sleds` until there are no
|
|
/// more results.
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `sort_by`
|
|
pub fn hardware_sleds_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Sled, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.hardware_sleds_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.hardware_sleds_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch information about a sled in the system
|
|
///
|
|
///Sends a `GET` request to `/hardware/sleds/{sled_id}`
|
|
///
|
|
///Arguments:
|
|
/// - `sled_id`: The sled's unique ID.
|
|
pub async fn hardware_sleds_get_sled<'a>(
|
|
&'a self,
|
|
sled_id: &'a uuid::Uuid,
|
|
) -> Result<ResponseValue<types::Sled>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/hardware/sleds/{}",
|
|
self.baseurl,
|
|
encode_path(&sled_id.to_string()),
|
|
);
|
|
let request = self.client.get(url).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 global images
|
|
///
|
|
///Returns a list of all the global images. Global images are returned
|
|
/// sorted by creation date, with the most recent images appearing first.
|
|
///
|
|
///Sends a `GET` request to `/images`
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `page_token`: Token returned by previous call to retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn images_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::GlobalImageResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/images", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 global images as a Stream
|
|
///
|
|
///Returns a list of all the global images. Global images are returned
|
|
/// sorted by creation date, with the most recent images appearing first.
|
|
///
|
|
///Sends repeated `GET` requests to `/images` until there are no more
|
|
/// results.
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `sort_by`
|
|
pub fn images_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::GlobalImage, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.images_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.images_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a global image
|
|
///
|
|
///Create a new global image. This image can then be used by any user as a
|
|
/// base for instances.
|
|
///
|
|
///Sends a `POST` request to `/images`
|
|
pub async fn images_post<'a>(
|
|
&'a self,
|
|
body: &'a types::ImageCreate,
|
|
) -> Result<ResponseValue<types::GlobalImage>, Error<types::Error>> {
|
|
let url = format!("{}/images", self.baseurl,);
|
|
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 => 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 global image
|
|
///
|
|
///Returns the details of a specific global image.
|
|
///
|
|
///Sends a `GET` request to `/images/{image_name}`
|
|
pub async fn images_get_image<'a>(
|
|
&'a self,
|
|
image_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::GlobalImage>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/images/{}",
|
|
self.baseurl,
|
|
encode_path(&image_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() {
|
|
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 global image
|
|
///
|
|
///Permanently delete a global image. This operation cannot be undone. Any
|
|
/// instances using the global image will continue to run, however new
|
|
/// instances can not be created with this image.
|
|
///
|
|
///Sends a `DELETE` request to `/images/{image_name}`
|
|
pub async fn images_delete_image<'a>(
|
|
&'a self,
|
|
image_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/images/{}",
|
|
self.baseurl,
|
|
encode_path(&image_name.to_string()),
|
|
);
|
|
let request = self.client.delete(url).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 `POST` request to `/login`
|
|
pub async fn spoof_login<'a>(
|
|
&'a self,
|
|
body: &'a types::LoginParams,
|
|
) -> Result<ResponseValue<ByteStream>, Error<ByteStream>> {
|
|
let url = format!("{}/login", self.baseurl,);
|
|
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)),
|
|
_ => Err(Error::ErrorResponse(ResponseValue::stream(response))),
|
|
}
|
|
}
|
|
|
|
///Sends a `POST` request to `/logout`
|
|
pub async fn logout<'a>(&'a self) -> Result<ResponseValue<ByteStream>, Error<ByteStream>> {
|
|
let url = format!("{}/logout", self.baseurl,);
|
|
let request = self.client.post(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))),
|
|
}
|
|
}
|
|
|
|
///List all organizations
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn organizations_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> Result<ResponseValue<types::OrganizationResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/organizations", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 organizations as a Stream
|
|
///
|
|
///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 organizations_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Organization, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.organizations_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.organizations_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a new organization
|
|
///
|
|
///Sends a `POST` request to `/organizations`
|
|
pub async fn organizations_post<'a>(
|
|
&'a self,
|
|
body: &'a types::OrganizationCreate,
|
|
) -> Result<ResponseValue<types::Organization>, Error<types::Error>> {
|
|
let url = format!("{}/organizations", self.baseurl,);
|
|
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 => 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 specific organization
|
|
///
|
|
///Sends a `GET` request to `/organizations/{organization_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
pub async fn organizations_get_organization<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Organization>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}",
|
|
self.baseurl,
|
|
encode_path(&organization_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() {
|
|
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 specific organization
|
|
///
|
|
///Sends a `PUT` request to `/organizations/{organization_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
/// - `body`
|
|
pub async fn organizations_put_organization<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
body: &'a types::OrganizationUpdate,
|
|
) -> Result<ResponseValue<types::Organization>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}",
|
|
self.baseurl,
|
|
encode_path(&organization_name.to_string()),
|
|
);
|
|
let request = self.client.put(url).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 specific organization
|
|
///
|
|
///Sends a `DELETE` request to `/organizations/{organization_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
pub async fn organizations_delete_organization<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}",
|
|
self.baseurl,
|
|
encode_path(&organization_name.to_string()),
|
|
);
|
|
let request = self.client.delete(url).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 IAM policy for this Organization
|
|
///
|
|
///Sends a `GET` request to `/organizations/{organization_name}/policy`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
pub async fn organization_get_policy<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::OrganizationRolesPolicy>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}/policy",
|
|
self.baseurl,
|
|
encode_path(&organization_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() {
|
|
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 IAM policy for this Organization
|
|
///
|
|
///Sends a `PUT` request to `/organizations/{organization_name}/policy`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
/// - `body`
|
|
pub async fn organization_put_policy<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
body: &'a types::OrganizationRolesPolicy,
|
|
) -> Result<ResponseValue<types::OrganizationRolesPolicy>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}/policy",
|
|
self.baseurl,
|
|
encode_path(&organization_name.to_string()),
|
|
);
|
|
let request = self.client.put(url).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 all projects
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn organization_projects_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> Result<ResponseValue<types::ProjectResultsPage>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}/projects",
|
|
self.baseurl,
|
|
encode_path(&organization_name.to_string()),
|
|
);
|
|
let mut query = Vec::new();
|
|
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).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 projects as a Stream
|
|
///
|
|
///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 organization_projects_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Project, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.organization_projects_get(organization_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.organization_projects_get(
|
|
organization_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a new project
|
|
///
|
|
///Sends a `POST` request to `/organizations/{organization_name}/projects`
|
|
///
|
|
///Arguments:
|
|
/// - `organization_name`: The organization's unique name.
|
|
/// - `body`
|
|
pub async fn organization_projects_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
body: &'a types::ProjectCreate,
|
|
) -> Result<ResponseValue<types::Project>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/organizations/{}/projects",
|
|
self.baseurl,
|
|
encode_path(&organization_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() {
|
|
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 specific project
|
|
///
|
|
///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 organization_projects_get_project<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Project>, Error<types::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).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 specific project
|
|
///
|
|
///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 organization_projects_put_project<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::ProjectUpdate,
|
|
) -> Result<ResponseValue<types::Project>, Error<types::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).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 specific project
|
|
///
|
|
///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 organization_projects_delete_project<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 in a project
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn project_disks_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::DiskResultsPage>, Error<types::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::new();
|
|
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).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 in a project as a Stream
|
|
///
|
|
///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 project_disks_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Disk, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.project_disks_get(organization_name, project_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.project_disks_get(
|
|
organization_name,
|
|
project_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a disk in a project
|
|
///
|
|
///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 project_disks_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::DiskCreate,
|
|
) -> Result<ResponseValue<types::Disk>, Error<types::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).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 single disk in a project
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/disks/
|
|
/// {disk_name}`
|
|
pub async fn project_disks_get_disk<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
disk_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Disk>, Error<types::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).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 from a project
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/disks/
|
|
/// {disk_name}`
|
|
pub async fn project_disks_delete_disk<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
disk_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn project_images_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::ImageResultsPage>, Error<types::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::new();
|
|
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).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 project_images_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Image, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.project_images_get(organization_name, project_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.project_images_get(
|
|
organization_name,
|
|
project_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.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 project_images_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::ImageCreate,
|
|
) -> Result<ResponseValue<types::Image>, Error<types::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).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 an image
|
|
///
|
|
///Get the details of a specific image in a project.
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/images/
|
|
/// {image_name}`
|
|
pub async fn project_images_get_image<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
image_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Image>, Error<types::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).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 project_images_delete_image<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
image_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 in a project
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn project_instances_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::InstanceResultsPage>, Error<types::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::new();
|
|
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).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 in a project 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 project_instances_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Instance, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.project_instances_get(organization_name, project_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.project_instances_get(
|
|
organization_name,
|
|
project_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create an instance in a project
|
|
///
|
|
///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 project_instances_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::InstanceCreate,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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 an instance in a project
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}`
|
|
pub async fn project_instances_get_instance<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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 from a project
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}`
|
|
pub async fn project_instances_delete_instance<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 attached to this instance
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn instance_disks_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::DiskResultsPage>, Error<types::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::new();
|
|
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).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 attached to this instance as a Stream
|
|
///
|
|
///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_disks_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Disk, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.instance_disks_get(
|
|
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.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.instance_disks_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/disks/attach`
|
|
pub async fn instance_disks_attach<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
body: &'a types::DiskIdentifier,
|
|
) -> Result<ResponseValue<types::Disk>, Error<types::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).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)),
|
|
}
|
|
}
|
|
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/disks/detach`
|
|
pub async fn instance_disks_detach<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
body: &'a types::DiskIdentifier,
|
|
) -> Result<ResponseValue<types::Disk>, Error<types::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).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)),
|
|
}
|
|
}
|
|
|
|
///Migrate an instance to a different propolis-server, possibly on a
|
|
/// different sled
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/migrate`
|
|
pub async fn project_instances_migrate_instance<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
body: &'a types::InstanceMigrate,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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 attached to this instance
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn instance_network_interfaces_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::NetworkInterfaceResultsPage>, Error<types::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::new();
|
|
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).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 attached to this instance 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_interfaces_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::NetworkInterface, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.instance_network_interfaces_get(
|
|
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.into_iter().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_interfaces_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a network interface for an instance
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/network-interfaces`
|
|
pub async fn instance_network_interfaces_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
body: &'a types::NetworkInterfaceCreate,
|
|
) -> Result<ResponseValue<types::NetworkInterface>, Error<types::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).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 an interface attached to an instance
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/network-interfaces/{interface_name}`
|
|
pub async fn instance_network_interfaces_get_interface<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
interface_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::NetworkInterface>, Error<types::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).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)),
|
|
}
|
|
}
|
|
|
|
///Detach a network interface from an instance
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/network-interfaces/{interface_name}`
|
|
pub async fn instance_network_interfaces_delete_interface<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
interface_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/reboot`
|
|
pub async fn project_instances_instance_reboot<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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)),
|
|
}
|
|
}
|
|
|
|
///Boot an instance
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/start`
|
|
pub async fn project_instances_instance_start<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/instances/
|
|
/// {instance_name}/stop`
|
|
pub async fn project_instances_instance_stop<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
instance_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Instance>, Error<types::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).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 the IAM policy for this Project
|
|
///
|
|
///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 organization_projects_get_project_policy<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::ProjectRolesPolicy>, Error<types::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).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 IAM policy for this Project
|
|
///
|
|
///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 organization_projects_put_project_policy<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::ProjectRolesPolicy,
|
|
) -> Result<ResponseValue<types::ProjectRolesPolicy>, Error<types::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).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 in a project
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn project_snapshots_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::SnapshotResultsPage>, Error<types::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::new();
|
|
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).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 in a project 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 project_snapshots_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Snapshot, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.project_snapshots_get(organization_name, project_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.project_snapshots_get(
|
|
organization_name,
|
|
project_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a snapshot of 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 project_snapshots_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::SnapshotCreate,
|
|
) -> Result<ResponseValue<types::Snapshot>, Error<types::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).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 snapshot in a project
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/snapshots/
|
|
/// {snapshot_name}`
|
|
pub async fn project_snapshots_get_snapshot<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
snapshot_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Snapshot>, Error<types::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).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 from a project
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/snapshots/
|
|
/// {snapshot_name}`
|
|
pub async fn project_snapshots_delete_snapshot<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
snapshot_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 in a project
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn project_vpcs_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::VpcResultsPage>, Error<types::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::new();
|
|
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).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 in a project 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 project_vpcs_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Vpc, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.project_vpcs_get(organization_name, project_name, limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.project_vpcs_get(
|
|
organization_name,
|
|
project_name,
|
|
None,
|
|
state.as_deref(),
|
|
None,
|
|
)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a VPC in a project
|
|
///
|
|
///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 project_vpcs_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
body: &'a types::VpcCreate,
|
|
) -> Result<ResponseValue<types::Vpc>, Error<types::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).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 VPC in a project
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}`
|
|
pub async fn project_vpcs_get_vpc<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Vpc>, Error<types::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).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 project_vpcs_put_vpc<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
body: &'a types::VpcUpdate,
|
|
) -> Result<ResponseValue<types::Vpc>, Error<types::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).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 from a project
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}`
|
|
pub async fn project_vpcs_delete_vpc<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 for a VPC
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/firewall/rules`
|
|
pub async fn vpc_firewall_rules_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::VpcFirewallRules>, Error<types::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).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 the firewall rules for a VPC
|
|
///
|
|
///Sends a `PUT` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/firewall/rules`
|
|
pub async fn vpc_firewall_rules_put<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
body: &'a types::VpcFirewallRuleUpdateParams,
|
|
) -> Result<ResponseValue<types::VpcFirewallRules>, Error<types::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).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 VPC Custom and System 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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn vpc_routers_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::VpcRouterResultsPage>, Error<types::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::new();
|
|
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).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 VPC Custom and System 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_routers_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::VpcRouter, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.vpc_routers_get(
|
|
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.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.vpc_routers_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a VPC Router
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers`
|
|
pub async fn vpc_routers_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
body: &'a types::VpcRouterCreate,
|
|
) -> Result<ResponseValue<types::VpcRouter>, Error<types::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).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 VPC Router
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}`
|
|
pub async fn vpc_routers_get_router<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
router_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::VpcRouter>, Error<types::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).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 Router
|
|
///
|
|
///Sends a `PUT` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}`
|
|
pub async fn vpc_routers_put_router<'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<ResponseValue<types::VpcRouter>, Error<types::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).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 from its VPC
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}`
|
|
pub async fn vpc_routers_delete_router<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
router_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 Router's routes
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn routers_routes_get<'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<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::RouterRouteResultsPage>, Error<types::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::new();
|
|
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).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 Router's routes as a Stream
|
|
///
|
|
///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 routers_routes_get_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<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::RouterRoute, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.routers_routes_get(
|
|
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.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.routers_routes_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a VPC Router
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}/routes`
|
|
pub async fn routers_routes_post<'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<ResponseValue<types::RouterRoute>, Error<types::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).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 VPC Router route
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}/routes/{route_name}`
|
|
pub async fn routers_routes_get_route<'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<ResponseValue<types::RouterRoute>, Error<types::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).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 route
|
|
///
|
|
///Sends a `PUT` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}/routes/{route_name}`
|
|
pub async fn routers_routes_put_route<'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<ResponseValue<types::RouterRoute>, Error<types::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).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 from its router
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/routers/{router_name}/routes/{route_name}`
|
|
pub async fn routers_routes_delete_route<'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<ResponseValue<()>, Error<types::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).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 in a VPC
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn vpc_subnets_get<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::VpcSubnetResultsPage>, Error<types::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::new();
|
|
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).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 in a VPC 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_subnets_get_stream<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::VpcSubnet, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.vpc_subnets_get(
|
|
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.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.vpc_subnets_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a subnet in a VPC
|
|
///
|
|
///Sends a `POST` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/subnets`
|
|
pub async fn vpc_subnets_post<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
body: &'a types::VpcSubnetCreate,
|
|
) -> Result<ResponseValue<types::VpcSubnet>, Error<types::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).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 subnet in a VPC
|
|
///
|
|
///Sends a `GET` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/subnets/{subnet_name}`
|
|
pub async fn vpc_subnets_get_subnet<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
subnet_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::VpcSubnet>, Error<types::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).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 Subnet
|
|
///
|
|
///Sends a `PUT` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/subnets/{subnet_name}`
|
|
pub async fn vpc_subnets_put_subnet<'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<ResponseValue<types::VpcSubnet>, Error<types::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).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 from a VPC
|
|
///
|
|
///Sends a `DELETE` request to
|
|
/// `/organizations/{organization_name}/projects/{project_name}/vpcs/
|
|
/// {vpc_name}/subnets/{subnet_name}`
|
|
pub async fn vpc_subnets_delete_subnet<'a>(
|
|
&'a self,
|
|
organization_name: &'a types::Name,
|
|
project_name: &'a types::Name,
|
|
vpc_name: &'a types::Name,
|
|
subnet_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::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).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 in a VPC subnet
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn subnet_network_interfaces_get<'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<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::NetworkInterfaceResultsPage>, Error<types::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::new();
|
|
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).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 in a VPC subnet 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 subnet_network_interfaces_get_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<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::NetworkInterface, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.subnet_network_interfaces_get(
|
|
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.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.subnet_network_interfaces_get(
|
|
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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch the top-level IAM policy
|
|
///
|
|
///Sends a `GET` request to `/policy`
|
|
pub async fn policy_get<'a>(
|
|
&'a self,
|
|
) -> Result<ResponseValue<types::FleetRolesPolicy>, Error<types::Error>> {
|
|
let url = format!("{}/policy", self.baseurl,);
|
|
let request = self.client.get(url).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 `/policy`
|
|
pub async fn policy_put<'a>(
|
|
&'a self,
|
|
body: &'a types::FleetRolesPolicy,
|
|
) -> Result<ResponseValue<types::FleetRolesPolicy>, Error<types::Error>> {
|
|
let url = format!("{}/policy", self.baseurl,);
|
|
let request = self.client.put(url).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 the 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 retreive the
|
|
/// subsequent page
|
|
pub async fn roles_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
) -> Result<ResponseValue<types::RoleResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/roles", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 the 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 roles_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
) -> impl futures::Stream<Item = Result<types::Role, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.roles_get(limit, None)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.roles_get(None, state.as_deref())
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch a specific built-in role
|
|
///
|
|
///Sends a `GET` request to `/roles/{role_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `role_name`: The built-in role's unique name.
|
|
pub async fn roles_get_role<'a>(
|
|
&'a self,
|
|
role_name: &'a str,
|
|
) -> Result<ResponseValue<types::Role>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/roles/{}",
|
|
self.baseurl,
|
|
encode_path(&role_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() {
|
|
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 sagas (for debugging)
|
|
///
|
|
///Sends a `GET` request to `/sagas`
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `page_token`: Token returned by previous call to retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn sagas_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> Result<ResponseValue<types::SagaResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/sagas", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 sagas (for debugging) as a Stream
|
|
///
|
|
///Sends repeated `GET` requests to `/sagas` until there are no more
|
|
/// results.
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `sort_by`
|
|
pub fn sagas_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::IdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Saga, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.sagas_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.sagas_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch information about a single saga (for debugging)
|
|
///
|
|
///Sends a `GET` request to `/sagas/{saga_id}`
|
|
pub async fn sagas_get_saga<'a>(
|
|
&'a self,
|
|
saga_id: &'a uuid::Uuid,
|
|
) -> Result<ResponseValue<types::Saga>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/sagas/{}",
|
|
self.baseurl,
|
|
encode_path(&saga_id.to_string()),
|
|
);
|
|
let request = self.client.get(url).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<'a>(
|
|
&'a self,
|
|
) -> Result<ResponseValue<types::SessionUser>, Error<types::Error>> {
|
|
let url = format!("{}/session/me", self.baseurl,);
|
|
let request = self.client.get(url).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 the current user's SSH public keys
|
|
///
|
|
///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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn sshkeys_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::SshKeyResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/session/me/sshkeys", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 the current user's SSH public keys as a Stream
|
|
///
|
|
///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 sshkeys_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::SshKey, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.sshkeys_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.sshkeys_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a new SSH public key for the current user
|
|
///
|
|
///Sends a `POST` request to `/session/me/sshkeys`
|
|
pub async fn sshkeys_post<'a>(
|
|
&'a self,
|
|
body: &'a types::SshKeyCreate,
|
|
) -> Result<ResponseValue<types::SshKey>, Error<types::Error>> {
|
|
let url = format!("{}/session/me/sshkeys", self.baseurl,);
|
|
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 => 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 (by name) an SSH public key belonging to the current user
|
|
///
|
|
///Sends a `GET` request to `/session/me/sshkeys/{ssh_key_name}`
|
|
pub async fn sshkeys_get_key<'a>(
|
|
&'a self,
|
|
ssh_key_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::SshKey>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/session/me/sshkeys/{}",
|
|
self.baseurl,
|
|
encode_path(&ssh_key_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() {
|
|
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 (by name) an SSH public key belonging to the current user
|
|
///
|
|
///Sends a `DELETE` request to `/session/me/sshkeys/{ssh_key_name}`
|
|
pub async fn sshkeys_delete_key<'a>(
|
|
&'a self,
|
|
ssh_key_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/session/me/sshkeys/{}",
|
|
self.baseurl,
|
|
encode_path(&ssh_key_name.to_string()),
|
|
);
|
|
let request = self.client.delete(url).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 `/silos`
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `page_token`: Token returned by previous call to retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn silos_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> Result<ResponseValue<types::SiloResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/silos", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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)),
|
|
}
|
|
}
|
|
|
|
///Sends repeated `GET` requests to `/silos` until there are no more
|
|
/// results.
|
|
///
|
|
///Arguments:
|
|
/// - `limit`: Maximum number of items returned by a single call
|
|
/// - `sort_by`
|
|
pub fn silos_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameOrIdSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::Silo, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.silos_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.silos_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Create a new silo
|
|
///
|
|
///Sends a `POST` request to `/silos`
|
|
pub async fn silos_post<'a>(
|
|
&'a self,
|
|
body: &'a types::SiloCreate,
|
|
) -> Result<ResponseValue<types::Silo>, Error<types::Error>> {
|
|
let url = format!("{}/silos", self.baseurl,);
|
|
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 => 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 specific silo
|
|
///
|
|
///Sends a `GET` request to `/silos/{silo_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `silo_name`: The silo's unique name.
|
|
pub async fn silos_get_silo<'a>(
|
|
&'a self,
|
|
silo_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::Silo>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/silos/{}",
|
|
self.baseurl,
|
|
encode_path(&silo_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() {
|
|
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 specific silo
|
|
///
|
|
///Sends a `DELETE` request to `/silos/{silo_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `silo_name`: The silo's unique name.
|
|
pub async fn silos_delete_silo<'a>(
|
|
&'a self,
|
|
silo_name: &'a types::Name,
|
|
) -> Result<ResponseValue<()>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/silos/{}",
|
|
self.baseurl,
|
|
encode_path(&silo_name.to_string()),
|
|
);
|
|
let request = self.client.delete(url).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 IAM policy for this Silo
|
|
///
|
|
///Sends a `GET` request to `/silos/{silo_name}/policy`
|
|
///
|
|
///Arguments:
|
|
/// - `silo_name`: The silo's unique name.
|
|
pub async fn silos_get_silo_policy<'a>(
|
|
&'a self,
|
|
silo_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::SiloRolesPolicy>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/silos/{}/policy",
|
|
self.baseurl,
|
|
encode_path(&silo_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() {
|
|
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 IAM policy for this Silo
|
|
///
|
|
///Sends a `PUT` request to `/silos/{silo_name}/policy`
|
|
///
|
|
///Arguments:
|
|
/// - `silo_name`: The silo's unique name.
|
|
/// - `body`
|
|
pub async fn silos_put_silo_policy<'a>(
|
|
&'a self,
|
|
silo_name: &'a types::Name,
|
|
body: &'a types::SiloRolesPolicy,
|
|
) -> Result<ResponseValue<types::SiloRolesPolicy>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/silos/{}/policy",
|
|
self.baseurl,
|
|
encode_path(&silo_name.to_string()),
|
|
);
|
|
let request = self.client.put(url).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 all 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 retreive the
|
|
/// subsequent page
|
|
pub async fn timeseries_schema_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
) -> Result<ResponseValue<types::TimeseriesSchemaResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/timeseries/schema", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 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<std::num::NonZeroU32>,
|
|
) -> impl futures::Stream<Item = Result<types::TimeseriesSchema, Error<types::Error>>> + Unpin + '_
|
|
{
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.timeseries_schema_get(limit, None)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().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.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Refresh update metadata
|
|
///
|
|
///Sends a `POST` request to `/updates/refresh`
|
|
pub async fn updates_refresh<'a>(&'a self) -> Result<ResponseValue<()>, Error<types::Error>> {
|
|
let url = format!("{}/updates/refresh", self.baseurl,);
|
|
let request = self.client.post(url).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 the built-in system 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 retreive the
|
|
/// subsequent page
|
|
/// - `sort_by`
|
|
pub async fn users_get<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
page_token: Option<&'a str>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> Result<ResponseValue<types::UserResultsPage>, Error<types::Error>> {
|
|
let url = format!("{}/users", self.baseurl,);
|
|
let mut query = Vec::new();
|
|
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).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 the built-in system 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 users_get_stream<'a>(
|
|
&'a self,
|
|
limit: Option<std::num::NonZeroU32>,
|
|
sort_by: Option<types::NameSortMode>,
|
|
) -> impl futures::Stream<Item = Result<types::User, Error<types::Error>>> + Unpin + '_ {
|
|
use futures::StreamExt;
|
|
use futures::TryFutureExt;
|
|
use futures::TryStreamExt;
|
|
self.users_get(limit, None, sort_by)
|
|
.map_ok(move |page| {
|
|
let page = page.into_inner();
|
|
let first = futures::stream::iter(page.items.into_iter().map(Ok));
|
|
let rest = futures::stream::try_unfold(page.next_page, move |state| async move {
|
|
if state.is_none() {
|
|
Ok(None)
|
|
} else {
|
|
self.users_get(None, state.as_deref(), None)
|
|
.map_ok(|page| {
|
|
let page = page.into_inner();
|
|
Some((
|
|
futures::stream::iter(page.items.into_iter().map(Ok)),
|
|
page.next_page,
|
|
))
|
|
})
|
|
.await
|
|
}
|
|
})
|
|
.try_flatten();
|
|
first.chain(rest)
|
|
})
|
|
.try_flatten_stream()
|
|
.boxed()
|
|
}
|
|
|
|
///Fetch a specific built-in system user
|
|
///
|
|
///Sends a `GET` request to `/users/{user_name}`
|
|
///
|
|
///Arguments:
|
|
/// - `user_name`: The built-in user's unique name.
|
|
pub async fn users_get_user<'a>(
|
|
&'a self,
|
|
user_name: &'a types::Name,
|
|
) -> Result<ResponseValue<types::User>, Error<types::Error>> {
|
|
let url = format!(
|
|
"{}/users/{}",
|
|
self.baseurl,
|
|
encode_path(&user_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() {
|
|
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)),
|
|
}
|
|
}
|
|
}
|