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