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