wip: proxy admin api requests through admin rpc, prepare new cli
Some checks failed
ci/woodpecker/push/debug Pipeline failed
Some checks failed
ci/woodpecker/push/debug Pipeline failed
This commit is contained in:
parent
6ed78abb5c
commit
145130481e
6 changed files with 194 additions and 78 deletions
|
@ -1,3 +1,4 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -77,18 +78,18 @@ admin_endpoints![
|
|||
// because they directly produce an http::Response
|
||||
// **********************************************
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OptionsRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CheckDomainRequest {
|
||||
pub domain: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HealthRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MetricsRequest;
|
||||
|
||||
// **********************************************
|
||||
|
@ -97,10 +98,10 @@ pub struct MetricsRequest;
|
|||
|
||||
// ---- GetClusterStatus ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetClusterStatusRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetClusterStatusResponse {
|
||||
pub node: String,
|
||||
|
@ -112,7 +113,7 @@ pub struct GetClusterStatusResponse {
|
|||
pub nodes: Vec<NodeResp>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NodeResp {
|
||||
pub id: String,
|
||||
|
@ -128,7 +129,7 @@ pub struct NodeResp {
|
|||
pub metadata_partition: Option<FreeSpaceResp>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NodeRoleResp {
|
||||
pub id: String,
|
||||
|
@ -137,7 +138,7 @@ pub struct NodeRoleResp {
|
|||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FreeSpaceResp {
|
||||
pub available: u64,
|
||||
|
@ -146,7 +147,7 @@ pub struct FreeSpaceResp {
|
|||
|
||||
// ---- GetClusterHealth ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetClusterHealthRequest;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -167,10 +168,10 @@ pub struct GetClusterHealthResponse {
|
|||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConnectClusterNodesRequest(pub Vec<String>);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConnectClusterNodesResponse(pub Vec<ConnectNodeResponse>);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ConnectNodeResponse {
|
||||
pub success: bool,
|
||||
|
@ -179,10 +180,10 @@ pub struct ConnectNodeResponse {
|
|||
|
||||
// ---- GetClusterLayout ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetClusterLayoutRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetClusterLayoutResponse {
|
||||
pub version: u64,
|
||||
|
@ -190,7 +191,7 @@ pub struct GetClusterLayoutResponse {
|
|||
pub staged_role_changes: Vec<NodeRoleChange>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NodeRoleChange {
|
||||
pub id: String,
|
||||
|
@ -198,7 +199,7 @@ pub struct NodeRoleChange {
|
|||
pub action: NodeRoleChangeEnum,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum NodeRoleChangeEnum {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -213,21 +214,21 @@ pub enum NodeRoleChangeEnum {
|
|||
|
||||
// ---- UpdateClusterLayout ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateClusterLayoutRequest(pub Vec<NodeRoleChange>);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateClusterLayoutResponse(pub GetClusterLayoutResponse);
|
||||
|
||||
// ---- ApplyClusterLayout ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplyClusterLayoutRequest {
|
||||
pub version: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplyClusterLayoutResponse {
|
||||
pub message: Vec<String>,
|
||||
|
@ -236,10 +237,10 @@ pub struct ApplyClusterLayoutResponse {
|
|||
|
||||
// ---- RevertClusterLayout ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RevertClusterLayoutRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RevertClusterLayoutResponse(pub GetClusterLayoutResponse);
|
||||
|
||||
// **********************************************
|
||||
|
@ -248,13 +249,13 @@ pub struct RevertClusterLayoutResponse(pub GetClusterLayoutResponse);
|
|||
|
||||
// ---- ListKeys ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ListKeysRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ListKeysResponse(pub Vec<ListKeysResponseItem>);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ListKeysResponseItem {
|
||||
pub id: String,
|
||||
|
@ -263,14 +264,14 @@ pub struct ListKeysResponseItem {
|
|||
|
||||
// ---- GetKeyInfo ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetKeyInfoRequest {
|
||||
pub id: Option<String>,
|
||||
pub search: Option<String>,
|
||||
pub show_secret_key: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetKeyInfoResponse {
|
||||
pub name: String,
|
||||
|
@ -281,14 +282,14 @@ pub struct GetKeyInfoResponse {
|
|||
pub buckets: Vec<KeyInfoBucketResponse>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KeyPerm {
|
||||
#[serde(default)]
|
||||
pub create_bucket: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KeyInfoBucketResponse {
|
||||
pub id: String,
|
||||
|
@ -297,7 +298,7 @@ pub struct KeyInfoBucketResponse {
|
|||
pub permissions: ApiBucketKeyPerm,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApiBucketKeyPerm {
|
||||
#[serde(default)]
|
||||
|
@ -310,18 +311,18 @@ pub struct ApiBucketKeyPerm {
|
|||
|
||||
// ---- CreateKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateKeyRequest {
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateKeyResponse(pub GetKeyInfoResponse);
|
||||
|
||||
// ---- ImportKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ImportKeyRequest {
|
||||
pub access_key_id: String,
|
||||
|
@ -329,21 +330,21 @@ pub struct ImportKeyRequest {
|
|||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ImportKeyResponse(pub GetKeyInfoResponse);
|
||||
|
||||
// ---- UpdateKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateKeyRequest {
|
||||
pub id: String,
|
||||
pub body: UpdateKeyRequestBody,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateKeyResponse(pub GetKeyInfoResponse);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateKeyRequestBody {
|
||||
pub name: Option<String>,
|
||||
|
@ -353,12 +354,12 @@ pub struct UpdateKeyRequestBody {
|
|||
|
||||
// ---- DeleteKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeleteKeyRequest {
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeleteKeyResponse;
|
||||
|
||||
// **********************************************
|
||||
|
@ -367,13 +368,13 @@ pub struct DeleteKeyResponse;
|
|||
|
||||
// ---- ListBuckets ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ListBucketsRequest;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ListBucketsResponse(pub Vec<ListBucketsResponseItem>);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ListBucketsResponseItem {
|
||||
pub id: String,
|
||||
|
@ -381,7 +382,7 @@ pub struct ListBucketsResponseItem {
|
|||
pub local_aliases: Vec<BucketLocalAlias>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BucketLocalAlias {
|
||||
pub access_key_id: String,
|
||||
|
@ -390,13 +391,13 @@ pub struct BucketLocalAlias {
|
|||
|
||||
// ---- GetBucketInfo ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct GetBucketInfoRequest {
|
||||
pub id: Option<String>,
|
||||
pub global_alias: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetBucketInfoResponse {
|
||||
pub id: String,
|
||||
|
@ -414,14 +415,14 @@ pub struct GetBucketInfoResponse {
|
|||
pub quotas: ApiBucketQuotas,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetBucketInfoWebsiteResponse {
|
||||
pub index_document: String,
|
||||
pub error_document: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetBucketInfoKey {
|
||||
pub access_key_id: String,
|
||||
|
@ -430,7 +431,7 @@ pub struct GetBucketInfoKey {
|
|||
pub bucket_local_aliases: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApiBucketQuotas {
|
||||
pub max_size: Option<u64>,
|
||||
|
@ -439,17 +440,17 @@ pub struct ApiBucketQuotas {
|
|||
|
||||
// ---- CreateBucket ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateBucketRequest {
|
||||
pub global_alias: Option<String>,
|
||||
pub local_alias: Option<CreateBucketLocalAlias>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateBucketResponse(pub GetBucketInfoResponse);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateBucketLocalAlias {
|
||||
pub access_key_id: String,
|
||||
|
@ -460,23 +461,23 @@ pub struct CreateBucketLocalAlias {
|
|||
|
||||
// ---- UpdateBucket ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateBucketRequest {
|
||||
pub id: String,
|
||||
pub body: UpdateBucketRequestBody,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateBucketResponse(pub GetBucketInfoResponse);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateBucketRequestBody {
|
||||
pub website_access: Option<UpdateBucketWebsiteAccess>,
|
||||
pub quotas: Option<ApiBucketQuotas>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateBucketWebsiteAccess {
|
||||
pub enabled: bool,
|
||||
|
@ -486,12 +487,12 @@ pub struct UpdateBucketWebsiteAccess {
|
|||
|
||||
// ---- DeleteBucket ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeleteBucketRequest {
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeleteBucketResponse;
|
||||
|
||||
// **********************************************
|
||||
|
@ -500,13 +501,13 @@ pub struct DeleteBucketResponse;
|
|||
|
||||
// ---- AllowBucketKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AllowBucketKeyRequest(pub BucketKeyPermChangeRequest);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AllowBucketKeyResponse(pub GetBucketInfoResponse);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BucketKeyPermChangeRequest {
|
||||
pub bucket_id: String,
|
||||
|
@ -516,10 +517,10 @@ pub struct BucketKeyPermChangeRequest {
|
|||
|
||||
// ---- DenyBucketKey ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DenyBucketKeyRequest(pub BucketKeyPermChangeRequest);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DenyBucketKeyResponse(pub GetBucketInfoResponse);
|
||||
|
||||
// **********************************************
|
||||
|
@ -528,7 +529,7 @@ pub struct DenyBucketKeyResponse(pub GetBucketInfoResponse);
|
|||
|
||||
// ---- AddBucketAlias ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddBucketAliasRequest {
|
||||
pub bucket_id: String,
|
||||
|
@ -536,10 +537,10 @@ pub struct AddBucketAliasRequest {
|
|||
pub alias: BucketAliasEnum,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AddBucketAliasResponse(pub GetBucketInfoResponse);
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BucketAliasEnum {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -553,7 +554,7 @@ pub enum BucketAliasEnum {
|
|||
|
||||
// ---- RemoveBucketAlias ----
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RemoveBucketAliasRequest {
|
||||
pub bucket_id: String,
|
||||
|
@ -561,5 +562,5 @@ pub struct RemoveBucketAliasRequest {
|
|||
pub alias: BucketAliasEnum,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RemoveBucketAliasResponse(pub GetBucketInfoResponse);
|
||||
|
|
|
@ -56,7 +56,7 @@ impl From<HelperError> for Error {
|
|||
impl CommonErrorDerivative for Error {}
|
||||
|
||||
impl Error {
|
||||
fn code(&self) -> &'static str {
|
||||
pub fn code(&self) -> &'static str {
|
||||
match self {
|
||||
Error::Common(c) => c.aws_code(),
|
||||
Error::NoSuchAccessKey(_) => "NoSuchAccessKey",
|
||||
|
|
|
@ -4,7 +4,7 @@ macro_rules! admin_endpoints {
|
|||
$($endpoint:ident,)*
|
||||
] => {
|
||||
paste! {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum AdminApiRequest {
|
||||
$(
|
||||
$special_endpoint( [<$special_endpoint Request>] ),
|
||||
|
@ -14,7 +14,7 @@ macro_rules! admin_endpoints {
|
|||
)*
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum AdminApiResponse {
|
||||
$(
|
||||
|
@ -22,7 +22,7 @@ macro_rules! admin_endpoints {
|
|||
)*
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum TaggedAdminApiResponse {
|
||||
$(
|
||||
$endpoint( [<$endpoint Response>] ),
|
||||
|
@ -43,7 +43,7 @@ macro_rules! admin_endpoints {
|
|||
}
|
||||
|
||||
impl AdminApiResponse {
|
||||
fn tagged(self) -> TaggedAdminApiResponse {
|
||||
pub fn tagged(self) -> TaggedAdminApiResponse {
|
||||
match self {
|
||||
$(
|
||||
Self::$endpoint(res) => TaggedAdminApiResponse::$endpoint(res),
|
||||
|
@ -52,6 +52,24 @@ macro_rules! admin_endpoints {
|
|||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl From< [< $endpoint Request >] > for AdminApiRequest {
|
||||
fn from(req: [< $endpoint Request >]) -> AdminApiRequest {
|
||||
AdminApiRequest::$endpoint(req)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<TaggedAdminApiResponse> for [< $endpoint Response >] {
|
||||
type Error = TaggedAdminApiResponse;
|
||||
fn try_from(resp: TaggedAdminApiResponse) -> Result< [< $endpoint Response >], TaggedAdminApiResponse> {
|
||||
match resp {
|
||||
TaggedAdminApiResponse::$endpoint(v) => Ok(v),
|
||||
x => Err(x),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
#[async_trait]
|
||||
impl EndpointHandler for AdminApiRequest {
|
||||
type Response = AdminApiResponse;
|
||||
|
|
|
@ -30,6 +30,10 @@ use garage_model::key_table::*;
|
|||
use garage_model::s3::mpu_table::MultipartUpload;
|
||||
use garage_model::s3::version_table::Version;
|
||||
|
||||
use garage_api::admin::api::{AdminApiRequest, TaggedAdminApiResponse};
|
||||
use garage_api::admin::EndpointHandler as AdminApiEndpoint;
|
||||
use garage_api::generic_server::ApiError;
|
||||
|
||||
use crate::cli::*;
|
||||
use crate::repair::online::launch_online_repair;
|
||||
|
||||
|
@ -70,6 +74,15 @@ pub enum AdminRpc {
|
|||
versions: Vec<Result<Version, Uuid>>,
|
||||
uploads: Vec<MultipartUpload>,
|
||||
},
|
||||
|
||||
// Proxying HTTP Admin API endpoints
|
||||
ApiRequest(AdminApiRequest),
|
||||
ApiOkResponse(TaggedAdminApiResponse),
|
||||
ApiErrorResponse {
|
||||
http_code: u16,
|
||||
error_code: String,
|
||||
message: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl Rpc for AdminRpc {
|
||||
|
@ -503,6 +516,24 @@ impl AdminRpcHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ================== PROXYING ADMIN API REQUESTS ===================
|
||||
|
||||
async fn handle_api_request(
|
||||
self: &Arc<Self>,
|
||||
req: &AdminApiRequest,
|
||||
) -> Result<AdminRpc, Error> {
|
||||
let req = req.clone();
|
||||
let res = req.handle(&self.garage).await;
|
||||
match res {
|
||||
Ok(res) => Ok(AdminRpc::ApiOkResponse(res.tagged())),
|
||||
Err(e) => Ok(AdminRpc::ApiErrorResponse {
|
||||
http_code: e.http_status_code().as_u16(),
|
||||
error_code: e.code().to_string(),
|
||||
message: e.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
@ -520,6 +551,7 @@ impl EndpointHandler<AdminRpc> for AdminRpcHandler {
|
|||
AdminRpc::Worker(wo) => self.handle_worker_cmd(wo).await,
|
||||
AdminRpc::BlockOperation(bo) => self.handle_block_cmd(bo).await,
|
||||
AdminRpc::MetaOperation(mo) => self.handle_meta_cmd(mo).await,
|
||||
AdminRpc::ApiRequest(r) => self.handle_api_request(r).await,
|
||||
m => Err(GarageError::unexpected_rpc_message(m).into()),
|
||||
}
|
||||
}
|
||||
|
|
63
src/garage/cli_v2/mod.rs
Normal file
63
src/garage/cli_v2/mod.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use format_table::format_table;
|
||||
use garage_util::error::*;
|
||||
|
||||
use garage_rpc::layout::*;
|
||||
use garage_rpc::system::*;
|
||||
use garage_rpc::*;
|
||||
|
||||
use garage_api::admin::api::*;
|
||||
use garage_api::admin::EndpointHandler as AdminApiEndpoint;
|
||||
|
||||
use crate::admin::*;
|
||||
use crate::cli::*;
|
||||
|
||||
pub struct Cli {
|
||||
pub system_rpc_endpoint: Arc<Endpoint<SystemRpc, ()>>,
|
||||
pub admin_rpc_endpoint: Arc<Endpoint<AdminRpc, ()>>,
|
||||
pub rpc_host: NodeID,
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
pub async fn handle(&self, cmd: Command) -> Result<(), Error> {
|
||||
println!("{:?}", self.api_request(GetClusterStatusRequest).await?);
|
||||
Ok(())
|
||||
/*
|
||||
match cmd {
|
||||
_ => todo!(),
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
pub async fn api_request<T>(&self, req: T) -> Result<<T as AdminApiEndpoint>::Response, Error>
|
||||
where
|
||||
T: AdminApiEndpoint,
|
||||
AdminApiRequest: From<T>,
|
||||
<T as AdminApiEndpoint>::Response: TryFrom<TaggedAdminApiResponse>,
|
||||
{
|
||||
let req = AdminApiRequest::from(req);
|
||||
let req_name = req.name();
|
||||
match self
|
||||
.admin_rpc_endpoint
|
||||
.call(&self.rpc_host, AdminRpc::ApiRequest(req), PRIO_NORMAL)
|
||||
.await?
|
||||
.ok_or_message("xoxo")?
|
||||
{
|
||||
AdminRpc::ApiOkResponse(resp) => <T as AdminApiEndpoint>::Response::try_from(resp)
|
||||
.map_err(|_| Error::Message(format!("{} returned unexpected response", req_name))),
|
||||
AdminRpc::ApiErrorResponse {
|
||||
http_code,
|
||||
error_code,
|
||||
message,
|
||||
} => Err(Error::Message(format!(
|
||||
"{} returned {} ({}): {}",
|
||||
req_name, error_code, http_code, message
|
||||
))),
|
||||
m => Err(Error::unexpected_rpc_message(m)),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ extern crate tracing;
|
|||
|
||||
mod admin;
|
||||
mod cli;
|
||||
mod cli_v2;
|
||||
mod repair;
|
||||
mod secrets;
|
||||
mod server;
|
||||
|
@ -284,10 +285,11 @@ async fn cli_command(opt: Opt) -> Result<(), Error> {
|
|||
let system_rpc_endpoint = netapp.endpoint::<SystemRpc, ()>(SYSTEM_RPC_PATH.into());
|
||||
let admin_rpc_endpoint = netapp.endpoint::<AdminRpc, ()>(ADMIN_RPC_PATH.into());
|
||||
|
||||
match cli_command_dispatch(opt.cmd, &system_rpc_endpoint, &admin_rpc_endpoint, id).await {
|
||||
Err(HelperError::Internal(i)) => Err(Error::Message(format!("Internal error: {}", i))),
|
||||
Err(HelperError::BadRequest(b)) => Err(Error::Message(b)),
|
||||
Err(e) => Err(Error::Message(format!("{}", e))),
|
||||
Ok(x) => Ok(x),
|
||||
}
|
||||
let cli = cli_v2::Cli {
|
||||
system_rpc_endpoint,
|
||||
admin_rpc_endpoint,
|
||||
rpc_host: id,
|
||||
};
|
||||
|
||||
cli.handle(opt.cmd).await
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue