Remove compute-environment dependency on internal IProjectLaunchDefaultsResource.DefaultHttpsEndpoint
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
## Background
Both the **Kubernetes** and **Radius** compute-environment publishers need to detect and skip the *synthetic default HTTPS endpoint* on a `ProjectResource` when materializing project endpoints into container ports / cluster Services. If they don't skip it, they emit a phantom `:443` Service (or a duplicate port) that nothing listens on, because containers do not terminate TLS in-cluster.
Today both publishers do this by reaching into an **internal** framework API:
```csharp
if (resource is IProjectLaunchDefaultsResource projectResource &&
endpoint == projectResource.DefaultHttpsEndpoint)
{
// skip the synthetic HTTPS endpoint
}
```
- Kubernetes: `src/Aspire.Hosting.Kubernetes/KubernetesResource.cs:231-232`
- Radius (added in #18797): `src/Aspire.Hosting.Radius/Publishing/RadiusServiceDiscovery.cs:118-119`
Because `IProjectLaunchDefaultsResource` (and its `DefaultHttpsEndpoint` member) is `internal` to `Aspire.Hosting`, each publisher must be added to `InternalsVisibleTo` in `src/Aspire.Hosting/Aspire.Hosting.csproj`:
- `Aspire.Hosting.Kubernetes` (existing)
- `Aspire.Hosting.Radius` + `Aspire.Hosting.Radius.Tests` (added in #18797)
## Problem
This is a recurring need: any compute environment that emits per-scheme cluster Services (or otherwise turns project endpoints into ports) has to distinguish the synthetic default HTTPS endpoint. Requiring each such integration to take an `InternalsVisibleTo` dependency on `Aspire.Hosting` internals:
- couples out-of-box (and, conceptually, third-party) compute environments to a private implementation detail;
- doesn't scale — third-party compute environments can't add themselves to our `InternalsVisibleTo`;
- duplicates the same `is IProjectLaunchDefaultsResource && == DefaultHttpsEndpoint` logic in every publisher.
For contrast, `Aspire.Hosting.Docker` does **not** need this today: Docker Compose maps host ports rather than creating per-scheme ClusterIP Services, so it uses only the public `ResolveEndpoints()` plus a literal `8080` fallback and never special-cases the synthetic HTTPS endpoint (`src/Aspire.Hosting.Docker/DockerComposeServiceExtensions.cs:129-141`).
## Proposal (design to be done in this issue, in the future)
Investigate a first-class, **public** way to express "this is the synthetic default HTTPS endpoint that should not be materialized as an in-cluster port/Service," so compute environments no longer need internal access. Options to explore during design:
- A public predicate/marker surfaced through the already-public `ResolveEndpoints()` result (e.g., a flag on `ResolvedEndpoint`, or `endpoint.IsSyntheticDefaultHttpsEndpoint()`).
- Folding the skip directly into `ResolveEndpoints()` so publishers get a consistent resolved-port view without re-deriving the rule.
- A public marker meaning "deployment tool assigns the port / no in-cluster TLS."
Once a public API exists, remove the `InternalsVisibleTo` entries for the compute-environment integrations (Kubernetes, Radius) and de-duplicate the logic across publishers.
## References
- PR that introduced the second consumer: #18797
- Related core behavior: #14029 (the framework's `SetBothPortsEnvVariables()` skips `DefaultHttpsEndpoint`)
Contributor guide
Research direction
Start with the internal IProjectLaunchDefaultsResource usage in src/Aspire.Hosting.Kubernetes/KubernetesResource.cs, src/Aspire.Hosting.Radius/Publishing/RadiusServiceDiscovery.cs, and the public ResolveEndpoints() result. Review #18797 and #14029, then define and test a public way to identify the synthetic HTTPS endpoint; done means the publishers no longer duplicate the check or require their InternalsVisibleTo entries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100