feat: native Rust bastion tunnel - eliminate az CLI Python dependency (#998)#999
feat: native Rust bastion tunnel - eliminate az CLI Python dependency (#998)#999rysweet wants to merge 2 commits into
Conversation
Implement native WebSocket tunnel in rust/crates/azlin-azure/src/native_tunnel.rs using tokio-tungstenite + tokio, replacing Python az CLI subprocess spawning. - open_tunnel() returns (local_port, JoinHandle) for bidirectional TCP<->WS forwarding - Token exchange and WSS URL construction matching azext_bastion protocol - Integration in bastion_tunnel.rs, cmd_connect.rs, main.rs BastionTunnelPool - Configurable bastion_tunnel_timeout in AzlinConfig (default 30s) - azlin bastion sweep command to clean orphaned az processes from before migration - TunnelType field in registry for native vs legacy tunnel tracking - 25 unit tests + 16 integration tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
handle_client previously hardcoded build_wss_url_standard(), making build_wss_url_developer() dead code. Introduces WssUrlMode enum with NodeScoped (Standard/Premium) and EndpointScoped (Developer) variants to properly route WSS URL construction through open_tunnel. - Add WssUrlMode enum modeling transport behavior, not marketing SKU - Thread url_mode through open_tunnel -> handle_client - Caller passes NodeScoped explicitly (no Default derive to prevent silent fallback) - Add 3 new tests for URL mode variants and routing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Dependency ReviewPR: feat: native Rust bastion tunnel - eliminate az CLI Python dependency (#998) New Dependencies Introduced
Removed Dependencies (Effectively)
Risk AssessmentBreaking changes: Low risk for end users — the tunnel is internal plumbing. The public CLI interface ( Dependency health:
Security posture:
Test coverage: The PR includes Scale of change: 1,978 additions / 315 deletions across 29 files. This is a significant but well-scoped refactor — the core logic is concentrated in Recommendation: Review carefully before mergingThe dependency choices are sound and low-risk. The main review focus should be on:
Overall: The dependency additions (
|
Summary
Replaces all
az network bastion tunnelandaz network bastion sshPython subprocess spawning with a native Rust WebSocket tunnel implementation.Problem
Each
azlin listleaked ~7 orphaned Python processes because/usr/bin/azis a bash wrapper spawning Python. Thechild.kill()Drop only terminated bash, leaving Python alive. Over time this exhausted Azure Bastion connection limits and WSL vsock resources.Solution
Native Rust bastion tunnel using
tokio-tungsteniteWebSocket client that speaks the Azure Bastion tunnel protocol directly. Zero child processes, zero leaks.Changes (1,978+/315- across 29 files)
native_tunnel.rs(458 lines) — Core WebSocket tunnel: Azure AD auth, WSS connection, bidirectional TCP↔WebSocket forwardingnative_tunnel_unit.rs(430 lines) — Comprehensive testsbastion_tunnel.rs— Rewired to use native tunnel instead ofazsubprocessmain.rs— RemovedBastionTunnelPool,pick_unused_local_port,wait_for_local_port_listenercmd_connect.rs— Native tunnel for SSH connections (no moreaz bastion ssh)cmd_list_data.rs— Native tunnel for tmux session enumerationcmd_tunnel.rs— Simplified with native tunnelconfig.rs— Addedbastion_tunnel_timeout(configurable, default 30s)cmd_network.rs— Addedazlin bastion sweepcommandCloses #998
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com