/*
* Hanzo Cloud API
*
* The Hanzo Cloud API as a customer calls it: every operation under /v1/ except the operator's admin product, relay routes, legacy spellings and capabilities still reached by flag. Tagged by product: the first path segment after /v1/.
*
* The version of the OpenAPI document: v1
*
* Generated by: https://openapi-generator.tech
*/
use reqwest;
use serde::{Deserialize, Serialize, de::Error as _};
use crate::{apis::ResponseContent, models};
use super::{Error, configuration, ContentType};
/// struct for typed errors of method [`delete_s3_buckets_by_bucket`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum DeleteS3BucketsByBucketError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_s3_buckets`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetS3BucketsError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_s3_buckets_by_bucket_objects`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetS3BucketsByBucketObjectsError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`get_s3_health`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetS3HealthError {
Status503(models::S3Health),
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`post_s3_buckets`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PostS3BucketsError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`post_s3_buckets_by_bucket_objects`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PostS3BucketsByBucketObjectsError {
UnknownValue(serde_json::Value),
}
/// Removes an EMPTY bucket and answers 204. A non-empty bucket is 409 rather than a cascade: deleting a tenant's objects behind a single bucket call is not a thing this surface will do silently. A bucket the caller's org does not own is the same 404 an unknown name gives. Billed per call: the balance is checked BEFORE anything is touched, so an unfunded org is refused with nothing deleted, and the debit lands only once the bucket is gone.
pub async fn delete_s3_buckets_by_bucket(configuration: &configuration::Configuration, bucket: &str) -> Result<(), Error<DeleteS3BucketsByBucketError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_bucket = bucket;
let uri_str = format!("{}/v1/s3/buckets/{bucket}", configuration.base_path, bucket=crate::apis::urlencode(p_bucket));
let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<DeleteS3BucketsByBucketError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Lists the caller org's own buckets. Only the caller's: every bucket is physically named under a per-org prefix and the listing strips that prefix, so a tenant sees friendly names and another tenant's buckets are not in the answer at all. Another org's bucket is not refused but INVISIBLE, so this cannot be used to learn that a name is taken elsewhere. Billed per call: the balance is checked BEFORE anything is touched, so an unfunded org is refused with nothing done, and the debit lands only once the work has succeeded.
pub async fn get_s3_buckets(configuration: &configuration::Configuration, ) -> Result<models::BucketList, Error<GetS3BucketsError>> {
let uri_str = format!("{}/v1/s3/buckets", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BucketList`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BucketList`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetS3BucketsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Lists one folder level of a bucket. Folder-style by default: sub-prefixes come back as directory entries, which is the file-manager view. `?recursive=true` lists every key flat under the prefix instead. Keys are RELATIVE to `?prefix=`, and the listing is bounded so a huge bucket cannot exhaust memory — Total is what came back, not what the bucket holds. Billed per call: the balance is checked BEFORE anything is touched, so an unfunded org is refused with nothing read, and the debit lands only once the listing has succeeded.
pub async fn get_s3_buckets_by_bucket_objects(configuration: &configuration::Configuration, bucket: &str, prefix: Option<&str>, recursive: Option<&str>) -> Result<models::ObjectList, Error<GetS3BucketsByBucketObjectsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_bucket = bucket;
let p_prefix = prefix;
let p_recursive = recursive;
let uri_str = format!("{}/v1/s3/buckets/{bucket}/objects", configuration.base_path, bucket=crate::apis::urlencode(p_bucket));
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref param_value) = p_prefix {
req_builder = req_builder.query(&[("prefix", ¶m_value.to_string())]);
}
if let Some(ref param_value) = p_recursive {
req_builder = req_builder.query(&[("recursive", ¶m_value.to_string())]);
}
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ObjectList`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ObjectList`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetS3BucketsByBucketObjectsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Health reports whether this deployment can serve object storage. It is a REAL probe rather than a constant: 200 when admin credentials are present, so the store is reachable in principle, and 503 with the reason when they are not. It is deliberately NOT gated — liveness has to be probe-able without a token — so it is the one operation here that names no bucket and bills nothing.
pub async fn get_s3_health(configuration: &configuration::Configuration, ) -> Result<models::S3Health, Error<GetS3HealthError>> {
let uri_str = format!("{}/v1/s3/health", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::S3Health`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::S3Health`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<GetS3HealthError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Makes a new bucket for the caller's org and answers 201 with it. The physical name is derived from the caller's validated org, so a tenant can only ever create inside its own namespace and no request field can redirect that. A name already taken in the org is 409. Billed per call: the balance is checked BEFORE anything is touched, so an unfunded org is refused with nothing created, and the debit lands only once the bucket exists.
pub async fn post_s3_buckets(configuration: &configuration::Configuration, bucket_in: models::BucketIn) -> Result<models::BucketItem, Error<PostS3BucketsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_bucket_in = bucket_in;
let uri_str = format!("{}/v1/s3/buckets", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_bucket_in);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BucketItem`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BucketItem`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<PostS3BucketsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Mints a presigned PUT URL the caller uploads to DIRECTLY. The bytes never pass through this binary and the admin credential never leaves the server: the URL is signed against the PUBLIC host, scoped to exactly this bucket and key, and expires. A deployment with no public endpoint configured cannot mint one and answers 503 rather than a URL that will not work. Billed per call — for MINTING the URL, which is the work this operation does; the upload that follows it goes straight to the store and is not seen here. The balance is checked BEFORE anything is touched, so an unfunded org is refused with no URL issued.
pub async fn post_s3_buckets_by_bucket_objects(configuration: &configuration::Configuration, bucket: &str, upload_in: models::UploadIn) -> Result<models::PresignResponse, Error<PostS3BucketsByBucketObjectsError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_bucket = bucket;
let p_upload_in = upload_in;
let uri_str = format!("{}/v1/s3/buckets/{bucket}/objects", configuration.base_path, bucket=crate::apis::urlencode(p_bucket));
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_upload_in);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
let content_type = resp
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let content_type = super::ContentType::from(content_type);
if !status.is_client_error() && !status.is_server_error() {
let content = resp.text().await?;
match content_type {
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PresignResponse`"))),
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PresignResponse`")))),
}
} else {
let content = resp.text().await?;
let entity: Option<PostS3BucketsByBucketObjectsError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}