Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organize dashboard config to use strongly typed options, support primary/secondary API keys and rotation #3119

Merged
merged 5 commits into from
Mar 26, 2024

Conversation

JamesNK
Copy link
Member

@JamesNK JamesNK commented Mar 23, 2024

Fixes #2996

  • Change dashboard config to be loaded via options
    • Use options validation
    • Use options post config to apply shortcut config over the top of structured config, e.g. DOTNET_DASHBOARD_OTLP_ENDPOINT_URL is set to Dashboard:Otlp:EndpointUrl.
  • Change OLTP API key auth to have primary and secondary keys
  • Change OTLP API key auth to use IOptionsMonitor<T> to get latest keys after config changes
  • Add DOTNET_DASHBOARD_CONFIG_FILE_PATH which configs a location to load JSON from a file. This can be used in cloud hosting scenarios to point at a mounted volume. Changes to the file can be applied to dashboard without restarting the app (for API key rotation without process restart)
  • Tests

TODO:

  • Resource service endpoint URL doesn't use new config yet
  • Update dashboard readme
  • Remove old code
Microsoft Reviewers: Open in CodeFlow

@JamesNK
Copy link
Member Author

JamesNK commented Mar 25, 2024

Review please 🙏

@JamesNK JamesNK changed the title Dashboard configpocalypse Organize dashboard config to use strongly typed options, support primary/secondary API keys and rotation Mar 25, 2024
@JamesNK JamesNK force-pushed the jamesnk/otlpkeys-configuration branch from c5e3c1a to 12de1fb Compare March 26, 2024 01:16
Comment on lines 51 to 52
public string? StoreName { get; set; }
public StoreLocation? Location { get; set; }
Copy link
Member Author

@JamesNK JamesNK Mar 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drewnoakes I changed StoreName and Location just properties on the cert options.

Couple of reasons:

  • This matches Kestrel endpoint config for HTTPS.
  • Having store name and location in a nested KeyStore section seems odd when the subject isn't. And FilePath/Password isn't nested under a file section. Simpler to just have a flat list of properties.

@davidfowl
Copy link
Member

@eerhardt we should use the config binder source gen and config schema generator, right?

Comment on lines +366 to 369
.AddScheme<OtlpCompositeAuthenticationHandlerOptions, OtlpCompositeAuthenticationHandler>(OtlpCompositeAuthenticationDefaults.AuthenticationScheme, o => { })
.AddScheme<OtlpApiKeyAuthenticationHandlerOptions, OtlpApiKeyAuthenticationHandler>(OtlpApiKeyAuthenticationDefaults.AuthenticationScheme, o => { })
.AddScheme<OtlpConnectionAuthenticationHandlerOptions, OtlpConnectionAuthenticationHandler>(OtlpConnectionAuthenticationDefaults.AuthenticationScheme, o => { })
.AddCertificate(options =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not important for this PR but it would look nicer if these were hidden in a helper extension method. Sorta like AddCertifcate is 😄

@@ -119,7 +118,7 @@ GrpcChannel CreateChannel()
ClientCertificates = certificates
};

configuration.Bind("ResourceServiceClient:Ssl", httpHandler.SslOptions);
configuration.Bind("Dashboard:ResourceServiceClient:Ssl", httpHandler.SslOptions);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this come from options? It's because we're binding this type directly...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drewnoakes ?

I think it's used as a simple way to set TLS config in tests without having to explicitly add more config.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should own all of the options types and copy settings over explicitly. Less fragile. Can be follow up.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about continuing to do this, but not advertising it in docs? In other words, it's an internal implementaiton detail. A private API.

Then we add new options if people ask for them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we preserve the schema?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. What do you mean?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You said don't document it, I assume that to mean, we don't document it because we might change it later so it would be a breaking change if we do.

I'm asking if we know what the existing schema is, and can we preserve it to avoid breaking people.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about this type adding something then suddenly config binding breaks. Or we switch to the source generator then it breaks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not public API so we can switch the type behind the scenes.

Copy link
Member

@davidfowl davidfowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left feedback, but this LGTM

src/Aspire.Dashboard/DashboardWebApplication.cs Outdated Show resolved Hide resolved
src/Aspire.Dashboard/DashboardWebApplication.cs Outdated Show resolved Hide resolved
src/Aspire.Dashboard/DashboardWebApplication.cs Outdated Show resolved Hide resolved
src/Aspire.Dashboard/README.md Outdated Show resolved Hide resolved
src/Aspire.Dashboard/README.md Outdated Show resolved Hide resolved
src/Aspire.Hosting/Dcp/ApplicationExecutor.cs Outdated Show resolved Hide resolved
src/Shared/DashboardConfigNames.cs Show resolved Hide resolved
@JamesNK JamesNK enabled auto-merge (squash) March 26, 2024 13:15
@JamesNK JamesNK merged commit 14a97ab into main Mar 26, 2024
8 checks passed
@JamesNK JamesNK deleted the jamesnk/otlpkeys-configuration branch March 26, 2024 14:06
@JamesNK
Copy link
Member Author

JamesNK commented Mar 26, 2024

/backport to release/8.0-preview5

Copy link
Contributor

Started backporting to release/8.0-preview5: https://github.com/dotnet/aspire/actions/runs/8437452822

@eerhardt
Copy link
Member

@eerhardt we should use the config binder source gen

I would use the config binder source gen, yes. It's main benefit is trimming and AOT, but it also helps with startup perf because you don't need to use reflection to inspect the Options properties and set their values. The reflection based ConfigBinder is notoriously slow.

and config schema generator, right?

The config schema generator would have less value here because we don't ship a NuGet package for the Dashboard. Today, the only thing consuming these schemas is we put them in the NuGet packages, and when someone adds a PackageRef VS will pick it up and combine it in the appsettings.json schema. But here there is no flow like that. It would be useful for documentation purposes, or if we wanted to ship the config schema some other way.

@github-actions github-actions bot locked and limited conversation to collaborators Apr 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make dashboard configuration align with standard .NET configuration
4 participants