refactor: route admin topology reads through app context (#3774)

* refactor: route admin topology reads through app context

* chore: accept app context layer baseline entries
This commit is contained in:
Zhengchao An
2026-06-23 11:22:20 +08:00
committed by GitHub
parent 0acc8f8b43
commit 2fe059811a
12 changed files with 215 additions and 49 deletions
+44 -7
View File
@@ -5,21 +5,22 @@ 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-runtime-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`.
- Based on: API-159 branch while PR #3772 is pending.
- Branch: `overtrue/arch-admin-topology-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`.
- Based on: API-160 branch while PR #3773 is pending.
- PR type for this branch: `consumer-migration`
- Runtime behavior changes: none.
- Rust code changes: route admin/server action credentials, region, and server
config consumers through AppContext resolvers with legacy global fallback.
- Rust code changes: route admin topology endpoint, deployment-id, and runtime
port consumers through AppContext resolvers 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
regressions, plus external runtime, test, fuzz, and storage-owner module
ECStore compatibility bypasses, plus runtime crate, owner crate, test/fuzz,
and storage owner thin bridge regressions, plus app context and notify
event-bridge thin module regressions.
- 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 owner facade cleanup.
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 owner facade cleanup.
## Phase 0 Tasks
@@ -4312,6 +4313,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
migration guard, formatting, diff hygiene, Rust risk scan, branch freshness
check, pre-commit, and three-expert review.
- [x] `API-161` Route admin topology reads through AppContext resolvers.
- Do: add deployment-id and runtime-port AppContext interfaces, reuse the
endpoints resolver, default legacy adapters, and route admin topology
consumers through resolvers.
- Acceptance: admin site replication, replication handlers, and router code
no longer directly read endpoints, deployment id, or runtime port globals
outside AppContext default adapters.
- Must preserve: site replication endpoint inference, console-port fallback,
replication same-target validation, stale same-deployment target detection,
and legacy global fallback when AppContext is absent.
- Verification: RustFS compile coverage, targeted context resolver tests,
migration guard, formatting, diff hygiene, Rust risk scan, branch freshness
check, pre-commit, and three-expert review.
## Next PRs
1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries.
@@ -4347,11 +4362,33 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
| Quality/architecture | pass | API-160 keeps admin runtime action credentials, region, and server config reads behind AppContext resolver boundaries. |
| Migration preservation | pass | Admin authorization, object-ZIP token encryption, object-lambda signing, OIDC restart detection, and site replication metadata keep legacy fallback behavior. |
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, Rust risk scan, and pre-commit passed for API-160. |
| Quality/architecture | pass | API-161 keeps admin topology endpoint, deployment id, and runtime port reads behind AppContext resolver boundaries. |
| Migration preservation | pass | Site replication endpoint inference, same-target checks, same-deployment stale target detection, and runtime-port fallback keep legacy behavior. |
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, Rust risk scan, and pre-commit passed for API-161. |
| Testing/verification | pass | CI follow-up: layer dependency baseline accepts the reviewed AppContext resolver reverse dependencies, and the layer guard passes. |
## Verification Notes
Passed before push:
- Issue #660 API-161 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.
- `./scripts/check_layer_dependencies.sh`: passed after CI baseline
follow-up.
- `make pre-commit`: passed.
- AppContext admin topology resolver scan: passed; direct admin deployment
id, endpoint, and runtime port global reads are isolated to AppContext
default adapters.
- Rust risk scan: no new production panic/todo/unsafe/cast risks added; new
unwrap/expect hits are resolver fallback plumbing or test assertions.
- Issue #660 API-160 current slice:
- `cargo check --tests -p rustfs`: passed.
- `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`:
+2 -3
View File
@@ -14,7 +14,6 @@
use super::super::StorageError;
use super::super::bucket_target_sys::{BucketTargetError, BucketTargetSys};
use super::super::global_rustfs_port;
use super::super::metadata::BUCKET_TARGETS_FILE;
use super::super::metadata_sys;
use super::super::metadata_sys::get_replication_config;
@@ -25,7 +24,7 @@ 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::utils::read_compatible_admin_body;
use crate::app::context::resolve_object_store_handle;
use crate::app::context::{resolve_object_store_handle, resolve_runtime_port};
use crate::auth::{check_key_valid, get_session_token};
use crate::error::ApiError;
use crate::server::{ADMIN_PREFIX, RemoteAddr};
@@ -223,7 +222,7 @@ impl Operation for SetRemoteTargetHandler {
let same_target = rustfs_utils::net::is_local_host(
target_url.host().unwrap_or(Host::Domain("localhost")),
target_url.port().unwrap_or(80),
global_rustfs_port(),
resolve_runtime_port(),
)
.unwrap_or_default();
+11 -9
View File
@@ -25,7 +25,6 @@ use super::super::replication::{ResyncOpts, get_global_replication_pool};
use super::super::target::{ARN, BucketTarget, BucketTargetType, BucketTargets, Credentials};
use super::super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
use super::super::{delete_admin_config, read_admin_config, save_admin_config};
use super::super::{get_global_deployment_id, get_global_endpoints_opt, global_rustfs_port};
use crate::admin::auth::validate_admin_request;
use crate::admin::router::{AdminOperation, Operation, S3Router};
use crate::admin::site_replication_identity::{
@@ -33,7 +32,10 @@ use crate::admin::site_replication_identity::{
site_identity_key,
};
use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body};
use crate::app::context::{resolve_object_store_handle, resolve_region, resolve_server_config};
use crate::app::context::{
resolve_deployment_id, resolve_endpoints_handle, resolve_object_store_handle, resolve_region, resolve_runtime_port,
resolve_server_config,
};
use crate::auth::{check_key_valid, get_session_token};
use crate::config::get_config_snapshot;
use crate::error::ApiError;
@@ -671,7 +673,7 @@ fn runtime_tls_enabled_with(endpoints: Option<&super::super::EndpointServerPools
}
fn runtime_tls_enabled() -> bool {
let endpoints = get_global_endpoints_opt();
let endpoints = resolve_endpoints_handle();
runtime_tls_enabled_with(endpoints.as_ref())
}
@@ -822,7 +824,7 @@ fn request_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
.map(str::to_string)
.or_else(|| uri.authority().map(|value| value.as_str().to_string()))
.or_else(|| {
get_global_endpoints_opt().and_then(|endpoints| {
resolve_endpoints_handle().and_then(|endpoints| {
endpoints
.as_ref()
.iter()
@@ -831,7 +833,7 @@ fn request_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
.map(|endpoint| endpoint.host_port())
})
})
.unwrap_or_else(|| format!("127.0.0.1:{}", global_rustfs_port()));
.unwrap_or_else(|| format!("127.0.0.1:{}", resolve_runtime_port()));
format!("{scheme}://{host}")
}
@@ -859,7 +861,7 @@ fn site_replication_local_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
if !matches!(parsed.scheme(), "http" | "https") || parsed.host_str().is_none() {
return request_endpoint(&Uri::from_static("/"), &HeaderMap::new());
}
if parsed.port_or_known_default() == runtime_console_port() && parsed.set_port(Some(global_rustfs_port())).is_ok() {
if parsed.port_or_known_default() == runtime_console_port() && parsed.set_port(Some(resolve_runtime_port())).is_ok() {
parsed.to_string().trim_end_matches('/').to_string()
} else {
endpoint
@@ -899,7 +901,7 @@ fn non_negative_u64(value: i64) -> u64 {
fn current_local_peer(req: &S3Request<Body>, state: &SiteReplicationState) -> PeerInfo {
let endpoint = site_replication_local_endpoint(&req.uri, &req.headers);
let deployment_id = get_global_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
let deployment_id = resolve_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
let stored_peer = state.peers.get(&deployment_id);
PeerInfo {
@@ -923,7 +925,7 @@ fn current_local_peer(req: &S3Request<Body>, state: &SiteReplicationState) -> Pe
fn current_local_runtime_peer(state: &SiteReplicationState) -> PeerInfo {
let endpoint = current_local_runtime_endpoint();
let deployment_id = get_global_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
let deployment_id = resolve_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
let stored_peer = state.peers.get(&deployment_id);
PeerInfo {
@@ -4287,7 +4289,7 @@ impl Operation for SiteReplicationEditHandler {
};
for target in current_state.peers.values() {
let local_target = get_global_deployment_id()
let local_target = resolve_deployment_id()
.as_ref()
.is_some_and(|deployment_id| deployment_id == &target.deployment_id);
if local_target {
+1 -15
View File
@@ -136,9 +136,7 @@ mod ecstore_error {
}
mod ecstore_global {
pub(crate) use crate::storage::ecstore_global::{
GLOBAL_BOOT_TIME, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, global_rustfs_port,
};
pub(crate) use crate::storage::ecstore_global::{GLOBAL_BOOT_TIME, get_global_bucket_monitor};
}
#[allow(unused_imports)]
@@ -516,18 +514,6 @@ pub(crate) fn get_global_bucket_monitor() -> Option<Arc<bandwidth::monitor::Moni
ecstore_global::get_global_bucket_monitor()
}
pub(crate) fn get_global_deployment_id() -> Option<String> {
ecstore_global::get_global_deployment_id()
}
pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
ecstore_global::get_global_endpoints_opt()
}
pub(crate) fn global_rustfs_port() -> u16 {
ecstore_global::global_rustfs_port()
}
pub(crate) async fn collect_local_metrics(
types: MetricType,
opts: &CollectMetricsOpts,
+3 -3
View File
@@ -16,6 +16,7 @@ use super::GLOBAL_BOOT_TIME;
use super::PeerRestClient;
use super::bandwidth::monitor::BandwidthDetails;
use super::bucket_target_sys::{BucketTargetSys, PutObjectOptions, RemoveObjectOptions, S3ClientError, TargetClient};
use super::get_global_bucket_monitor;
use super::get_global_notification_sys;
use super::metadata::BUCKET_TARGETS_FILE;
use super::metadata_sys;
@@ -26,10 +27,9 @@ use super::replication::{
use super::target::{BucketTarget, BucketTargetType, BucketTargets};
use super::versioning_sys::BucketVersioningSys;
use super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
use super::{get_global_bucket_monitor, get_global_deployment_id};
use crate::admin::console::{is_console_path, make_console_server};
use crate::admin::handlers::oidc::is_oidc_path;
use crate::app::context::{resolve_object_store_handle, resolve_region, resolve_server_config};
use crate::app::context::{resolve_deployment_id, resolve_object_store_handle, resolve_region, resolve_server_config};
use crate::app::object_usecase::DefaultObjectUsecase;
use crate::auth::{check_key_valid, get_session_token};
use crate::error::ApiError;
@@ -1829,7 +1829,7 @@ async fn check_replication_target(bucket: &str, target: &BucketTarget) -> Replic
if target.target_bucket == bucket
&& !target.deployment_id.is_empty()
&& get_global_deployment_id().as_deref() == Some(target.deployment_id.as_str())
&& resolve_deployment_id().as_deref() == Some(target.deployment_id.as_str())
{
result.status = "FAILED".to_string();
result.error = Some("target bucket must not match source bucket on the same deployment".to_string());
+65 -3
View File
@@ -84,6 +84,16 @@ pub fn resolve_endpoints_handle() -> Option<EndpointServerPools> {
resolve_endpoints_handle_with(get_global_app_context(), || default_endpoints_interface().handle())
}
/// Resolve deployment identity using AppContext-first precedence.
pub fn resolve_deployment_id() -> Option<String> {
resolve_deployment_id_with(get_global_app_context(), || default_deployment_id_interface().get())
}
/// Resolve runtime port using AppContext-first precedence.
pub fn resolve_runtime_port() -> u16 {
resolve_runtime_port_with(get_global_app_context(), || default_runtime_port_interface().get())
}
/// Resolve lock client using AppContext-first precedence.
pub fn resolve_lock_client() -> Option<Arc<dyn LockClient>> {
resolve_lock_client_with(get_global_app_context(), || default_lock_client_interface().handle())
@@ -163,6 +173,14 @@ fn resolve_endpoints_handle_with(
context.and_then(|context| context.endpoints().handle()).or_else(fallback)
}
fn resolve_deployment_id_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> Option<String>) -> Option<String> {
context.and_then(|context| context.deployment_id().get()).or_else(fallback)
}
fn resolve_runtime_port_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> u16) -> u16 {
context.map_or_else(fallback, |context| context.runtime_port().get())
}
fn resolve_lock_client_with(
context: Option<Arc<AppContext>>,
fallback: impl FnOnce() -> Option<Arc<dyn LockClient>>,
@@ -226,9 +244,9 @@ mod tests {
use crate::app::context::global::AppContextTestInterfaces;
use crate::app::context::handles::default_notify_interface;
use crate::app::context::interfaces::{
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface,
KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, RegionInterface, ServerConfigInterface,
TierConfigInterface,
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, RegionInterface,
RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
};
use crate::config::{RustFSBufferConfig, WorkloadProfile};
use async_trait::async_trait;
@@ -292,6 +310,26 @@ mod tests {
}
}
struct TestDeploymentIdInterface {
id: Option<String>,
}
impl DeploymentIdInterface for TestDeploymentIdInterface {
fn get(&self) -> Option<String> {
self.id.clone()
}
}
struct TestRuntimePortInterface {
port: u16,
}
impl RuntimePortInterface for TestRuntimePortInterface {
fn get(&self) -> u16 {
self.port
}
}
struct TestLockClientInterface {
client: Option<Arc<dyn LockClient>>,
}
@@ -426,6 +464,10 @@ mod tests {
let fallback_lock_client: Arc<dyn LockClient> = Arc::new(LocalClient::new());
let context_node_name = "context-node".to_string();
let fallback_node_name = "fallback-node".to_string();
let context_deployment_id = "context-deployment".to_string();
let fallback_deployment_id = "fallback-deployment".to_string();
let context_runtime_port = 19000;
let fallback_runtime_port = 29000;
let context_credentials = Credentials {
access_key: "context-access-key".to_string(),
..Default::default()
@@ -454,6 +496,12 @@ mod tests {
endpoints: Arc::new(TestEndpointsInterface {
endpoints: Some(endpoints.clone()),
}),
deployment_id: Arc::new(TestDeploymentIdInterface {
id: Some(context_deployment_id.clone()),
}),
runtime_port: Arc::new(TestRuntimePortInterface {
port: context_runtime_port,
}),
lock_client: Arc::new(TestLockClientInterface {
client: Some(context_lock_client.clone()),
}),
@@ -497,6 +545,15 @@ mod tests {
.drives_per_set,
endpoints.as_ref()[0].drives_per_set
);
assert_eq!(
resolve_deployment_id_with(Some(context.clone()), || Some(fallback_deployment_id.clone()))
.expect("context deployment id"),
context_deployment_id
);
assert_eq!(
resolve_runtime_port_with(Some(context.clone()), || fallback_runtime_port),
context_runtime_port
);
assert!(Arc::ptr_eq(
&resolve_lock_client_with(Some(context.clone()), || None).expect("context lock client"),
&context_lock_client
@@ -549,6 +606,11 @@ mod tests {
.drives_per_set,
endpoints.as_ref()[0].drives_per_set
);
assert_eq!(
resolve_deployment_id_with(None, || Some(fallback_deployment_id.clone())).expect("fallback deployment id"),
fallback_deployment_id
);
assert_eq!(resolve_runtime_port_with(None, || fallback_runtime_port), fallback_runtime_port);
assert!(Arc::ptr_eq(
&resolve_lock_client_with(None, || Some(fallback_lock_client.clone())).expect("fallback lock client"),
&fallback_lock_client
+21 -5
View File
@@ -15,14 +15,14 @@
use super::super::{ECStore, set_object_store_resolver};
use super::handles::{
IamHandle, KmsHandle, default_action_credential_interface, default_bucket_metadata_interface,
default_buffer_config_interface, default_endpoints_interface, default_kms_runtime_interface,
default_buffer_config_interface, default_deployment_id_interface, default_endpoints_interface, default_kms_runtime_interface,
default_local_node_name_interface, default_lock_client_interface, default_notify_interface, default_region_interface,
default_server_config_interface, default_tier_config_interface,
default_runtime_port_interface, default_server_config_interface, default_tier_config_interface,
};
use super::interfaces::{
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface, KmsInterface,
KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface, RegionInterface, ServerConfigInterface,
TierConfigInterface,
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface,
RegionInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
};
use rustfs_iam::{store::object::ObjectStore, sys::IamSys};
use rustfs_kms::KmsServiceManager;
@@ -39,6 +39,8 @@ pub struct AppContext {
notify: Arc<dyn NotifyInterface>,
bucket_metadata: Arc<dyn BucketMetadataInterface>,
endpoints: Arc<dyn EndpointsInterface>,
deployment_id: Arc<dyn DeploymentIdInterface>,
runtime_port: Arc<dyn RuntimePortInterface>,
lock_client: Arc<dyn LockClientInterface>,
local_node_name: Arc<dyn LocalNodeNameInterface>,
action_credentials: Arc<dyn ActionCredentialInterface>,
@@ -58,6 +60,8 @@ impl AppContext {
notify: default_notify_interface(),
bucket_metadata: default_bucket_metadata_interface(),
endpoints: default_endpoints_interface(),
deployment_id: default_deployment_id_interface(),
runtime_port: default_runtime_port_interface(),
lock_client: default_lock_client_interface(),
local_node_name: default_local_node_name_interface(),
action_credentials: default_action_credential_interface(),
@@ -105,6 +109,14 @@ impl AppContext {
self.endpoints.clone()
}
pub fn deployment_id(&self) -> Arc<dyn DeploymentIdInterface> {
self.deployment_id.clone()
}
pub fn runtime_port(&self) -> Arc<dyn RuntimePortInterface> {
self.runtime_port.clone()
}
pub fn lock_client(&self) -> Arc<dyn LockClientInterface> {
self.lock_client.clone()
}
@@ -142,6 +154,8 @@ pub(super) struct AppContextTestInterfaces {
pub(super) notify: Arc<dyn NotifyInterface>,
pub(super) bucket_metadata: Arc<dyn BucketMetadataInterface>,
pub(super) endpoints: Arc<dyn EndpointsInterface>,
pub(super) deployment_id: Arc<dyn DeploymentIdInterface>,
pub(super) runtime_port: Arc<dyn RuntimePortInterface>,
pub(super) lock_client: Arc<dyn LockClientInterface>,
pub(super) local_node_name: Arc<dyn LocalNodeNameInterface>,
pub(super) action_credentials: Arc<dyn ActionCredentialInterface>,
@@ -162,6 +176,8 @@ impl AppContext {
notify: interfaces.notify,
bucket_metadata: interfaces.bucket_metadata,
endpoints: interfaces.endpoints,
deployment_id: interfaces.deployment_id,
runtime_port: interfaces.runtime_port,
lock_client: interfaces.lock_client,
local_node_name: interfaces.local_node_name,
action_credentials: interfaces.action_credentials,
+35 -4
View File
@@ -15,11 +15,14 @@
use super::super::EndpointServerPools;
use super::super::TierConfigMgr;
use super::super::metadata_sys::{BucketMetadataSys, get_global_bucket_metadata_sys};
use super::super::{get_global_endpoints_opt, get_global_lock_client, get_global_region, get_global_tier_config_mgr};
use super::super::{
get_global_deployment_id, get_global_endpoints_opt, get_global_lock_client, get_global_region, get_global_tier_config_mgr,
global_rustfs_port,
};
use super::interfaces::{
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface, KmsInterface,
KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface, RegionInterface, ServerConfigInterface,
TierConfigInterface,
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface,
RegionInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
};
use crate::config::{RustFSBufferConfig, get_global_buffer_config};
use async_trait::async_trait;
@@ -129,6 +132,26 @@ impl EndpointsInterface for EndpointsHandle {
}
}
/// Default deployment identity interface adapter.
#[derive(Default)]
pub struct DeploymentIdHandle;
impl DeploymentIdInterface for DeploymentIdHandle {
fn get(&self) -> Option<String> {
get_global_deployment_id()
}
}
/// Default runtime port interface adapter.
#[derive(Default)]
pub struct RuntimePortHandle;
impl RuntimePortInterface for RuntimePortHandle {
fn get(&self) -> u16 {
global_rustfs_port()
}
}
/// Default lock client interface adapter.
#[derive(Default)]
pub struct LockClientHandle;
@@ -216,6 +239,14 @@ pub fn default_endpoints_interface() -> Arc<dyn EndpointsInterface> {
Arc::new(EndpointsHandle)
}
pub fn default_deployment_id_interface() -> Arc<dyn DeploymentIdInterface> {
Arc::new(DeploymentIdHandle)
}
pub fn default_runtime_port_interface() -> Arc<dyn RuntimePortInterface> {
Arc::new(RuntimePortHandle)
}
pub fn default_lock_client_interface() -> Arc<dyn LockClientInterface> {
Arc::new(LockClientHandle)
}
+10
View File
@@ -70,6 +70,16 @@ pub trait EndpointsInterface: Send + Sync {
fn handle(&self) -> Option<EndpointServerPools>;
}
/// Deployment identity interface for admin topology integration.
pub trait DeploymentIdInterface: Send + Sync {
fn get(&self) -> Option<String>;
}
/// Runtime port interface for admin topology integration.
pub trait RuntimePortInterface: Send + Sync {
fn get(&self) -> u16;
}
/// Lock client interface for application-layer use-cases.
pub trait LockClientInterface: Send + Sync {
fn handle(&self) -> Option<Arc<dyn LockClient>>;
+8
View File
@@ -630,6 +630,10 @@ pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
crate::storage::get_global_endpoints_opt()
}
pub(crate) fn get_global_deployment_id() -> Option<String> {
crate::storage::get_global_deployment_id()
}
pub(crate) fn get_global_lock_client() -> Option<Arc<dyn rustfs_lock::client::LockClient>> {
crate::storage::get_global_lock_client()
}
@@ -638,6 +642,10 @@ pub(crate) fn get_global_region() -> Option<s3s::region::Region> {
crate::storage::get_global_region()
}
pub(crate) fn global_rustfs_port() -> u16 {
crate::storage::global_rustfs_port()
}
pub(crate) fn get_global_tier_config_mgr() -> Arc<tokio::sync::RwLock<TierConfigMgr>> {
crate::storage::get_global_tier_config_mgr()
}
+8
View File
@@ -813,10 +813,18 @@ pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
ecstore_global::get_global_endpoints_opt()
}
pub(crate) fn get_global_deployment_id() -> Option<String> {
ecstore_global::get_global_deployment_id()
}
pub(crate) fn get_global_region() -> Option<s3s::region::Region> {
ecstore_global::get_global_region()
}
pub(crate) fn global_rustfs_port() -> u16 {
ecstore_global::global_rustfs_port()
}
pub(crate) fn get_global_tier_config_mgr() -> Arc<tokio::sync::RwLock<TierConfigMgr>> {
ecstore_global::get_global_tier_config_mgr()
}
+7
View File
@@ -41,15 +41,22 @@ accepted|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::F
accepted|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config|config resolution uses global AppContext
accepted|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config|config resolution uses global AppContext
accepted|rustfs/src/server/http.rs|infra->interface|crate::admin|HTTP server routes to admin handlers
accepted|rustfs/src/server/layer.rs|infra->app|crate::app::context::resolve_kms_runtime_service_manager|HTTP layer reads KMS runtime through AppContext resolver
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::console::is_console_path|pure path predicate for routing
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::HealthProbe|HTTP layer builds health responses
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::build_health_response_parts|HTTP layer builds health responses
accepted|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle|readiness checks endpoint availability through AppContext resolver
accepted|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready|readiness checks IAM availability through AppContext resolver
accepted|rustfs/src/startup_iam.rs|infra->app|crate::app::context::AppContext|startup wires IAM bootstrap through AppContext
accepted|rustfs/src/storage/ecfs_extend.rs|infra->app|crate::app::context::resolve_buffer_config|storage buffer sizing reads runtime config through AppContext resolver
accepted|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery|storage extension uses current ECFS interface query type
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::FS|storage tests exercise current ECFS interface path
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::validate_object_lock_configuration_input|storage tests exercise current ECFS object-lock validator
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_initiator|storage tests use current S3 API initiator helper
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_owner|storage tests use current S3 API owner helper
accepted|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name|RPC health labels node identity through AppContext resolver
accepted|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle|node RPC IAM operations use AppContext resolver fallback
accepted|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_lock_client|node RPC locking uses AppContext resolver fallback
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_dynamic_config_runtime_state|node RPC reloads admin runtime state
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot|node RPC reloads admin runtime state
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state|node RPC reloads admin runtime state