mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-22 17:48:56 +01:00
cli: improve code tunnel with existing tunnels (#188091)
- Apply the name/tunnel-name from the CLI to automatically (do a normal tag sync). Previously the CLI could host tunnels that were unusable unless the consumer did the tag setup, which they should not. - Allow "tunnel ID" to be specified in the new `<id>.<cluster>` format that devtunnels has adopted.
This commit is contained in:
@@ -548,6 +548,7 @@ pub enum OutputFormat {
|
||||
#[derive(Args, Clone, Debug, Default)]
|
||||
pub struct ExistingTunnelArgs {
|
||||
/// Name you'd like to assign preexisting tunnel to use to connect the tunnel
|
||||
/// Old option, new code sohuld just use `--name`.
|
||||
#[clap(long, hide = true)]
|
||||
pub tunnel_name: Option<String>,
|
||||
|
||||
|
||||
@@ -59,20 +59,31 @@ impl From<AuthProvider> for crate::auth::AuthProvider {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExistingTunnelArgs> for Option<dev_tunnels::ExistingTunnel> {
|
||||
fn from(d: ExistingTunnelArgs) -> Option<dev_tunnels::ExistingTunnel> {
|
||||
if let (Some(tunnel_id), Some(tunnel_name), Some(cluster), Some(host_token)) =
|
||||
(d.tunnel_id, d.tunnel_name, d.cluster, d.host_token)
|
||||
{
|
||||
fn fulfill_existing_tunnel_args(
|
||||
d: ExistingTunnelArgs,
|
||||
name_arg: &Option<String>,
|
||||
) -> Option<dev_tunnels::ExistingTunnel> {
|
||||
let tunnel_name = d.tunnel_name.or_else(|| name_arg.clone());
|
||||
|
||||
match (d.tunnel_id, d.cluster, d.host_token) {
|
||||
(Some(tunnel_id), None, Some(host_token)) => {
|
||||
let i = tunnel_id.find('.')?;
|
||||
Some(dev_tunnels::ExistingTunnel {
|
||||
tunnel_id,
|
||||
tunnel_id: tunnel_id[..i].to_string(),
|
||||
cluster: tunnel_id[i + 1..].to_string(),
|
||||
tunnel_name,
|
||||
host_token,
|
||||
cluster,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
(Some(tunnel_id), Some(cluster), Some(host_token)) => Some(dev_tunnels::ExistingTunnel {
|
||||
tunnel_id,
|
||||
tunnel_name,
|
||||
host_token,
|
||||
cluster,
|
||||
}),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,8 +423,10 @@ async fn serve_with_csa(
|
||||
let auth = Auth::new(&paths, log.clone());
|
||||
let mut dt = dev_tunnels::DevTunnels::new(&log, auth, &paths);
|
||||
loop {
|
||||
let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() {
|
||||
dt.start_existing_tunnel(d).await
|
||||
let tunnel = if let Some(t) =
|
||||
fulfill_existing_tunnel_args(gateway_args.tunnel.clone(), &gateway_args.name)
|
||||
{
|
||||
dt.start_existing_tunnel(t).await
|
||||
} else {
|
||||
dt.start_new_launcher_tunnel(gateway_args.name.as_deref(), gateway_args.random_name)
|
||||
.await
|
||||
|
||||
@@ -229,7 +229,7 @@ lazy_static! {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExistingTunnel {
|
||||
/// Name you'd like to assign preexisting tunnel to use to connect to the VS Code Server
|
||||
pub tunnel_name: String,
|
||||
pub tunnel_name: Option<String>,
|
||||
|
||||
/// Token to authenticate and use preexisting tunnel
|
||||
pub host_token: String,
|
||||
@@ -393,7 +393,12 @@ impl DevTunnels {
|
||||
};
|
||||
|
||||
tunnel = self
|
||||
.sync_tunnel_tags(&persisted.name, tunnel, &HOST_TUNNEL_REQUEST_OPTIONS)
|
||||
.sync_tunnel_tags(
|
||||
&self.client,
|
||||
&persisted.name,
|
||||
tunnel,
|
||||
&HOST_TUNNEL_REQUEST_OPTIONS,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let locator = TunnelLocator::try_from(&tunnel).unwrap();
|
||||
@@ -532,6 +537,7 @@ impl DevTunnels {
|
||||
/// other version tags.
|
||||
async fn sync_tunnel_tags(
|
||||
&self,
|
||||
client: &TunnelManagementClient,
|
||||
name: &str,
|
||||
tunnel: Tunnel,
|
||||
options: &TunnelRequestOptions,
|
||||
@@ -558,7 +564,7 @@ impl DevTunnels {
|
||||
let result = spanf!(
|
||||
self.log,
|
||||
self.log.span("dev-tunnel.protocol-tag-update"),
|
||||
self.client.update_tunnel(&tunnel_update, options)
|
||||
client.update_tunnel(&tunnel_update, options)
|
||||
);
|
||||
|
||||
result.map_err(|e| wrap(e, "tunnel tag update failed").into())
|
||||
@@ -639,6 +645,12 @@ impl DevTunnels {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_placeholder_name() -> String {
|
||||
let mut n = clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy());
|
||||
n.make_ascii_lowercase();
|
||||
n
|
||||
}
|
||||
|
||||
async fn get_name_for_tunnel(
|
||||
&mut self,
|
||||
preferred_name: Option<&str>,
|
||||
@@ -670,10 +682,7 @@ impl DevTunnels {
|
||||
use_random_name = true;
|
||||
}
|
||||
|
||||
let mut placeholder_name =
|
||||
clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy());
|
||||
placeholder_name.make_ascii_lowercase();
|
||||
|
||||
let mut placeholder_name = Self::get_placeholder_name();
|
||||
if !is_name_free(&placeholder_name) {
|
||||
for i in 2.. {
|
||||
let fixed_name = format!("{}{}", placeholder_name, i);
|
||||
@@ -715,7 +724,10 @@ impl DevTunnels {
|
||||
tunnel: ExistingTunnel,
|
||||
) -> Result<ActiveTunnel, AnyError> {
|
||||
let tunnel_details = PersistedTunnel {
|
||||
name: tunnel.tunnel_name,
|
||||
name: match tunnel.tunnel_name {
|
||||
Some(n) => n,
|
||||
None => Self::get_placeholder_name(),
|
||||
},
|
||||
id: tunnel.tunnel_id,
|
||||
cluster: tunnel.cluster,
|
||||
};
|
||||
@@ -725,10 +737,23 @@ impl DevTunnels {
|
||||
tunnel.host_token.clone(),
|
||||
));
|
||||
|
||||
let client = mgmt.into();
|
||||
self.sync_tunnel_tags(
|
||||
&client,
|
||||
&tunnel_details.name,
|
||||
Tunnel {
|
||||
cluster_id: Some(tunnel_details.cluster.clone()),
|
||||
tunnel_id: Some(tunnel_details.id.clone()),
|
||||
..Default::default()
|
||||
},
|
||||
&HOST_TUNNEL_REQUEST_OPTIONS,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.start_tunnel(
|
||||
tunnel_details.locator(),
|
||||
&tunnel_details,
|
||||
mgmt.into(),
|
||||
client,
|
||||
StaticAccessTokenProvider::new(tunnel.host_token),
|
||||
)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user