mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-08 14:23:13 +00:00
refactor(admin): migrate OIDC consumers to app context (#3800)
This commit is contained in:
@@ -12,7 +12,9 @@ for later deletion.
|
|||||||
|
|
||||||
## Open Items
|
## Open Items
|
||||||
|
|
||||||
No compatibility code is currently registered.
|
- `CTX-002`
|
||||||
|
- Why: admin OIDC and STS consumers now resolve through `resolve_oidc_handle()`, but that resolver still falls back to legacy global OIDC state while the AppContext-owned OIDC wiring is being completed.
|
||||||
|
- Remove after: OIDC ownership is initialized and consumed through AppContext end-to-end, and `resolve_oidc_handle()` no longer needs the legacy global fallback path.
|
||||||
|
|
||||||
## Review Checklist
|
## Review Checklist
|
||||||
|
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ impl Config {
|
|||||||
let http_prefix = rustfs_config::RUSTFS_HTTP_PREFIX;
|
let http_prefix = rustfs_config::RUSTFS_HTTP_PREFIX;
|
||||||
|
|
||||||
// Collect OIDC provider info if available
|
// Collect OIDC provider info if available
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let oidc = resolve_oidc_handle()
|
let oidc = resolve_oidc_handle()
|
||||||
.map(|sys| {
|
.map(|sys| {
|
||||||
sys.list_visible_providers()
|
sys.list_visible_providers()
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ pub struct ListOidcProvidersHandler {}
|
|||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl Operation for ListOidcProvidersHandler {
|
impl Operation for ListOidcProvidersHandler {
|
||||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
||||||
|
|
||||||
let providers = oidc_sys.list_visible_providers();
|
let providers = oidc_sys.list_visible_providers();
|
||||||
@@ -439,6 +440,7 @@ impl Operation for OidcAuthorizeHandler {
|
|||||||
return Err(s3_error!(InvalidRequest, "invalid provider_id"));
|
return Err(s3_error!(InvalidRequest, "invalid provider_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
||||||
|
|
||||||
// Derive the callback redirect URI from the request
|
// Derive the callback redirect URI from the request
|
||||||
@@ -512,6 +514,7 @@ impl Operation for OidcCallbackHandler {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
||||||
|
|
||||||
let redirect_uri = derive_callback_uri(&req, provider_id)?;
|
let redirect_uri = derive_callback_uri(&req, provider_id)?;
|
||||||
@@ -599,6 +602,7 @@ impl Operation for OidcLogoutHandler {
|
|||||||
return redirect_response(&fallback_location);
|
return redirect_response(&fallback_location);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let location = match resolve_oidc_handle() {
|
let location = match resolve_oidc_handle() {
|
||||||
Some(oidc_sys) => match oidc_sys.build_logout_url(&logout_token, &fallback_location).await {
|
Some(oidc_sys) => match oidc_sys.build_logout_url(&logout_token, &fallback_location).await {
|
||||||
Ok(Some(url)) => url,
|
Ok(Some(url)) => url,
|
||||||
@@ -628,6 +632,7 @@ impl Operation for OidcLogoutHandler {
|
|||||||
/// an explicit redirect_uri is recommended to prevent header manipulation.
|
/// an explicit redirect_uri is recommended to prevent header manipulation.
|
||||||
fn derive_callback_uri(req: &S3Request<Body>, provider_id: &str) -> S3Result<String> {
|
fn derive_callback_uri(req: &S3Request<Body>, provider_id: &str) -> S3Result<String> {
|
||||||
// Use explicitly configured redirect_uri if available
|
// Use explicitly configured redirect_uri if available
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
if let Some(oidc_sys) = resolve_oidc_handle()
|
if let Some(oidc_sys) = resolve_oidc_handle()
|
||||||
&& let Some(config) = oidc_sys.get_provider_config(provider_id)
|
&& let Some(config) = oidc_sys.get_provider_config(provider_id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ fn has_identity_authorization_context(policies: &[String], groups: &[String]) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn configured_roles_claim_key(provider_id: &str) -> Option<String> {
|
fn configured_roles_claim_key(provider_id: &str) -> Option<String> {
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
resolve_oidc_handle()
|
resolve_oidc_handle()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|oidc_sys| oidc_sys.get_provider_config(provider_id))
|
.and_then(|oidc_sys| oidc_sys.get_provider_config(provider_id))
|
||||||
@@ -316,6 +317,7 @@ async fn handle_assume_role_with_web_identity(body: AssumeRoleRequest) -> S3Resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the JWT and extract claims
|
// Verify the JWT and extract claims
|
||||||
|
// RUSTFS_COMPAT_TODO(CTX-002): admin OIDC consumers still depend on the resolver's global fallback while AppContext OIDC wiring is incomplete. Remove after OIDC ownership moves fully into AppContext and the global fallback is retired.
|
||||||
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
let oidc_sys = resolve_oidc_handle().ok_or_else(|| s3_error!(InternalError, "OIDC not initialized"))?;
|
||||||
|
|
||||||
let (claims, provider_id) = oidc_sys
|
let (claims, provider_id) = oidc_sys
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
use super::super::storageclass;
|
use super::super::storageclass;
|
||||||
use super::super::{STORAGE_CLASS_SUB_SYS, read_admin_config_without_migrate};
|
use super::super::{STORAGE_CLASS_SUB_SYS, read_admin_config_without_migrate};
|
||||||
use crate::app::context::{
|
use crate::app::context::{
|
||||||
publish_server_config, publish_storage_class_config, resolve_notification_system, resolve_object_store_handle,
|
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,
|
||||||
};
|
};
|
||||||
use rustfs_audit::reload_audit_config;
|
use rustfs_audit::reload_audit_config;
|
||||||
use rustfs_config::audit::{AUDIT_MQTT_SUB_SYS, AUDIT_REDIS_DEFAULT_CHANNEL, AUDIT_WEBHOOK_SUB_SYS};
|
use rustfs_config::audit::{AUDIT_MQTT_SUB_SYS, AUDIT_REDIS_DEFAULT_CHANNEL, AUDIT_WEBHOOK_SUB_SYS};
|
||||||
@@ -66,6 +67,10 @@ fn invalid_request(message: impl Into<String>) -> S3Error {
|
|||||||
S3Error::with_message(S3ErrorCode::InvalidRequest, message.into())
|
S3Error::with_message(S3ErrorCode::InvalidRequest, message.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_runtime_config_store_for_context(context: Option<&AppContext>) -> S3Result<std::sync::Arc<crate::app::ECStore>> {
|
||||||
|
resolve_object_store_handle_for_context(context).ok_or_else(|| internal_error("storage layer not initialized"))
|
||||||
|
}
|
||||||
|
|
||||||
async fn apply_storage_class_runtime_config(config: &ServerConfig) -> S3Result<()> {
|
async fn apply_storage_class_runtime_config(config: &ServerConfig) -> S3Result<()> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = resolve_object_store_handle() else {
|
||||||
return Err(internal_error("storage layer not initialized"));
|
return Err(internal_error("storage layer not initialized"));
|
||||||
@@ -292,14 +297,12 @@ pub async fn apply_dynamic_config_for_subsystem(config: &ServerConfig, sub_syste
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reload_dynamic_config_runtime_state(sub_system: &str) -> S3Result<()> {
|
pub async fn reload_dynamic_config_runtime_state_for_context(context: Option<&AppContext>, sub_system: &str) -> S3Result<()> {
|
||||||
if !is_dynamic_config_subsystem(sub_system) {
|
if !is_dynamic_config_subsystem(sub_system) {
|
||||||
return Err(internal_error(format!("unsupported dynamic config subsystem: {sub_system}")));
|
return Err(internal_error(format!("unsupported dynamic config subsystem: {sub_system}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let store = resolve_runtime_config_store_for_context(context)?;
|
||||||
return Err(internal_error("storage layer not initialized"));
|
|
||||||
};
|
|
||||||
|
|
||||||
let config = read_admin_config_without_migrate(store).await.map_err(|err| {
|
let config = read_admin_config_without_migrate(store).await.map_err(|err| {
|
||||||
warn!("peer reload_dynamic_config: failed to load server config for {sub_system}: {err}");
|
warn!("peer reload_dynamic_config: failed to load server config for {sub_system}: {err}");
|
||||||
@@ -312,10 +315,13 @@ pub async fn reload_dynamic_config_runtime_state(sub_system: &str) -> S3Result<(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reload_runtime_config_snapshot() -> S3Result<()> {
|
pub async fn reload_dynamic_config_runtime_state(sub_system: &str) -> S3Result<()> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let context = get_global_app_context();
|
||||||
return Err(internal_error("storage layer not initialized"));
|
reload_dynamic_config_runtime_state_for_context(context.as_deref(), sub_system).await
|
||||||
};
|
}
|
||||||
|
|
||||||
|
pub async fn reload_runtime_config_snapshot_for_context(context: Option<&AppContext>) -> S3Result<()> {
|
||||||
|
let store = resolve_runtime_config_store_for_context(context)?;
|
||||||
|
|
||||||
let config = read_admin_config_without_migrate(store).await.map_err(|err| {
|
let config = read_admin_config_without_migrate(store).await.map_err(|err| {
|
||||||
warn!("peer reload_runtime_config_snapshot: failed to load server config: {err}");
|
warn!("peer reload_runtime_config_snapshot: failed to load server config: {err}");
|
||||||
@@ -340,6 +346,11 @@ pub async fn reload_runtime_config_snapshot() -> S3Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn reload_runtime_config_snapshot() -> S3Result<()> {
|
||||||
|
let context = get_global_app_context();
|
||||||
|
reload_runtime_config_snapshot_for_context(context.as_deref()).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn signal_dynamic_config_reload(sub_system: &str) {
|
pub async fn signal_dynamic_config_reload(sub_system: &str) {
|
||||||
if !is_dynamic_config_subsystem(sub_system) {
|
if !is_dynamic_config_subsystem(sub_system) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
use super::super::Error as StorageError;
|
use super::super::Error as StorageError;
|
||||||
use super::super::{read_admin_config, save_admin_config};
|
use super::super::{read_admin_config, save_admin_config};
|
||||||
use crate::admin::site_replication_identity::{deployment_id_for_endpoint, normalize_peer_map_by_identity_with};
|
use crate::admin::site_replication_identity::{deployment_id_for_endpoint, normalize_peer_map_by_identity_with};
|
||||||
use crate::app::context::resolve_object_store_handle;
|
use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context};
|
||||||
use rustfs_madmin::PeerInfo;
|
use rustfs_madmin::PeerInfo;
|
||||||
use s3s::{S3Error, S3ErrorCode, S3Result};
|
use s3s::{S3Error, S3ErrorCode, S3Result};
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
@@ -90,8 +90,8 @@ fn normalize_site_replication_state_json(data: &[u8]) -> Result<Option<Vec<u8>>,
|
|||||||
///
|
///
|
||||||
/// RustFS does not currently keep a separate in-memory cache for this state,
|
/// RustFS does not currently keep a separate in-memory cache for this state,
|
||||||
/// so "reload" means validating that the persisted JSON is readable.
|
/// so "reload" means validating that the persisted JSON is readable.
|
||||||
pub async fn reload_site_replication_runtime_state() -> S3Result<()> {
|
pub async fn reload_site_replication_runtime_state_for_context(context: Option<&AppContext>) -> S3Result<()> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = resolve_object_store_handle_for_context(context) else {
|
||||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -116,6 +116,11 @@ pub async fn reload_site_replication_runtime_state() -> S3Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn reload_site_replication_runtime_state() -> S3Result<()> {
|
||||||
|
let context = get_global_app_context();
|
||||||
|
reload_site_replication_runtime_state_for_context(context.as_deref()).await
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -84,16 +84,16 @@ pub fn resolve_iam_handle() -> Option<Arc<IamSys<ObjectStore>>> {
|
|||||||
resolve_iam_handle_with(get_global_app_context(), rustfs_iam::get_global_iam_sys)
|
resolve_iam_handle_with(get_global_app_context(), rustfs_iam::get_global_iam_sys)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a ready IAM system handle using AppContext-first precedence.
|
|
||||||
pub fn resolve_ready_iam_handle() -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> {
|
|
||||||
resolve_ready_iam_handle_with(get_global_app_context(), rustfs_iam::get)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolve OIDC system handle using AppContext-first precedence.
|
/// Resolve OIDC system handle using AppContext-first precedence.
|
||||||
pub fn resolve_oidc_handle() -> Option<Arc<OidcSys>> {
|
pub fn resolve_oidc_handle() -> Option<Arc<OidcSys>> {
|
||||||
resolve_oidc_handle_with(get_global_app_context(), rustfs_iam::get_oidc)
|
resolve_oidc_handle_with(get_global_app_context(), rustfs_iam::get_oidc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a ready IAM system handle using AppContext-first precedence.
|
||||||
|
pub fn resolve_ready_iam_handle() -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> {
|
||||||
|
resolve_ready_iam_handle_with(get_global_app_context(), rustfs_iam::get)
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolve token signing key using AppContext-first precedence.
|
/// Resolve token signing key using AppContext-first precedence.
|
||||||
pub fn resolve_token_signing_key() -> Option<String> {
|
pub fn resolve_token_signing_key() -> Option<String> {
|
||||||
resolve_token_signing_key_with(get_global_app_context(), rustfs_iam::manager::get_token_signing_key)
|
resolve_token_signing_key_with(get_global_app_context(), rustfs_iam::manager::get_token_signing_key)
|
||||||
@@ -1254,6 +1254,8 @@ mod tests {
|
|||||||
assert_eq!(resolve_outbound_tls_generation_with(None, || TlsGeneration(99)), TlsGeneration(99));
|
assert_eq!(resolve_outbound_tls_generation_with(None, || TlsGeneration(99)), TlsGeneration(99));
|
||||||
assert!(!resolve_iam_ready_with(None, || false));
|
assert!(!resolve_iam_ready_with(None, || false));
|
||||||
assert!(resolve_iam_handle_with(None, || None).is_none());
|
assert!(resolve_iam_handle_with(None, || None).is_none());
|
||||||
|
// OIDC fallback path: both context absent and fallback return None.
|
||||||
|
assert!(resolve_oidc_handle_with(None, || None).is_none());
|
||||||
assert!(Arc::ptr_eq(
|
assert!(Arc::ptr_eq(
|
||||||
&resolve_bucket_metadata_handle_with(None, || Some(bucket_metadata.clone())).expect("fallback bucket metadata"),
|
&resolve_bucket_metadata_handle_with(None, || Some(bucket_metadata.clone())).expect("fallback bucket metadata"),
|
||||||
&bucket_metadata
|
&bucket_metadata
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use crate::storage::{Error as StorageError, read_config, resolve_object_store_handle, save_config};
|
use crate::app::context::resolve_object_store_handle;
|
||||||
|
use crate::storage::{Error as StorageError, read_config, save_config};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use crate::app::context::{resolve_endpoints_handle, resolve_iam_ready, resolve_lock_clients_handle};
|
use crate::app::context::{
|
||||||
|
resolve_endpoints_handle, resolve_iam_ready, resolve_lock_clients_handle, resolve_object_store_handle,
|
||||||
|
};
|
||||||
use crate::server::{ServiceState, ServiceStateManager};
|
use crate::server::{ServiceState, ServiceStateManager};
|
||||||
use crate::server::{has_path_prefix, is_table_catalog_path};
|
use crate::server::{has_path_prefix, is_table_catalog_path};
|
||||||
use crate::storage::{Endpoint, EndpointServerPools, is_dist_erasure, resolve_object_store_handle};
|
use crate::storage::{Endpoint, EndpointServerPools, is_dist_erasure};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::storage::{Endpoints, PoolEndpoints};
|
use crate::storage::{Endpoints, PoolEndpoints};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ impl NodeService {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(LoadBucketMetadataResponse {
|
return Ok(Response::new(LoadBucketMetadataResponse {
|
||||||
success: false,
|
success: false,
|
||||||
error_info: Some("errServerNotInitialized".to_string()),
|
error_info: Some("errServerNotInitialized".to_string()),
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ impl NodeService {
|
|||||||
&self,
|
&self,
|
||||||
_request: Request<LocalStorageInfoRequest>,
|
_request: Request<LocalStorageInfoRequest>,
|
||||||
) -> Result<Response<LocalStorageInfoResponse>, Status> {
|
) -> Result<Response<LocalStorageInfoResponse>, Status> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(LocalStorageInfoResponse {
|
return Ok(Response::new(LocalStorageInfoResponse {
|
||||||
success: false,
|
success: false,
|
||||||
storage_info: Bytes::new(),
|
storage_info: Bytes::new(),
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ use crate::admin::service::{
|
|||||||
config::{reload_dynamic_config_runtime_state, reload_runtime_config_snapshot},
|
config::{reload_dynamic_config_runtime_state, reload_runtime_config_snapshot},
|
||||||
site_replication::reload_site_replication_runtime_state,
|
site_replication::reload_site_replication_runtime_state,
|
||||||
};
|
};
|
||||||
use crate::app::context::{resolve_iam_handle, resolve_lock_client};
|
use crate::app::context::{
|
||||||
|
AppContext, get_global_app_context, resolve_iam_handle, resolve_lock_client, resolve_object_store_handle_for_context,
|
||||||
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use futures_util::future::join_all;
|
use futures_util::future::join_all;
|
||||||
@@ -171,17 +173,36 @@ mod lock;
|
|||||||
#[path = "metrics.rs"]
|
#[path = "metrics.rs"]
|
||||||
mod metrics;
|
mod metrics;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct NodeService {
|
pub struct NodeService {
|
||||||
local_peer: LocalPeerS3Client,
|
local_peer: LocalPeerS3Client,
|
||||||
|
context: Option<Arc<AppContext>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for NodeService {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("NodeService")
|
||||||
|
.field("local_peer", &self.local_peer)
|
||||||
|
.field("context_present", &self.context.is_some())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_server() -> NodeService {
|
pub fn make_server() -> NodeService {
|
||||||
|
let context = get_global_app_context();
|
||||||
|
make_server_for_context(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_server_for_context(context: Option<Arc<AppContext>>) -> NodeService {
|
||||||
let local_peer = LocalPeerS3Client::new(None, None);
|
let local_peer = LocalPeerS3Client::new(None, None);
|
||||||
NodeService { local_peer }
|
NodeService { local_peer, context }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeService {
|
impl NodeService {
|
||||||
|
fn resolve_object_store(&self) -> Option<Arc<crate::app::ECStore>> {
|
||||||
|
let context = self.context.clone().or_else(get_global_app_context);
|
||||||
|
resolve_object_store_handle_for_context(context.as_deref())
|
||||||
|
}
|
||||||
|
|
||||||
async fn find_disk(&self, disk_path: &str) -> Option<DiskStore> {
|
async fn find_disk(&self, disk_path: &str) -> Option<DiskStore> {
|
||||||
find_local_disk_by_ref(disk_path).await
|
find_local_disk_by_ref(disk_path).await
|
||||||
}
|
}
|
||||||
@@ -900,7 +921,7 @@ impl Node for NodeService {
|
|||||||
&self,
|
&self,
|
||||||
_request: Request<ReloadSiteReplicationConfigRequest>,
|
_request: Request<ReloadSiteReplicationConfigRequest>,
|
||||||
) -> Result<Response<ReloadSiteReplicationConfigResponse>, Status> {
|
) -> Result<Response<ReloadSiteReplicationConfigResponse>, Status> {
|
||||||
let Some(_store) = resolve_object_store_handle() else {
|
let Some(_store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(ReloadSiteReplicationConfigResponse {
|
return Ok(Response::new(ReloadSiteReplicationConfigResponse {
|
||||||
success: false,
|
success: false,
|
||||||
error_info: Some("errServerNotInitialized".to_string()),
|
error_info: Some("errServerNotInitialized".to_string()),
|
||||||
@@ -989,7 +1010,7 @@ impl Node for NodeService {
|
|||||||
&self,
|
&self,
|
||||||
_request: Request<ReloadPoolMetaRequest>,
|
_request: Request<ReloadPoolMetaRequest>,
|
||||||
) -> Result<Response<ReloadPoolMetaResponse>, Status> {
|
) -> Result<Response<ReloadPoolMetaResponse>, Status> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(ReloadPoolMetaResponse {
|
return Ok(Response::new(ReloadPoolMetaResponse {
|
||||||
success: false,
|
success: false,
|
||||||
error_info: Some("errServerNotInitialized".to_string()),
|
error_info: Some("errServerNotInitialized".to_string()),
|
||||||
@@ -1014,7 +1035,7 @@ impl Node for NodeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn stop_rebalance(&self, request: Request<StopRebalanceRequest>) -> Result<Response<StopRebalanceResponse>, Status> {
|
async fn stop_rebalance(&self, request: Request<StopRebalanceRequest>) -> Result<Response<StopRebalanceResponse>, Status> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(StopRebalanceResponse {
|
return Ok(Response::new(StopRebalanceResponse {
|
||||||
success: false,
|
success: false,
|
||||||
error_info: Some("errServerNotInitialized".to_string()),
|
error_info: Some("errServerNotInitialized".to_string()),
|
||||||
@@ -1035,7 +1056,7 @@ impl Node for NodeService {
|
|||||||
request: Request<LoadRebalanceMetaRequest>,
|
request: Request<LoadRebalanceMetaRequest>,
|
||||||
) -> Result<Response<LoadRebalanceMetaResponse>, Status> {
|
) -> Result<Response<LoadRebalanceMetaResponse>, Status> {
|
||||||
let LoadRebalanceMetaRequest { start_rebalance } = request.into_inner();
|
let LoadRebalanceMetaRequest { start_rebalance } = request.into_inner();
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
log_load_rebalance_meta_rejected!("server_not_initialized", start_rebalance);
|
log_load_rebalance_meta_rejected!("server_not_initialized", start_rebalance);
|
||||||
return Ok(Response::new(LoadRebalanceMetaResponse {
|
return Ok(Response::new(LoadRebalanceMetaResponse {
|
||||||
success: false,
|
success: false,
|
||||||
@@ -1174,7 +1195,7 @@ impl Node for NodeService {
|
|||||||
&self,
|
&self,
|
||||||
_request: Request<LoadTransitionTierConfigRequest>,
|
_request: Request<LoadTransitionTierConfigRequest>,
|
||||||
) -> Result<Response<LoadTransitionTierConfigResponse>, Status> {
|
) -> Result<Response<LoadTransitionTierConfigResponse>, Status> {
|
||||||
let Some(store) = resolve_object_store_handle() else {
|
let Some(store) = self.resolve_object_store() else {
|
||||||
return Ok(Response::new(LoadTransitionTierConfigResponse {
|
return Ok(Response::new(LoadTransitionTierConfigResponse {
|
||||||
success: false,
|
success: false,
|
||||||
error_info: Some("errServerNotInitialized".to_string()),
|
error_info: Some("errServerNotInitialized".to_string()),
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ dep|rustfs/src/init.rs|infra->interface|crate::admin
|
|||||||
dep|rustfs/src/protocols/client.rs|infra->app|crate::app::context::resolve_action_credentials
|
dep|rustfs/src/protocols/client.rs|infra->app|crate::app::context::resolve_action_credentials
|
||||||
dep|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::FS
|
dep|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::FS
|
||||||
dep|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config
|
dep|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config
|
||||||
|
dep|rustfs/src/server/module_switch.rs|infra->app|crate::app::context::resolve_object_store_handle
|
||||||
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_notify_interface
|
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_notify_interface
|
||||||
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config
|
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config
|
||||||
dep|rustfs/src/server/http.rs|infra->interface|crate::admin
|
dep|rustfs/src/server/http.rs|infra->interface|crate::admin
|
||||||
@@ -57,6 +58,7 @@ dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::
|
|||||||
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle
|
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle
|
||||||
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready
|
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready
|
||||||
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_lock_clients_handle
|
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_lock_clients_handle
|
||||||
|
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_object_store_handle
|
||||||
dep|rustfs/src/server/tls_material.rs|infra->app|crate::app::context::resolve_outbound_tls_generation
|
dep|rustfs/src/server/tls_material.rs|infra->app|crate::app::context::resolve_outbound_tls_generation
|
||||||
dep|rustfs/src/startup_bucket_metadata.rs|infra->app|crate::app::context::resolve_replication_pool_handle
|
dep|rustfs/src/startup_bucket_metadata.rs|infra->app|crate::app::context::resolve_replication_pool_handle
|
||||||
dep|rustfs/src/startup_tls_material.rs|infra->app|crate::app::context::resolve_outbound_tls_generation
|
dep|rustfs/src/startup_tls_material.rs|infra->app|crate::app::context::resolve_outbound_tls_generation
|
||||||
@@ -75,8 +77,11 @@ dep|rustfs/src/storage/helper.rs|infra->app|crate::app::context::resolve_notify_
|
|||||||
dep|rustfs/src/storage/rpc/disk.rs|infra->app|crate::app::context::resolve_internode_metrics
|
dep|rustfs/src/storage/rpc/disk.rs|infra->app|crate::app::context::resolve_internode_metrics
|
||||||
dep|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name
|
dep|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name
|
||||||
dep|rustfs/src/storage/rpc/http_service.rs|infra->app|crate::app::context::resolve_internode_metrics
|
dep|rustfs/src/storage/rpc/http_service.rs|infra->app|crate::app::context::resolve_internode_metrics
|
||||||
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::AppContext
|
||||||
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::get_global_app_context
|
||||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle
|
||||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_lock_client
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_lock_client
|
||||||
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_object_store_handle_for_context
|
||||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_dynamic_config_runtime_state
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_dynamic_config_runtime_state
|
||||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot
|
||||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state
|
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state
|
||||||
|
|||||||
Reference in New Issue
Block a user