From 1c4bcd4372c39fdbaadbbc0eac939b2aff7849c2 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Thu, 25 Jun 2026 13:09:02 +0800 Subject: [PATCH] refactor: centralize admin runtime sources (#3845) --- docs/architecture/migration-progress.md | 31 +++++++++++++++---- rustfs/src/admin/auth.rs | 4 +-- rustfs/src/admin/console.rs | 2 +- rustfs/src/admin/handlers/account_info.rs | 4 +-- .../admin/handlers/audit_runtime_config.rs | 2 +- rustfs/src/admin/handlers/config_admin.rs | 2 +- rustfs/src/admin/handlers/group.rs | 10 +++--- rustfs/src/admin/handlers/heal.rs | 2 +- rustfs/src/admin/handlers/is_admin.rs | 6 ++-- rustfs/src/admin/handlers/kms_dynamic.rs | 2 +- rustfs/src/admin/handlers/kms_keys.rs | 2 +- rustfs/src/admin/handlers/kms_management.rs | 2 +- .../src/admin/handlers/object_zip_download.rs | 2 +- rustfs/src/admin/handlers/oidc.rs | 2 +- rustfs/src/admin/handlers/policies.rs | 14 ++++----- rustfs/src/admin/handlers/quota.rs | 2 +- rustfs/src/admin/handlers/replication.rs | 2 +- rustfs/src/admin/handlers/scanner.rs | 2 +- rustfs/src/admin/handlers/service_account.rs | 18 +++++------ rustfs/src/admin/handlers/site_replication.rs | 12 +++---- rustfs/src/admin/handlers/sts.rs | 4 +-- rustfs/src/admin/handlers/system.rs | 2 +- rustfs/src/admin/handlers/table_catalog.rs | 5 +-- rustfs/src/admin/handlers/tls_debug.rs | 2 +- rustfs/src/admin/handlers/trace.rs | 2 +- rustfs/src/admin/handlers/user.rs | 14 ++++----- rustfs/src/admin/mod.rs | 1 + rustfs/src/admin/router.rs | 2 +- rustfs/src/admin/runtime_sources.rs | 26 ++++++++++++++++ rustfs/src/admin/service/config.rs | 2 +- rustfs/src/admin/service/site_replication.rs | 2 +- scripts/check_architecture_migration_rules.sh | 11 +++++++ 32 files changed, 127 insertions(+), 69 deletions(-) create mode 100644 rustfs/src/admin/runtime_sources.rs diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 54e8cddc4..681d05ff4 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,9 +5,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block ## Current Context - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) -- Branch: `overtrue/arch-server-storage-runtime-source-readers` -- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204`. -- Based on: stacked on PR #3828 head after PR #3827. +- Branch: `overtrue/arch-admin-runtime-sources-batch` +- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205`. +- Based on: `origin/main` after PR #3843. - PR type for this branch: `consumer-migration` - Runtime behavior changes: none. - Rust code changes: route replication pool, outbound TLS generation, runtime @@ -44,7 +44,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block runtime source helpers, plus startup/root KMS, credentials, region, readiness-time, observability, metrics, buffer, and TLS runtime source helpers, plus server readiness/audit/event/module-switch runtime source - helpers and storage request/RPC/SSE runtime source helpers, + helpers, storage request/RPC/SSE runtime source helpers, and admin + handler/service/router runtime source helpers, through AppContext-first or owner-crate resolver boundaries. - CI/script changes: lock completed owner and test/fuzz boundaries against bare/glob imports, scattered raw ECStore facade subpaths, and startup @@ -54,8 +55,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block and storage owner thin bridge regressions, plus app context and notify event-bridge thin module regressions, plus IAM runtime-source bypasses; accept the reviewed AppContext resolver reverse dependencies in the layer - baseline. -- Docs changes: record the API-136 through API-204 owner facade and lifecycle + baseline, and block direct admin AppContext resolver consumers outside the + admin runtime-source boundary. +- Docs changes: record the API-136 through API-205 owner facade and lifecycle runtime-source cleanup. ## Phase 0 Tasks @@ -4938,6 +4940,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block migration/layer guards, diff hygiene, residual direct AppContext scan, Rust risk scan, fast PR gate, and full PR gate before PR. +- [x] `API-205` Centralize admin runtime source readers. + - Do: route admin handler, router, auth, console, and service runtime + AppContext resolver consumers through the admin runtime-source boundary. + - Acceptance: admin consumers no longer import AppContext resolvers directly, + and migration rules reject new direct admin AppContext resolver consumers + outside `rustfs/src/admin/runtime_sources.rs`. + - Must preserve: admin auth/authorization, IAM readiness errors, KMS manager + fallback, OIDC console behavior, replication status, site replication peer + TLS behavior, dynamic config publication, object-store reads, region + rendering, scanner reports, and bucket metadata/admin storage behavior. + - Verification: focused RustFS admin compile/tests, formatting, migration and + layer guards, diff hygiene, residual direct AppContext scan, Rust risk + scan, fast PR gate, and full PR gate before PR. + ## Next PRs 1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries. @@ -4946,6 +4962,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| +| Quality/architecture | pass | API-205 keeps direct admin AppContext resolver consumers behind the admin runtime-source boundary and adds a guard against regressions. | +| Migration preservation | pass | Admin auth, IAM readiness, KMS manager fallback, site replication TLS, config publication, and object-store resolver behavior preserve existing semantics. | +| Testing/verification | pass | Focused admin compile/tests, formatting, migration/layer guards, residual scan, fast PR gate, and full PR gate are planned before PR. | | Quality/architecture | pass | API-199 keeps RustFS test tier-config and TLS-generation mutation behind AppContext-owned runtime-source helpers and retires the stale tier-config test compat shim. | | Migration preservation | pass | Lifecycle transition tier registration and site replication peer-client generation-cache behavior preserve existing semantics. | | Testing/verification | pass | Focused RustFS tests, formatting, migration/layer guards, residual scan, fast PR gate, and full PR gate are planned before PR. | diff --git a/rustfs/src/admin/auth.rs b/rustfs/src/admin/auth.rs index faf5dd46c..a2742c401 100644 --- a/rustfs/src/admin/auth.rs +++ b/rustfs/src/admin/auth.rs @@ -56,7 +56,7 @@ pub async fn validate_admin_request( actions: Vec, remote_addr: Option, ) -> S3Result<()> { - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam not init")); }; let ctx = AuthContext { @@ -146,7 +146,7 @@ pub async fn validate_admin_request_with_bucket_object( remote_addr: Option, resource: AdminResourceScope<'_>, ) -> S3Result<()> { - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam not init")); }; let ctx = AuthContext { diff --git a/rustfs/src/admin/console.rs b/rustfs/src/admin/console.rs index 5e7aa18e3..45737f372 100644 --- a/rustfs/src/admin/console.rs +++ b/rustfs/src/admin/console.rs @@ -13,8 +13,8 @@ // limitations under the License. use crate::admin::handlers::health::{HealthProbe, build_health_response_parts, collect_dependency_readiness}; +use crate::admin::runtime_sources::resolve_oidc_handle; use crate::app::admin_usecase::DefaultAdminUsecase; -use crate::app::context::resolve_oidc_handle; use crate::license::has_valid_license; use crate::server::has_path_prefix; use crate::server::{ diff --git a/rustfs/src/admin/handlers/account_info.rs b/rustfs/src/admin/handlers/account_info.rs index c542e45cc..7b50aab3a 100644 --- a/rustfs/src/admin/handlers/account_info.rs +++ b/rustfs/src/admin/handlers/account_info.rs @@ -15,7 +15,7 @@ use super::super::versioning_sys::BucketVersioningSys; use crate::admin::auth::authenticate_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_action_credentials, resolve_object_store_handle}; +use crate::admin::runtime_sources::{resolve_action_credentials, resolve_object_store_handle}; use crate::auth::get_condition_values; use crate::server::{ADMIN_PREFIX, RemoteAddr}; use http::{HeaderMap, HeaderValue}; @@ -69,7 +69,7 @@ impl Operation for AccountInfoHandler { let (cred, owner) = authenticate_request(&req.headers, &req.uri, &input_cred).await?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; diff --git a/rustfs/src/admin/handlers/audit_runtime_config.rs b/rustfs/src/admin/handlers/audit_runtime_config.rs index f7994d8d4..9fec069cb 100644 --- a/rustfs/src/admin/handlers/audit_runtime_config.rs +++ b/rustfs/src/admin/handlers/audit_runtime_config.rs @@ -14,7 +14,7 @@ use super::super::{read_admin_config_without_migrate, save_admin_server_config}; use crate::admin::handlers::target_descriptor::AdminTargetSpec; -use crate::app::context::resolve_object_store_handle; +use crate::admin::runtime_sources::resolve_object_store_handle; use rustfs_audit::{audit_system, start_audit_system as start_global_audit_system, system::AuditSystemState}; use rustfs_config::DEFAULT_DELIMITER; use rustfs_config::server_config::Config; diff --git a/rustfs/src/admin/handlers/config_admin.rs b/rustfs/src/admin/handlers/config_admin.rs index ac1f62ca1..7be19b9f0 100644 --- a/rustfs/src/admin/handlers/config_admin.rs +++ b/rustfs/src/admin/handlers/config_admin.rs @@ -19,12 +19,12 @@ use super::super::{ }; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::admin::runtime_sources::{publish_server_config, resolve_object_store_handle, resolve_server_config}; use crate::admin::service::config::{ apply_dynamic_config_for_subsystem, is_dynamic_config_subsystem, signal_config_snapshot_reload, signal_dynamic_config_reload, validate_server_config, }; use crate::admin::utils::{encode_compatible_admin_payload, is_compat_admin_request, read_compatible_admin_body}; -use crate::app::context::{publish_server_config, resolve_object_store_handle, resolve_server_config}; use crate::auth::{check_key_valid, get_session_token}; use crate::error::ApiError; use crate::server::{ADMIN_PREFIX, RemoteAddr}; diff --git a/rustfs/src/admin/handlers/group.rs b/rustfs/src/admin/handlers/group.rs index c8149b3a8..f454f8f08 100644 --- a/rustfs/src/admin/handlers/group.rs +++ b/rustfs/src/admin/handlers/group.rs @@ -115,7 +115,7 @@ impl Operation for ListGroups { ) .await?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -180,7 +180,7 @@ impl Operation for GetGroup { GroupQuery::default() } }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -256,7 +256,7 @@ impl Operation for DeleteGroup { let group = decode_delete_group_name(¶ms)?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -394,7 +394,7 @@ impl Operation for SetGroupStatus { return Err(s3_error!(InvalidArgument, "group is required")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -537,7 +537,7 @@ impl Operation for UpdateGroupMembers { "admin group state" ); - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; diff --git a/rustfs/src/admin/handlers/heal.rs b/rustfs/src/admin/handlers/heal.rs index 662505a3f..e0d8d2b84 100644 --- a/rustfs/src/admin/handlers/heal.rs +++ b/rustfs/src/admin/handlers/heal.rs @@ -16,7 +16,7 @@ use super::super::ecstore_utils::is_valid_object_prefix; use super::super::is_reserved_or_invalid_bucket; use crate::admin::auth::{authenticate_request, validate_admin_request}; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::resolve_object_store_handle; +use crate::admin::runtime_sources::resolve_object_store_handle; use crate::server::ADMIN_PREFIX; use crate::server::RemoteAddr; use crate::storage::request_context::spawn_traced; diff --git a/rustfs/src/admin/handlers/is_admin.rs b/rustfs/src/admin/handlers/is_admin.rs index 920d84157..8e062046a 100644 --- a/rustfs/src/admin/handlers/is_admin.rs +++ b/rustfs/src/admin/handlers/is_admin.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::admin::router::Operation; -use crate::app::context::resolve_action_credentials; +use crate::admin::runtime_sources::resolve_action_credentials; use crate::auth::{check_key_valid, constant_time_eq, get_condition_values, get_session_token}; use http::{HeaderMap, HeaderValue}; use hyper::StatusCode; @@ -58,8 +58,8 @@ impl Operation for IsAdminHandler { true } else { let empty_claims = HashMap::new(); - let iam_store = - crate::app::context::resolve_ready_iam_handle().map_err(|_| s3_error!(InternalError, "iam not init"))?; + let iam_store = crate::admin::runtime_sources::resolve_ready_iam_handle() + .map_err(|_| s3_error!(InternalError, "iam not init"))?; let conditions = get_condition_values(&req.headers, &cred, None, None, None); iam_store .is_allowed(&Args { diff --git a/rustfs/src/admin/handlers/kms_dynamic.rs b/rustfs/src/admin/handlers/kms_dynamic.rs index 9e5b5aead..93862ad41 100644 --- a/rustfs/src/admin/handlers/kms_dynamic.rs +++ b/rustfs/src/admin/handlers/kms_dynamic.rs @@ -17,7 +17,7 @@ use super::super::{read_admin_config, save_admin_config}; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{ +use crate::admin::runtime_sources::{ resolve_kms_runtime_service_manager, resolve_object_store_handle, resolve_or_init_kms_runtime_service_manager, }; use crate::auth::{check_key_valid, get_session_token}; diff --git a/rustfs/src/admin/handlers/kms_keys.rs b/rustfs/src/admin/handlers/kms_keys.rs index 95e43939f..fecf78384 100644 --- a/rustfs/src/admin/handlers/kms_keys.rs +++ b/rustfs/src/admin/handlers/kms_keys.rs @@ -16,7 +16,7 @@ use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_kms_runtime_service_manager, resolve_or_init_kms_runtime_service_manager}; +use crate::admin::runtime_sources::{resolve_kms_runtime_service_manager, resolve_or_init_kms_runtime_service_manager}; use crate::auth::{check_key_valid, get_session_token}; use crate::server::{ADMIN_PREFIX, RemoteAddr}; use base64::Engine; diff --git a/rustfs/src/admin/handlers/kms_management.rs b/rustfs/src/admin/handlers/kms_management.rs index 3d95647b2..b5482cc23 100644 --- a/rustfs/src/admin/handlers/kms_management.rs +++ b/rustfs/src/admin/handlers/kms_management.rs @@ -17,7 +17,7 @@ use super::kms_keys::{CreateKeyHandler, DescribeKeyHandler, GenerateDataKeyHandler, ListKeysHandler}; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_kms_runtime_service_manager, resolve_or_init_kms_runtime_service_manager}; +use crate::admin::runtime_sources::{resolve_kms_runtime_service_manager, resolve_or_init_kms_runtime_service_manager}; use crate::auth::{check_key_valid, get_session_token}; use crate::server::{ADMIN_PREFIX, RemoteAddr}; use hyper::{HeaderMap, Method, StatusCode}; diff --git a/rustfs/src/admin/handlers/object_zip_download.rs b/rustfs/src/admin/handlers/object_zip_download.rs index f0fc24a16..41e363f2e 100644 --- a/rustfs/src/admin/handlers/object_zip_download.rs +++ b/rustfs/src/admin/handlers/object_zip_download.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::admin::router::{ADMIN_OBJECT_ZIP_DOWNLOADS_PATH, AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_action_credentials, resolve_object_store_handle, resolve_region}; +use crate::admin::runtime_sources::{resolve_action_credentials, resolve_object_store_handle, resolve_region}; use crate::auth::{check_key_valid, get_session_token}; use crate::error::ApiError; use crate::license::license_check; diff --git a/rustfs/src/admin/handlers/oidc.rs b/rustfs/src/admin/handlers/oidc.rs index d3419f290..ac7bcb9bf 100644 --- a/rustfs/src/admin/handlers/oidc.rs +++ b/rustfs/src/admin/handlers/oidc.rs @@ -16,7 +16,7 @@ use super::super::{read_admin_config_without_migrate, save_admin_server_config}; use super::sts::create_oidc_sts_credentials; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_object_store_handle, resolve_oidc_handle, resolve_server_config}; +use crate::admin::runtime_sources::{resolve_object_store_handle, resolve_oidc_handle, resolve_server_config}; use crate::auth::{check_key_valid, get_session_token}; use crate::server::{ADMIN_PREFIX, MINIO_ADMIN_PREFIX, RemoteAddr}; use http::StatusCode; diff --git a/rustfs/src/admin/handlers/policies.rs b/rustfs/src/admin/handlers/policies.rs index e4d667e44..35aff9fd1 100644 --- a/rustfs/src/admin/handlers/policies.rs +++ b/rustfs/src/admin/handlers/policies.rs @@ -144,7 +144,7 @@ impl Operation for ListCannedPolicies { } }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -252,7 +252,7 @@ impl Operation for AddCannedPolicy { if policy.version.is_empty() { return Err(s3_error!(InvalidArgument, "policy version is required")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -340,7 +340,7 @@ impl Operation for InfoCannedPolicy { return Err(s3_error!(InvalidArgument, "too many policies")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -401,7 +401,7 @@ impl Operation for RemoveCannedPolicy { return Err(s3_error!(InvalidArgument, "policy name is required")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -492,7 +492,7 @@ impl Operation for SetPolicyForUserOrGroup { return Err(s3_error!(InvalidArgument, "user or group is required")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -825,7 +825,7 @@ async fn handle_builtin_policy_entities(req: S3Request) -> S3Result, is_attach: bool .map_err(|e| s3_error!(InvalidRequest, "unmarshal policy association body failed, e: {:?}", e))?; validate_policy_association_req(&assoc_req)?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam not init")); }; diff --git a/rustfs/src/admin/handlers/quota.rs b/rustfs/src/admin/handlers/quota.rs index c1c9ae9fd..167e564dc 100644 --- a/rustfs/src/admin/handlers/quota.rs +++ b/rustfs/src/admin/handlers/quota.rs @@ -19,7 +19,7 @@ use super::super::quota::checker::QuotaChecker; use super::super::quota::{BucketQuota, QuotaError, QuotaOperation}; use crate::admin::auth::{validate_admin_request, validate_admin_request_with_bucket}; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::{resolve_bucket_metadata_handle, resolve_object_store_handle}; +use crate::admin::runtime_sources::{resolve_bucket_metadata_handle, resolve_object_store_handle}; use crate::auth::{check_key_valid, get_session_token}; use crate::server::ADMIN_PREFIX; use hyper::{Method, StatusCode}; diff --git a/rustfs/src/admin/handlers/replication.rs b/rustfs/src/admin/handlers/replication.rs index 1dddeb8e8..354fa383f 100644 --- a/rustfs/src/admin/handlers/replication.rs +++ b/rustfs/src/admin/handlers/replication.rs @@ -22,8 +22,8 @@ use super::super::target::BucketTarget; use crate::admin::auth::validate_admin_request; use crate::admin::handlers::site_replication::site_replication_peer_deployment_id_for_endpoint; use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::admin::runtime_sources::{resolve_object_store_handle, resolve_replication_stats_handle, resolve_runtime_port}; use crate::admin::utils::read_compatible_admin_body; -use crate::app::context::{resolve_object_store_handle, resolve_replication_stats_handle, resolve_runtime_port}; use crate::auth::{check_key_valid, get_session_token}; use crate::error::ApiError; use crate::server::{ADMIN_PREFIX, RemoteAddr}; diff --git a/rustfs/src/admin/handlers/scanner.rs b/rustfs/src/admin/handlers/scanner.rs index bcead3793..4f6664a79 100644 --- a/rustfs/src/admin/handlers/scanner.rs +++ b/rustfs/src/admin/handlers/scanner.rs @@ -14,7 +14,7 @@ use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::resolve_scanner_metrics_report; +use crate::admin::runtime_sources::resolve_scanner_metrics_report; use crate::auth::{check_key_valid, get_session_token}; use crate::server::{ADMIN_PREFIX, RemoteAddr}; use http::{HeaderMap, HeaderValue}; diff --git a/rustfs/src/admin/handlers/service_account.rs b/rustfs/src/admin/handlers/service_account.rs index 4a9f3f093..f4dd5394d 100644 --- a/rustfs/src/admin/handlers/service_account.rs +++ b/rustfs/src/admin/handlers/service_account.rs @@ -15,8 +15,8 @@ use super::iam_error::iam_error_to_s3_error; use crate::admin::access_key_identity; use crate::admin::handlers::site_replication::site_replication_iam_change_hook; +use crate::admin::runtime_sources::resolve_action_credentials; use crate::admin::utils::{encode_compatible_admin_payload, has_space_be, is_compat_admin_request, read_compatible_admin_body}; -use crate::app::context::resolve_action_credentials; use crate::auth::{constant_time_eq, get_condition_values, get_session_token}; use crate::server::{ADMIN_PREFIX, RemoteAddr}; use crate::{ @@ -292,7 +292,7 @@ impl Operation for AddServiceAccount { req_is_derived_cred = true; } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -513,7 +513,7 @@ impl Operation for UpdateServiceAccount { return Err(s3_error!(InvalidRequest, "get cred failed")); }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -642,7 +642,7 @@ impl Operation for InfoServiceAccount { let access_key = query.access_key; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -719,7 +719,7 @@ impl Operation for TemporaryAccountInfo { let (cred, owner) = check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -789,7 +789,7 @@ impl Operation for InfoAccessKey { query.access_key }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -912,7 +912,7 @@ impl Operation for ListServiceAccount { // cred.parent_user // }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -1049,7 +1049,7 @@ impl Operation for ListAccessKeysBulk { let (cred, owner) = check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -1252,7 +1252,7 @@ impl Operation for DeleteServiceAccount { return Err(s3_error!(InvalidArgument, "access key is empty")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; diff --git a/rustfs/src/admin/handlers/site_replication.rs b/rustfs/src/admin/handlers/site_replication.rs index 7d1469b97..564838053 100644 --- a/rustfs/src/admin/handlers/site_replication.rs +++ b/rustfs/src/admin/handlers/site_replication.rs @@ -26,16 +26,16 @@ use super::super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _ use super::super::{delete_admin_config, read_admin_config, save_admin_config}; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::admin::runtime_sources::{ + resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, resolve_object_store_handle, resolve_oidc_handle, + resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_region, resolve_replication_pool_handle, + resolve_replication_stats_handle, resolve_runtime_port, resolve_server_config, resolve_token_signing_key, +}; use crate::admin::site_replication_identity::{ canonical_endpoint, deployment_id_for_endpoint, normalize_peer_map_by_identity_with, same_identity_endpoint, site_identity_key, }; use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body}; -use crate::app::context::{ - resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, resolve_object_store_handle, resolve_oidc_handle, - resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_region, resolve_replication_pool_handle, - resolve_replication_stats_handle, resolve_runtime_port, resolve_server_config, resolve_token_signing_key, -}; use crate::auth::{check_key_valid, get_session_token}; use crate::config::get_config_snapshot; use crate::error::ApiError; @@ -4603,7 +4603,7 @@ mod tests { use super::super::super::Endpoint; use super::super::super::{EndpointServerPools, Endpoints, PoolEndpoints}; use super::*; - use crate::app::context::{resolve_outbound_tls_generation, set_test_outbound_tls_generation}; + use crate::admin::runtime_sources::{resolve_outbound_tls_generation, set_test_outbound_tls_generation}; use http::{HeaderMap, HeaderValue, Uri}; use rustfs_policy::policy::action::S3Action; use serial_test::serial; diff --git a/rustfs/src/admin/handlers/sts.rs b/rustfs/src/admin/handlers/sts.rs index 6ff1e0206..122f84be6 100644 --- a/rustfs/src/admin/handlers/sts.rs +++ b/rustfs/src/admin/handlers/sts.rs @@ -188,7 +188,7 @@ async fn handle_assume_role( return Err(s3_error!(InvalidRequest, "AccessDenied")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; let conditions = crate::auth::get_condition_values(&headers, &cred, None, None, remote_addr); @@ -441,7 +441,7 @@ pub async fn create_oidc_sts_credentials( // Store temp user in IAM let iam_store = - crate::app::context::resolve_ready_iam_handle().map_err(|_| s3_error!(InternalError, "IAM not initialized"))?; + crate::admin::runtime_sources::resolve_ready_iam_handle().map_err(|_| s3_error!(InternalError, "IAM not initialized"))?; let updated_at = iam_store .set_temp_user(&new_cred.access_key, &new_cred, None) diff --git a/rustfs/src/admin/handlers/system.rs b/rustfs/src/admin/handlers/system.rs index 1cbae5ce3..0a1b05dba 100644 --- a/rustfs/src/admin/handlers/system.rs +++ b/rustfs/src/admin/handlers/system.rs @@ -15,8 +15,8 @@ use super::{cluster_snapshot, metrics}; use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; +use crate::admin::runtime_sources::resolve_endpoints_handle; use crate::app::admin_usecase::{DefaultAdminUsecase, QueryServerInfoRequest}; -use crate::app::context::resolve_endpoints_handle; use crate::auth::{check_key_valid, get_session_token}; use crate::runtime_capabilities::{EndpointTopologySnapshotProvider, RustFsObservabilitySnapshotProvider}; use crate::server::{ADMIN_PREFIX, RemoteAddr}; diff --git a/rustfs/src/admin/handlers/table_catalog.rs b/rustfs/src/admin/handlers/table_catalog.rs index 23f0fe589..ab686dfca 100644 --- a/rustfs/src/admin/handlers/table_catalog.rs +++ b/rustfs/src/admin/handlers/table_catalog.rs @@ -13,12 +13,12 @@ // limitations under the License. use super::super::{ECStore, metadata::table_catalog_path_hash, metadata_sys}; +use crate::admin::runtime_sources::{resolve_object_store_handle, resolve_token_signing_key}; use crate::admin::{ auth::{AdminResourceScope, validate_admin_request, validate_admin_request_with_bucket_object}, router::{AdminOperation, Operation, S3Router}, }; use crate::app::admin_usecase::DefaultAdminUsecase; -use crate::app::context::{resolve_object_store_handle, resolve_token_signing_key}; use crate::auth::{check_key_valid, get_session_token}; use crate::server::{RemoteAddr, TABLE_CATALOG_COMPAT_PREFIX, TABLE_CATALOG_PREFIX}; use crate::table_catalog::{DEFAULT_WAREHOUSE_ID, TableCatalogStore}; @@ -713,7 +713,8 @@ impl TableCredentialIssuer for IamTableCredentialIssuer { .map_err(|err| s3_error!(InternalError, "failed to generate table credentials: {}", err))?; bind_table_credential_parent(&mut credential, principal); - let iam_store = crate::app::context::resolve_ready_iam_handle().map_err(|_| s3_error!(InternalError, "iam not init"))?; + let iam_store = + crate::admin::runtime_sources::resolve_ready_iam_handle().map_err(|_| s3_error!(InternalError, "iam not init"))?; iam_store .set_temp_user(&credential.access_key, &credential, None) .await diff --git a/rustfs/src/admin/handlers/tls_debug.rs b/rustfs/src/admin/handlers/tls_debug.rs index 24632a4bf..6324572b8 100644 --- a/rustfs/src/admin/handlers/tls_debug.rs +++ b/rustfs/src/admin/handlers/tls_debug.rs @@ -14,7 +14,7 @@ use super::profile::authorize_profile_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::app::context::resolve_outbound_tls_state; +use crate::admin::runtime_sources::resolve_outbound_tls_state; use crate::server::ADMIN_PREFIX; use http::StatusCode; use http::{HeaderMap, HeaderValue}; diff --git a/rustfs/src/admin/handlers/trace.rs b/rustfs/src/admin/handlers/trace.rs index fa6484911..45fabd80e 100644 --- a/rustfs/src/admin/handlers/trace.rs +++ b/rustfs/src/admin/handlers/trace.rs @@ -14,7 +14,7 @@ use super::super::PeerRestClient; use crate::admin::router::Operation; -use crate::app::context::resolve_endpoints_handle; +use crate::admin::runtime_sources::resolve_endpoints_handle; use http::StatusCode; use hyper::Uri; use matchit::Params; diff --git a/rustfs/src/admin/handlers/user.rs b/rustfs/src/admin/handlers/user.rs index d09b8c37a..ddf80ca8c 100644 --- a/rustfs/src/admin/handlers/user.rs +++ b/rustfs/src/admin/handlers/user.rs @@ -227,7 +227,7 @@ impl Operation for AddUser { return Err(s3_error!(InvalidArgument, "cannot create a user with the system access key")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -356,7 +356,7 @@ impl Operation for SetUserStatus { let status = AccountStatus::try_from(query.status.as_deref().unwrap_or_default()) .map_err(|e| S3Error::with_message(S3ErrorCode::InvalidArgument, e))?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -408,7 +408,7 @@ impl Operation for ListUsers { } }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -481,7 +481,7 @@ impl Operation for RemoveUser { return Err(s3_error!(InvalidArgument, "cannot remove the current user")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -558,7 +558,7 @@ impl Operation for GetUserInfo { return Err(s3_error!(InvalidArgument, "access key is empty")); } - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InternalError, "iam is not initialized")); }; @@ -654,7 +654,7 @@ impl Operation for ExportIam { ) .await?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -888,7 +888,7 @@ impl Operation for ImportIam { let mut zip_reader = ZipArchive::new(Cursor::new(body)).map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, e.to_string()))?; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = crate::admin::runtime_sources::resolve_ready_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; diff --git a/rustfs/src/admin/mod.rs b/rustfs/src/admin/mod.rs index 291457a7e..827218330 100644 --- a/rustfs/src/admin/mod.rs +++ b/rustfs/src/admin/mod.rs @@ -21,6 +21,7 @@ mod plugin_contract; #[allow(dead_code)] pub(crate) mod route_policy; pub mod router; +pub(crate) mod runtime_sources; pub mod service; pub mod site_replication_identity; pub mod utils; diff --git a/rustfs/src/admin/router.rs b/rustfs/src/admin/router.rs index f8d240dc5..cd05604a7 100644 --- a/rustfs/src/admin/router.rs +++ b/rustfs/src/admin/router.rs @@ -24,7 +24,7 @@ use super::versioning_sys::BucketVersioningSys; use super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _}; use crate::admin::console::{is_console_path, make_console_server}; use crate::admin::handlers::oidc::is_oidc_path; -use crate::app::context::{ +use crate::admin::runtime_sources::{ resolve_boot_time, resolve_bucket_monitor_handle, resolve_deployment_id, resolve_notification_system, resolve_object_store_handle, resolve_region, resolve_replication_pool_handle, resolve_replication_stats_handle, resolve_server_config, diff --git a/rustfs/src/admin/runtime_sources.rs b/rustfs/src/admin/runtime_sources.rs new file mode 100644 index 000000000..544d4aefe --- /dev/null +++ b/rustfs/src/admin/runtime_sources.rs @@ -0,0 +1,26 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub(crate) use crate::app::context::{ + AppContext, get_global_app_context, publish_server_config, publish_storage_class_config, resolve_action_credentials, + resolve_boot_time, resolve_bucket_metadata_handle, resolve_bucket_monitor_handle, resolve_deployment_id, + resolve_endpoints_handle, resolve_iam_handle, resolve_kms_runtime_service_manager, resolve_notification_system, + resolve_object_store_handle, resolve_object_store_handle_for_context, resolve_oidc_handle, + resolve_or_init_kms_runtime_service_manager, resolve_outbound_tls_generation, resolve_outbound_tls_state, + resolve_ready_iam_handle, resolve_region, resolve_replication_pool_handle, resolve_replication_stats_handle, + resolve_runtime_port, resolve_scanner_metrics_report, resolve_server_config, resolve_token_signing_key, +}; + +#[cfg(test)] +pub(crate) use crate::app::context::set_test_outbound_tls_generation; diff --git a/rustfs/src/admin/service/config.rs b/rustfs/src/admin/service/config.rs index c4e85b7d2..8a96bbc18 100644 --- a/rustfs/src/admin/service/config.rs +++ b/rustfs/src/admin/service/config.rs @@ -14,7 +14,7 @@ use super::super::storageclass; use super::super::{STORAGE_CLASS_SUB_SYS, read_admin_config_without_migrate}; -use crate::app::context::{ +use crate::admin::runtime_sources::{ AppContext, get_global_app_context, publish_server_config, publish_storage_class_config, resolve_notification_system, resolve_object_store_handle, resolve_object_store_handle_for_context, }; diff --git a/rustfs/src/admin/service/site_replication.rs b/rustfs/src/admin/service/site_replication.rs index 896179713..b8f152fa7 100644 --- a/rustfs/src/admin/service/site_replication.rs +++ b/rustfs/src/admin/service/site_replication.rs @@ -14,8 +14,8 @@ use super::super::Error as StorageError; use super::super::{read_admin_config, save_admin_config}; +use crate::admin::runtime_sources::{AppContext, get_global_app_context, resolve_object_store_handle_for_context}; use crate::admin::site_replication_identity::{deployment_id_for_endpoint, normalize_peer_map_by_identity_with}; -use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context}; use rustfs_madmin::PeerInfo; use s3s::{S3Error, S3ErrorCode, S3Result}; use serde_json::{Map, Value}; diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 12e73212c..ccd730781 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -156,6 +156,7 @@ RUSTFS_APP_CONTEXT_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_app_contex RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_startup_runtime_source_bypass_hits.txt" RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_server_runtime_source_bypass_hits.txt" RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_storage_runtime_source_bypass_hits.txt" +RUSTFS_ADMIN_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_admin_runtime_source_bypass_hits.txt" awk ' /^## PR Types$/ { @@ -1372,6 +1373,16 @@ if [[ -s "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then report_failure "RustFS storage runtime source reads must stay behind rustfs/src/storage/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename 'crate::app::context::|use crate::app::context' rustfs/src/admin \ + | rg -v '^rustfs/src/admin/runtime_sources\.rs:' || true +) >"$RUSTFS_ADMIN_RUNTIME_SOURCE_BYPASS_HITS_FILE" + +if [[ -s "$RUSTFS_ADMIN_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then + report_failure "RustFS admin runtime source reads must stay behind rustfs/src/admin/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_ADMIN_RUNTIME_SOURCE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename 'rustfs_ecstore::api::' \