Skip to main content

rc_core/admin/
mod.rs

1//! Admin API module
2//!
3//! This module provides the AdminApi trait and types for managing
4//! IAM users, policies, groups, service accounts, and cluster operations.
5
6mod cluster;
7pub mod tier;
8mod types;
9
10pub use cluster::{
11    BackendInfo, BackendType, BucketsInfo, ClusterInfo, DiskInfo, HealDriveInfo, HealDriveInfos,
12    HealResultItem, HealScanMode, HealStartRequest, HealStatus, HealingDiskInfo, MemStats,
13    ObjectsInfo, PoolDecommissionInfo, PoolErasureSetInfo, PoolStatus, PoolTarget,
14    RebalancePoolProgress, RebalancePoolStatus, RebalanceStartResult, RebalanceStatus, ServerInfo,
15    UsageInfo,
16};
17pub use tier::{
18    TierAliyun, TierAzure, TierConfig, TierCreds, TierGCS, TierHuaweicloud, TierMinIO, TierR2,
19    TierRustFS, TierS3, TierTencent, TierType,
20};
21pub use types::{
22    BucketQuota, CreateServiceAccountRequest, Group, GroupStatus, Policy, PolicyEntity, PolicyInfo,
23    ServiceAccount, ServiceAccountCreateResponse, ServiceAccountCredentials, SetPolicyRequest,
24    UpdateGroupMembersRequest, User, UserStatus,
25};
26
27use async_trait::async_trait;
28
29use crate::error::Result;
30
31/// Admin API trait for IAM and cluster management operations
32///
33/// This trait defines the interface for managing users, policies, groups,
34/// service accounts, and cluster operations on S3-compatible storage systems
35/// that support the RustFS/MinIO Admin API.
36#[async_trait]
37pub trait AdminApi: Send + Sync {
38    // ==================== Cluster Operations ====================
39
40    /// Get cluster information including servers, disks, and usage
41    async fn cluster_info(&self) -> Result<ClusterInfo>;
42
43    /// Get current heal status
44    async fn heal_status(&self) -> Result<HealStatus>;
45
46    /// Start a heal operation
47    async fn heal_start(&self, request: HealStartRequest) -> Result<HealStatus>;
48
49    /// Stop a running heal operation
50    async fn heal_stop(&self) -> Result<()>;
51
52    /// List storage pools
53    async fn list_pools(&self) -> Result<Vec<PoolStatus>>;
54
55    /// Get storage pool status
56    async fn pool_status(&self, target: PoolTarget) -> Result<PoolStatus>;
57
58    /// Start decommissioning one or more storage pools
59    async fn decommission_start(&self, target: PoolTarget) -> Result<()>;
60
61    /// Cancel decommissioning a storage pool
62    async fn decommission_cancel(&self, target: PoolTarget) -> Result<()>;
63
64    /// Start a rebalance operation
65    async fn rebalance_start(&self) -> Result<RebalanceStartResult>;
66
67    /// Get rebalance status
68    async fn rebalance_status(&self) -> Result<RebalanceStatus>;
69
70    /// Stop a running rebalance operation
71    async fn rebalance_stop(&self) -> Result<()>;
72
73    // ==================== User Operations ====================
74
75    /// List all users
76    async fn list_users(&self) -> Result<Vec<User>>;
77
78    /// Get user information
79    async fn get_user(&self, access_key: &str) -> Result<User>;
80
81    /// Create a new user
82    async fn create_user(&self, access_key: &str, secret_key: &str) -> Result<User>;
83
84    /// Delete a user
85    async fn delete_user(&self, access_key: &str) -> Result<()>;
86
87    /// Set user status (enable/disable)
88    async fn set_user_status(&self, access_key: &str, status: UserStatus) -> Result<()>;
89
90    // ==================== Policy Operations ====================
91
92    /// List all policies
93    async fn list_policies(&self) -> Result<Vec<PolicyInfo>>;
94
95    /// Get policy information
96    async fn get_policy(&self, name: &str) -> Result<Policy>;
97
98    /// Create a new policy
99    async fn create_policy(&self, name: &str, policy_document: &str) -> Result<()>;
100
101    /// Delete a policy
102    async fn delete_policy(&self, name: &str) -> Result<()>;
103
104    /// Attach policy to a user or group
105    async fn attach_policy(
106        &self,
107        policy_names: &[String],
108        entity_type: PolicyEntity,
109        entity_name: &str,
110    ) -> Result<()>;
111
112    /// Detach policy from a user or group
113    async fn detach_policy(
114        &self,
115        policy_names: &[String],
116        entity_type: PolicyEntity,
117        entity_name: &str,
118    ) -> Result<()>;
119
120    // ==================== Group Operations ====================
121
122    /// List all groups
123    async fn list_groups(&self) -> Result<Vec<String>>;
124
125    /// Get group information
126    async fn get_group(&self, name: &str) -> Result<Group>;
127
128    /// Create a new group
129    async fn create_group(&self, name: &str, members: Option<&[String]>) -> Result<Group>;
130
131    /// Delete a group
132    async fn delete_group(&self, name: &str) -> Result<()>;
133
134    /// Set group status (enable/disable)
135    async fn set_group_status(&self, name: &str, status: GroupStatus) -> Result<()>;
136
137    /// Add members to a group
138    async fn add_group_members(&self, group: &str, members: &[String]) -> Result<()>;
139
140    /// Remove members from a group
141    async fn remove_group_members(&self, group: &str, members: &[String]) -> Result<()>;
142
143    // ==================== Service Account Operations ====================
144
145    /// List service accounts for a user
146    async fn list_service_accounts(&self, user: Option<&str>) -> Result<Vec<ServiceAccount>>;
147
148    /// Get service account information
149    async fn get_service_account(&self, access_key: &str) -> Result<ServiceAccount>;
150
151    /// Create a new service account
152    async fn create_service_account(
153        &self,
154        request: CreateServiceAccountRequest,
155    ) -> Result<ServiceAccount>;
156
157    /// Delete a service account
158    async fn delete_service_account(&self, access_key: &str) -> Result<()>;
159
160    // ==================== Bucket Quota Operations ====================
161
162    /// Set bucket quota in bytes
163    async fn set_bucket_quota(&self, bucket: &str, quota: u64) -> Result<BucketQuota>;
164
165    /// Get bucket quota information
166    async fn get_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
167
168    /// Clear bucket quota
169    async fn clear_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
170
171    // ==================== Tier Operations ====================
172
173    /// List all configured storage tiers
174    async fn list_tiers(&self) -> Result<Vec<TierConfig>>;
175
176    /// Get tier statistics
177    async fn tier_stats(&self) -> Result<serde_json::Value>;
178
179    /// Add a new storage tier
180    async fn add_tier(&self, config: TierConfig) -> Result<()>;
181
182    /// Edit tier credentials
183    async fn edit_tier(&self, name: &str, creds: TierCreds) -> Result<()>;
184
185    /// Remove a storage tier
186    async fn remove_tier(&self, name: &str, force: bool) -> Result<()>;
187
188    // ==================== Replication Target Operations ====================
189
190    /// Set a remote replication target for a bucket, returns the ARN
191    async fn set_remote_target(
192        &self,
193        bucket: &str,
194        target: crate::replication::BucketTarget,
195        update: bool,
196    ) -> Result<String>;
197
198    /// List remote replication targets for a bucket
199    async fn list_remote_targets(
200        &self,
201        bucket: &str,
202    ) -> Result<Vec<crate::replication::BucketTarget>>;
203
204    /// Remove a remote replication target
205    async fn remove_remote_target(&self, bucket: &str, arn: &str) -> Result<()>;
206
207    /// Get replication metrics for a bucket
208    async fn replication_metrics(&self, bucket: &str) -> Result<serde_json::Value>;
209}
210
211#[cfg(test)]
212mod tests {
213    use super::*;
214
215    // Test that types are re-exported correctly
216    #[test]
217    fn test_user_status_reexport() {
218        assert_eq!(UserStatus::Enabled.to_string(), "enabled");
219        assert_eq!(UserStatus::Disabled.to_string(), "disabled");
220    }
221
222    #[test]
223    fn test_group_status_reexport() {
224        assert_eq!(GroupStatus::Enabled.to_string(), "enabled");
225        assert_eq!(GroupStatus::Disabled.to_string(), "disabled");
226    }
227
228    #[test]
229    fn test_policy_entity_reexport() {
230        assert_eq!(PolicyEntity::User.to_string(), "user");
231        assert_eq!(PolicyEntity::Group.to_string(), "group");
232    }
233
234    #[test]
235    fn test_user_new() {
236        let user = User::new("testuser");
237        assert_eq!(user.access_key, "testuser");
238        assert_eq!(user.status, UserStatus::Enabled);
239    }
240
241    #[test]
242    fn test_group_new() {
243        let group = Group::new("developers");
244        assert_eq!(group.name, "developers");
245        assert_eq!(group.status, GroupStatus::Enabled);
246    }
247
248    #[test]
249    fn test_policy_new() {
250        let policy = Policy::new("readonly", r#"{"Version":"2012-10-17","Statement":[]}"#);
251        assert_eq!(policy.name, "readonly");
252        assert!(policy.parse_document().is_ok());
253    }
254
255    #[test]
256    fn test_service_account_new() {
257        let sa = ServiceAccount::new("AKIAIOSFODNN7EXAMPLE");
258        assert_eq!(sa.access_key, "AKIAIOSFODNN7EXAMPLE");
259        assert!(sa.secret_key.is_none());
260    }
261}