From c421e73fefe1c2c3d1bb21f3e7740a000b8a27f6 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Tue, 23 Jun 2026 12:20:57 +0800 Subject: [PATCH] refactor: route site replication iam through app context (#3777) --- docs/architecture/migration-progress.md | 45 ++++++++++++++++--- rustfs/src/admin/handlers/site_replication.rs | 16 +++---- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 2a456e3e9..3c662fe79 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,14 +5,13 @@ 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-admin-peer-systems-context-resolvers` -- 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`. -- Based on: API-161 branch while PR #3774 is pending. +- Branch: `overtrue/arch-admin-site-replication-iam-context` +- 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`. +- Based on: API-162 branch while PR #3776 is pending. - PR type for this branch: `consumer-migration` - Runtime behavior changes: none. -- Rust code changes: route admin and app notification-system, bucket-monitor, - and replication-pool consumers through AppContext resolvers with legacy - global fallback. +- Rust code changes: route admin site-replication IAM consumers through the + AppContext IAM resolver with legacy global fallback. - CI/script changes: lock completed owner and test/fuzz boundaries against bare/glob imports, scattered raw ECStore facade subpaths, and startup runtime/root-server/table/S3/app shared/app bucket/app ECStore/admin facade @@ -21,7 +20,7 @@ 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; accept the reviewed AppContext resolver reverse dependencies in the layer baseline. -- Docs changes: record the 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 owner facade cleanup. +- Docs changes: record the 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 owner facade cleanup. ## Phase 0 Tasks @@ -4345,6 +4344,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block migration guard, formatting, diff hygiene, residual global-read scan, Rust risk scan, branch freshness check, and three-expert review. +- [x] `API-163` Route admin site-replication IAM reads through AppContext. + - Do: replace admin site-replication direct IAM global reads with the + AppContext IAM handle resolver. + - Acceptance: site-replication service-account, IAM export, IAM item import, + and peer-join service-account paths no longer directly call the IAM global + accessor. + - Must preserve: site-replicator service-account lookup/update/create, + exported IAM policy/user/group/policy-mapping payloads, imported IAM item + reconciliation, peer join service-account upsert, and legacy fallback when + AppContext is absent. + - Verification: RustFS compile coverage, targeted context resolver tests, + migration guard, formatting, diff hygiene, residual IAM global-read scan, + Rust risk scan, branch freshness check, and three-expert review. + ## Next PRs 1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries. @@ -4387,11 +4400,29 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Quality/architecture | pass | API-162 keeps admin peer-system notification, bucket-monitor, and replication-pool reads behind AppContext resolver boundaries. | | Migration preservation | pass | Tier/rebalance/config propagation, live event peers, replication metrics, and resync operations keep legacy fallback behavior. | | Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, residual scan, Rust risk scan, and pre-commit passed for API-162. | +| Quality/architecture | pass | API-163 keeps admin site-replication IAM reads behind the AppContext IAM resolver boundary. | +| Migration preservation | pass | Site-replicator service-account, IAM export/import, and peer-join service-account paths keep legacy fallback behavior. | +| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, residual IAM scan, and Rust risk scan passed for API-163. | ## Verification Notes Passed before push: +- Issue #660 API-163 current slice: + - `cargo check --tests -p rustfs`: passed. + - `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`: + passed. + - `cargo fmt --all`: passed. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `bash -n scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - AppContext site-replication IAM resolver scan: passed; direct admin + site-replication IAM global reads are isolated to AppContext fallback + plumbing. + - Rust risk scan: no new production unwrap/expect, panic/todo/unsafe, or cast + risks added. + - Issue #660 API-162 current slice: - `cargo check --tests -p rustfs`: passed. - `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`: diff --git a/rustfs/src/admin/handlers/site_replication.rs b/rustfs/src/admin/handlers/site_replication.rs index 68f160dc0..2f0faaa64 100644 --- a/rustfs/src/admin/handlers/site_replication.rs +++ b/rustfs/src/admin/handlers/site_replication.rs @@ -32,7 +32,7 @@ use crate::admin::site_replication_identity::{ }; use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body}; use crate::app::context::{ - resolve_deployment_id, resolve_endpoints_handle, resolve_object_store_handle, resolve_region, + resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, resolve_object_store_handle, resolve_region, resolve_replication_pool_handle, resolve_runtime_port, resolve_server_config, }; use crate::auth::{check_key_valid, get_session_token}; @@ -51,11 +51,11 @@ use rustfs_config::{ MAX_ADMIN_REQUEST_BODY_SIZE, }; use rustfs_iam::error::is_err_no_such_service_account; +use rustfs_iam::get_oidc; use rustfs_iam::store::{MappedPolicy, UserType}; use rustfs_iam::sys::{ NewServiceAccountOpts, SITE_REPLICATOR_SERVICE_ACCOUNT, UpdateServiceAccountOpts, get_claims_from_token_with_secret, }; -use rustfs_iam::{get_global_iam_sys, get_oidc}; use rustfs_madmin::{ BucketBandwidth, GroupStatus, IDPSettings, InProgressMetric, InQueueMetric, LDAPConfigSettings, LDAPSettings, OpenIDProviderSettings, PeerInfo, PeerSite, QStat, ReplProxyMetric, ReplicateAddStatus, ReplicateEditStatus, @@ -1114,7 +1114,7 @@ fn reconcile_peer_with_actual_identity(mut state: SiteReplicationState, actual_p } async fn site_replicator_service_account_secret(access_key: &str) -> S3Result { - let Some(iam_sys) = get_global_iam_sys() else { + let Some(iam_sys) = resolve_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -1131,7 +1131,7 @@ fn legacy_site_replicator_state_secret(state: &SiteReplicationState) -> Option S3Result { - let Some(iam_sys) = get_global_iam_sys() else { + let Some(iam_sys) = resolve_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -1177,7 +1177,7 @@ async fn set_site_replicator_service_account_secret(parent_user: &str, secret_ke } async fn ensure_site_replicator_service_account(parent_user: &str, rotate_secret: bool) -> S3Result<(String, String)> { - let Some(iam_sys) = get_global_iam_sys() else { + let Some(iam_sys) = resolve_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; @@ -1619,7 +1619,7 @@ async fn build_sr_info(state: &SiteReplicationState, local_peer: &PeerInfo) -> S info.buckets.insert(bucket.name, entry); } - if let Some(iam_sys) = get_global_iam_sys() { + if let Some(iam_sys) = resolve_iam_handle() { for (name, policy_doc) in iam_sys.list_policy_docs("").await.map_err(ApiError::from)? { info.policies.insert( name, @@ -3502,7 +3502,7 @@ fn group_info_requires_upsert(update: &rustfs_madmin::GroupAddRemove) -> bool { } async fn apply_iam_item(item: SRIAMItem) -> S3Result<()> { - let Some(iam_sys) = get_global_iam_sys() else { + let Some(iam_sys) = resolve_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); }; let incoming_updated_at = item.updated_at; @@ -4010,7 +4010,7 @@ impl Operation for SRPeerJoinHandler { } if !join_req.svc_acct_access_key.is_empty() && !join_req.svc_acct_secret_key.is_empty() { - let Some(iam_sys) = get_global_iam_sys() else { + let Some(iam_sys) = resolve_iam_handle() else { return Err(s3_error!(InvalidRequest, "iam not init")); };