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