Add custom domain support to tunnel management SDKs#605
Merged
DavidObando merged 1 commit intomainfrom Apr 3, 2026
Merged
Conversation
Design ------ When a tunnel service deployment uses a custom domain (e.g. "app.github.dev"), the control-plane URL is derived by prepending "cp." to that domain, producing "https://cp.app.github.dev/". Because custom-domain deployments handle cluster routing at the infrastructure level, the SDK must not rewrite the hostname with a cluster ID the way it does for the standard multi-cluster "global.rel.tunnels.api.visualstudio.com" deployment. Implementation (all five SDKs) ------------------------------ 1. Added an `isCustomDomain` flag to each management client, set automatically in the constructor when the service URI hostname starts with "cp.". 2. The `BuildUri` / `buildUri` / `build_uri` method now skips the cluster-ID-to-hostname rewriting logic when `isCustomDomain` is true, leaving the hostname unchanged. 3. Added a static factory method on each client to construct from a custom domain string: - C#: TunnelManagementClient.ForCustomDomain(domain, ...) - TypeScript: TunnelManagementHttpClient.forCustomDomain(domain, ...) - Go: NewManagerForCustomDomain(domain, ...) - Java: TunnelManagementClient.forCustomDomain(domain, ...) - Rust: new_tunnel_management_for_custom_domain(ua, domain) Each factory validates the domain, builds the "https://cp.{domain}/" service URI, and delegates to the existing constructor/builder. Files changed ------------- cs/src/Management/TunnelManagementClient.cs - Added `isCustomDomain` field, set in constructor. - BuildUri() skips ReplaceTunnelServiceHostnameClusterId when custom domain is detected. - Added ForCustomDomain() static factory. ts/src/management/tunnelManagementHttpClient.ts - Added `isCustomDomain` field, set in constructor. - buildUri() skips cluster-ID hostname manipulation. - Added forCustomDomain() static factory. go/tunnels/manager.go - Added `isCustomDomain` field on Manager struct. - buildUri() skips cluster-ID prepend when true. - Added NewManagerForCustomDomain() function. java/src/.../management/TunnelManagementClient.java - Added `isCustomDomain` field, set in constructor. - buildUri() skips cluster-ID manipulation. - Added forCustomDomain() static factory. rs/src/management/http_client.rs - Added `is_custom_domain` to struct, builder, and From impl. - build_uri() skips cluster-ID rewriting. - Added new_tunnel_management_for_custom_domain() builder fn. - environment() setter auto-detects "cp." prefix. Tests added ----------- Each SDK has two new tests: - Custom domain URI keeps "cp.{domain}" hostname unchanged. - Standard service URI still rewrites hostname with cluster ID. C#: CustomDomainDoesNotModifyHostname, StandardServiceUriReplacesClusterIdInHostname TS: customDomainDoesNotModifyHostname, standardServiceUriReplacesClusterIdInHostname Go: TestCustomDomainDoesNotModifyHostname, TestStandardServiceUriReplacesClusterId Java: forCustomDomainCreatesClient, forCustomDomainRejectsBlank Rust: custom_domain_does_not_modify_hostname, standard_service_uri_replaces_cluster_id
klvnraju
approved these changes
Apr 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design
When a tunnel service deployment uses a custom domain (e.g. "app.github.dev"), the control-plane URL is derived by prepending "cp." to that domain, producing "https://cp.app.github.dev/". Because custom-domain deployments handle cluster routing at the infrastructure level, the SDK must not rewrite the hostname with a cluster ID the way it does for the standard multi-cluster "global.rel.tunnels.api.visualstudio.com" deployment.
Implementation (all five SDKs)
Added an
isCustomDomainflag to each management client, set automatically in the constructor when the service URI hostname starts with "cp.".The
BuildUri/buildUri/build_urimethod now skips the cluster-ID-to-hostname rewriting logic whenisCustomDomainis true, leaving the hostname unchanged.Added a static factory method on each client to construct from a custom domain string:
Each factory validates the domain, builds the "https://cp.{domain}/" service URI, and delegates to the existing constructor/builder.
Files changed
cs/src/Management/TunnelManagementClient.cs
isCustomDomainfield, set in constructor.ts/src/management/tunnelManagementHttpClient.ts
isCustomDomainfield, set in constructor.go/tunnels/manager.go
isCustomDomainfield on Manager struct.java/src/.../management/TunnelManagementClient.java
isCustomDomainfield, set in constructor.rs/src/management/http_client.rs
is_custom_domainto struct, builder, and From impl.Tests added
Each SDK has two new tests:
C#: CustomDomainDoesNotModifyHostname,
StandardServiceUriReplacesClusterIdInHostname
TS: customDomainDoesNotModifyHostname,
standardServiceUriReplacesClusterIdInHostname
Go: TestCustomDomainDoesNotModifyHostname,
TestStandardServiceUriReplacesClusterId
Java: forCustomDomainCreatesClient,
forCustomDomainRejectsBlank
Rust: custom_domain_does_not_modify_hostname,
standard_service_uri_replaces_cluster_id
Other Tasks:
npm view @microsoft/dev-tunnels-contracts). This will fix issues where yarn will pull the old version of packages and will cause mismatched dependencies. See example PR