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