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 access_keys;
7mod account;
8mod bucket_metadata;
9mod capabilities;
10mod cluster;
11mod configuration;
12mod diagnostics;
13mod iam;
14mod inspect_archive;
15mod kms;
16mod kms_diagnostic;
17mod observability;
18mod oidc;
19mod replication;
20mod site;
21pub mod tier;
22mod types;
23
24pub use access_keys::{
25    AccessKeyKind, AccessKeyListType, AccessKeyProvider, AccessKeyRecord, BulkAccessKeyApi,
26    BulkAccessKeyQuery, IAM_ACCESS_KEYS_BULK_CAPABILITY, IAM_ACCESS_KEYS_BULK_LDAP_CAPABILITY,
27    IAM_ACCESS_KEYS_BULK_OPENID_CAPABILITY, MAX_IAM_ACCESS_KEY_RESULTS,
28    MAX_IAM_ACCESS_KEY_SELECTOR_BYTES, MAX_IAM_ACCESS_KEY_SELECTORS,
29    MAX_IAM_ACCESS_KEYS_RESPONSE_BYTES,
30};
31pub use account::{
32    ACCOUNT_CAPABILITY, ACCOUNT_MFA_CAPABILITY, AccountApi, AccountInfo, AccountMfaApi,
33    AccountMfaSummary, AccountMutability, CredentialsSource, IdentityType,
34    MAX_ACCOUNT_RESPONSE_BYTES, MfaEnrollment, MfaStatus, PasswordChangeResult, RecoveryCodes,
35    SecretValue, USER_MFA_CAPABILITY, UserCredentialApi, UserMfaStatus,
36};
37pub use bucket_metadata::{
38    BUCKET_METADATA_CAPABILITY, BucketMetadataApi, BucketMetadataArchive,
39    MAX_BUCKET_METADATA_ARCHIVE_BYTES,
40};
41pub use capabilities::{
42    AdvertisedAdminCapability, CapabilityAvailability, CapabilityEntry, CapabilityReport,
43    ClusterSnapshotMetadata, ClusterSnapshotSummary, DiagnosticCapability,
44    DiagnosticCapabilityGuardError, ExtensionMetadata, ExtensionsCatalog,
45    RuntimeCapabilitiesSnapshot, RuntimeCapabilitiesSummary, RuntimeCapabilityState,
46    RuntimeCapabilityStatus,
47};
48pub use cluster::{
49    BackendInfo, BackendType, BucketsInfo, ClusterInfo, DecommissionPoolStatus, DecommissionStatus,
50    DiskInfo, HealDriveInfo, HealDriveInfos, HealResultItem, HealRuntimeState, HealScanMode,
51    HealStartRequest, HealStatus, HealTaskRequest, HealingDiskInfo, MemStats, ObjectsInfo,
52    PoolDecommissionInfo, PoolErasureSetInfo, PoolStatus, PoolTarget, RebalanceCleanupWarnings,
53    RebalancePoolProgress, RebalancePoolStatus, RebalanceStartResult, RebalanceStatus, ServerInfo,
54    UsageInfo,
55};
56pub use configuration::{
57    ConfigApi, ConfigChange, ConfigDiff, ConfigDocument, ConfigHelp, ConfigHelpEntry,
58    ConfigHistoryEntry, ConfigMutationResult, ModuleSwitches, config_document_fields,
59    config_import_diff, config_mutation_diff, redact_config_document, validate_config_directive,
60    validate_config_import,
61};
62pub use diagnostics::{
63    ClientDevnullRequest, ClientDevnullResult, ClusterComponentSnapshot, ClusterComponentSnapshots,
64    ClusterListingSnapshot, ClusterSnapshotDocument, ClusterUsageSnapshot,
65    DEFAULT_CLIENT_DEVNULL_BYTES, DEFAULT_CLIENT_DEVNULL_CONCURRENCY,
66    DEFAULT_CLIENT_DEVNULL_TIMEOUT, DetailedHealthSnapshot, DiagnosticClusterSnapshot,
67    DiagnosticClusterSummary, DiagnosticReadApi, HealthCpuSnapshot, HealthDriveSnapshot,
68    HealthMemorySnapshot, HealthOsSnapshot, HealthProcessSnapshot,
69    MAX_CLIENT_DEVNULL_AGGREGATE_BYTES, MAX_CLIENT_DEVNULL_CONCURRENCY, MAX_CLIENT_DEVNULL_TIMEOUT,
70    MAX_DIAGNOSTIC_RESPONSE_BYTES,
71};
72pub use iam::{
73    GroupPolicyEntities, IAM_POLICY_DETACH_CAPABILITY, IAM_POLICY_ENTITIES_CAPABILITY,
74    IamArchiveApi, IamArchiveImportResult, IamArchiveImportSection, IamArchiveInventory,
75    IamArchiveResultEntities, IamMutationApi, IamReadApi, MAX_IAM_ARCHIVE_BYTES,
76    MAX_IAM_IMPORT_RESPONSE_BYTES, MAX_IAM_POLICY_DETACH_POLICIES,
77    MAX_IAM_POLICY_DETACH_REQUEST_BYTES, MAX_IAM_POLICY_DETACH_RESPONSE_BYTES,
78    MAX_IAM_POLICY_DETACH_SELECTOR_BYTES, MAX_IAM_POLICY_ENTITIES_RESPONSE_BYTES,
79    MAX_IAM_POLICY_ENTITY_SELECTOR_BYTES, MAX_IAM_POLICY_ENTITY_SELECTORS, PolicyDetachEntity,
80    PolicyDetachRequest, PolicyDetachResult, PolicyEntities, PolicyEntitiesQuery,
81    PolicyEntitiesResult, UserPolicyEntities,
82};
83pub use inspect_archive::{
84    EncryptedInspectArchive, INSPECT_ARCHIVE_CAPABILITY, INSPECT_ARCHIVE_COMPLETION,
85    INSPECT_ARCHIVE_CONTENT_TYPE, INSPECT_ARCHIVE_ENCRYPTION, INSPECT_ARCHIVE_ROUTE,
86    INSPECT_ARCHIVE_VERSION, InspectArchiveApi, InspectArchiveCancellation,
87    InspectArchiveCapabilityContract, InspectArchiveKey, InspectArchiveManifest,
88    InspectArchiveTransportRequest, MAX_INSPECT_ARCHIVE_BYTES, MAX_INSPECT_ARCHIVE_DURATION,
89    MAX_INSPECT_ARCHIVE_METADATA_BYTES_PER_DRIVE, PublishedInspectArchive, VerifiedInspectArchive,
90    decrypt_and_validate_inspect_archive, decrypt_and_validate_inspect_archive_with_cancel,
91    publish_inspect_archive, validate_inspect_archive_output_directory,
92};
93pub use kms::{
94    KmsApi, KmsBackendKind, KmsCacheSummary, KmsCancelKeyDeletionResult, KmsConfigSummary,
95    KmsConfigureRequest, KmsCreateKeyRequest, KmsCreateKeyResult, KmsDeleteKeyRequest,
96    KmsDeleteKeyResult, KmsKey, KmsKeyPage, KmsKeyState, KmsKeyUsage, KmsLocalConfigureRequest,
97    KmsServiceState, KmsStatus, KmsVaultAuthMethod, KmsVaultKv2ConfigureRequest,
98    KmsVaultTransitConfigureRequest,
99};
100pub use kms_diagnostic::{
101    KMS_DIAGNOSTIC_CONTENT_BYTES, KmsDiagnosticStore, KmsRoundTripError, KmsRoundTripErrorClass,
102    KmsRoundTripPhase, KmsRoundTripReport, KmsRoundTripTimings, run_kms_round_trip,
103};
104pub use observability::{
105    MAX_METRICS_LINE_BYTES, MAX_METRICS_RESPONSE_BYTES, MAX_METRICS_SAMPLES, MetricGroup,
106    MetricGroups, MetricsBatch, MetricsQuery, MetricsScope, ObservabilityApi, RealtimeMetrics,
107    ScannerCycleSchedule, ScannerFreshness, ScannerHealth, ScannerMetrics, ScannerRuntimeConfig,
108    ScannerRuntimeConfigValue, ScannerStatus, StorageBackend, StorageBackendKind, StorageDisk,
109    StorageDiskMetrics, StorageInfo,
110};
111pub use oidc::{
112    MAX_OIDC_RESPONSE_BYTES, OidcMutationApi, OidcMutationRequest, OidcMutationResult,
113    OidcProvider, OidcProviderList, OidcProviderSource, OidcReadApi, OidcValidationRequest,
114    OidcValidationResult,
115};
116pub use replication::{
117    MAX_REPLICATION_DIFF_RESPONSE_BYTES, MAX_REPLICATION_INSPECTION_RESPONSE_BYTES,
118    ReplicationCountSize, ReplicationDiff, ReplicationDiffApi, ReplicationDiffEntry,
119    ReplicationInspectionApi, ReplicationLatencyMetric, ReplicationMetricScope, ReplicationMetrics,
120    ReplicationMrf, ReplicationMrfTarget, ReplicationQueueMetric, ReplicationTargetMetric,
121    ReplicationTransferRate,
122};
123pub use site::{
124    MAX_SITE_REPLICATION_CA_CERT_BYTES, MAX_SITE_REPLICATION_ERROR_RESPONSE_BYTES,
125    MAX_SITE_REPLICATION_REPAIR_RESPONSE_BYTES, MAX_SITE_REPLICATION_REQUEST_BYTES,
126    MAX_SITE_REPLICATION_SUCCESS_RESPONSE_BYTES, PeerSiteSpec, ReplicateEditStatus,
127    SITE_REPLICATION_REPAIR_CAPABILITY, ServiceActionResult, SiteRemoveSpec, SiteReplicationInfo,
128    SiteReplicationPeer, SiteReplicationRepairApi, SiteReplicationRepairCapabilityContract,
129    SiteReplicationRepairFamilyStatus, SiteReplicationRepairOperationStatus,
130    SiteReplicationRepairPreflight, SiteReplicationRepairRequest, SiteReplicationRepairSiteStatus,
131    SiteReplicationRepairTaskStatus, SiteReplicationResyncBucketStatus,
132    SiteReplicationResyncOperation, SiteReplicationResyncStatus, SiteStatusOptions,
133    validate_site_replication_ca_bundle, validate_site_replication_repair_operation_id,
134    validate_site_replication_repair_token,
135};
136pub use tier::{
137    ManualTransitionJobResponse, ManualTransitionQueueSnapshot, ManualTransitionRunReport,
138    ManualTransitionRunRequest, ManualTransitionRunResponse, TierAliyun, TierAzure, TierConfig,
139    TierCreds, TierGCS, TierHuaweicloud, TierMinIO, TierR2, TierRustFS, TierS3, TierTencent,
140    TierType,
141};
142pub use types::{
143    AccessKeyDetails, AccessKeyInfo, BucketQuota, CreateServiceAccountRequest, Group, GroupStatus,
144    LdapAccessKeyInfo, OpenIdAccessKeyInfo, Policy, PolicyEntity, PolicyInfo, ServiceAccount,
145    ServiceAccountCreateResponse, ServiceAccountCredentials, SetPolicyRequest,
146    UpdateGroupMembersRequest, UpdateServiceAccountRequest, User, UserStatus,
147};
148
149use async_trait::async_trait;
150
151use crate::error::Result;
152
153/// Admin API trait for IAM and cluster management operations
154///
155/// This trait defines the interface for managing users, policies, groups,
156/// service accounts, and cluster operations on S3-compatible storage systems
157/// that support the RustFS Admin API.
158#[async_trait]
159pub trait AdminApi: Send + Sync {
160    // ==================== Cluster Operations ====================
161
162    /// Get cluster information including servers, disks, and usage
163    async fn cluster_info(&self) -> Result<ClusterInfo>;
164
165    /// Get current heal status
166    async fn heal_status(&self) -> Result<HealStatus>;
167
168    /// Start a heal operation
169    async fn heal_start(&self, request: HealStartRequest) -> Result<HealStatus>;
170
171    /// Get status for a token-scoped heal task
172    async fn heal_task_status(&self, request: HealTaskRequest) -> Result<HealStatus>;
173
174    /// Stop a running heal operation
175    async fn heal_stop(&self) -> Result<()>;
176
177    /// Stop a token-scoped heal task
178    async fn heal_task_stop(&self, request: HealTaskRequest) -> Result<HealStatus>;
179
180    /// List storage pools
181    async fn list_pools(&self) -> Result<Vec<PoolStatus>>;
182
183    /// Get storage pool status
184    async fn pool_status(&self, target: PoolTarget) -> Result<PoolStatus>;
185
186    /// Start decommissioning one or more storage pools
187    async fn decommission_start(&self, target: PoolTarget) -> Result<()>;
188
189    /// Cancel decommissioning a storage pool
190    async fn decommission_cancel(&self, target: PoolTarget) -> Result<()>;
191
192    /// Clear failed or canceled decommissioning metadata for a storage pool
193    async fn decommission_clear(&self, target: PoolTarget) -> Result<()>;
194
195    /// Get decommissioning status
196    async fn decommission_status(&self, target: Option<PoolTarget>) -> Result<DecommissionStatus>;
197
198    /// Start a rebalance operation
199    async fn rebalance_start(&self) -> Result<RebalanceStartResult>;
200
201    /// Get rebalance status
202    async fn rebalance_status(&self) -> Result<RebalanceStatus>;
203
204    /// Stop a running rebalance operation
205    async fn rebalance_stop(&self) -> Result<()>;
206
207    // ==================== User Operations ====================
208
209    /// List all users
210    async fn list_users(&self) -> Result<Vec<User>>;
211
212    /// Get user information
213    async fn get_user(&self, access_key: &str) -> Result<User>;
214
215    /// Create a new user
216    async fn create_user(&self, access_key: &str, secret_key: &str) -> Result<User>;
217
218    /// Delete a user
219    async fn delete_user(&self, access_key: &str) -> Result<()>;
220
221    /// Set user status (enable/disable)
222    async fn set_user_status(&self, access_key: &str, status: UserStatus) -> Result<()>;
223
224    // ==================== Policy Operations ====================
225
226    /// List all policies
227    async fn list_policies(&self) -> Result<Vec<PolicyInfo>>;
228
229    /// Get policy information
230    async fn get_policy(&self, name: &str) -> Result<Policy>;
231
232    /// Create a new policy
233    async fn create_policy(&self, name: &str, policy_document: &str) -> Result<()>;
234
235    /// Delete a policy
236    async fn delete_policy(&self, name: &str) -> Result<()>;
237
238    /// Attach policy to a user or group
239    async fn attach_policy(
240        &self,
241        policy_names: &[String],
242        entity_type: PolicyEntity,
243        entity_name: &str,
244    ) -> Result<()>;
245
246    /// Detach policy from a user or group
247    async fn detach_policy(
248        &self,
249        policy_names: &[String],
250        entity_type: PolicyEntity,
251        entity_name: &str,
252    ) -> Result<()>;
253
254    // ==================== Group Operations ====================
255
256    /// List all groups
257    async fn list_groups(&self) -> Result<Vec<String>>;
258
259    /// Get group information
260    async fn get_group(&self, name: &str) -> Result<Group>;
261
262    /// Create a new group
263    async fn create_group(&self, name: &str, members: Option<&[String]>) -> Result<Group>;
264
265    /// Delete a group
266    async fn delete_group(&self, name: &str) -> Result<()>;
267
268    /// Set group status (enable/disable)
269    async fn set_group_status(&self, name: &str, status: GroupStatus) -> Result<()>;
270
271    /// Add members to a group
272    async fn add_group_members(&self, group: &str, members: &[String]) -> Result<()>;
273
274    /// Remove members from a group
275    async fn remove_group_members(&self, group: &str, members: &[String]) -> Result<()>;
276
277    // ==================== Service Account Operations ====================
278
279    /// List service accounts for a user
280    async fn list_service_accounts(&self, user: Option<&str>) -> Result<Vec<ServiceAccount>>;
281
282    /// Get service account information
283    async fn get_service_account(&self, access_key: &str) -> Result<ServiceAccount>;
284
285    /// Create a new service account
286    async fn create_service_account(
287        &self,
288        request: CreateServiceAccountRequest,
289    ) -> Result<ServiceAccount>;
290
291    /// Update an existing service account
292    async fn update_service_account(
293        &self,
294        access_key: &str,
295        request: UpdateServiceAccountRequest,
296    ) -> Result<()>;
297
298    /// Delete a service account
299    async fn delete_service_account(&self, access_key: &str) -> Result<()>;
300
301    /// Get information for any access key type.
302    async fn get_access_key_info(&self, access_key: &str) -> Result<AccessKeyInfo>;
303
304    // ==================== Bucket Quota Operations ====================
305
306    /// Set bucket quota in bytes
307    async fn set_bucket_quota(&self, bucket: &str, quota: u64) -> Result<BucketQuota>;
308
309    /// Get bucket quota information
310    async fn get_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
311
312    /// Clear bucket quota
313    async fn clear_bucket_quota(&self, bucket: &str) -> Result<BucketQuota>;
314
315    // ==================== Tier Operations ====================
316
317    /// List all configured storage tiers
318    async fn list_tiers(&self) -> Result<Vec<TierConfig>>;
319
320    /// Get tier statistics
321    async fn tier_stats(&self) -> Result<serde_json::Value>;
322
323    /// Add a new storage tier
324    async fn add_tier(&self, config: TierConfig) -> Result<()>;
325
326    /// Edit tier credentials
327    async fn edit_tier(&self, name: &str, creds: TierCreds) -> Result<()>;
328
329    /// Remove a storage tier
330    async fn remove_tier(&self, name: &str, force: bool) -> Result<()>;
331
332    /// Run bounded manual lifecycle transition evaluation for a bucket scope.
333    async fn run_manual_transition(
334        &self,
335        request: ManualTransitionRunRequest,
336    ) -> Result<ManualTransitionRunResponse>;
337
338    /// Start a durable manual lifecycle transition job for a bucket scope.
339    async fn run_manual_transition_async(
340        &self,
341        request: ManualTransitionRunRequest,
342    ) -> Result<ManualTransitionRunResponse>;
343
344    /// Inspect a durable manual lifecycle transition job.
345    async fn manual_transition_job_status(
346        &self,
347        job_id: &str,
348    ) -> Result<ManualTransitionJobResponse>;
349
350    /// Request cancellation for a durable manual lifecycle transition job.
351    async fn cancel_manual_transition_job(
352        &self,
353        job_id: &str,
354    ) -> Result<ManualTransitionJobResponse>;
355
356    // ==================== Replication Target Operations ====================
357
358    /// Set a remote replication target for a bucket, returns the ARN
359    async fn set_remote_target(
360        &self,
361        bucket: &str,
362        target: crate::replication::BucketTarget,
363        update: bool,
364    ) -> Result<String>;
365
366    /// List remote replication targets for a bucket
367    async fn list_remote_targets(
368        &self,
369        bucket: &str,
370    ) -> Result<Vec<crate::replication::BucketTarget>>;
371
372    /// Remove a remote replication target
373    async fn remove_remote_target(&self, bucket: &str, arn: &str) -> Result<()>;
374
375    // ==================== Service Control Operations ====================
376
377    /// Request a service action (restart, stop, freeze, unfreeze)
378    async fn service_action(&self, action: &str) -> Result<ServiceActionResult>;
379
380    // ==================== Site Replication Operations ====================
381
382    /// Get current site replication configuration
383    async fn site_replication_info(&self) -> Result<SiteReplicationInfo>;
384
385    /// Edit a peer using a complete read-modify-write snapshot
386    async fn site_replication_edit(
387        &self,
388        peer: &SiteReplicationPeer,
389    ) -> Result<ReplicateEditStatus>;
390
391    /// Start, inspect, or cancel a resync toward one complete peer snapshot
392    async fn site_replication_resync(
393        &self,
394        operation: SiteReplicationResyncOperation,
395        peer: &SiteReplicationPeer,
396    ) -> Result<SiteReplicationResyncStatus>;
397
398    /// Add peer sites to the site replication cluster
399    async fn site_replication_add(&self, sites: &[PeerSiteSpec]) -> Result<serde_json::Value>;
400
401    /// Get site replication status
402    async fn site_replication_status(
403        &self,
404        options: &SiteStatusOptions,
405    ) -> Result<serde_json::Value>;
406
407    /// Remove sites from the site replication cluster
408    async fn site_replication_remove(&self, spec: &SiteRemoveSpec) -> Result<serde_json::Value>;
409}
410
411/// Read-only RustFS runtime capability discovery.
412#[async_trait]
413pub trait CapabilityApi: Send + Sync {
414    /// Discover capabilities, bypassing the process cache when `refresh` is true.
415    async fn discover_capabilities(&self, refresh: bool) -> Result<CapabilityReport>;
416}
417
418/// Bounded active RustFS diagnostic probes.
419#[async_trait]
420pub trait DiagnosticApi: CapabilityApi {
421    /// Measure client-to-server upload throughput without persisting an object.
422    async fn client_devnull(&self, request: ClientDevnullRequest) -> Result<ClientDevnullResult>;
423}
424
425#[cfg(test)]
426mod tests {
427    use super::*;
428
429    // Test that types are re-exported correctly
430    #[test]
431    fn test_user_status_reexport() {
432        assert_eq!(UserStatus::Enabled.to_string(), "enabled");
433        assert_eq!(UserStatus::Disabled.to_string(), "disabled");
434    }
435
436    #[test]
437    fn test_group_status_reexport() {
438        assert_eq!(GroupStatus::Enabled.to_string(), "enabled");
439        assert_eq!(GroupStatus::Disabled.to_string(), "disabled");
440    }
441
442    #[test]
443    fn test_policy_entity_reexport() {
444        assert_eq!(PolicyEntity::User.to_string(), "user");
445        assert_eq!(PolicyEntity::Group.to_string(), "group");
446    }
447
448    #[test]
449    fn test_user_new() {
450        let user = User::new("testuser");
451        assert_eq!(user.access_key, "testuser");
452        assert_eq!(user.status, UserStatus::Enabled);
453    }
454
455    #[test]
456    fn test_group_new() {
457        let group = Group::new("developers");
458        assert_eq!(group.name, "developers");
459        assert_eq!(group.status, GroupStatus::Enabled);
460    }
461
462    #[test]
463    fn test_policy_new() {
464        let policy = Policy::new("readonly", r#"{"Version":"2012-10-17","Statement":[]}"#);
465        assert_eq!(policy.name, "readonly");
466        assert!(policy.parse_document().is_ok());
467    }
468
469    #[test]
470    fn test_service_account_new() {
471        let sa = ServiceAccount::new("AKIAIOSFODNN7EXAMPLE");
472        assert_eq!(sa.access_key, "AKIAIOSFODNN7EXAMPLE");
473        assert!(sa.secret_key.is_none());
474    }
475}