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;
7mod types;
8
9pub use cluster::{
10    BackendInfo, BackendType, BucketsInfo, ClusterInfo, DiskInfo, HealDriveInfo, HealDriveInfos,
11    HealResultItem, HealScanMode, HealStartRequest, HealStatus, HealingDiskInfo, MemStats,
12    ObjectsInfo, ServerInfo, UsageInfo,
13};
14pub use types::{
15    BucketQuota, CreateServiceAccountRequest, Group, GroupStatus, Policy, PolicyEntity, PolicyInfo,
16    ServiceAccount, ServiceAccountCreateResponse, ServiceAccountCredentials, SetPolicyRequest,
17    UpdateGroupMembersRequest, User, UserStatus,
18};
19
20use async_trait::async_trait;
21
22use crate::error::Result;
23
24/// Admin API trait for IAM and cluster management operations
25///
26/// This trait defines the interface for managing users, policies, groups,
27/// service accounts, and cluster operations on S3-compatible storage systems
28/// that support the RustFS/MinIO Admin API.
29#[async_trait]
30pub trait AdminApi: Send + Sync {
31    // ==================== Cluster Operations ====================
32
33    /// Get cluster information including servers, disks, and usage
34    async fn cluster_info(&self) -> Result<ClusterInfo>;
35
36    /// Get current heal status
37    async fn heal_status(&self) -> Result<HealStatus>;
38
39    /// Start a heal operation
40    async fn heal_start(&self, request: HealStartRequest) -> Result<HealStatus>;
41
42    /// Stop a running heal operation
43    async fn heal_stop(&self) -> Result<()>;
44
45    // ==================== User Operations ====================
46
47    /// List all users
48    async fn list_users(&self) -> Result<Vec<User>>;
49
50    /// Get user information
51    async fn get_user(&self, access_key: &str) -> Result<User>;
52
53    /// Create a new user
54    async fn create_user(&self, access_key: &str, secret_key: &str) -> Result<User>;
55
56    /// Delete a user
57    async fn delete_user(&self, access_key: &str) -> Result<()>;
58
59    /// Set user status (enable/disable)
60    async fn set_user_status(&self, access_key: &str, status: UserStatus) -> Result<()>;
61
62    // ==================== Policy Operations ====================
63
64    /// List all policies
65    async fn list_policies(&self) -> Result<Vec<PolicyInfo>>;
66
67    /// Get policy information
68    async fn get_policy(&self, name: &str) -> Result<Policy>;
69
70    /// Create a new policy
71    async fn create_policy(&self, name: &str, policy_document: &str) -> Result<()>;
72
73    /// Delete a policy
74    async fn delete_policy(&self, name: &str) -> Result<()>;
75
76    /// Attach policy to a user or group
77    async fn attach_policy(
78        &self,
79        policy_names: &[String],
80        entity_type: PolicyEntity,
81        entity_name: &str,
82    ) -> Result<()>;
83
84    /// Detach policy from a user or group
85    async fn detach_policy(
86        &self,
87        policy_names: &[String],
88        entity_type: PolicyEntity,
89        entity_name: &str,
90    ) -> Result<()>;
91
92    // ==================== Group Operations ====================
93
94    /// List all groups
95    async fn list_groups(&self) -> Result<Vec<String>>;
96
97    /// Get group information
98    async fn get_group(&self, name: &str) -> Result<Group>;
99
100    /// Create a new group
101    async fn create_group(&self, name: &str, members: Option<&[String]>) -> Result<Group>;
102
103    /// Delete a group
104    async fn delete_group(&self, name: &str) -> Result<()>;
105
106    /// Set group status (enable/disable)
107    async fn set_group_status(&self, name: &str, status: GroupStatus) -> Result<()>;
108
109    /// Add members to a group
110    async fn add_group_members(&self, group: &str, members: &[String]) -> Result<()>;
111
112    /// Remove members from a group
113    async fn remove_group_members(&self, group: &str, members: &[String]) -> Result<()>;
114
115    // ==================== Service Account Operations ====================
116
117    /// List service accounts for a user
118    async fn list_service_accounts(&self, user: Option<&str>) -> Result<Vec<ServiceAccount>>;
119
120    /// Get service account information
121    async fn get_service_account(&self, access_key: &str) -> Result<ServiceAccount>;
122
123    /// Create a new service account
124    async fn create_service_account(
125        &self,
126        request: CreateServiceAccountRequest,
127    ) -> Result<ServiceAccount>;
128
129    /// Delete a service account
130    async fn delete_service_account(&self, access_key: &str) -> Result<()>;
131
132    // ==================== Bucket Quota Operations ====================
133
134    /// Set bucket quota in bytes
135    async fn set_bucket_quota(&self, bucket: &str, quota: u64) -> Result<BucketQuota>;
136
137    /// Get bucket quota information
138    async fn get_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
139
140    /// Clear bucket quota
141    async fn clear_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
142}
143
144#[cfg(test)]
145mod tests {
146    use super::*;
147
148    // Test that types are re-exported correctly
149    #[test]
150    fn test_user_status_reexport() {
151        assert_eq!(UserStatus::Enabled.to_string(), "enabled");
152        assert_eq!(UserStatus::Disabled.to_string(), "disabled");
153    }
154
155    #[test]
156    fn test_group_status_reexport() {
157        assert_eq!(GroupStatus::Enabled.to_string(), "enabled");
158        assert_eq!(GroupStatus::Disabled.to_string(), "disabled");
159    }
160
161    #[test]
162    fn test_policy_entity_reexport() {
163        assert_eq!(PolicyEntity::User.to_string(), "user");
164        assert_eq!(PolicyEntity::Group.to_string(), "group");
165    }
166
167    #[test]
168    fn test_user_new() {
169        let user = User::new("testuser");
170        assert_eq!(user.access_key, "testuser");
171        assert_eq!(user.status, UserStatus::Enabled);
172    }
173
174    #[test]
175    fn test_group_new() {
176        let group = Group::new("developers");
177        assert_eq!(group.name, "developers");
178        assert_eq!(group.status, GroupStatus::Enabled);
179    }
180
181    #[test]
182    fn test_policy_new() {
183        let policy = Policy::new("readonly", r#"{"Version":"2012-10-17","Statement":[]}"#);
184        assert_eq!(policy.name, "readonly");
185        assert!(policy.parse_document().is_ok());
186    }
187
188    #[test]
189    fn test_service_account_new() {
190        let sa = ServiceAccount::new("AKIAIOSFODNN7EXAMPLE");
191        assert_eq!(sa.access_key, "AKIAIOSFODNN7EXAMPLE");
192        assert!(sa.secret_key.is_none());
193    }
194}