diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index 231974315..3efe283bf 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -614,15 +614,16 @@ pub(super) async fn resolve_true_destination( let state = &services().server.log.capture; let logs = Arc::new(Mutex::new(String::new())); let capture = Capture::new(state, Some(filter), capture::fmt_markdown(logs.clone())); - let (actual_dest, hostname_uri); - { - let _capture_scope = capture.start(); - (actual_dest, hostname_uri) = resolve_actual_dest(&server_name, !no_cache).await?; - }; + + let capture_scope = capture.start(); + let actual = resolve_actual_dest(&server_name, !no_cache).await?; + drop(capture_scope); let msg = format!( - "{}\nDestination: {actual_dest}\nHostname URI: {hostname_uri}", - logs.lock().expect("locked") + "{}\nDestination: {}\nHostname URI: {}", + logs.lock().expect("locked"), + actual.dest, + actual.host, ); Ok(RoomMessageEventContent::text_markdown(msg)) } diff --git a/src/admin/query/mod.rs b/src/admin/query/mod.rs index 946e6ec82..ea7036d04 100644 --- a/src/admin/query/mod.rs +++ b/src/admin/query/mod.rs @@ -2,6 +2,7 @@ mod account_data; mod appservice; mod globals; mod presence; +mod resolver; mod room_alias; mod room_state_cache; mod sending; @@ -12,12 +13,12 @@ use conduit::Result; use room_state_cache::room_state_cache; use ruma::{ events::{room::message::RoomMessageEventContent, RoomAccountDataEventType}, - RoomAliasId, RoomId, ServerName, UserId, + OwnedServerName, RoomAliasId, RoomId, ServerName, UserId, }; use self::{ - account_data::account_data, appservice::appservice, globals::globals, presence::presence, room_alias::room_alias, - sending::sending, users::users, + account_data::account_data, appservice::appservice, globals::globals, presence::presence, resolver::resolver, + room_alias::room_alias, sending::sending, users::users, }; #[cfg_attr(test, derive(Debug))] @@ -55,6 +56,10 @@ pub(super) enum QueryCommand { /// - users.rs iterators and getters #[command(subcommand)] Users(Users), + + /// - resolver service + #[command(subcommand)] + Resolver(Resolver), } #[cfg_attr(test, derive(Debug))] @@ -287,6 +292,21 @@ pub(super) enum Users { Iter, } +#[cfg_attr(test, derive(Debug))] +#[derive(Subcommand)] +/// Resolver service and caches +pub(super) enum Resolver { + /// Query the destinations cache + DestinationsCache { + server_name: Option, + }, + + /// Query the overrides cache + OverridesCache { + name: Option, + }, +} + /// Processes admin query commands pub(super) async fn process(command: QueryCommand, _body: Vec<&str>) -> Result { Ok(match command { @@ -298,5 +318,6 @@ pub(super) async fn process(command: QueryCommand, _body: Vec<&str>) -> Result globals(command).await?, QueryCommand::Sending(command) => sending(command).await?, QueryCommand::Users(command) => users(command).await?, + QueryCommand::Resolver(command) => resolver(command).await?, }) } diff --git a/src/admin/query/resolver.rs b/src/admin/query/resolver.rs new file mode 100644 index 000000000..2a2554b5f --- /dev/null +++ b/src/admin/query/resolver.rs @@ -0,0 +1,87 @@ +use std::fmt::Write; + +use conduit::{utils::time, Result}; +use ruma::{events::room::message::RoomMessageEventContent, OwnedServerName}; + +use super::Resolver; +use crate::services; + +/// All the getters and iterators in key_value/users.rs +pub(super) async fn resolver(subcommand: Resolver) -> Result { + match subcommand { + Resolver::DestinationsCache { + server_name, + } => destinations_cache(server_name).await, + Resolver::OverridesCache { + name, + } => overrides_cache(name).await, + } +} + +async fn destinations_cache(server_name: Option) -> Result { + use service::sending::CachedDest; + + let mut out = String::new(); + writeln!(out, "| Server Name | Destination | Hostname | Expires |")?; + writeln!(out, "| ----------- | ----------- | -------- | ------- |")?; + let row = |( + name, + &CachedDest { + ref dest, + ref host, + expire, + }, + )| { + let expire = time::format(expire, "%+"); + writeln!(out, "| {name} | {dest} | {host} | {expire} |").expect("wrote line"); + }; + + let map = services() + .globals + .resolver + .destinations + .read() + .expect("locked"); + + if let Some(server_name) = server_name.as_ref() { + map.get_key_value(server_name).map(row); + } else { + map.iter().for_each(row); + } + + Ok(RoomMessageEventContent::notice_markdown(out)) +} + +async fn overrides_cache(server_name: Option) -> Result { + use service::sending::CachedOverride; + + let mut out = String::new(); + writeln!(out, "| Server Name | IP | Port | Expires |")?; + writeln!(out, "| ----------- | --- | ----:| ------- |")?; + let row = |( + name, + &CachedOverride { + ref ips, + port, + expire, + }, + )| { + let expire = time::format(expire, "%+"); + writeln!(out, "| {name} | {ips:?} | {port} | {expire} |").expect("wrote line"); + }; + + let map = services() + .globals + .resolver + .overrides + .read() + .expect("locked"); + + if let Some(server_name) = server_name.as_ref() { + map.get_key_value(server_name).map(row); + } else { + map.iter().for_each(row); + } + + Ok(RoomMessageEventContent::notice_markdown(out)) +}