Skip to content

Commit 10b017e

Browse files
tillrohrmannclaude
andcommitted
fix: route Knative service URLs through cloud tunnel when using Restate Cloud
The Knative reconciler was passing the raw in-cluster Route URL directly to register_service_with_restate, which Restate Cloud cannot reach. This adds maybe_tunnel_url() to RestateAdminEndpoint and uses it in the Knative path, matching the existing ReplicaSet behavior. Also simplifies service_url() to use the same method internally. Closes #120 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c21405d commit 10b017e

2 files changed

Lines changed: 35 additions & 21 deletions

File tree

src/controllers/restatedeployment/reconcilers/knative.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,11 @@ async fn register_or_lookup_deployment(
662662
})?;
663663

664664
let url = Url::parse(url_str)?;
665+
let url = rsd
666+
.spec
667+
.restate
668+
.register
669+
.maybe_tunnel_url(&ctx.rce_store, url)?;
665670

666671
let deployment_id = rsd
667672
.register_service_with_restate(ctx, &url, rsd.spec.restate.use_http11.as_ref().cloned())

src/resources/restatedeployments.rs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -374,30 +374,39 @@ impl RestateAdminEndpoint {
374374
service_path: Option<&str>,
375375
cluster_dns: &str,
376376
) -> crate::Result<Url> {
377-
match (
378-
self.cluster.as_deref(),
379-
self.cloud.as_deref(),
380-
self.service.as_ref(),
381-
self.url.as_ref(),
382-
) {
383-
(Some(_), None, None, None)
384-
| (None, None, Some(_), None)
385-
| (None, None, None, Some(_)) => {
386-
Ok(service_url(service_name, service_namespace, 9080, service_path, cluster_dns)?)
387-
}
388-
(None, Some(cloud), None, None) => {
389-
let Some(rce) = rce_store.get(&ObjectRef::new(cloud)) else {
390-
return Err(crate::Error::RestateCloudEnvironmentNotFound(cloud.into()))
391-
};
392-
393-
let service_url = service_url(service_name, service_namespace, 9080, service_path, cluster_dns)?;
377+
self.validate_exactly_one_set()?;
378+
let url = service_url(service_name, service_namespace, 9080, service_path, cluster_dns)?;
379+
self.maybe_tunnel_url(rce_store, url)
380+
}
394381

395-
Ok(rce.tunnel_url(service_url)?)
396-
}
397-
_ => Err(crate::Error::InvalidRestateConfig(
382+
fn validate_exactly_one_set(&self) -> crate::Result<()> {
383+
let count = self.cluster.is_some() as u8
384+
+ self.cloud.is_some() as u8
385+
+ self.service.is_some() as u8
386+
+ self.url.is_some() as u8;
387+
if count != 1 {
388+
return Err(crate::Error::InvalidRestateConfig(
398389
"Exactly one of `cluster`, `cloud`, `service` or `url` must be specified in spec.restate"
399390
.into(),
400-
)),
391+
));
392+
}
393+
Ok(())
394+
}
395+
396+
/// If this endpoint is configured to use Restate Cloud, rewrite the given URL
397+
/// to go through the cloud tunnel. Otherwise, return the URL unchanged.
398+
pub fn maybe_tunnel_url(
399+
&self,
400+
rce_store: &Store<RestateCloudEnvironment>,
401+
url: Url,
402+
) -> crate::Result<Url> {
403+
if let Some(cloud) = self.cloud.as_deref() {
404+
let Some(rce) = rce_store.get(&ObjectRef::new(cloud)) else {
405+
return Err(crate::Error::RestateCloudEnvironmentNotFound(cloud.into()));
406+
};
407+
Ok(rce.tunnel_url(url)?)
408+
} else {
409+
Ok(url)
401410
}
402411
}
403412

0 commit comments

Comments
 (0)