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