use std::net::SocketAddr; use serde::{Deserialize, Serialize}; use crate::helpers::is_default; pub enum AdminApiRequest { // Cluster operations GetClusterStatus(GetClusterStatusRequest), GetClusterHealth(GetClusterHealthRequest), ConnectClusterNodes(ConnectClusterNodesRequest), GetClusterLayout(GetClusterLayoutRequest), UpdateClusterLayout(UpdateClusterLayoutRequest), ApplyClusterLayout(ApplyClusterLayoutRequest), RevertClusterLayout(RevertClusterLayoutRequest), } pub enum AdminApiResponse { // Cluster operations GetClusterStatus(GetClusterStatusResponse), GetClusterHealth(GetClusterHealthResponse), ConnectClusterNodes(ConnectClusterNodesResponse), GetClusterLayout(GetClusterLayoutResponse), UpdateClusterLayout(UpdateClusterLayoutResponse), ApplyClusterLayout(ApplyClusterLayoutResponse), RevertClusterLayout(RevertClusterLayoutResponse), } // ********************************************** // Metrics-related endpoints // ********************************************** // TODO: do we want this here ?? // ---- Metrics ---- pub struct MetricsRequest; // ---- Health ---- pub struct HealthRequest; // ********************************************** // Cluster operations // ********************************************** // ---- GetClusterStatus ---- pub struct GetClusterStatusRequest; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetClusterStatusResponse { pub node: String, pub garage_version: &'static str, pub garage_features: Option<&'static [&'static str]>, pub rust_version: &'static str, pub db_engine: String, pub layout_version: u64, pub nodes: Vec, } #[derive(Serialize, Default)] #[serde(rename_all = "camelCase")] pub struct NodeResp { pub id: String, pub role: Option, pub addr: Option, pub hostname: Option, pub is_up: bool, pub last_seen_secs_ago: Option, pub draining: bool, #[serde(skip_serializing_if = "Option::is_none")] pub data_partition: Option, #[serde(skip_serializing_if = "Option::is_none")] pub metadata_partition: Option, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct NodeRoleResp { pub id: String, pub zone: String, pub capacity: Option, pub tags: Vec, } #[derive(Serialize, Default)] #[serde(rename_all = "camelCase")] pub struct FreeSpaceResp { pub available: u64, pub total: u64, } // ---- GetClusterHealth ---- pub struct GetClusterHealthRequest; #[derive(Debug, Clone, Copy, Serialize)] #[serde(rename_all = "camelCase")] pub struct GetClusterHealthResponse { pub status: &'static str, pub known_nodes: usize, pub connected_nodes: usize, pub storage_nodes: usize, pub storage_nodes_ok: usize, pub partitions: usize, pub partitions_quorum: usize, pub partitions_all_ok: usize, } // ---- ConnectClusterNodes ---- #[derive(Debug, Clone, Deserialize)] pub struct ConnectClusterNodesRequest(pub Vec); #[derive(Serialize)] pub struct ConnectClusterNodesResponse(pub Vec); #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ConnectClusterNodeResponse { pub success: bool, pub error: Option, } // ---- GetClusterLayout ---- pub struct GetClusterLayoutRequest; #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetClusterLayoutResponse { pub version: u64, pub roles: Vec, pub staged_role_changes: Vec, } #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NodeRoleChange { pub id: String, #[serde(flatten)] pub action: NodeRoleChangeEnum, } #[derive(Serialize, Deserialize)] #[serde(untagged)] pub enum NodeRoleChangeEnum { #[serde(rename_all = "camelCase")] Remove { remove: bool }, #[serde(rename_all = "camelCase")] Update { zone: String, capacity: Option, tags: Vec, }, } // ---- UpdateClusterLayout ---- #[derive(Deserialize)] pub struct UpdateClusterLayoutRequest(pub Vec); #[derive(Serialize)] pub struct UpdateClusterLayoutResponse(pub GetClusterLayoutResponse); // ---- ApplyClusterLayout ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct ApplyClusterLayoutRequest { pub version: u64, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ApplyClusterLayoutResponse { pub message: Vec, pub layout: GetClusterLayoutResponse, } // ---- RevertClusterLayout ---- pub struct RevertClusterLayoutRequest; #[derive(Serialize)] pub struct RevertClusterLayoutResponse(pub GetClusterLayoutResponse); // ********************************************** // Access key operations // ********************************************** // ---- ListKeys ---- pub struct ListKeysRequest; #[derive(Serialize)] pub struct ListKeysResponse(pub Vec); #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ListKeysResponseItem { pub id: String, pub name: String, } // ---- GetKeyInfo ---- pub struct GetKeyInfoRequest { pub id: Option, pub search: Option, pub show_secret_key: bool, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetKeyInfoResponse { pub name: String, pub access_key_id: String, #[serde(skip_serializing_if = "is_default")] pub secret_access_key: Option, pub permissions: KeyPerm, pub buckets: Vec, } #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct KeyPerm { #[serde(default)] pub create_bucket: bool, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct KeyInfoBucketResponse { pub id: String, pub global_aliases: Vec, pub local_aliases: Vec, pub permissions: ApiBucketKeyPerm, } #[derive(Serialize, Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct ApiBucketKeyPerm { #[serde(default)] pub read: bool, #[serde(default)] pub write: bool, #[serde(default)] pub owner: bool, } // ---- CreateKey ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct CreateKeyRequest { pub name: Option, } #[derive(Serialize)] pub struct CreateKeyResponse(pub GetKeyInfoResponse); // ---- ImportKey ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct ImportKeyRequest { pub access_key_id: String, pub secret_access_key: String, pub name: Option, } #[derive(Serialize)] pub struct ImportKeyResponse(pub GetKeyInfoResponse); // ---- UpdateKey ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct UpdateKeyRequest { // TODO: id (get parameter) goes here pub name: Option, pub allow: Option, pub deny: Option, } #[derive(Serialize)] pub struct UpdateKeyResponse(pub GetKeyInfoResponse); // ---- DeleteKey ---- pub struct DeleteKeyRequest { pub id: String, } pub struct DeleteKeyResponse; // ********************************************** // Bucket operations // ********************************************** // ---- ListBuckets ---- pub struct ListBucketsRequest; pub struct ListBucketsResponse(pub Vec); #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ListBucketsResponseItem { pub id: String, pub global_aliases: Vec, pub local_aliases: Vec, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct BucketLocalAlias { pub access_key_id: String, pub alias: String, } // ---- GetBucketInfo ---- pub struct GetBucketInfoRequest { pub id: Option, pub global_alias: Option, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetBucketInfoResponse { pub id: String, pub global_aliases: Vec, pub website_access: bool, #[serde(default)] pub website_config: Option, pub keys: Vec, pub objects: i64, pub bytes: i64, pub unfinished_uploads: i64, pub unfinished_multipart_uploads: i64, pub unfinished_multipart_upload_parts: i64, pub unfinished_multipart_upload_bytes: i64, pub quotas: ApiBucketQuotas, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetBucketInfoWebsiteResponse { pub index_document: String, pub error_document: Option, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct GetBucketInfoKey { pub access_key_id: String, pub name: String, pub permissions: ApiBucketKeyPerm, pub bucket_local_aliases: Vec, } #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ApiBucketQuotas { pub max_size: Option, pub max_objects: Option, } // ---- CreateBucket ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct CreateBucketRequest { pub global_alias: Option, pub local_alias: Option, } #[derive(Serialize)] pub struct CreateBucketResponse(GetBucketInfoResponse); #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct CreateBucketLocalAlias { pub access_key_id: String, pub alias: String, #[serde(default)] pub allow: ApiBucketKeyPerm, } // ---- UpdateBucket ---- #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct UpdateBucketRequest { pub website_access: Option, pub quotas: Option, } #[derive(Serialize)] pub struct UpdateBucketResponse(GetBucketInfoResponse); #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct UpdateBucketWebsiteAccess { pub enabled: bool, pub index_document: Option, pub error_document: Option, } // ---- DeleteBucket ---- pub struct DeleteBucketRequest { pub id: String, } pub struct DeleteBucketResponse; // ********************************************** // Operations on permissions for keys on buckets // ********************************************** // ---- BucketAllowKey ---- pub struct BucketAllowKeyRequest(pub BucketKeyPermChangeRequest); pub struct BucketAllowKeyResponse; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct BucketKeyPermChangeRequest { pub bucket_id: String, pub access_key_id: String, pub permissions: ApiBucketKeyPerm, } // ---- BucketDenyKey ---- pub struct BucketDenyKeyRequest(pub BucketKeyPermChangeRequest); pub struct BucketDenyKeyResponse; // ********************************************** // Operations on bucket aliases // ********************************************** // ---- GlobalAliasBucket ---- pub struct GlobalAliasBucketRequest { pub id: String, pub alias: String, } pub struct GlobalAliasBucketReponse; // ---- GlobalUnaliasBucket ---- pub struct GlobalUnaliasBucketRequest { pub id: String, pub alias: String, } pub struct GlobalUnaliasBucketReponse; // ---- LocalAliasBucket ---- pub struct LocalAliasBucketRequest { pub id: String, pub access_key_id: String, pub alias: String, } pub struct LocalAliasBucketReponse; // ---- LocalUnaliasBucket ---- pub struct LocalUnaliasBucketRequest { pub id: String, pub access_key_id: String, pub alias: String, } pub struct LocalUnaliasBucketReponse;