refactor: remove proxy admin endpoint (#13687)

## Summary
- delete the network proxy admin server and its runtime listener/task
plumbing
- remove the admin endpoint config, runtime, requirement, protocol,
schema, and debug-surface fields
- update proxy docs to reflect the remaining HTTP and SOCKS listeners
only
This commit is contained in:
viyatb-oai
2026-03-05 22:03:16 -08:00
committed by GitHub
parent f9ce403b5a
commit 6a79ed5920
24 changed files with 30 additions and 476 deletions

View File

@@ -1,4 +1,3 @@
use crate::admin;
use crate::config;
use crate::http_proxy;
use crate::network_policy::NetworkPolicyDecider;
@@ -26,15 +25,13 @@ pub struct Args {}
struct ReservedListeners {
http: Mutex<Option<StdTcpListener>>,
socks: Mutex<Option<StdTcpListener>>,
admin: Mutex<Option<StdTcpListener>>,
}
impl ReservedListeners {
fn new(http: StdTcpListener, socks: Option<StdTcpListener>, admin: StdTcpListener) -> Self {
fn new(http: StdTcpListener, socks: Option<StdTcpListener>) -> Self {
Self {
http: Mutex::new(Some(http)),
socks: Mutex::new(socks),
admin: Mutex::new(Some(admin)),
}
}
@@ -53,14 +50,6 @@ impl ReservedListeners {
.unwrap_or_else(std::sync::PoisonError::into_inner);
guard.take()
}
fn take_admin(&self) -> Option<StdTcpListener> {
let mut guard = self
.admin
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
guard.take()
}
}
#[derive(Clone)]
@@ -68,7 +57,6 @@ pub struct NetworkProxyBuilder {
state: Option<Arc<NetworkProxyState>>,
http_addr: Option<SocketAddr>,
socks_addr: Option<SocketAddr>,
admin_addr: Option<SocketAddr>,
managed_by_codex: bool,
policy_decider: Option<Arc<dyn NetworkPolicyDecider>>,
blocked_request_observer: Option<Arc<dyn BlockedRequestObserver>>,
@@ -80,7 +68,6 @@ impl Default for NetworkProxyBuilder {
state: None,
http_addr: None,
socks_addr: None,
admin_addr: None,
managed_by_codex: true,
policy_decider: None,
blocked_request_observer: None,
@@ -104,11 +91,6 @@ impl NetworkProxyBuilder {
self
}
pub fn admin_addr(mut self, addr: SocketAddr) -> Self {
self.admin_addr = Some(addr);
self
}
pub fn managed_by_codex(mut self, managed_by_codex: bool) -> Self {
self.managed_by_codex = managed_by_codex;
self
@@ -153,10 +135,10 @@ impl NetworkProxyBuilder {
.set_blocked_request_observer(self.blocked_request_observer.clone())
.await;
let current_cfg = state.current_cfg().await?;
let (requested_http_addr, requested_socks_addr, requested_admin_addr, reserved_listeners) =
let (requested_http_addr, requested_socks_addr, reserved_listeners) =
if self.managed_by_codex {
let runtime = config::resolve_runtime(&current_cfg)?;
let (http_listener, socks_listener, admin_listener) =
let (http_listener, socks_listener) =
reserve_loopback_ephemeral_listeners(current_cfg.network.enable_socks5)
.context("reserve managed loopback proxy listeners")?;
let http_addr = http_listener
@@ -169,17 +151,12 @@ impl NetworkProxyBuilder {
} else {
runtime.socks_addr
};
let admin_addr = admin_listener
.local_addr()
.context("failed to read reserved admin API address")?;
(
http_addr,
socks_addr,
admin_addr,
Some(Arc::new(ReservedListeners::new(
http_listener,
socks_listener,
admin_listener,
))),
)
} else {
@@ -187,16 +164,14 @@ impl NetworkProxyBuilder {
(
self.http_addr.unwrap_or(runtime.http_addr),
self.socks_addr.unwrap_or(runtime.socks_addr),
self.admin_addr.unwrap_or(runtime.admin_addr),
None,
)
};
// Reapply bind clamping for caller overrides so unix-socket proxying stays loopback-only.
let (http_addr, socks_addr, admin_addr) = config::clamp_bind_addrs(
let (http_addr, socks_addr) = config::clamp_bind_addrs(
requested_http_addr,
requested_socks_addr,
requested_admin_addr,
&current_cfg.network,
);
@@ -210,7 +185,6 @@ impl NetworkProxyBuilder {
dangerously_allow_all_unix_sockets: current_cfg
.network
.dangerously_allow_all_unix_sockets,
admin_addr,
reserved_listeners,
policy_decider: self.policy_decider,
})
@@ -219,7 +193,7 @@ impl NetworkProxyBuilder {
fn reserve_loopback_ephemeral_listeners(
reserve_socks_listener: bool,
) -> Result<(StdTcpListener, Option<StdTcpListener>, StdTcpListener)> {
) -> Result<(StdTcpListener, Option<StdTcpListener>)> {
let http_listener =
reserve_loopback_ephemeral_listener().context("reserve HTTP proxy listener")?;
let socks_listener = if reserve_socks_listener {
@@ -227,9 +201,7 @@ fn reserve_loopback_ephemeral_listeners(
} else {
None
};
let admin_listener =
reserve_loopback_ephemeral_listener().context("reserve admin API listener")?;
Ok((http_listener, socks_listener, admin_listener))
Ok((http_listener, socks_listener))
}
fn reserve_loopback_ephemeral_listener() -> Result<StdTcpListener> {
@@ -246,7 +218,6 @@ pub struct NetworkProxy {
allow_local_binding: bool,
allow_unix_sockets: Vec<String>,
dangerously_allow_all_unix_sockets: bool,
admin_addr: SocketAddr,
reserved_listeners: Option<Arc<ReservedListeners>>,
policy_decider: Option<Arc<dyn NetworkPolicyDecider>>,
}
@@ -258,7 +229,6 @@ impl std::fmt::Debug for NetworkProxy {
f.debug_struct("NetworkProxy")
.field("http_addr", &self.http_addr)
.field("socks_addr", &self.socks_addr)
.field("admin_addr", &self.admin_addr)
.finish_non_exhaustive()
}
}
@@ -268,7 +238,6 @@ impl PartialEq for NetworkProxy {
self.http_addr == other.http_addr
&& self.socks_addr == other.socks_addr
&& self.allow_local_binding == other.allow_local_binding
&& self.admin_addr == other.admin_addr
}
}
@@ -421,10 +390,6 @@ impl NetworkProxy {
self.socks_addr
}
pub fn admin_addr(&self) -> SocketAddr {
self.admin_addr
}
pub async fn add_allowed_domain(&self, host: &str) -> Result<()> {
self.state.add_allowed_domain(host).await
}
@@ -475,7 +440,6 @@ impl NetworkProxy {
let reserved_listeners = self.reserved_listeners.as_ref();
let http_listener = reserved_listeners.and_then(|listeners| listeners.take_http());
let socks_listener = reserved_listeners.and_then(|listeners| listeners.take_socks());
let admin_listener = reserved_listeners.and_then(|listeners| listeners.take_admin());
let http_state = self.state.clone();
let http_decider = self.policy_decider.clone();
@@ -520,21 +484,10 @@ impl NetworkProxy {
} else {
None
};
let admin_state = self.state.clone();
let admin_addr = self.admin_addr;
let admin_task = tokio::spawn(async move {
match admin_listener {
Some(listener) => {
admin::run_admin_api_with_std_listener(admin_state, listener).await
}
None => admin::run_admin_api(admin_state, admin_addr).await,
}
});
Ok(NetworkProxyHandle {
http_task: Some(http_task),
socks_task,
admin_task: Some(admin_task),
completed: false,
})
}
@@ -543,7 +496,6 @@ impl NetworkProxy {
pub struct NetworkProxyHandle {
http_task: Option<JoinHandle<Result<()>>>,
socks_task: Option<JoinHandle<Result<()>>>,
admin_task: Option<JoinHandle<Result<()>>>,
completed: bool,
}
@@ -552,24 +504,20 @@ impl NetworkProxyHandle {
Self {
http_task: Some(tokio::spawn(async { Ok(()) })),
socks_task: None,
admin_task: Some(tokio::spawn(async { Ok(()) })),
completed: true,
}
}
pub async fn wait(mut self) -> Result<()> {
let http_task = self.http_task.take().context("missing http proxy task")?;
let admin_task = self.admin_task.take().context("missing admin proxy task")?;
let socks_task = self.socks_task.take();
let http_result = http_task.await;
let admin_result = admin_task.await;
let socks_result = match socks_task {
Some(task) => Some(task.await),
None => None,
};
self.completed = true;
http_result??;
admin_result??;
if let Some(socks_result) = socks_result {
socks_result??;
}
@@ -577,12 +525,7 @@ impl NetworkProxyHandle {
}
pub async fn shutdown(mut self) -> Result<()> {
abort_tasks(
self.http_task.take(),
self.socks_task.take(),
self.admin_task.take(),
)
.await;
abort_tasks(self.http_task.take(), self.socks_task.take()).await;
self.completed = true;
Ok(())
}
@@ -598,11 +541,9 @@ async fn abort_task(task: Option<JoinHandle<Result<()>>>) {
async fn abort_tasks(
http_task: Option<JoinHandle<Result<()>>>,
socks_task: Option<JoinHandle<Result<()>>>,
admin_task: Option<JoinHandle<Result<()>>>,
) {
abort_task(http_task).await;
abort_task(socks_task).await;
abort_task(admin_task).await;
}
impl Drop for NetworkProxyHandle {
@@ -612,9 +553,8 @@ impl Drop for NetworkProxyHandle {
}
let http_task = self.http_task.take();
let socks_task = self.socks_task.take();
let admin_task = self.admin_task.take();
tokio::spawn(async move {
abort_tasks(http_task, socks_task, admin_task).await;
abort_tasks(http_task, socks_task).await;
});
}
}
@@ -648,10 +588,8 @@ mod tests {
assert!(proxy.http_addr.ip().is_loopback());
assert!(proxy.socks_addr.ip().is_loopback());
assert!(proxy.admin_addr.ip().is_loopback());
assert_ne!(proxy.http_addr.port(), 0);
assert_ne!(proxy.socks_addr.port(), 0);
assert_ne!(proxy.admin_addr.port(), 0);
}
#[tokio::test]
@@ -659,7 +597,6 @@ mod tests {
let settings = NetworkProxySettings {
proxy_url: "http://127.0.0.1:43128".to_string(),
socks_url: "http://127.0.0.1:48081".to_string(),
admin_url: "http://127.0.0.1:48080".to_string(),
..NetworkProxySettings::default()
};
let state = Arc::new(network_proxy_state_for_policy(settings));
@@ -678,10 +615,6 @@ mod tests {
proxy.socks_addr,
"127.0.0.1:48081".parse::<SocketAddr>().unwrap()
);
assert_eq!(
proxy.admin_addr,
"127.0.0.1:48080".parse::<SocketAddr>().unwrap()
);
}
#[tokio::test]
@@ -706,7 +639,6 @@ mod tests {
};
assert!(proxy.http_addr.ip().is_loopback());
assert!(proxy.admin_addr.ip().is_loopback());
assert_eq!(
proxy.socks_addr,
"127.0.0.1:43129".parse::<SocketAddr>().unwrap()