The Rust client for Origin Cloud's REST APIs. Its service crates are generated
from the API definitions in
origincloudhq/api; origincloud-core is
what they share: credentials, endpoints, retries, errors, long-running
operations and read-your-writes.
[dependencies]
origincloud-core = "0.1"
origincloud-pvs = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }| Crate | API |
|---|---|
origincloud-core |
The client every service crate uses, and longrunning::v1beta1 for resuming an operation by name |
origincloud-pvs |
Persistent volumes: volumes, snapshots, storage classes (origincloud_pvs::v1beta1) |
origincloud-location |
Regions and zones, and the services each zone offers (origincloud_location::v1beta1) |
origincloud-compute |
Instances, images, key pairs, volume attachments and the instance catalog (origincloud_compute::v1beta1) |
origincloud-network |
VPCs, subnets, routing, gateways, floating IPs, network interfaces, security groups, ACLs and DNS policies (origincloud_network::v1beta1) |
origincloud-resourcemanager |
Organizations, projects and their quotas (origincloud_resourcemanager::v1beta1) |
origincloud-iam |
Users, service accounts, roles, role bindings, permissions and the audit log (origincloud_iam::v1beta1) |
use origincloud_core::protobuf::FieldMask;
use origincloud_core::Client;
use origincloud_pvs::v1beta1::{
CreateVolumeRequest, DeleteVolumeRequest, UpdateVolumeRequest, Volume, VolumeClient,
};
#[tokio::main]
async fn main() -> Result<(), origincloud_core::Error> {
let client = Client::new()?;
let volumes = VolumeClient::new(&client);
let volume = volumes
.create_volume(CreateVolumeRequest {
parent: "projects/my-project-123/zones/eu-central1-az1".to_owned(),
volume: Some(Volume { size_gib: 10, ..Default::default() }),
..Default::default()
})
.await?
.wait()
.await?;
let volume = volumes
.update_volume(UpdateVolumeRequest {
volume: Some(Volume { name: volume.name, size_gib: 20, ..Default::default() }),
update_mask: Some(FieldMask::new(["size_gib"])),
..Default::default()
})
.await?
.wait()
.await?;
println!("{} has {} GiB", volume.name, volume.size_gib);
volumes
.delete_volume(DeleteVolumeRequest { name: volume.name, ..Default::default() })
.await?
.wait()
.await?;
Ok(())
}Client::new takes the first of:
ORIGINCLOUD_ACCESS_TOKEN: an access token, sent as it is.ORIGINCLOUD_CLIENT_IDandORIGINCLOUD_CLIENT_SECRET: a service account's credential, exchanged for access tokens as they expire. This is what automation should use.- The session the
originCLI stored at its last login (origin id login).
Client::builder().credentials(...) sets them explicitly instead.
- Endpoints. Every service answers at
{service}.origincloudapis.eu, which serves every resource wherever it lives.ClientBuilder::region, orORIGINCLOUD_REGION, picks a region's front door instead,{service}.{region}.origincloudapis.eu, for the services that have one; a global service, such as location, keeps its regionless host. - Operations. A create, update or delete returns an
Operation; itswaitreturns the resource once the change is complete, or the error the change failed with. - Retries. A call answered as retryable is sent again with a growing delay, when sending it again is safe: a read, or a mutation with a request id. The client fills in an empty request id, so a retried create never creates twice.
- Read-your-writes. The client keeps the consistency token each write answers with and sends it with later calls, so a read right after a write, or after waiting on an operation, sees it. The token answered last is the one kept: of concurrent writes, a read is sure to see the last answered.
- Pages. Each list method has an
all_...counterpart that streams every page. - Errors. A refused call returns
Error::Api; branch onError::reason, the platform's error code.ApiError::metadatasays more about some reasons, such as the name of the resource aCONFLICTis about. - Runtime. The clients are
async, on Tokio, and send their calls with reqwest.
A service crate's modules are its API's versions: origincloud_pvs::v1beta1 is
the preview version of the PVS API and may change in incompatible ways, like
the API itself. The crates follow semantic versioning; before 1.0, a minor
version may change the Rust API incompatibly.
Issues and pull requests are welcome. The service crates are generated from the API definitions, so a change to what a service offers starts as an issue; see CONTRIBUTING.md for how the SDK is built and checked.
Apache License 2.0; see LICENSE.