Skip to content

Commit ad8be4d

Browse files
committed
feat(services): publish authoritative application origins
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
1 parent b8e0f49 commit ad8be4d

38 files changed

Lines changed: 1795 additions & 757 deletions

File tree

‎crates/openshell-cli/src/run.rs‎

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,17 @@ pub async fn sandbox_create(
723723
Err(status) => return Err(miette::miette!(status.to_string())),
724724
};
725725
let response = response.into_inner();
726+
let application_service_urls = response.application_service_urls;
726727
let service_urls = response
727728
.service_urls
728729
.into_iter()
729-
.map(|(service, url)| (service, service_url_for_gateway(&url, &effective_server)))
730+
.map(|(service, url)| {
731+
let url = application_service_urls
732+
.get(&service)
733+
.cloned()
734+
.unwrap_or_else(|| service_url_for_gateway(&url, &effective_server));
735+
(service, url)
736+
})
730737
.collect::<HashMap<_, _>>();
731738
let sandbox = response
732739
.sandbox
@@ -1115,10 +1122,7 @@ pub async fn sandbox_create(
11151122
"\u{2713}".green().bold(),
11161123
);
11171124
if let Some(url) = service_urls.get("").filter(|url| !url.is_empty()) {
1118-
eprintln!(
1119-
" Access at: {}",
1120-
service_url_for_gateway(url, &effective_server)
1121-
);
1125+
eprintln!(" Access at: {url}");
11221126
}
11231127
}
11241128

@@ -4361,7 +4365,7 @@ pub async fn service_expose(
43614365
);
43624366
}
43634367
if !response.url.is_empty() {
4364-
let url = service_url_for_gateway(&response.url, server);
4368+
let url = preferred_service_url(&response, server);
43654369
println!(" URL: {}", url.cyan());
43664370
}
43674371
Ok(())
@@ -4574,7 +4578,7 @@ fn print_service_endpoint_table(
45744578
let url = if response.url.is_empty() {
45754579
String::new()
45764580
} else {
4577-
service_url_for_gateway(&response.url, gateway_endpoint)
4581+
preferred_service_url(response, gateway_endpoint)
45784582
};
45794583
Some((
45804584
workspace.to_string(),
@@ -4665,7 +4669,7 @@ fn service_endpoint_to_json(
46654669
let url = if response.url.is_empty() {
46664670
String::new()
46674671
} else {
4668-
service_url_for_gateway(&response.url, gateway_endpoint)
4672+
preferred_service_url(response, gateway_endpoint)
46694673
};
46704674

46714675
Some(serde_json::json!({
@@ -4675,6 +4679,8 @@ fn service_endpoint_to_json(
46754679
"target_port": endpoint.target_port,
46764680
"authorization_mode": service_authorization_mode_name(endpoint.authorization_mode),
46774681
"url": url,
4682+
"application_url": response.application_url,
4683+
"gateway_url": service_url_for_gateway(&response.gateway_url, gateway_endpoint),
46784684
}))
46794685
}
46804686

@@ -4689,13 +4695,16 @@ fn service_authorization_mode_name(mode: i32) -> &'static str {
46894695
}
46904696
}
46914697

4692-
/// Read gcloud Application Default Credentials from disk.
4693-
///
4694-
/// Returns `(client_id, client_secret, refresh_token)`.
4695-
///
4696-
/// Checks `GOOGLE_APPLICATION_CREDENTIALS` first; falls back to
4697-
/// `$CLOUDSDK_CONFIG/application_default_credentials.json` when set, then to
4698-
/// `~/.config/gcloud/application_default_credentials.json`.
4698+
/// Application origins are independent of the gateway transport. Only legacy
4699+
/// gateway URLs inherit a caller's external gateway port.
4700+
fn preferred_service_url(response: &ServiceEndpointResponse, gateway: &str) -> String {
4701+
if response.application_url.is_empty() {
4702+
service_url_for_gateway(&response.url, gateway)
4703+
} else {
4704+
response.application_url.clone()
4705+
}
4706+
}
4707+
46994708
fn service_url_for_gateway(service_url: &str, gateway_endpoint: &str) -> String {
47004709
let (Ok(mut service_url), Ok(gateway_endpoint)) = (
47014710
url::Url::parse(service_url),
@@ -7324,6 +7333,8 @@ mod tests {
73247333
#[test]
73257334
fn service_endpoint_json_has_raw_fields_and_normalized_url() {
73267335
let response = ServiceEndpointResponse {
7336+
application_url: String::new(),
7337+
gateway_url: String::new(),
73277338
endpoint: Some(ServiceEndpoint {
73287339
metadata: Some(ObjectMeta {
73297340
workspace: "team-a".to_string(),
@@ -7349,6 +7360,8 @@ mod tests {
73497360
"target_port": 8080,
73507361
"authorization_mode": "bearer_passthrough",
73517362
"url": "https://api.openshell.localhost:17670/",
7363+
"application_url": "",
7364+
"gateway_url": "",
73527365
})
73537366
);
73547367
assert!(service_endpoint_to_json(&ServiceEndpointResponse::default(), "unused").is_none());
@@ -8108,6 +8121,20 @@ mod tests {
81088121
assert!(rootfs_tar_sources_supported_for_gateway(None));
81098122
}
81108123

8124+
#[test]
8125+
fn application_origin_is_preserved_when_gateway_uses_a_port_forward() {
8126+
let response = ServiceEndpointResponse {
8127+
application_url: "https://default--demo--web.services.example.com:10443/".into(),
8128+
gateway_url: "https://default--demo--web.api.example.com:8080/".into(),
8129+
url: "https://default--demo--web.services.example.com:10443/".into(),
8130+
..Default::default()
8131+
};
8132+
assert_eq!(
8133+
super::preferred_service_url(&response, "https://localhost:29092"),
8134+
response.application_url
8135+
);
8136+
}
8137+
81118138
#[test]
81128139
fn service_url_for_gateway_uses_external_gateway_port() {
81138140
assert_eq!(

‎crates/openshell-cli/tests/provider_commands_integration.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ impl OpenShell for TestOpenShell {
378378
let name = request.name;
379379
// Return a minimal sandbox with metadata for CAS operations
380380
Ok(Response::new(SandboxResponse {
381+
application_service_urls: HashMap::new(),
382+
gateway_service_urls: HashMap::new(),
381383
sandbox: Some(Sandbox {
382384
metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta {
383385
id: format!("sb-{name}"),

‎crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ impl OpenShell for TestOpenShell {
237237
},
238238
);
239239
Ok(Response::new(SandboxResponse {
240+
application_service_urls: HashMap::new(),
241+
gateway_service_urls: HashMap::new(),
240242
sandbox: Some(sandbox),
241243
service_urls,
242244
}))
@@ -291,6 +293,8 @@ impl OpenShell for TestOpenShell {
291293
};
292294
sandbox.set_phase(SandboxPhase::Ready as i32);
293295
Ok(Response::new(SandboxResponse {
296+
application_service_urls: HashMap::new(),
297+
gateway_service_urls: HashMap::new(),
294298
sandbox: Some(sandbox),
295299
service_urls: HashMap::new(),
296300
}))
@@ -527,6 +531,8 @@ impl OpenShell for TestOpenShell {
527531
.push(request.into_inner());
528532
Ok(Response::new(
529533
openshell_core::proto::ServiceEndpointResponse {
534+
application_url: String::new(),
535+
gateway_url: String::new(),
530536
url: "https://default--sandbox.openshell.localhost:17670/".to_string(),
531537
..Default::default()
532538
},
@@ -539,6 +545,8 @@ impl OpenShell for TestOpenShell {
539545
) -> Result<Response<openshell_core::proto::ServiceEndpointResponse>, Status> {
540546
Ok(Response::new(
541547
openshell_core::proto::ServiceEndpointResponse {
548+
application_url: String::new(),
549+
gateway_url: String::new(),
542550
url: "https://default--sandbox.openshell.localhost:17670/".to_string(),
543551
..Default::default()
544552
},

‎crates/openshell-cli/tests/sandbox_exec_streaming_integration.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ macro_rules! mock_gateway {
188188
async fn get_sandbox(&self, _: Request<proto::GetSandboxRequest>) -> Result<Response<proto::SandboxResponse>, Status> {
189189
self.calls.lock().unwrap().lookups += 1;
190190
Ok(Response::new(proto::SandboxResponse {
191+
application_service_urls: std::collections::HashMap::new(),
192+
gateway_service_urls: std::collections::HashMap::new(),
191193
sandbox: Some(proto::Sandbox {
192194
metadata: Some(proto::datamodel::v1::ObjectMeta {
193195
id: "test-id".to_string(),

‎crates/openshell-cli/tests/sandbox_name_fallback_integration.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ impl OpenShell for TestOpenShell {
187187
let name = request.name.clone();
188188
*self.state.last_get_name.lock().await = Some(name.clone());
189189
Ok(Response::new(SandboxResponse {
190+
application_service_urls: std::collections::HashMap::new(),
191+
gateway_service_urls: std::collections::HashMap::new(),
190192
sandbox: Some(Sandbox {
191193
metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta {
192194
id: "test-id".to_string(),

0 commit comments

Comments
 (0)