mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(proxy): record tunnel stability metrics
This commit is contained in:
@@ -93,15 +93,6 @@ impl ServerTab {
|
||||
required: true,
|
||||
help: "Node name for identification in Aether dashboard",
|
||||
},
|
||||
Field {
|
||||
label: "Upstream Proxy",
|
||||
key: "upstream_proxy_url",
|
||||
value: String::new(),
|
||||
kind: FieldKind::Text,
|
||||
required: false,
|
||||
help:
|
||||
"Optional provider egress proxy, e.g. http://127.0.0.1:8080 or socks5h://127.0.0.1:1080",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -115,12 +106,6 @@ impl ServerTab {
|
||||
}
|
||||
tab
|
||||
}
|
||||
|
||||
fn set_field_value(&mut self, key: &str, value: &str) {
|
||||
if let Some(field) = self.fields.iter_mut().find(|field| field.key == key) {
|
||||
field.value = value.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- App state ----------------------------------------------------------------
|
||||
@@ -153,6 +138,15 @@ impl App {
|
||||
server_tabs: vec![ServerTab::new()],
|
||||
active_tab: 0,
|
||||
global_fields: vec![
|
||||
Field {
|
||||
label: "Egress Proxy",
|
||||
key: "upstream_proxy_url",
|
||||
value: String::new(),
|
||||
kind: FieldKind::Text,
|
||||
required: false,
|
||||
help:
|
||||
"Optional egress proxy for Aether tunnel/API and provider requests, e.g. http://127.0.0.1:8080 or socks5h://127.0.0.1:1080",
|
||||
},
|
||||
Field {
|
||||
label: "Install Service",
|
||||
key: "install_service",
|
||||
@@ -282,6 +276,7 @@ impl App {
|
||||
"allow_private_targets" => cfg.allow_private_targets.map(|v| v.to_string()),
|
||||
"heartbeat_interval" => cfg.heartbeat_interval.map(|v| v.to_string()),
|
||||
"redirect_replay_budget_bytes" => cfg.redirect_replay_budget_bytes.clone(),
|
||||
"upstream_proxy_url" => cfg.upstream_proxy_url.clone(),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(v) = val {
|
||||
@@ -296,11 +291,6 @@ impl App {
|
||||
} else {
|
||||
self.server_tabs = servers.iter().map(ServerTab::from_entry).collect();
|
||||
}
|
||||
if let Some(proxy_url) = cfg.upstream_proxy_url.as_deref() {
|
||||
for tab in &mut self.server_tabs {
|
||||
tab.set_field_value("upstream_proxy_url", proxy_url);
|
||||
}
|
||||
}
|
||||
self.active_tab = 0;
|
||||
self.selected = 0;
|
||||
self.scroll_offset = 0;
|
||||
@@ -322,12 +312,6 @@ impl App {
|
||||
.filter(|v| !v.is_empty())
|
||||
}
|
||||
|
||||
fn get_shared_server_field(&self, key: &str) -> Option<String> {
|
||||
self.server_tabs
|
||||
.iter()
|
||||
.find_map(|tab| Self::get_tab(tab, key))
|
||||
}
|
||||
|
||||
fn toggle_enabled(&self, key: &str) -> bool {
|
||||
self.get_global(key).as_deref() == Some("true")
|
||||
}
|
||||
@@ -373,7 +357,7 @@ impl App {
|
||||
}
|
||||
|
||||
fn parse_optional_upstream_proxy_url(&self) -> anyhow::Result<Option<String>> {
|
||||
let Some(raw) = self.get_shared_server_field("upstream_proxy_url") else {
|
||||
let Some(raw) = self.get_global("upstream_proxy_url") else {
|
||||
return Ok(None);
|
||||
};
|
||||
let trimmed = raw.trim();
|
||||
@@ -381,7 +365,7 @@ impl App {
|
||||
return Ok(None);
|
||||
}
|
||||
UpstreamProxyConfig::parse(trimmed)
|
||||
.map_err(|err| anyhow::anyhow!("upstream proxy URL invalid: {err}"))?;
|
||||
.map_err(|err| anyhow::anyhow!("egress proxy URL invalid: {err}"))?;
|
||||
Ok(Some(trimmed.to_string()))
|
||||
}
|
||||
|
||||
@@ -613,11 +597,7 @@ impl App {
|
||||
}
|
||||
// -- Add / remove server --
|
||||
KeyCode::Char('+') | KeyCode::Char('a') => {
|
||||
let upstream_proxy_url = self.get_shared_server_field("upstream_proxy_url");
|
||||
let mut tab = ServerTab::new();
|
||||
if let Some(proxy_url) = upstream_proxy_url.as_deref() {
|
||||
tab.set_field_value("upstream_proxy_url", proxy_url);
|
||||
}
|
||||
let tab = ServerTab::new();
|
||||
self.server_tabs.push(tab);
|
||||
self.active_tab = self.server_tabs.len() - 1;
|
||||
self.selected = 0;
|
||||
@@ -694,14 +674,7 @@ impl App {
|
||||
|
||||
fn commit_edit_buffer(&mut self) -> bool {
|
||||
if self.validate_edit() {
|
||||
let key = self.selected_field().key;
|
||||
if key == "upstream_proxy_url" {
|
||||
for tab in &mut self.server_tabs {
|
||||
tab.set_field_value(key, &self.edit_buffer);
|
||||
}
|
||||
} else {
|
||||
self.selected_field_mut().value = self.edit_buffer.clone();
|
||||
}
|
||||
self.selected_field_mut().value = self.edit_buffer.clone();
|
||||
self.modified = true;
|
||||
self.mode = Mode::Normal;
|
||||
true
|
||||
@@ -1124,23 +1097,20 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_app_places_upstream_proxy_under_node_name() {
|
||||
fn new_app_places_egress_proxy_in_global_fields() {
|
||||
let app = sample_app();
|
||||
let keys: Vec<&str> = app.server_tabs[0]
|
||||
let server_keys: Vec<&str> = app.server_tabs[0]
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| field.key)
|
||||
.collect();
|
||||
let global_keys: Vec<&str> = app.global_fields.iter().map(|field| field.key).collect();
|
||||
|
||||
assert_eq!(
|
||||
keys,
|
||||
vec![
|
||||
"aether_url",
|
||||
"management_token",
|
||||
"node_name",
|
||||
"upstream_proxy_url"
|
||||
]
|
||||
server_keys,
|
||||
vec!["aether_url", "management_token", "node_name"]
|
||||
);
|
||||
assert_eq!(global_keys.first().copied(), Some("upstream_proxy_url"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1172,7 +1142,7 @@ mod tests {
|
||||
set_global_field(&mut app, "allow_private_targets", "true");
|
||||
set_global_field(&mut app, "heartbeat_interval", "45");
|
||||
set_global_field(&mut app, "redirect_replay_budget_bytes", "6m");
|
||||
set_server_field(&mut app, "upstream_proxy_url", "socks5h://127.0.0.1:1080");
|
||||
set_global_field(&mut app, "upstream_proxy_url", "socks5h://127.0.0.1:1080");
|
||||
|
||||
let cfg = app.to_config().expect("config should serialize");
|
||||
assert_eq!(cfg.allow_private_targets, Some(true));
|
||||
@@ -1194,14 +1164,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_config_rejects_invalid_upstream_proxy_url() {
|
||||
fn to_config_rejects_invalid_egress_proxy_url() {
|
||||
let mut app = sample_app();
|
||||
set_server_field(&mut app, "upstream_proxy_url", "ftp://proxy.example");
|
||||
set_global_field(&mut app, "upstream_proxy_url", "ftp://proxy.example");
|
||||
|
||||
let error = app
|
||||
.to_config()
|
||||
.expect_err("invalid upstream proxy should be rejected");
|
||||
assert!(error.to_string().contains("upstream proxy URL"));
|
||||
.expect_err("invalid egress proxy should be rejected");
|
||||
assert!(error.to_string().contains("egress proxy URL"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user