From f59b33943f0d927c16e5ca09d76467e1180f21b0 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Tue, 26 Mar 2024 14:26:14 +1100 Subject: [PATCH 01/39] Minimal change to kick start the branch. --- .../AppHost/Properties/launchSettings.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 28409a226a..2551cbc933 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -1,28 +1,28 @@ { "profiles": { - "http": { + "https": { "commandName": "Project", "launchBrowser": true, "dotnetRunMessages": true, - "applicationUrl": "http://localhost:15888", + "applicationUrl": "https://localhost:15887;http://localhost:15888", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16037", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" } }, - "https": { + "http": { "commandName": "Project", "launchBrowser": true, "dotnetRunMessages": true, - "applicationUrl": "https://localhost:15887;http://localhost:15888", + "applicationUrl": "http://localhost:15888", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16037", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" } }, From 9700e0439c2797b5712618e7ec0e7a1e6ad88127 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Tue, 26 Mar 2024 20:46:21 +1100 Subject: [PATCH 02/39] WIP. --- .../AppHost/Properties/launchSettings.json | 3 +- src/Aspire.Hosting/Aspire.Hosting.csproj | 1 + .../Dashboard/DashboardTokenProvider.cs | 37 +++++++++++++++++++ src/Aspire.Hosting/Dcp/ApplicationExecutor.cs | 27 +++++++++++++- src/Aspire.Hosting/DistributedApplication.cs | 1 + .../DistributedApplicationBuilder.cs | 1 + src/Shared/KnownEnvironmentVariables.cs | 12 ++++++ 7 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs create mode 100644 src/Shared/KnownEnvironmentVariables.cs diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 2551cbc933..1171e0f9ee 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -23,7 +23,8 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURE_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/src/Aspire.Hosting/Aspire.Hosting.csproj b/src/Aspire.Hosting/Aspire.Hosting.csproj index 750e9cb609..389f245470 100644 --- a/src/Aspire.Hosting/Aspire.Hosting.csproj +++ b/src/Aspire.Hosting/Aspire.Hosting.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs new file mode 100644 index 0000000000..91a01c7259 --- /dev/null +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text; +using Aspire.Hosting.Utils; +using Microsoft.Extensions.Configuration; + +namespace Aspire.Hosting.Dashboard; + +internal interface IDashboardTokenProvider +{ + public string BrowserToken { get; } + public string OltpToken { get; } + public string ResourceServerToken { get; } +} + +internal class DashboardTokenProvider : IDashboardTokenProvider +{ + public DashboardTokenProvider(IConfiguration configuration) + { + BrowserToken = GenerateToken(configuration[KnownEnvironmentVariables.BrowserToken]); + OltpToken = GenerateToken(); + ResourceServerToken = GenerateToken(); + } + + private static string GenerateToken(string? overrideValue = null) + { + var rawToken = overrideValue ?? PasswordGenerator.Generate(24, true, true, true, true, 6, 6, 6, 6); + var rawTokenBytes = Encoding.UTF8.GetBytes(rawToken); + var encodedToken = Convert.ToHexString(rawTokenBytes); + return encodedToken; + } + + public string BrowserToken { get; init; } + public string OltpToken { get; init; } + public string ResourceServerToken { get; init; } +} diff --git a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs index 90bdc2ca7d..0a3ebded91 100644 --- a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs +++ b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs @@ -69,7 +69,9 @@ internal sealed class ApplicationExecutor(ILogger logger, DistributedApplicationExecutionContext executionContext, ResourceNotificationService notificationService, ResourceLoggerService loggerService, - IDcpDependencyCheckService dcpDependencyCheckService) + IDcpDependencyCheckService dcpDependencyCheckService, + IDashboardTokenProvider tokenProvider + ) { private const string DebugSessionPortVar = "DEBUG_SESSION_PORT"; @@ -831,6 +833,8 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella ]); } + ApplyDashboardTokens(dashboardExecutableSpec.Env); + var dashboardExecutable = new Executable(dashboardExecutableSpec) { Metadata = { Name = KnownResourceNames.AspireDashboard } @@ -840,6 +844,27 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella PrintDashboardUrls(dashboardUrls); } + private void ApplyDashboardTokens(List envSpec) + { + envSpec.Add(new() + { + Name = KnownEnvironmentVariables.OltpToken, + Value = tokenProvider.OltpToken + }); + + envSpec.Add(new() + { + Name = KnownEnvironmentVariables.ResourceServerToken, + Value = tokenProvider.ResourceServerToken + }); + + envSpec.Add(new() + { + Name = KnownEnvironmentVariables.BrowserToken, + Value = tokenProvider.BrowserToken + }); + } + private void PrintDashboardUrls(string delimitedUrlList) { if (StringUtils.TryGetUriFromDelimitedString(delimitedUrlList, ";", out var firstDashboardUrl)) diff --git a/src/Aspire.Hosting/DistributedApplication.cs b/src/Aspire.Hosting/DistributedApplication.cs index 5e98677c38..fb5d72d4ff 100644 --- a/src/Aspire.Hosting/DistributedApplication.cs +++ b/src/Aspire.Hosting/DistributedApplication.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Lifecycle; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index cef9bd6be1..f03255f535 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -92,6 +92,7 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) _innerBuilder.Services.AddSingleton(); _innerBuilder.Services.AddHostedService(sp => sp.GetRequiredService()); _innerBuilder.Services.AddLifecycleHook(); + _innerBuilder.Services.AddSingleton(); // DCP stuff _innerBuilder.Services.AddSingleton(); diff --git a/src/Shared/KnownEnvironmentVariables.cs b/src/Shared/KnownEnvironmentVariables.cs new file mode 100644 index 0000000000..3e016ebb6d --- /dev/null +++ b/src/Shared/KnownEnvironmentVariables.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Hosting; + +internal static class KnownEnvironmentVariables +{ + public static string BrowserToken => "DOTNET_DASHBOARD_FRONTEND_TOKEN"; + public static string ResourceServerToken => "DOTNET_DASHBOARD_RESOURCE_SERVER_TOKEN"; + public static string OltpToken => "DOTNET_DASHBOARD_OLTP_TOKEN"; + public static string AllowUnsecureTransport => "ASPIRE_ALLOW_UNSECURE_TRANSPORT"; +} From eb14d598ac1692a0bf3c23f84b5c8f54d4811a7f Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 00:09:31 +1100 Subject: [PATCH 03/39] WIP --- .../AppHost/Properties/launchSettings.json | 5 ++- playground/TestShop/AppHost/appsettings.json | 2 +- .../DashboardAuthenticationOptions.cs | 10 +++++ ...DashboardAuthenticationOptionsValidator.cs | 33 ++++++++++++++++ .../Dashboard/DashboardServiceHost.cs | 3 +- .../Dashboard/DashboardTokenProvider.cs | 12 +++--- src/Aspire.Hosting/Dcp/ApplicationExecutor.cs | 39 +++++++------------ src/Aspire.Hosting/DistributedApplication.cs | 1 - .../DistributedApplicationBuilder.cs | 4 ++ src/Shared/KnownEnvironmentVariables.cs | 5 +-- 10 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs create mode 100644 src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 1171e0f9ee..2365fdda7e 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16037", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE__DASHBOARD__AUTHENTICATION__BROWSERTOKEN": "ABC123" } }, "http": { @@ -24,7 +25,7 @@ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", - "ASPIRE_ALLOW_UNSECURE_TRANSPORT": "true" + //"ASPIRE__DASHBOARD__AUTHENTICATION__ALLOWUNSECURETRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/TestShop/AppHost/appsettings.json b/playground/TestShop/AppHost/appsettings.json index 31c092aa45..80f87c3b44 100644 --- a/playground/TestShop/AppHost/appsettings.json +++ b/playground/TestShop/AppHost/appsettings.json @@ -3,7 +3,7 @@ "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", - "Aspire.Hosting.Dcp": "Warning" + "Aspire.Hosting.Dcp": "Debug" } } } diff --git a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs b/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs new file mode 100644 index 0000000000..57e10bf15e --- /dev/null +++ b/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Aspire.Hosting.Dashboard; + +internal class DashboardAuthenticationOptions +{ + public bool? AllowUnsecureTransport { get; set; } + public string? BrowserToken { get; set; } +} diff --git a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs new file mode 100644 index 0000000000..2192833ecc --- /dev/null +++ b/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Aspire.Hosting.Dashboard; + +internal class DashboardAuthenticationOptionsValidator(IConfiguration configuration) : IValidateOptions +{ + public ValidateOptionsResult Validate(string? name, DashboardAuthenticationOptions options) + { + if (configuration[KnownEnvironmentVariables.AspNetCoreUrls] is not { } applicationUrls) + { + throw new DistributedApplicationException($"AppHost does not have applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable set."); + } + + var firstApplicationUrl = applicationUrls.Split(";").First(); + + if (!Uri.TryCreate(firstApplicationUrl, UriKind.Absolute, out var parsedFirstApplicationUrl)) + { + throw new DistributedApplicationException($"AppHost applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable could not be parsed as a URI."); + } + + if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) + { + throw new DistributedApplicationException($"AppHost cannot use a non-TLS URL for applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} unless DashboardAuthenticationOptions.AllowUnsecureTransport is set to true."); + } + + _ = configuration; + return ValidateOptionsResult.Success; + } +} diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs index 20ee29d084..b9e64df20b 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs @@ -54,7 +54,8 @@ public DashboardServiceHost( ILoggerFactory loggerFactory, IConfigureOptions loggerOptions, ResourceNotificationService resourceNotificationService, - ResourceLoggerService resourceLoggerService) + ResourceLoggerService resourceLoggerService + ) { _logger = loggerFactory.CreateLogger(); diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 91a01c7259..e0ea1b0737 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -3,7 +3,7 @@ using System.Text; using Aspire.Hosting.Utils; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; namespace Aspire.Hosting.Dashboard; @@ -16,18 +16,18 @@ internal interface IDashboardTokenProvider internal class DashboardTokenProvider : IDashboardTokenProvider { - public DashboardTokenProvider(IConfiguration configuration) + public DashboardTokenProvider(IOptions dashboardAuthenticationOptions) { - BrowserToken = GenerateToken(configuration[KnownEnvironmentVariables.BrowserToken]); + BrowserToken = dashboardAuthenticationOptions.Value.BrowserToken ?? GenerateToken(); OltpToken = GenerateToken(); ResourceServerToken = GenerateToken(); } - private static string GenerateToken(string? overrideValue = null) + private static string GenerateToken() { - var rawToken = overrideValue ?? PasswordGenerator.Generate(24, true, true, true, true, 6, 6, 6, 6); + var rawToken = PasswordGenerator.Generate(24, true, true, true, true, 6, 6, 6, 6); var rawTokenBytes = Encoding.UTF8.GetBytes(rawToken); - var encodedToken = Convert.ToHexString(rawTokenBytes); + var encodedToken = Convert.ToHexString(rawTokenBytes).ToLower(); return encodedToken; } diff --git a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs index 0a3ebded91..beda540c41 100644 --- a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs +++ b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs @@ -70,7 +70,8 @@ internal sealed class ApplicationExecutor(ILogger logger, ResourceNotificationService notificationService, ResourceLoggerService loggerService, IDcpDependencyCheckService dcpDependencyCheckService, - IDashboardTokenProvider tokenProvider + IOptions dashboardAuthenticationOptions, + IDashboardTokenProvider dashboardTokenProvider ) { private const string DebugSessionPortVar = "DEBUG_SESSION_PORT"; @@ -710,6 +711,19 @@ private void ConfigureAspireDashboardResource(IResource dashboardResource) var grpcEndpointUrl = await _dashboardEndpointProvider.GetResourceServiceUriAsync(context.CancellationToken).ConfigureAwait(false); + if (dashboardAuthenticationOptions.Value.AllowUnsecureTransport.GetValueOrDefault(false)) + { + // Configure for insecure running. + context.EnvironmentVariables["DISABLEAUTHPLACEHOLDER"] = true; + } + else + { + // Configure for secure running. + context.EnvironmentVariables["BROWSERTOKENPLACEHOLDER"] = dashboardTokenProvider.BrowserToken; + context.EnvironmentVariables["OTLPTOKENPLACEHOLDER"] = dashboardTokenProvider.OltpToken; + context.EnvironmentVariables["RESOURCESERVERTOKENPLACEHOLDER"] = dashboardTokenProvider.ResourceServerToken; + } + context.EnvironmentVariables["ASPNETCORE_URLS"] = appHostApplicationUrl; context.EnvironmentVariables["DOTNET_RESOURCE_SERVICE_ENDPOINT_URL"] = grpcEndpointUrl; context.EnvironmentVariables["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"] = otlpEndpointUrl; @@ -833,8 +847,6 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella ]); } - ApplyDashboardTokens(dashboardExecutableSpec.Env); - var dashboardExecutable = new Executable(dashboardExecutableSpec) { Metadata = { Name = KnownResourceNames.AspireDashboard } @@ -844,27 +856,6 @@ private async Task StartDashboardAsDcpExecutableAsync(CancellationToken cancella PrintDashboardUrls(dashboardUrls); } - private void ApplyDashboardTokens(List envSpec) - { - envSpec.Add(new() - { - Name = KnownEnvironmentVariables.OltpToken, - Value = tokenProvider.OltpToken - }); - - envSpec.Add(new() - { - Name = KnownEnvironmentVariables.ResourceServerToken, - Value = tokenProvider.ResourceServerToken - }); - - envSpec.Add(new() - { - Name = KnownEnvironmentVariables.BrowserToken, - Value = tokenProvider.BrowserToken - }); - } - private void PrintDashboardUrls(string delimitedUrlList) { if (StringUtils.TryGetUriFromDelimitedString(delimitedUrlList, ";", out var firstDashboardUrl)) diff --git a/src/Aspire.Hosting/DistributedApplication.cs b/src/Aspire.Hosting/DistributedApplication.cs index fb5d72d4ff..5e98677c38 100644 --- a/src/Aspire.Hosting/DistributedApplication.cs +++ b/src/Aspire.Hosting/DistributedApplication.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Lifecycle; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index f03255f535..aa39c8df71 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -10,8 +10,10 @@ using Aspire.Hosting.Publishing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace Aspire.Hosting; @@ -89,6 +91,8 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) _innerBuilder.Services.AddSingleton(); // Dashboard + _innerBuilder.Services.AddOptions().Bind(Configuration.GetSection("Aspire:Dashboard:Authentication")); + _innerBuilder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, DashboardAuthenticationOptionsValidator>()); _innerBuilder.Services.AddSingleton(); _innerBuilder.Services.AddHostedService(sp => sp.GetRequiredService()); _innerBuilder.Services.AddLifecycleHook(); diff --git a/src/Shared/KnownEnvironmentVariables.cs b/src/Shared/KnownEnvironmentVariables.cs index 3e016ebb6d..0aba61a7bf 100644 --- a/src/Shared/KnownEnvironmentVariables.cs +++ b/src/Shared/KnownEnvironmentVariables.cs @@ -5,8 +5,5 @@ namespace Aspire.Hosting; internal static class KnownEnvironmentVariables { - public static string BrowserToken => "DOTNET_DASHBOARD_FRONTEND_TOKEN"; - public static string ResourceServerToken => "DOTNET_DASHBOARD_RESOURCE_SERVER_TOKEN"; - public static string OltpToken => "DOTNET_DASHBOARD_OLTP_TOKEN"; - public static string AllowUnsecureTransport => "ASPIRE_ALLOW_UNSECURE_TRANSPORT"; + public static string AspNetCoreUrls = "ASPNETCORE_URLS"; } From 9024c6c3982d746026fd7b356550aa2fdac80159 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 09:34:19 +1100 Subject: [PATCH 04/39] Remove unnecessary change. --- src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs index b9e64df20b..20ee29d084 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs @@ -54,8 +54,7 @@ public DashboardServiceHost( ILoggerFactory loggerFactory, IConfigureOptions loggerOptions, ResourceNotificationService resourceNotificationService, - ResourceLoggerService resourceLoggerService - ) + ResourceLoggerService resourceLoggerService) { _logger = loggerFactory.CreateLogger(); From a2c89288e898794cb85b3a25ae257ad8e7f6acae Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 09:40:05 +1100 Subject: [PATCH 05/39] Change mins to zero to increase entropy. --- src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index e0ea1b0737..ba34daac59 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -25,7 +25,7 @@ public DashboardTokenProvider(IOptions dashboard private static string GenerateToken() { - var rawToken = PasswordGenerator.Generate(24, true, true, true, true, 6, 6, 6, 6); + var rawToken = PasswordGenerator.Generate(24, true, true, true, true, 0, 0, 0, 0); var rawTokenBytes = Encoding.UTF8.GetBytes(rawToken); var encodedToken = Convert.ToHexString(rawTokenBytes).ToLower(); return encodedToken; From 6729211147b24b3fa89c12d95d3f0e8e32f7732a Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 09:41:50 +1100 Subject: [PATCH 06/39] Make token properties read-only. --- src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index ba34daac59..73d02d0874 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -31,7 +31,7 @@ private static string GenerateToken() return encodedToken; } - public string BrowserToken { get; init; } - public string OltpToken { get; init; } - public string ResourceServerToken { get; init; } + public string BrowserToken { get; } + public string OltpToken { get; } + public string ResourceServerToken { get; } } From 8fb7574a1c524211414176a8a0fd32b8788cf14a Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 10:46:26 +1100 Subject: [PATCH 07/39] WIP --- .../Dashboard/DashboardServiceHost.cs | 9 ++++++++- .../Dashboard/DashboardTokenProvider.cs | 4 ++-- ...nticationOptions.cs => TransportOptions.cs} | 2 +- ...lidator.cs => TransportOptionsValidator.cs} | 6 +++--- src/Aspire.Hosting/Dcp/ApplicationExecutor.cs | 18 +----------------- .../DistributedApplicationBuilder.cs | 9 +++++++-- src/Shared/KnownEnvironmentVariables.cs | 1 + 7 files changed, 23 insertions(+), 26 deletions(-) rename src/Aspire.Hosting/Dashboard/{DashboardAuthenticationOptions.cs => TransportOptions.cs} (85%) rename src/Aspire.Hosting/Dashboard/{DashboardAuthenticationOptionsValidator.cs => TransportOptionsValidator.cs} (81%) diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs index 20ee29d084..424bad8c89 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs @@ -54,8 +54,15 @@ public DashboardServiceHost( ILoggerFactory loggerFactory, IConfigureOptions loggerOptions, ResourceNotificationService resourceNotificationService, - ResourceLoggerService resourceLoggerService) + ResourceLoggerService resourceLoggerService, + IOptions transportOptions) { + // TODO: This is a temporary addition until P6 when we fully implement + // the dashboard auth features. For now we want to throw if the + // applicationUrl in the AppHost launch settings has a http endpoint + // and the ASPIRE_ALLOW_UNSECURED_TRANSPORT value is not set to true. + _ = transportOptions.Value.AllowUnsecureTransport; + _logger = loggerFactory.CreateLogger(); if (!options.DashboardEnabled || executionContext.IsPublishMode) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 73d02d0874..94806a13e2 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -16,9 +16,9 @@ internal interface IDashboardTokenProvider internal class DashboardTokenProvider : IDashboardTokenProvider { - public DashboardTokenProvider(IOptions dashboardAuthenticationOptions) + public DashboardTokenProvider(IOptions transportOptions) { - BrowserToken = dashboardAuthenticationOptions.Value.BrowserToken ?? GenerateToken(); + BrowserToken = transportOptions.Value.BrowserToken ?? GenerateToken(); OltpToken = GenerateToken(); ResourceServerToken = GenerateToken(); } diff --git a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs b/src/Aspire.Hosting/Dashboard/TransportOptions.cs similarity index 85% rename from src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs rename to src/Aspire.Hosting/Dashboard/TransportOptions.cs index 57e10bf15e..f65b6da008 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptions.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptions.cs @@ -3,7 +3,7 @@ namespace Aspire.Hosting.Dashboard; -internal class DashboardAuthenticationOptions +internal class TransportOptions { public bool? AllowUnsecureTransport { get; set; } public string? BrowserToken { get; set; } diff --git a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs similarity index 81% rename from src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs rename to src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 2192833ecc..88aabccfa0 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardAuthenticationOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -6,9 +6,9 @@ namespace Aspire.Hosting.Dashboard; -internal class DashboardAuthenticationOptionsValidator(IConfiguration configuration) : IValidateOptions +internal class TransportOptionsValidator(IConfiguration configuration) : IValidateOptions { - public ValidateOptionsResult Validate(string? name, DashboardAuthenticationOptions options) + public ValidateOptionsResult Validate(string? name, TransportOptions options) { if (configuration[KnownEnvironmentVariables.AspNetCoreUrls] is not { } applicationUrls) { @@ -24,7 +24,7 @@ public ValidateOptionsResult Validate(string? name, DashboardAuthenticationOptio if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - throw new DistributedApplicationException($"AppHost cannot use a non-TLS URL for applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} unless DashboardAuthenticationOptions.AllowUnsecureTransport is set to true."); + throw new DistributedApplicationException($"AppHost cannot use a non-TLS URL for applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} unless DashboardAuthenticationOptions.AllowUnsecureTransport is set to true. See https://aka.ms/dotnet/aspire/allowunsecuredtransport."); } _ = configuration; diff --git a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs index beda540c41..90bdc2ca7d 100644 --- a/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs +++ b/src/Aspire.Hosting/Dcp/ApplicationExecutor.cs @@ -69,10 +69,7 @@ internal sealed class ApplicationExecutor(ILogger logger, DistributedApplicationExecutionContext executionContext, ResourceNotificationService notificationService, ResourceLoggerService loggerService, - IDcpDependencyCheckService dcpDependencyCheckService, - IOptions dashboardAuthenticationOptions, - IDashboardTokenProvider dashboardTokenProvider - ) + IDcpDependencyCheckService dcpDependencyCheckService) { private const string DebugSessionPortVar = "DEBUG_SESSION_PORT"; @@ -711,19 +708,6 @@ private void ConfigureAspireDashboardResource(IResource dashboardResource) var grpcEndpointUrl = await _dashboardEndpointProvider.GetResourceServiceUriAsync(context.CancellationToken).ConfigureAwait(false); - if (dashboardAuthenticationOptions.Value.AllowUnsecureTransport.GetValueOrDefault(false)) - { - // Configure for insecure running. - context.EnvironmentVariables["DISABLEAUTHPLACEHOLDER"] = true; - } - else - { - // Configure for secure running. - context.EnvironmentVariables["BROWSERTOKENPLACEHOLDER"] = dashboardTokenProvider.BrowserToken; - context.EnvironmentVariables["OTLPTOKENPLACEHOLDER"] = dashboardTokenProvider.OltpToken; - context.EnvironmentVariables["RESOURCESERVERTOKENPLACEHOLDER"] = dashboardTokenProvider.ResourceServerToken; - } - context.EnvironmentVariables["ASPNETCORE_URLS"] = appHostApplicationUrl; context.EnvironmentVariables["DOTNET_RESOURCE_SERVICE_ENDPOINT_URL"] = grpcEndpointUrl; context.EnvironmentVariables["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"] = otlpEndpointUrl; diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index aa39c8df71..4495ea2ee9 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -91,8 +91,8 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) _innerBuilder.Services.AddSingleton(); // Dashboard - _innerBuilder.Services.AddOptions().Bind(Configuration.GetSection("Aspire:Dashboard:Authentication")); - _innerBuilder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, DashboardAuthenticationOptionsValidator>()); + _innerBuilder.Services.AddOptions().PostConfigure(MapTransportOptionsFromCustomKeys); + _innerBuilder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, TransportOptionsValidator>()); _innerBuilder.Services.AddSingleton(); _innerBuilder.Services.AddHostedService(sp => sp.GetRequiredService()); _innerBuilder.Services.AddLifecycleHook(); @@ -124,6 +124,11 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) LogBuilderConstructed(this); } + private void MapTransportOptionsFromCustomKeys(TransportOptions options) + { + options.AllowUnsecureTransport = Configuration.GetBool(KnownEnvironmentVariables.AllowUnsecuredTransport, false); + } + private static bool IsOtlpApiKeyAuthDisabled(IConfiguration configuration) { return configuration.GetBool(DisableOtlpApiKeyAuthKey) ?? false; diff --git a/src/Shared/KnownEnvironmentVariables.cs b/src/Shared/KnownEnvironmentVariables.cs index 0aba61a7bf..bafd8058b9 100644 --- a/src/Shared/KnownEnvironmentVariables.cs +++ b/src/Shared/KnownEnvironmentVariables.cs @@ -6,4 +6,5 @@ namespace Aspire.Hosting; internal static class KnownEnvironmentVariables { public static string AspNetCoreUrls = "ASPNETCORE_URLS"; + public static string AllowUnsecuredTransport = "ASPIRE_ALLOW_UNSECURED_TRANSPORT"; } From 6eb42d222724b2aa82d572f9be05ea7a01896ac8 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 10:51:21 +1100 Subject: [PATCH 08/39] Improved error message. --- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 88aabccfa0..db53449a2c 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -24,7 +24,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - throw new DistributedApplicationException($"AppHost cannot use a non-TLS URL for applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} unless DashboardAuthenticationOptions.AllowUnsecureTransport is set to true. See https://aka.ms/dotnet/aspire/allowunsecuredtransport."); + throw new DistributedApplicationException($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the 'ASPIRE_ALLOW_UNSECURED_TRANSPORT' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } _ = configuration; From 02e9ad9e62b68385e66f1b9acc6835e0adfd97bd Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 10:52:05 +1100 Subject: [PATCH 09/39] Improve exception. --- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index db53449a2c..61c38729fa 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -19,7 +19,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (!Uri.TryCreate(firstApplicationUrl, UriKind.Absolute, out var parsedFirstApplicationUrl)) { - throw new DistributedApplicationException($"AppHost applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable could not be parsed as a URI."); + throw new DistributedApplicationException($"AppHost applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable with value '{firstApplicationUrl}' could not be parsed as a URI."); } if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) From a5ee58fb5bc60b0dcf1040455e86cca379f99724 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 10:53:38 +1100 Subject: [PATCH 10/39] Tweak exception message. --- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 61c38729fa..fc4e80705d 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -19,7 +19,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (!Uri.TryCreate(firstApplicationUrl, UriKind.Absolute, out var parsedFirstApplicationUrl)) { - throw new DistributedApplicationException($"AppHost applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable with value '{firstApplicationUrl}' could not be parsed as a URI."); + throw new DistributedApplicationException($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); } if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) From 8dcdf0cd61341e13d3268bede9b79875d2be09a5 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 10:56:25 +1100 Subject: [PATCH 11/39] Return validation result instead of throwing. --- playground/TestShop/AppHost/Properties/launchSettings.json | 2 +- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 2365fdda7e..7f2d0f798a 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -24,7 +24,7 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" //"ASPIRE__DASHBOARD__AUTHENTICATION__ALLOWUNSECURETRANSPORT": "true" } }, diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index fc4e80705d..930db4f90e 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -12,22 +12,21 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) { if (configuration[KnownEnvironmentVariables.AspNetCoreUrls] is not { } applicationUrls) { - throw new DistributedApplicationException($"AppHost does not have applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable set."); + return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable set."); } var firstApplicationUrl = applicationUrls.Split(";").First(); if (!Uri.TryCreate(firstApplicationUrl, UriKind.Absolute, out var parsedFirstApplicationUrl)) { - throw new DistributedApplicationException($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); + return ValidateOptionsResult.Fail($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); } if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - throw new DistributedApplicationException($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the 'ASPIRE_ALLOW_UNSECURED_TRANSPORT' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the 'ASPIRE_ALLOW_UNSECURED_TRANSPORT' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } - _ = configuration; return ValidateOptionsResult.Success; } } From 4a2c658c5f9c8530e634786d5c671e79352c5886 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 11:05:26 +1100 Subject: [PATCH 12/39] Add defaults to password gen, and add #if def for ToHexStringLower --- src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs | 8 +++++++- src/Aspire.Hosting/Utils/PasswordGenerator.cs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 94806a13e2..9c475a105a 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -25,9 +25,15 @@ public DashboardTokenProvider(IOptions transportOptions) private static string GenerateToken() { - var rawToken = PasswordGenerator.Generate(24, true, true, true, true, 0, 0, 0, 0); + var rawToken = PasswordGenerator.Generate(24); var rawTokenBytes = Encoding.UTF8.GetBytes(rawToken); + +#if NET9_0_OR_GREATER + var encodedToken = Convert.ToHexStringLower(rawTokenBytes); +#else var encodedToken = Convert.ToHexString(rawTokenBytes).ToLower(); +#endif + return encodedToken; } diff --git a/src/Aspire.Hosting/Utils/PasswordGenerator.cs b/src/Aspire.Hosting/Utils/PasswordGenerator.cs index 21d3cc69f6..6df74cabf9 100644 --- a/src/Aspire.Hosting/Utils/PasswordGenerator.cs +++ b/src/Aspire.Hosting/Utils/PasswordGenerator.cs @@ -55,8 +55,8 @@ internal static class PasswordGenerator /// log base 2 [67^x * 23^a * 23^b * 10^c * 11^d * (a + b + c + d)! / (a! * b! * c! * d!)] /// public static string Generate(int minLength, - bool lower, bool upper, bool numeric, bool special, - int minLower, int minUpper, int minNumeric, int minSpecial) + bool lower = true, bool upper = true, bool numeric = true, bool special = true, + int minLower = 0, int minUpper = 0, int minNumeric = 0, int minSpecial = 0) { ArgumentOutOfRangeException.ThrowIfNegative(minLength); ArgumentOutOfRangeException.ThrowIfNegative(minLower); From f827070c5abdeb01d0c8e50eabd2dffd468003ee Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 11:43:43 +1100 Subject: [PATCH 13/39] Add flag to allow setting on ASPIRE_ALLOW_UNSECURED_TRANSPORT for test project. --- tests/testproject/TestProject.AppHost/TestProgram.cs | 12 +++++++++--- .../TestProject.AppHost/TestProject.AppHost.csproj | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/testproject/TestProject.AppHost/TestProgram.cs b/tests/testproject/TestProject.AppHost/TestProgram.cs index 9efd9b56e0..6667ff6759 100644 --- a/tests/testproject/TestProject.AppHost/TestProgram.cs +++ b/tests/testproject/TestProject.AppHost/TestProgram.cs @@ -9,8 +9,9 @@ public class TestProgram : IDisposable { - private TestProgram(string[] args, Assembly assembly, bool includeIntegrationServices, bool includeNodeApp, bool disableDashboard) + private TestProgram(string[] args, Assembly assembly, bool includeIntegrationServices, bool includeNodeApp, bool disableDashboard, bool allowUnsecuredTransport) { + ISet? resourcesToSkip = null; for (int i = 0; i < args.Length; i++) { @@ -35,6 +36,11 @@ private TestProgram(string[] args, Assembly assembly, bool includeIntegrationSer AppBuilder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions { Args = args, DisableDashboard = disableDashboard, AssemblyName = assembly.FullName }); + if (allowUnsecuredTransport) + { + AppBuilder.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + } + var serviceAPath = Path.Combine(Projects.TestProject_AppHost.ProjectPath, @"..\TestProject.ServiceA\TestProject.ServiceA.csproj"); ServiceABuilder = AppBuilder.AddProject("servicea", serviceAPath, launchProfileName: "http"); @@ -123,8 +129,8 @@ private TestProgram(string[] args, Assembly assembly, bool includeIntegrationSer AppBuilder.Services.AddLifecycleHook(); } - public static TestProgram Create(string[]? args = null, bool includeIntegrationServices = false, bool includeNodeApp = false, bool disableDashboard = true) => - new TestProgram(args ?? [], typeof(T).Assembly, includeIntegrationServices, includeNodeApp, disableDashboard); + public static TestProgram Create(string[]? args = null, bool includeIntegrationServices = false, bool includeNodeApp = false, bool disableDashboard = true, bool allowUnsecuredTransport = true) => + new TestProgram(args ?? [], typeof(T).Assembly, includeIntegrationServices, includeNodeApp, disableDashboard, allowUnsecuredTransport); public IDistributedApplicationBuilder AppBuilder { get; private set; } public IResourceBuilder ServiceABuilder { get; private set; } diff --git a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj index 8247cf4340..0b0e121ed6 100644 --- a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj +++ b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj @@ -8,6 +8,10 @@ true + + + + From 3bc8cd19b0da6661d8095ede5ad77f78a777d835 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 12:06:41 +1100 Subject: [PATCH 14/39] Getting tests passing. --- .../Aspire.Hosting.Testing.Tests.csproj | 4 ++++ .../DistributedApplicationFixtureOfT.cs | 2 +- .../TestingBuilderTests.cs | 4 +++- .../TestingFactoryTests.cs | 16 +++++++++++++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj b/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj index db7a21609a..785af8999c 100644 --- a/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj +++ b/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj @@ -12,6 +12,10 @@ + + + + diff --git a/tests/Aspire.Hosting.Testing.Tests/DistributedApplicationFixtureOfT.cs b/tests/Aspire.Hosting.Testing.Tests/DistributedApplicationFixtureOfT.cs index 60f40eed85..0a9c2261ec 100644 --- a/tests/Aspire.Hosting.Testing.Tests/DistributedApplicationFixtureOfT.cs +++ b/tests/Aspire.Hosting.Testing.Tests/DistributedApplicationFixtureOfT.cs @@ -4,7 +4,7 @@ namespace Aspire.Hosting.Testing.Tests; -public sealed class DistributedApplicationFixture : DistributedApplicationFactory, IAsyncLifetime where TEntryPoint : class +public class DistributedApplicationFixture : DistributedApplicationFactory, IAsyncLifetime where TEntryPoint : class { public DistributedApplicationFixture() { diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs index 78035ea944..e66ce83ce2 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs @@ -14,8 +14,8 @@ public class TestingBuilderTests public async Task HasEndPoints() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); + appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); - await app.StartAsync(); // Get an endpoint from a resource @@ -33,6 +33,7 @@ public async Task HasEndPoints() public async Task CanGetResources() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); + appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -59,6 +60,7 @@ public async Task HttpClientGetTest() public async Task GetHttpClientBeforeStart() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); + appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); Assert.Throws(() => app.CreateHttpClient("mywebapp1")); } diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs index 2bc3d5fc29..ba5ee74272 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Testing.Tests; -public class TestingFactoryTests(DistributedApplicationFixture fixture) : IClassFixture> +public class TestingFactoryTests(DistributedApplicationFixtureWithAllowUnsecureTransport fixture) : IClassFixture> { private readonly DistributedApplication _app = fixture.Application; @@ -48,3 +48,17 @@ private sealed record WeatherForecast(DateOnly Date, int TemperatureC, string? S public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); } } + +public class DistributedApplicationFixtureWithAllowUnsecureTransport : DistributedApplicationFixture where TEntryPoint: class +{ + protected override void OnBuilding(DistributedApplicationBuilder applicationBuilder) + { + base.OnBuilding(applicationBuilder); + } + + protected override void OnBuilderCreated(DistributedApplicationBuilder applicationBuilder) + { + applicationBuilder.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + base.OnBuilderCreated(applicationBuilder); + } +} From 415fb6d508c28b171734263fa820c7322c882b1a Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 12:15:17 +1100 Subject: [PATCH 15/39] Fix test cases. --- .../Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs | 1 + .../Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs | 9 ++------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs index e66ce83ce2..5ced69afef 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs @@ -47,6 +47,7 @@ public async Task CanGetResources() public async Task HttpClientGetTest() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); + appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs index ba5ee74272..69d2963e52 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Testing.Tests; -public class TestingFactoryTests(DistributedApplicationFixtureWithAllowUnsecureTransport fixture) : IClassFixture> +public class TestingFactoryTests(DistributedApplicationFixtureWithAllowUnsecureTransport fixture) : IClassFixture> { private readonly DistributedApplication _app = fixture.Application; @@ -52,13 +52,8 @@ private sealed record WeatherForecast(DateOnly Date, int TemperatureC, string? S public class DistributedApplicationFixtureWithAllowUnsecureTransport : DistributedApplicationFixture where TEntryPoint: class { protected override void OnBuilding(DistributedApplicationBuilder applicationBuilder) - { - base.OnBuilding(applicationBuilder); - } - - protected override void OnBuilderCreated(DistributedApplicationBuilder applicationBuilder) { applicationBuilder.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; - base.OnBuilderCreated(applicationBuilder); + base.OnBuilding(applicationBuilder); } } From 93e053fc43b12237e0629f12311631112a3b26fd Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 12:29:52 +1100 Subject: [PATCH 16/39] Update src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs Co-authored-by: James Newton-King --- src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 9c475a105a..363d22b077 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -10,7 +10,7 @@ namespace Aspire.Hosting.Dashboard; internal interface IDashboardTokenProvider { public string BrowserToken { get; } - public string OltpToken { get; } + public string DashboardOtlpToken { get; } public string ResourceServerToken { get; } } From d7e6286eb59554c42a51bcbba866f77fbcf6e396 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 12:43:44 +1100 Subject: [PATCH 17/39] PR feedback. --- .../Dashboard/DashboardTokenProvider.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 363d22b077..6567490b82 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -3,6 +3,7 @@ using System.Text; using Aspire.Hosting.Utils; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Aspire.Hosting.Dashboard; @@ -16,10 +17,20 @@ internal interface IDashboardTokenProvider internal class DashboardTokenProvider : IDashboardTokenProvider { - public DashboardTokenProvider(IOptions transportOptions) + public DashboardTokenProvider(ILogger logger, IOptions transportOptions) { - BrowserToken = transportOptions.Value.BrowserToken ?? GenerateToken(); - OltpToken = GenerateToken(); + if (transportOptions.Value.BrowserToken is not { } browserToken) + { + logger.LogDebug("Browser token was not supplied from environment, will be automatically generated."); + BrowserToken = GenerateToken(); + } + else + { + logger.LogDebug("Browser token was supplied from environment, will not be generated."); + BrowserToken = browserToken; + } + + DashboardOtlpToken = GenerateToken(); ResourceServerToken = GenerateToken(); } @@ -38,6 +49,6 @@ private static string GenerateToken() } public string BrowserToken { get; } - public string OltpToken { get; } + public string DashboardOtlpToken { get; } public string ResourceServerToken { get; } } From 17afc6de01642e708439371a7c686f4f556f41b5 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 12:54:02 +1100 Subject: [PATCH 18/39] PR feedback. --- playground/TestShop/AppHost/Properties/launchSettings.json | 5 ++--- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 2 +- src/Aspire.Hosting/DistributedApplicationBuilder.cs | 5 ++++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 7f2d0f798a..abe97729ca 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -10,8 +10,7 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16037", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", - "ASPIRE__DASHBOARD__AUTHENTICATION__BROWSERTOKEN": "ABC123" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" } }, "http": { @@ -25,7 +24,7 @@ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" - //"ASPIRE__DASHBOARD__AUTHENTICATION__ALLOWUNSECURETRANSPORT": "true" + //"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 930db4f90e..0997d3ad98 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -24,7 +24,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the 'ASPIRE_ALLOW_UNSECURED_TRANSPORT' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the '{KnownEnvironmentVariables.AllowUnsecuredTransport}' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } return ValidateOptionsResult.Success; diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index 4495ea2ee9..b484206ce0 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -126,7 +126,10 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) private void MapTransportOptionsFromCustomKeys(TransportOptions options) { - options.AllowUnsecureTransport = Configuration.GetBool(KnownEnvironmentVariables.AllowUnsecuredTransport, false); + if (Configuration.GetBool(KnownEnvironmentVariables.AllowUnsecuredTransport) is { } allowUnsecuredTransport) + { + options.AllowUnsecureTransport = allowUnsecuredTransport; + } } private static bool IsOtlpApiKeyAuthDisabled(IConfiguration configuration) From edbd7b21387b003cb80b6dab51eb9dacf052fad1 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 13:03:25 +1100 Subject: [PATCH 19/39] Bikeshedding on arguments to PasswordGenerator :) --- .../Dashboard/DashboardTokenProvider.cs | 20 ++++++++++++++----- src/Aspire.Hosting/Utils/PasswordGenerator.cs | 4 ++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs index 6567490b82..b8dfd2ade2 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs @@ -10,7 +10,7 @@ namespace Aspire.Hosting.Dashboard; internal interface IDashboardTokenProvider { - public string BrowserToken { get; } + public string DashboardFrontendToken { get; } public string DashboardOtlpToken { get; } public string ResourceServerToken { get; } } @@ -22,12 +22,12 @@ public DashboardTokenProvider(ILogger logger, IOptions logger, IOptions public static string Generate(int minLength, - bool lower = true, bool upper = true, bool numeric = true, bool special = true, - int minLower = 0, int minUpper = 0, int minNumeric = 0, int minSpecial = 0) + bool lower, bool upper, bool numeric, bool special, + int minLower, int minUpper, int minNumeric, int minSpecial) { ArgumentOutOfRangeException.ThrowIfNegative(minLength); ArgumentOutOfRangeException.ThrowIfNegative(minLower); From 7f115c0b998c40dc29436472d6c1c2e3001449b7 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 13:28:47 +1100 Subject: [PATCH 20/39] Move transport check after guard clause. --- src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs index 424bad8c89..29da90b2e3 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs @@ -57,12 +57,6 @@ public DashboardServiceHost( ResourceLoggerService resourceLoggerService, IOptions transportOptions) { - // TODO: This is a temporary addition until P6 when we fully implement - // the dashboard auth features. For now we want to throw if the - // applicationUrl in the AppHost launch settings has a http endpoint - // and the ASPIRE_ALLOW_UNSECURED_TRANSPORT value is not set to true. - _ = transportOptions.Value.AllowUnsecureTransport; - _logger = loggerFactory.CreateLogger(); if (!options.DashboardEnabled || executionContext.IsPublishMode) @@ -72,6 +66,12 @@ public DashboardServiceHost( return; } + // TODO: This is a temporary addition until P6 when we fully implement + // the dashboard auth features. For now we want to throw if the + // applicationUrl in the AppHost launch settings has a http endpoint + // and the ASPIRE_ALLOW_UNSECURED_TRANSPORT value is not set to true. + _ = transportOptions.Value.AllowUnsecureTransport; + try { var builder = WebApplication.CreateSlimBuilder(); From 392b65269b348db6c73866c9d39f39055ead2b4b Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 13:35:50 +1100 Subject: [PATCH 21/39] KnownEnvironmentVaraibles to KnownConfigNames --- src/Aspire.Hosting/Aspire.Hosting.csproj | 2 +- .../Dashboard/TransportOptionsValidator.cs | 6 +-- .../DistributedApplicationBuilder.cs | 2 +- ...onmentVariables.cs => KnownConfigNames.cs} | 2 +- .../Aspire.Hosting.Testing.Tests.csproj | 2 +- .../TestingBuilderTests.cs | 8 ++-- .../TestingFactoryTests.cs | 2 +- tests/cosmos.module.bicep | 42 +++++++++++++++++++ .../TestProject.AppHost/TestProgram.cs | 2 +- .../TestProject.AppHost.csproj | 2 +- 10 files changed, 56 insertions(+), 14 deletions(-) rename src/Shared/{KnownEnvironmentVariables.cs => KnownConfigNames.cs} (86%) create mode 100644 tests/cosmos.module.bicep diff --git a/src/Aspire.Hosting/Aspire.Hosting.csproj b/src/Aspire.Hosting/Aspire.Hosting.csproj index e1f95b1900..8f72bc0a12 100644 --- a/src/Aspire.Hosting/Aspire.Hosting.csproj +++ b/src/Aspire.Hosting/Aspire.Hosting.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 0997d3ad98..82c8f550fc 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -10,9 +10,9 @@ internal class TransportOptionsValidator(IConfiguration configuration) : IValida { public ValidateOptionsResult Validate(string? name, TransportOptions options) { - if (configuration[KnownEnvironmentVariables.AspNetCoreUrls] is not { } applicationUrls) + if (configuration[KnownConfigNames.AspNetCoreUrls] is not { } applicationUrls) { - return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownEnvironmentVariables.AspNetCoreUrls} environment variable set."); + return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set."); } var firstApplicationUrl = applicationUrls.Split(";").First(); @@ -24,7 +24,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the '{KnownEnvironmentVariables.AllowUnsecuredTransport}' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } return ValidateOptionsResult.Success; diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index b484206ce0..5ce49fa8a6 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -126,7 +126,7 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) private void MapTransportOptionsFromCustomKeys(TransportOptions options) { - if (Configuration.GetBool(KnownEnvironmentVariables.AllowUnsecuredTransport) is { } allowUnsecuredTransport) + if (Configuration.GetBool(KnownConfigNames.AllowUnsecuredTransport) is { } allowUnsecuredTransport) { options.AllowUnsecureTransport = allowUnsecuredTransport; } diff --git a/src/Shared/KnownEnvironmentVariables.cs b/src/Shared/KnownConfigNames.cs similarity index 86% rename from src/Shared/KnownEnvironmentVariables.cs rename to src/Shared/KnownConfigNames.cs index bafd8058b9..0733b79a5e 100644 --- a/src/Shared/KnownEnvironmentVariables.cs +++ b/src/Shared/KnownConfigNames.cs @@ -3,7 +3,7 @@ namespace Aspire.Hosting; -internal static class KnownEnvironmentVariables +internal static class KnownConfigNames { public static string AspNetCoreUrls = "ASPNETCORE_URLS"; public static string AllowUnsecuredTransport = "ASPIRE_ALLOW_UNSECURED_TRANSPORT"; diff --git a/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj b/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj index 785af8999c..fc5752930e 100644 --- a/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj +++ b/tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs index 5ced69afef..d16bece185 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs @@ -14,7 +14,7 @@ public class TestingBuilderTests public async Task HasEndPoints() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -33,7 +33,7 @@ public async Task HasEndPoints() public async Task CanGetResources() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -47,7 +47,7 @@ public async Task CanGetResources() public async Task HttpClientGetTest() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -61,7 +61,7 @@ public async Task HttpClientGetTest() public async Task GetHttpClientBeforeStart() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownEnvironmentVariables.AllowUnsecuredTransport] = "true"; + appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); Assert.Throws(() => app.CreateHttpClient("mywebapp1")); } diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs index f0e75f2ec6..c3071c05ae 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs @@ -53,7 +53,7 @@ public class DistributedApplicationFixtureWithAllowUnsecureTransport - + From 341c1e04e4100a2788e2d4eea2a55d4da2cbe463 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 13:37:47 +1100 Subject: [PATCH 22/39] Reword failure message. --- src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 82c8f550fc..094338d2c7 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -24,7 +24,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) { - return ValidateOptionsResult.Fail($"Use of a non-TLS URL in the 'applicationUrl' setting of the launch profile unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to 'true'. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + return ValidateOptionsResult.Fail($"The 'applicationUrl' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } return ValidateOptionsResult.Success; From 0b6208845a7b5ce9195c82f30ca58feca4442a34 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 13:53:01 +1100 Subject: [PATCH 23/39] Add some test cases. --- .../TransportOptionsValidatorTests.cs | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs diff --git a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs new file mode 100644 index 0000000000..ebb9913bc7 --- /dev/null +++ b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.Hosting.Dashboard; +using Microsoft.Extensions.Configuration; +using Xunit; + +namespace Aspire.Hosting.Tests.Dashboard; + +public class TransportOptionsValidatorTests +{ + [Fact] + public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFalse() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The 'applicationUrl' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWithInvalidUrl() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var invalidUrl = "...invalid...url..."; + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = invalidUrl; + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The 'applicationUrl' setting of the launch profile has value '{invalidUrl}' which could not be parsed as a URI.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWithMissingUrl() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToTrue() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = true; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } + + [Fact] + public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToTrue() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = true; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } + + [Fact] + public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToFalse() + { + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + + var validator = new TransportOptionsValidator(config); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } +} From c63b4fde170886eb3ebf88e30ef4359047ba8afa Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 14:35:33 +1100 Subject: [PATCH 24/39] Use ValidateOnstart --- .../AppHost/Properties/launchSettings.json | 4 +-- playground/TestShop/AppHost/appsettings.json | 2 +- .../Dashboard/TransportOptionsValidator.cs | 7 +++- .../DistributedApplicationBuilder.cs | 2 +- .../TransportOptionsValidatorTests.cs | 33 +++++++++++++++---- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/playground/TestShop/AppHost/Properties/launchSettings.json b/playground/TestShop/AppHost/Properties/launchSettings.json index 2bc9c4cc1c..d6edcc61d1 100644 --- a/playground/TestShop/AppHost/Properties/launchSettings.json +++ b/playground/TestShop/AppHost/Properties/launchSettings.json @@ -23,8 +23,8 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17031", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" - //"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/TestShop/AppHost/appsettings.json b/playground/TestShop/AppHost/appsettings.json index 80f87c3b44..31c092aa45 100644 --- a/playground/TestShop/AppHost/appsettings.json +++ b/playground/TestShop/AppHost/appsettings.json @@ -3,7 +3,7 @@ "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", - "Aspire.Hosting.Dcp": "Debug" + "Aspire.Hosting.Dcp": "Warning" } } } diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 094338d2c7..0cf96cb1a5 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -6,10 +6,15 @@ namespace Aspire.Hosting.Dashboard; -internal class TransportOptionsValidator(IConfiguration configuration) : IValidateOptions +internal class TransportOptionsValidator(IConfiguration configuration, DistributedApplicationExecutionContext executionContext) : IValidateOptions { public ValidateOptionsResult Validate(string? name, TransportOptions options) { + if (executionContext.IsPublishMode) + { + return ValidateOptionsResult.Success; + } + if (configuration[KnownConfigNames.AspNetCoreUrls] is not { } applicationUrls) { return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set."); diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index 5ce49fa8a6..f990f5b28a 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -91,7 +91,7 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) _innerBuilder.Services.AddSingleton(); // Dashboard - _innerBuilder.Services.AddOptions().PostConfigure(MapTransportOptionsFromCustomKeys); + _innerBuilder.Services.AddOptions().ValidateOnStart().PostConfigure(MapTransportOptionsFromCustomKeys); _innerBuilder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, TransportOptionsValidator>()); _innerBuilder.Services.AddSingleton(); _innerBuilder.Services.AddHostedService(sp => sp.GetRequiredService()); diff --git a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs index ebb9913bc7..a9c13318ee 100644 --- a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs +++ b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs @@ -12,13 +12,14 @@ public class TransportOptionsValidatorTests [Fact] public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFalse() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -27,9 +28,25 @@ public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFals ); } + [Fact] + public void InvalidTransportOptionSucceedValidationInPublishMode() + { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Publish); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; + + var validator = new TransportOptionsValidator(config, executionContext); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } + [Fact] public void ValidationFailsWithInvalidUrl() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -37,7 +54,7 @@ public void ValidationFailsWithInvalidUrl() var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = invalidUrl; - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -49,12 +66,13 @@ public void ValidationFailsWithInvalidUrl() [Fact] public void ValidationFailsWithMissingUrl() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -66,13 +84,14 @@ public void ValidationFailsWithMissingUrl() [Fact] public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToTrue() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = true; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } @@ -80,13 +99,14 @@ public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToT [Fact] public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToTrue() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = true; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } @@ -94,13 +114,14 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo [Fact] public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToFalse() { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; - var validator = new TransportOptionsValidator(config); + var validator = new TransportOptionsValidator(config, executionContext); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } From d298d85e676e8289bbb71681565cbd8af8bf2669 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 14:44:16 +1100 Subject: [PATCH 25/39] Remove random file. --- tests/cosmos.module.bicep | 42 --------------------------------------- 1 file changed, 42 deletions(-) delete mode 100644 tests/cosmos.module.bicep diff --git a/tests/cosmos.module.bicep b/tests/cosmos.module.bicep deleted file mode 100644 index e3fc296687..0000000000 --- a/tests/cosmos.module.bicep +++ /dev/null @@ -1,42 +0,0 @@ -targetScope = 'resourceGroup' - -@description('') -param location string = resourceGroup().location - -@description('') -param keyVaultName string - - -resource keyVault_IeF8jZvXV 'Microsoft.KeyVault/vaults@2022-07-01' existing = { - name: keyVaultName -} - -resource cosmosDBAccount_5pKmb8KAZ 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = { - name: toLower(take(concat('cosmos', uniqueString(resourceGroup().id)), 24)) - location: location - tags: { - 'aspire-resource-name': 'cosmos' - } - kind: 'GlobalDocumentDB' - properties: { - databaseAccountOfferType: 'Standard' - consistencyPolicy: { - defaultConsistencyLevel: 'Session' - } - locations: [ - { - locationName: location - failoverPriority: 0 - } - ] - } -} - -resource keyVaultSecret_Ddsc3HjrA 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = { - parent: keyVault_IeF8jZvXV - name: 'connectionString' - location: location - properties: { - value: 'AccountEndpoint=${cosmosDBAccount_5pKmb8KAZ.properties.documentEndpoint};AccountKey=${cosmosDBAccount_5pKmb8KAZ.listkeys(cosmosDBAccount_5pKmb8KAZ.apiVersion).primaryMasterKey}' - } -} From da1ff6b21cb00c32f9682d6795e60ba6922ddb9d Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 14:50:31 +1100 Subject: [PATCH 26/39] We don't need the dummy call inside DashboardServiceHost. --- src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs index 29da90b2e3..20ee29d084 100644 --- a/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs +++ b/src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs @@ -54,8 +54,7 @@ public DashboardServiceHost( ILoggerFactory loggerFactory, IConfigureOptions loggerOptions, ResourceNotificationService resourceNotificationService, - ResourceLoggerService resourceLoggerService, - IOptions transportOptions) + ResourceLoggerService resourceLoggerService) { _logger = loggerFactory.CreateLogger(); @@ -66,12 +65,6 @@ public DashboardServiceHost( return; } - // TODO: This is a temporary addition until P6 when we fully implement - // the dashboard auth features. For now we want to throw if the - // applicationUrl in the AppHost launch settings has a http endpoint - // and the ASPIRE_ALLOW_UNSECURED_TRANSPORT value is not set to true. - _ = transportOptions.Value.AllowUnsecureTransport; - try { var builder = WebApplication.CreateSlimBuilder(); From 54e5dad98b754958fcc7c0f3c5616b7772063d31 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 16:46:35 +1100 Subject: [PATCH 27/39] bool? -> bool with some extra test coverage. --- .../Dashboard/TransportOptions.cs | 2 +- .../Dashboard/TransportOptionsValidator.cs | 4 ++-- .../TransportOptionsValidatorTests.cs | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptions.cs b/src/Aspire.Hosting/Dashboard/TransportOptions.cs index f65b6da008..5e6fe8b00f 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptions.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptions.cs @@ -5,6 +5,6 @@ namespace Aspire.Hosting.Dashboard; internal class TransportOptions { - public bool? AllowUnsecureTransport { get; set; } + public bool AllowUnsecureTransport { get; set; } public string? BrowserToken { get; set; } } diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 0cf96cb1a5..32c0112577 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -15,7 +15,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) return ValidateOptionsResult.Success; } - if (configuration[KnownConfigNames.AspNetCoreUrls] is not { } applicationUrls) + if (configuration[KnownConfigNames.AspNetCoreUrls] is not { } applicationUrls || string.IsNullOrEmpty(applicationUrls)) { return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set."); } @@ -27,7 +27,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) return ValidateOptionsResult.Fail($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); } - if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport.GetValueOrDefault(false)) + if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport) { return ValidateOptionsResult.Fail($"The 'applicationUrl' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } diff --git a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs index a9c13318ee..85976667fe 100644 --- a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs +++ b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs @@ -81,6 +81,25 @@ public void ValidationFailsWithMissingUrl() ); } + [Fact] + public void ValidationFailsWithStringEmptyUrl() + { + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = string.Empty; + + var validator = new TransportOptionsValidator(config, executionContext); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set.", + result.FailureMessage + ); + } + [Fact] public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToTrue() { From 84b02d6db3a6cf5716cf68a44d99fab9e026b708 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 16:51:09 +1100 Subject: [PATCH 28/39] Update apphost launch settings. --- playground/AWS/AWS.AppHost/Properties/launchSettings.json | 3 ++- .../AzureSearch.AppHost/Properties/launchSettings.json | 3 ++- .../Properties/launchSettings.json | 3 ++- .../CosmosEndToEnd.AppHost/Properties/launchSettings.json | 3 ++- .../CustomResources.AppHost/Properties/launchSettings.json | 3 ++- .../Properties/launchSettings.json | 3 ++- .../OpenAIEndToEnd.AppHost/Properties/launchSettings.json | 3 ++- .../Properties/launchSettings.json | 6 ++++-- .../PostgresEndToEnd.AppHost/Properties/launchSettings.json | 3 ++- .../Properties/launchSettings.json | 3 ++- .../Properties/launchSettings.json | 3 ++- .../Stress/Stress.AppHost/Properties/launchSettings.json | 3 ++- .../BicepSample.AppHost/Properties/launchSettings.json | 3 ++- .../cdk/CdkSample.AppHost/Properties/launchSettings.json | 3 ++- playground/dapr/AppHost/Properties/launchSettings.json | 3 ++- .../mongo/Mongo.AppHost/Properties/launchSettings.json | 3 ++- .../mysql/MySqlDb.AppHost/Properties/launchSettings.json | 3 ++- playground/nats/Nats.AppHost/Properties/launchSettings.json | 3 ++- .../orleans/OrleansAppHost/Properties/launchSettings.json | 3 ++- playground/seq/Seq.AppHost/Properties/launchSettings.json | 3 ++- .../signalr/SignalRAppHost/Properties/launchSettings.json | 3 ++- 21 files changed, 44 insertions(+), 22 deletions(-) diff --git a/playground/AWS/AWS.AppHost/Properties/launchSettings.json b/playground/AWS/AWS.AppHost/Properties/launchSettings.json index bde6c5a767..c42f4003c0 100644 --- a/playground/AWS/AWS.AppHost/Properties/launchSettings.json +++ b/playground/AWS/AWS.AppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16216" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16216", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "manifest-publish": { diff --git a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json index 69941b6f40..e1b66caf70 100644 --- a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json +++ b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" }, }, "generate-manifest": { diff --git a/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json b/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json b/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json b/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json +++ b/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json b/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json +++ b/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json index 3185d212b1..93cc71e600 100644 --- a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16195" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16195", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json b/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json index f0f955e2d6..8d86fe9f72 100644 --- a/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "http-UseConnectionString": { @@ -23,7 +24,8 @@ "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", - "SimulateProduction": "true" + "SimulateProduction": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json b/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json b/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json b/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/Stress/Stress.AppHost/Properties/launchSettings.json b/playground/Stress/Stress.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/Stress/Stress.AppHost/Properties/launchSettings.json +++ b/playground/Stress/Stress.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json b/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json +++ b/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json b/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json +++ b/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/dapr/AppHost/Properties/launchSettings.json b/playground/dapr/AppHost/Properties/launchSettings.json index eac35bd52b..d4184205a4 100644 --- a/playground/dapr/AppHost/Properties/launchSettings.json +++ b/playground/dapr/AppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/mongo/Mongo.AppHost/Properties/launchSettings.json b/playground/mongo/Mongo.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/mongo/Mongo.AppHost/Properties/launchSettings.json +++ b/playground/mongo/Mongo.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json b/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json index 24959e7527..335ab85b85 100644 --- a/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json +++ b/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/nats/Nats.AppHost/Properties/launchSettings.json b/playground/nats/Nats.AppHost/Properties/launchSettings.json index 1a551c295c..036bda6998 100644 --- a/playground/nats/Nats.AppHost/Properties/launchSettings.json +++ b/playground/nats/Nats.AppHost/Properties/launchSettings.json @@ -8,7 +8,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/orleans/OrleansAppHost/Properties/launchSettings.json b/playground/orleans/OrleansAppHost/Properties/launchSettings.json index e5c69689a7..5c8f76c528 100644 --- a/playground/orleans/OrleansAppHost/Properties/launchSettings.json +++ b/playground/orleans/OrleansAppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/seq/Seq.AppHost/Properties/launchSettings.json b/playground/seq/Seq.AppHost/Properties/launchSettings.json index 32514f6378..57b46a6163 100644 --- a/playground/seq/Seq.AppHost/Properties/launchSettings.json +++ b/playground/seq/Seq.AppHost/Properties/launchSettings.json @@ -10,7 +10,8 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", - "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { diff --git a/playground/signalr/SignalRAppHost/Properties/launchSettings.json b/playground/signalr/SignalRAppHost/Properties/launchSettings.json index cca203b452..9eddf3e4e8 100644 --- a/playground/signalr/SignalRAppHost/Properties/launchSettings.json +++ b/playground/signalr/SignalRAppHost/Properties/launchSettings.json @@ -9,7 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16099" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16099", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, "generate-manifest": { From 4e03c6401c3c841d628d1b108bc4987497c9e898 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 17:08:05 +1100 Subject: [PATCH 29/39] PR feedback. --- .../Dashboard/DashboardTokenProvider.cs | 64 ------------------- .../Dashboard/TransportOptionsValidator.cs | 3 +- .../DistributedApplicationBuilder.cs | 6 +- .../DistributedApplicationOptions.cs | 5 ++ .../TestProject.AppHost/TestProgram.cs | 7 +- 5 files changed, 13 insertions(+), 72 deletions(-) delete mode 100644 src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs diff --git a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs b/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs deleted file mode 100644 index b8dfd2ade2..0000000000 --- a/src/Aspire.Hosting/Dashboard/DashboardTokenProvider.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text; -using Aspire.Hosting.Utils; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace Aspire.Hosting.Dashboard; - -internal interface IDashboardTokenProvider -{ - public string DashboardFrontendToken { get; } - public string DashboardOtlpToken { get; } - public string ResourceServerToken { get; } -} - -internal class DashboardTokenProvider : IDashboardTokenProvider -{ - public DashboardTokenProvider(ILogger logger, IOptions transportOptions) - { - if (transportOptions.Value.BrowserToken is not { } browserToken) - { - logger.LogDebug("Browser token was not supplied from environment, will be automatically generated."); - DashboardFrontendToken = GenerateToken(); - } - else - { - logger.LogDebug("Browser token was supplied from environment, will not be generated."); - DashboardFrontendToken = browserToken; - } - - DashboardOtlpToken = GenerateToken(); - ResourceServerToken = GenerateToken(); - } - - private static string GenerateToken() - { - var rawToken = PasswordGenerator.Generate( - 24, - lower: true, - upper: true, - numeric: true, - special: true, - minLower: 0, - minUpper: 0, - minNumeric: 0, - minSpecial: 0); - - var rawTokenBytes = Encoding.UTF8.GetBytes(rawToken); - -#if NET9_0_OR_GREATER - var encodedToken = Convert.ToHexStringLower(rawTokenBytes); -#else - var encodedToken = Convert.ToHexString(rawTokenBytes).ToLower(); -#endif - - return encodedToken; - } - - public string DashboardFrontendToken { get; } - public string DashboardOtlpToken { get; } - public string ResourceServerToken { get; } -} diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 32c0112577..475fa90208 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -15,7 +15,8 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) return ValidateOptionsResult.Success; } - if (configuration[KnownConfigNames.AspNetCoreUrls] is not { } applicationUrls || string.IsNullOrEmpty(applicationUrls)) + var applicationUrls = configuration[KnownConfigNames.AspNetCoreUrls]; + if (string.IsNullOrEmpty(applicationUrls)) { return ValidateOptionsResult.Fail($"AppHost does not have applicationUrl in launch profile, or {KnownConfigNames.AspNetCoreUrls} environment variable set."); } diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index f990f5b28a..cac48ac9ac 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -82,6 +82,11 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) ["AppHost:Directory"] = AppHostDirectory }); + if (options.AllowUnsecuredTransport) + { + _innerBuilder.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; + } + // Core things _innerBuilder.Services.AddSingleton(sp => new DistributedApplicationModel(Resources)); _innerBuilder.Services.AddHostedService(); @@ -96,7 +101,6 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) _innerBuilder.Services.AddSingleton(); _innerBuilder.Services.AddHostedService(sp => sp.GetRequiredService()); _innerBuilder.Services.AddLifecycleHook(); - _innerBuilder.Services.AddSingleton(); // DCP stuff _innerBuilder.Services.AddSingleton(); diff --git a/src/Aspire.Hosting/DistributedApplicationOptions.cs b/src/Aspire.Hosting/DistributedApplicationOptions.cs index 7a3b55a116..890187eb43 100644 --- a/src/Aspire.Hosting/DistributedApplicationOptions.cs +++ b/src/Aspire.Hosting/DistributedApplicationOptions.cs @@ -43,6 +43,11 @@ public DistributedApplicationOptions() internal bool DashboardEnabled => !DisableDashboard; + /// + /// Allows the use of HTTP urls for for the AppHost resource endpoint. + /// + public bool AllowUnsecuredTransport { get; set; } + private string? ResolveProjectDirectory() { var assemblyMetadata = Assembly?.GetCustomAttributes(); diff --git a/tests/testproject/TestProject.AppHost/TestProgram.cs b/tests/testproject/TestProject.AppHost/TestProgram.cs index 27b778714c..235945587c 100644 --- a/tests/testproject/TestProject.AppHost/TestProgram.cs +++ b/tests/testproject/TestProject.AppHost/TestProgram.cs @@ -34,12 +34,7 @@ private TestProgram(string[] args, Assembly assembly, bool includeIntegrationSer disableDashboard = true; } - AppBuilder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions { Args = args, DisableDashboard = disableDashboard, AssemblyName = assembly.FullName }); - - if (allowUnsecuredTransport) - { - AppBuilder.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; - } + AppBuilder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions { Args = args, DisableDashboard = disableDashboard, AssemblyName = assembly.FullName, AllowUnsecuredTransport = allowUnsecuredTransport }); var serviceAPath = Path.Combine(Projects.TestProject_AppHost.ProjectPath, @"..\TestProject.ServiceA\TestProject.ServiceA.csproj"); From 82efb143b3c00d68c26142ec575e545b8ae383a2 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 17:26:24 +1100 Subject: [PATCH 30/39] Handle DistributedApplicationOptions.AllowUnsecuredTransport and DistributedApplicationOptions.DisableDashboard to do the right thing in terms of validation. --- .../Dashboard/TransportOptionsValidator.cs | 10 ++-- .../TransportOptionsValidatorTests.cs | 60 ++++++++++++++++--- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 475fa90208..1ff63a946b 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -6,11 +6,13 @@ namespace Aspire.Hosting.Dashboard; -internal class TransportOptionsValidator(IConfiguration configuration, DistributedApplicationExecutionContext executionContext) : IValidateOptions +internal class TransportOptionsValidator(IConfiguration configuration, DistributedApplicationExecutionContext executionContext, DistributedApplicationOptions distributedApplicationOptions) : IValidateOptions { - public ValidateOptionsResult Validate(string? name, TransportOptions options) + public ValidateOptionsResult Validate(string? name, TransportOptions transportOptions) { - if (executionContext.IsPublishMode) + var effectiveAllowUnsecureTransport = transportOptions.AllowUnsecureTransport || distributedApplicationOptions.DisableDashboard || distributedApplicationOptions.AllowUnsecuredTransport; + + if (executionContext.IsPublishMode || effectiveAllowUnsecureTransport) { return ValidateOptionsResult.Success; } @@ -28,7 +30,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions options) return ValidateOptionsResult.Fail($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); } - if (parsedFirstApplicationUrl.Scheme == "http" && !options.AllowUnsecureTransport) + if (parsedFirstApplicationUrl.Scheme == "http" && !effectiveAllowUnsecureTransport) { return ValidateOptionsResult.Fail($"The 'applicationUrl' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } diff --git a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs index 85976667fe..ef177f081a 100644 --- a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs +++ b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs @@ -12,6 +12,7 @@ public class TransportOptionsValidatorTests [Fact] public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFalse() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -19,7 +20,7 @@ public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFals var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -31,6 +32,7 @@ public void ValidationFailsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToFals [Fact] public void InvalidTransportOptionSucceedValidationInPublishMode() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Publish); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -38,7 +40,43 @@ public void InvalidTransportOptionSucceedValidationInPublishMode() var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } + + [Fact] + public void InvalidTransportOptionSucceedValidationWithDashboardDisabled() + { + var distributedApplicationOptions = new DistributedApplicationOptions() + { + DisableDashboard = true + }; + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Succeeded); + } + + [Fact] + public void InvalidTransportOptionSucceedValidationWithDistributedAppOptionsFlag() + { + var distributedApplicationOptions = new DistributedApplicationOptions() + { + AllowUnsecuredTransport = true + }; + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } @@ -46,6 +84,7 @@ public void InvalidTransportOptionSucceedValidationInPublishMode() [Fact] public void ValidationFailsWithInvalidUrl() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -54,7 +93,7 @@ public void ValidationFailsWithInvalidUrl() var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = invalidUrl; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -66,13 +105,14 @@ public void ValidationFailsWithInvalidUrl() [Fact] public void ValidationFailsWithMissingUrl() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -84,6 +124,7 @@ public void ValidationFailsWithMissingUrl() [Fact] public void ValidationFailsWithStringEmptyUrl() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -91,7 +132,7 @@ public void ValidationFailsWithStringEmptyUrl() var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = string.Empty; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Failed); Assert.Equal( @@ -103,6 +144,7 @@ public void ValidationFailsWithStringEmptyUrl() [Fact] public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToTrue() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = true; @@ -110,7 +152,7 @@ public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToT var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "http://localhost:1234"; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } @@ -118,6 +160,7 @@ public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToT [Fact] public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToTrue() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = true; @@ -125,7 +168,7 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } @@ -133,6 +176,7 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo [Fact] public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetToFalse() { + var distributedApplicationOptions = new DistributedApplicationOptions(); var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); var options = new TransportOptions(); options.AllowUnsecureTransport = false; @@ -140,7 +184,7 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; - var validator = new TransportOptionsValidator(config, executionContext); + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); Assert.True(result.Succeeded); } From b04f9d119f22701a092f5f100e806c9ef2441aa2 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 17:34:46 +1100 Subject: [PATCH 31/39] remove unnecessary set of config. --- src/Aspire.Hosting/DistributedApplicationBuilder.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Aspire.Hosting/DistributedApplicationBuilder.cs b/src/Aspire.Hosting/DistributedApplicationBuilder.cs index cac48ac9ac..b16f2a78dd 100644 --- a/src/Aspire.Hosting/DistributedApplicationBuilder.cs +++ b/src/Aspire.Hosting/DistributedApplicationBuilder.cs @@ -82,11 +82,6 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options) ["AppHost:Directory"] = AppHostDirectory }); - if (options.AllowUnsecuredTransport) - { - _innerBuilder.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; - } - // Core things _innerBuilder.Services.AddSingleton(sp => new DistributedApplicationModel(Resources)); _innerBuilder.Services.AddHostedService(); From 11c6e40df43f884e13b4ec81507343bc4d870698 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 20:50:21 +1100 Subject: [PATCH 32/39] Cover other URLs and complete code coverage. --- .../Dashboard/TransportOptionsValidator.cs | 37 ++++- src/Shared/KnownConfigNames.cs | 2 + .../TransportOptionsValidatorTests.cs | 148 +++++++++++++++++- 3 files changed, 180 insertions(+), 7 deletions(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs index 1ff63a946b..20e3fe2dd5 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptionsValidator.cs @@ -17,6 +17,7 @@ public ValidateOptionsResult Validate(string? name, TransportOptions transportOp return ValidateOptionsResult.Success; } + // Validate ASPNETCORE_URLS var applicationUrls = configuration[KnownConfigNames.AspNetCoreUrls]; if (string.IsNullOrEmpty(applicationUrls)) { @@ -30,11 +31,45 @@ public ValidateOptionsResult Validate(string? name, TransportOptions transportOp return ValidateOptionsResult.Fail($"The 'applicationUrl' setting of the launch profile has value '{firstApplicationUrl}' which could not be parsed as a URI."); } - if (parsedFirstApplicationUrl.Scheme == "http" && !effectiveAllowUnsecureTransport) + if (parsedFirstApplicationUrl.Scheme == "http") { return ValidateOptionsResult.Fail($"The 'applicationUrl' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); } + // Vaidate DOTNET_DASHBOARD_OTLP_ENDPOINT_URL + var dashboardOtlpEndpointUrl = configuration[KnownConfigNames.DashboardOtlpEndpointUrl]; + if (string.IsNullOrEmpty(dashboardOtlpEndpointUrl)) + { + return ValidateOptionsResult.Fail($"AppHost does not have the {KnownConfigNames.DashboardOtlpEndpointUrl} setting defined."); + } + + if (!Uri.TryCreate(dashboardOtlpEndpointUrl, UriKind.Absolute, out var parsedDashboardOtlpEndpointUrl)) + { + return ValidateOptionsResult.Fail($"The {KnownConfigNames.DashboardOtlpEndpointUrl} setting with a value of '{dashboardOtlpEndpointUrl}' could not be parsed as a URI."); + } + + if (parsedDashboardOtlpEndpointUrl.Scheme == "http") + { + return ValidateOptionsResult.Fail($"The '{KnownConfigNames.DashboardOtlpEndpointUrl}' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + } + + // Vaidate DOTNET_DASHBOARD_RESOURCE_SERVER_ENDPOINT_URL + var resourceServiceEndpointUrl = configuration[KnownConfigNames.ResourceServiceEndpointUrl]; + if (string.IsNullOrEmpty(resourceServiceEndpointUrl)) + { + return ValidateOptionsResult.Fail($"AppHost does not have the {KnownConfigNames.ResourceServiceEndpointUrl} setting defined."); + } + + if (!Uri.TryCreate(resourceServiceEndpointUrl, UriKind.Absolute, out var parsedResourceServiceEndpointUrl)) + { + return ValidateOptionsResult.Fail($"The {KnownConfigNames.ResourceServiceEndpointUrl} setting with a value of '{resourceServiceEndpointUrl}' could not be parsed as a URI."); + } + + if (parsedResourceServiceEndpointUrl.Scheme == "http") + { + return ValidateOptionsResult.Fail($"The '{KnownConfigNames.ResourceServiceEndpointUrl}' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details."); + } + return ValidateOptionsResult.Success; } } diff --git a/src/Shared/KnownConfigNames.cs b/src/Shared/KnownConfigNames.cs index 0733b79a5e..3e7efd5ac3 100644 --- a/src/Shared/KnownConfigNames.cs +++ b/src/Shared/KnownConfigNames.cs @@ -7,4 +7,6 @@ internal static class KnownConfigNames { public static string AspNetCoreUrls = "ASPNETCORE_URLS"; public static string AllowUnsecuredTransport = "ASPIRE_ALLOW_UNSECURED_TRANSPORT"; + public static string DashboardOtlpEndpointUrl = "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"; + public static string ResourceServiceEndpointUrl = "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL"; } diff --git a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs index ef177f081a..5d1084c5f5 100644 --- a/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs +++ b/tests/Aspire.Hosting.Tests/Dashboard/TransportOptionsValidatorTests.cs @@ -42,7 +42,7 @@ public void InvalidTransportOptionSucceedValidationInPublishMode() var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } [Fact] @@ -60,7 +60,7 @@ public void InvalidTransportOptionSucceedValidationWithDashboardDisabled() var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } [Fact] @@ -78,7 +78,7 @@ public void InvalidTransportOptionSucceedValidationWithDistributedAppOptionsFlag var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } [Fact] @@ -141,6 +141,140 @@ public void ValidationFailsWithStringEmptyUrl() ); } + [Fact] + public void ValidationFailsWhenResourceUrlNotDefined() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = string.Empty; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = "https://localhost:1236"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"AppHost does not have the {KnownConfigNames.ResourceServiceEndpointUrl} setting defined.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWhenOtlpUrlNotDefined() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = "https://localhost:1235"; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = string.Empty; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"AppHost does not have the {KnownConfigNames.DashboardOtlpEndpointUrl} setting defined.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWhenResourceServiceUrlMalformed() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var invalidUrl = "...invalid...url..."; + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = invalidUrl; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = "https://localhost:1236"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The {KnownConfigNames.ResourceServiceEndpointUrl} setting with a value of '{invalidUrl}' could not be parsed as a URI.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWhenOtlpUrlMalformed() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var invalidUrl = "...invalid...url..."; + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = "https://localhost:1235"; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = invalidUrl; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The {KnownConfigNames.DashboardOtlpEndpointUrl} setting with a value of '{invalidUrl}' could not be parsed as a URI.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWhenDashboardOtlpUrlIsHttp() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = "https://localhost:1235"; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = "http://localhost:1236"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The '{KnownConfigNames.DashboardOtlpEndpointUrl}' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details.", + result.FailureMessage + ); + } + + [Fact] + public void ValidationFailsWhenResourceServiceUrlIsHttp() + { + var distributedApplicationOptions = new DistributedApplicationOptions(); + var executionContext = new DistributedApplicationExecutionContext(DistributedApplicationOperation.Run); + var options = new TransportOptions(); + options.AllowUnsecureTransport = false; + + var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); + config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = "http://localhost:1235"; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = "https://localhost:1236"; + + var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); + var result = validator.Validate(null, options); + Assert.True(result.Failed); + Assert.Equal( + $"The '{KnownConfigNames.ResourceServiceEndpointUrl}' setting must be an https address unless the '{KnownConfigNames.AllowUnsecuredTransport}' environment variable is set to true. This configuration is commonly set in the launch profile. See https://aka.ms/dotnet/aspire/allowunsecuredtransport for more details.", + result.FailureMessage + ); + } + [Fact] public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToTrue() { @@ -154,7 +288,7 @@ public void ValidationSucceedsWhenHttpUrlSpecifiedWithAllowSecureTransportSetToT var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } [Fact] @@ -170,7 +304,7 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } [Fact] @@ -183,9 +317,11 @@ public void ValidationSucceedsWhenHttpsUrlSpecifiedWithAllowSecureTransportSetTo var config = new ConfigurationBuilder().AddInMemoryCollection().Build(); config[KnownConfigNames.AspNetCoreUrls] = "https://localhost:1234"; + config[KnownConfigNames.DashboardOtlpEndpointUrl] = "https://localhost:1235"; + config[KnownConfigNames.ResourceServiceEndpointUrl] = "https://localhost:1236"; var validator = new TransportOptionsValidator(config, executionContext, distributedApplicationOptions); var result = validator.Validate(null, options); - Assert.True(result.Succeeded); + Assert.True(result.Succeeded, result.FailureMessage); } } From 741dc58bc3c8e0fd08d0e4e1d51823b728f262ab Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 21:14:41 +1100 Subject: [PATCH 33/39] Fix issue of project not working in helix. --- .../TestProject.AppHost/TestProject.AppHost.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj index b89aa59e72..9fb041fbea 100644 --- a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj +++ b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj @@ -8,10 +8,6 @@ true - - - - @@ -37,6 +33,7 @@ + From b0300f97f6fc36fb4770dc299ca932b05432a614 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 21:18:41 +1100 Subject: [PATCH 34/39] Enable unsecured transport in helix fixture. --- tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs b/tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs index 46c1cefcd0..45118838cd 100644 --- a/tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs +++ b/tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs @@ -51,6 +51,7 @@ public IntegrationServicesFixture(IMessageSink diagnosticMessageSink) { BuildEnvironment.EnvVars["TestsRunningOutsideOfRepo"] = "true"; } + BuildEnvironment.EnvVars.Add("ASPIRE_ALLOW_UNSECURED_TRANSPORT", "true"); } public async Task InitializeAsync() From 9a605dfe2a91c37b8ad45ca3518ed9fa87376b2a Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Wed, 27 Mar 2024 21:54:36 +1100 Subject: [PATCH 35/39] Helix test debugging. --- tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj index 9fb041fbea..8247cf4340 100644 --- a/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj +++ b/tests/testproject/TestProject.AppHost/TestProject.AppHost.csproj @@ -33,7 +33,6 @@ - From d2b05e727b0096e43ae27a34fb1693964a2e6f4e Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 28 Mar 2024 00:35:15 +1100 Subject: [PATCH 36/39] Update TransportOptions.cs Co-authored-by: Eric Erhardt --- src/Aspire.Hosting/Dashboard/TransportOptions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Aspire.Hosting/Dashboard/TransportOptions.cs b/src/Aspire.Hosting/Dashboard/TransportOptions.cs index 5e6fe8b00f..ad6294c3d3 100644 --- a/src/Aspire.Hosting/Dashboard/TransportOptions.cs +++ b/src/Aspire.Hosting/Dashboard/TransportOptions.cs @@ -6,5 +6,4 @@ namespace Aspire.Hosting.Dashboard; internal class TransportOptions { public bool AllowUnsecureTransport { get; set; } - public string? BrowserToken { get; set; } } From b077b822830f0d7f94bdac238791ea911dd21f31 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 28 Mar 2024 10:34:54 +1100 Subject: [PATCH 37/39] Don't need to set config manually anymore. --- tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs index d16bece185..154885df8a 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingBuilderTests.cs @@ -14,7 +14,6 @@ public class TestingBuilderTests public async Task HasEndPoints() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -33,7 +32,6 @@ public async Task HasEndPoints() public async Task CanGetResources() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -47,7 +45,6 @@ public async Task CanGetResources() public async Task HttpClientGetTest() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); await app.StartAsync(); @@ -61,7 +58,6 @@ public async Task HttpClientGetTest() public async Task GetHttpClientBeforeStart() { var appHost = await DistributedApplicationTestingBuilder.CreateAsync(); - appHost.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; await using var app = await appHost.BuildAsync(); Assert.Throws(() => app.CreateHttpClient("mywebapp1")); } From 5ae82c1ff8f3e5855e2208e325e4f47fcdf309f3 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 28 Mar 2024 11:38:22 +1100 Subject: [PATCH 38/39] launchSettings apalooza --- .../Properties/launchSettings.json | 13 ++++++ .../Properties/launchSettings.json | 44 ++++++++++++------- .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 13 ++++++ .../Properties/launchSettings.json | 29 ++++++++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../AppHost/Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 13 ++++++ .../Properties/launchSettings.json | 13 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 14 ++++++ .../Properties/launchSettings.json | 13 ++++++ 21 files changed, 318 insertions(+), 16 deletions(-) diff --git a/playground/AWS/AWS.AppHost/Properties/launchSettings.json b/playground/AWS/AWS.AppHost/Properties/launchSettings.json index c42f4003c0..7def19447c 100644 --- a/playground/AWS/AWS.AppHost/Properties/launchSettings.json +++ b/playground/AWS/AWS.AppHost/Properties/launchSettings.json @@ -1,6 +1,18 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15068;http://localhost:15069", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16216", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16216", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, diff --git a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json index e1b66caf70..7867967352 100644 --- a/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json +++ b/playground/AzureSearchEndToEnd/AzureSearch.AppHost/Properties/launchSettings.json @@ -1,29 +1,41 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "http": { + "https": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:15288", + "applicationUrl": "https://localhost:15287;http://localhost:15288", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155", - "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16155", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" }, - }, - "generate-manifest": { - "commandName": "Project", - "launchBrowser": true, - "dotnetRunMessages": true, - "commandLineArgs": "--publisher manifest --output-path aspire-manifest.json", - "applicationUrl": "http://localhost:15288", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155" + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15288", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", + "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" + }, + "generate-manifest": { + "commandName": "Project", + "launchBrowser": true, + "dotnetRunMessages": true, + "commandLineArgs": "--publisher manifest --output-path aspire-manifest.json", + "applicationUrl": "http://localhost:15288", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16155" + } + } } } - } } diff --git a/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json b/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json b/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json index 57b46a6163..1568103ca4 100644 --- a/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/CosmosEndToEnd/CosmosEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json b/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json +++ b/playground/CustomResources/CustomResources.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json b/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json +++ b/playground/DatabaseMigration/DatabaseMigration.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json index 93cc71e600..a0a7265f68 100644 --- a/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/OpenAIEndToEnd/OpenAIEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,18 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15215;http://localhost:15216", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16195", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16195", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, diff --git a/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json b/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json index 8d86fe9f72..a00013526c 100644 --- a/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/ParameterEndToEnd/ParameterEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,33 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https-UseContainer": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, + "https-UseConnectionString": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", + "SimulateProduction": "true" + } + }, "http-UseContainer": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +37,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } @@ -23,6 +51,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "SimulateProduction": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" diff --git a/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json b/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json b/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/ProxylessEndToEnd/ProxylessEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json b/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json +++ b/playground/SqlServerEndToEnd/SqlServerEndToEnd.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/Stress/Stress.AppHost/Properties/launchSettings.json b/playground/Stress/Stress.AppHost/Properties/launchSettings.json index 57b46a6163..cefdd7e8a4 100644 --- a/playground/Stress/Stress.AppHost/Properties/launchSettings.json +++ b/playground/Stress/Stress.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17037", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json b/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json +++ b/playground/bicep/BicepSample.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json b/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json +++ b/playground/cdk/CdkSample.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/dapr/AppHost/Properties/launchSettings.json b/playground/dapr/AppHost/Properties/launchSettings.json index d4184205a4..89883cf642 100644 --- a/playground/dapr/AppHost/Properties/launchSettings.json +++ b/playground/dapr/AppHost/Properties/launchSettings.json @@ -1,5 +1,18 @@ { "profiles": { + "https": { + "commandName": "Project", + "launchBrowser": true, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16031", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "launchBrowser": true, @@ -9,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/mongo/Mongo.AppHost/Properties/launchSettings.json b/playground/mongo/Mongo.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/mongo/Mongo.AppHost/Properties/launchSettings.json +++ b/playground/mongo/Mongo.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json b/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json index 335ab85b85..df1073aafa 100644 --- a/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json +++ b/playground/mysql/MySqlDb.AppHost/Properties/launchSettings.json @@ -1,6 +1,18 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15223;http://localhost:15224", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16160", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, diff --git a/playground/nats/Nats.AppHost/Properties/launchSettings.json b/playground/nats/Nats.AppHost/Properties/launchSettings.json index 036bda6998..bd97744c4f 100644 --- a/playground/nats/Nats.AppHost/Properties/launchSettings.json +++ b/playground/nats/Nats.AppHost/Properties/launchSettings.json @@ -1,5 +1,17 @@ { "profiles": { + "https": { + "commandName": "Project", + "launchBrowser": true, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:18887;http://localhost:18888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16160", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" + } + }, "http": { "commandName": "Project", "launchBrowser": true, @@ -9,6 +21,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16160", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, diff --git a/playground/orleans/OrleansAppHost/Properties/launchSettings.json b/playground/orleans/OrleansAppHost/Properties/launchSettings.json index 5c8f76c528..6344471f89 100644 --- a/playground/orleans/OrleansAppHost/Properties/launchSettings.json +++ b/playground/orleans/OrleansAppHost/Properties/launchSettings.json @@ -1,5 +1,18 @@ { "profiles": { + "https": { + "commandName": "Project", + "launchBrowser": true, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16031", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "launchBrowser": true, @@ -9,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/seq/Seq.AppHost/Properties/launchSettings.json b/playground/seq/Seq.AppHost/Properties/launchSettings.json index 57b46a6163..f9dac51d48 100644 --- a/playground/seq/Seq.AppHost/Properties/launchSettings.json +++ b/playground/seq/Seq.AppHost/Properties/launchSettings.json @@ -1,6 +1,19 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15887;http://localhost:15888", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037", + "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +23,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } diff --git a/playground/signalr/SignalRAppHost/Properties/launchSettings.json b/playground/signalr/SignalRAppHost/Properties/launchSettings.json index 9eddf3e4e8..241071480d 100644 --- a/playground/signalr/SignalRAppHost/Properties/launchSettings.json +++ b/playground/signalr/SignalRAppHost/Properties/launchSettings.json @@ -1,6 +1,18 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:15015;http://localhost:15016", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:16099", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17037" + } + }, "http": { "commandName": "Project", "dotnetRunMessages": true, @@ -10,6 +22,7 @@ "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16099", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17038", "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" } }, From 654fa37cf8f5afb41d1598737e42f8b106fee792 Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Thu, 28 Mar 2024 12:17:26 +1100 Subject: [PATCH 39/39] Remove unnecessary fixture subclass. --- .../TestingFactoryTests.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs index c3071c05ae..c337dd1fb1 100644 --- a/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs +++ b/tests/Aspire.Hosting.Testing.Tests/TestingFactoryTests.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Testing.Tests; -public class TestingFactoryTests(DistributedApplicationFixtureWithAllowUnsecureTransport fixture) : IClassFixture> +public class TestingFactoryTests(DistributedApplicationFixture fixture) : IClassFixture> { private readonly DistributedApplication _app = fixture.Application; @@ -48,12 +48,3 @@ private sealed record WeatherForecast(DateOnly Date, int TemperatureC, string? S public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); } } - -public class DistributedApplicationFixtureWithAllowUnsecureTransport : DistributedApplicationFixture where TEntryPoint: class -{ - protected override void OnBuilding(DistributedApplicationBuilder applicationBuilder) - { - applicationBuilder.Configuration[KnownConfigNames.AllowUnsecuredTransport] = "true"; - base.OnBuilding(applicationBuilder); - } -}