Implement opt-in overlay TUN runtime
This commit is contained in:
parent
c2dee50dae
commit
d9728a326d
15 changed files with 2315 additions and 84 deletions
|
|
@ -24,6 +24,7 @@ geth-discovery = { path = "../geth-discovery" }
|
|||
geth-iroh = { path = "../geth-iroh" }
|
||||
geth-keychain = { path = "../geth-keychain" }
|
||||
geth-node = { path = "../geth-node" }
|
||||
geth-overlay = { path = "../geth-overlay" }
|
||||
geth-ssh-identity = { path = "../geth-ssh-identity" }
|
||||
geth-store = { path = "../geth-store" }
|
||||
geth-types = { path = "../geth-types" }
|
||||
|
|
|
|||
|
|
@ -1446,7 +1446,135 @@ fn overlay_plan_is_available_without_starting_packet_runtime() {
|
|||
assert_eq!(plan.resource.to_string(), "resource:overlay:home-lan");
|
||||
assert_eq!(plan.alpn, "/geth/overlay/1");
|
||||
assert!(plan.capabilities.contains(&"overlay.join".to_owned()));
|
||||
assert!(plan.runtime.contains("no TUN/Wintun"));
|
||||
assert!(plan.runtime.contains("overlay up"));
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_join_persists_membership_resource_and_leave_state() {
|
||||
let home = tempfile::tempdir().expect("tempdir");
|
||||
let paths = geth_config::GethPaths::from_home(home.path());
|
||||
let node = geth_node::init_node(&paths).expect("init node");
|
||||
|
||||
let joined = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::OverlayJoin {
|
||||
name: "home-lan".to_owned(),
|
||||
secret: "local-bootstrap-secret".to_owned(),
|
||||
cidr: Some("172.22.0.0/24".to_owned()),
|
||||
},
|
||||
)
|
||||
.expect("overlay join");
|
||||
match joined {
|
||||
geth_control::ControlResponse::OverlayJoined { join } => {
|
||||
assert!(join.enabled);
|
||||
assert_eq!(join.plan.resource.to_string(), "resource:overlay:home-lan");
|
||||
assert_eq!(join.network.state, geth_overlay::OverlayState::Joined);
|
||||
assert!(join.network.virtual_ip.is_some());
|
||||
assert!(join.note.contains("local bootstrap overlay"));
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
|
||||
let resources = geth_node::handle_request(&node, geth_control::ControlRequest::ResourceList)
|
||||
.expect("resource list");
|
||||
match resources {
|
||||
geth_control::ControlResponse::ResourceList { resources } => {
|
||||
assert!(resources.iter().any(|resource| {
|
||||
resource.id.to_string() == "resource:overlay:home-lan"
|
||||
&& resource.kind == geth_types::ResourceKind::Overlay
|
||||
}));
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
|
||||
let status = geth_node::handle_request(&node, geth_control::ControlRequest::OverlayStatus)
|
||||
.expect("overlay status");
|
||||
match status {
|
||||
geth_control::ControlResponse::OverlayStatus { networks, note } => {
|
||||
assert_eq!(networks.len(), 1);
|
||||
assert_eq!(networks[0].state, geth_overlay::OverlayState::Joined);
|
||||
assert!(note.contains("persisted locally"));
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
|
||||
geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::OverlayLeave {
|
||||
name: "home-lan".to_owned(),
|
||||
},
|
||||
)
|
||||
.expect("overlay leave");
|
||||
let status = geth_node::handle_request(&node, geth_control::ControlRequest::OverlayStatus)
|
||||
.expect("overlay status after leave");
|
||||
match status {
|
||||
geth_control::ControlResponse::OverlayStatus { networks, .. } => {
|
||||
assert_eq!(networks.len(), 1);
|
||||
assert_eq!(networks[0].state, geth_overlay::OverlayState::Stopped);
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_join_uses_bearer_invite_when_one_exists() {
|
||||
let home = tempfile::tempdir().expect("tempdir");
|
||||
let paths = geth_config::GethPaths::from_home(home.path());
|
||||
let node = geth_node::init_node(&paths).expect("init node");
|
||||
let resource = "resource:overlay:locked".to_owned();
|
||||
|
||||
geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::ResourceCreate {
|
||||
kind: "overlay".to_owned(),
|
||||
name: "locked".to_owned(),
|
||||
},
|
||||
)
|
||||
.expect("create overlay resource");
|
||||
let access = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::SecretBearerCreate {
|
||||
resource: resource.clone(),
|
||||
capabilities: vec!["overlay.join".to_owned()],
|
||||
expires_at_ms: None,
|
||||
},
|
||||
)
|
||||
.expect("create bearer invite");
|
||||
let token = match access {
|
||||
geth_control::ControlResponse::SecretBearerCreated { access } => {
|
||||
access.token.expect("private bearer token").to_string()
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
};
|
||||
|
||||
let denied = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::OverlayJoin {
|
||||
name: "locked".to_owned(),
|
||||
secret: "wrong-token".to_owned(),
|
||||
cidr: None,
|
||||
},
|
||||
)
|
||||
.expect_err("bad bearer should be rejected");
|
||||
assert!(denied.to_string().contains("overlay join requires"));
|
||||
|
||||
let joined = geth_node::handle_request(
|
||||
&node,
|
||||
geth_control::ControlRequest::OverlayJoin {
|
||||
name: "locked".to_owned(),
|
||||
secret: token,
|
||||
cidr: None,
|
||||
},
|
||||
)
|
||||
.expect("authorized overlay join");
|
||||
match joined {
|
||||
geth_control::ControlResponse::OverlayJoined { join } => {
|
||||
assert!(join.enabled);
|
||||
assert_eq!(join.network.state, geth_overlay::OverlayState::Joined);
|
||||
assert!(join.note.contains("bearer overlay.join authorization"));
|
||||
}
|
||||
other => panic!("unexpected response: {other:?}"),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue