-
Notifications
You must be signed in to change notification settings - Fork 651
Add CertificateClient and KeyClient support to Aspire.Azure.Security.KeyVault #8408
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
Changes from all commits
29ee021
1863222
57865d0
d4f760c
5b1206a
a3cd2a1
a9fe223
a11ef4a
fb11e58
70cc770
c2236bb
4919723
a1d8071
8ef9254
9dd500c
c53f6b6
1070dd1
1fd06b1
9fac8ee
df0d64a
71a1d57
88f9b21
a9fc82d
7679f1a
228b73f
6131630
0b92db3
3837592
6fe9df6
5941be1
4dcf0c9
5a5539b
9e70672
951e331
2d5bd2f
4c0d3e1
315fc61
0a75d14
526e23d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
using Aspire.Azure.Common; | ||
using Azure.Core; | ||
using Azure.Core.Extensions; | ||
using Microsoft.Extensions.Azure; | ||
|
||
namespace Aspire.Azure.Security.KeyVault; | ||
|
||
/// <summary> | ||
/// <para>Abstracts the common configuration binding required by <see cref="AzureComponent{TSettings, TClient, TClientOptions}"/></para> | ||
/// <para>Deriving type implements KeyVaultClient specific item:</para> | ||
/// <para><see cref="AzureComponent{TSettings, TClient, TClientOptions}.CreateHealthCheck(TClient, TSettings)"/></para> | ||
/// </summary> | ||
/// <typeparam name="TClient">The KeyVaultClient type for this component.</typeparam> | ||
/// <typeparam name="TOptions">The associated configuration for the <typeparamref name="TClient"/></typeparam> | ||
internal abstract class AbstractAzureKeyVaultComponent<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions> | ||
: AzureComponent<AzureSecurityKeyVaultSettings, TClient, TOptions> | ||
where TClient : class | ||
where TOptions : class | ||
{ | ||
internal abstract TClient CreateComponentClient(Uri vaultUri, TOptions options, TokenCredential cred); | ||
|
||
protected override IAzureClientBuilder<TClient, TOptions> AddClient(AzureClientFactoryBuilder azureFactoryBuilder, AzureSecurityKeyVaultSettings settings, string connectionName, string configurationSectionName) | ||
{ | ||
return azureFactoryBuilder.AddClient<TClient, TOptions>((options, cred, _) => | ||
{ | ||
if (settings.VaultUri is null) | ||
{ | ||
throw new InvalidOperationException($"VaultUri is missing. It should be provided in 'ConnectionStrings:{connectionName}' or under the 'VaultUri' key in the '{configurationSectionName}' configuration section."); | ||
} | ||
|
||
return CreateComponentClient(settings.VaultUri, options, cred); | ||
}); | ||
} | ||
|
||
protected override bool GetHealthCheckEnabled(AzureSecurityKeyVaultSettings settings) | ||
=> !settings.DisableHealthChecks; | ||
|
||
protected override TokenCredential? GetTokenCredential(AzureSecurityKeyVaultSettings settings) | ||
=> settings.Credential; | ||
|
||
protected override bool GetMetricsEnabled(AzureSecurityKeyVaultSettings settings) | ||
=> false; | ||
|
||
protected override bool GetTracingEnabled(AzureSecurityKeyVaultSettings settings) | ||
=> !settings.DisableTracing; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Aspire.Azure.Common; | ||
using Aspire.Azure.Security.KeyVault; | ||
using Azure.Core; | ||
using Azure.Core.Extensions; | ||
using Azure.Security.KeyVault.Certificates; | ||
using Microsoft.Extensions.Azure; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
|
||
namespace Microsoft.Extensions.Hosting; | ||
|
||
/// <summary> | ||
/// Representation of an <see cref="AzureComponent{TSettings, TClient, TClientOptions}"/> configured as a <see cref="CertificateClient"/> | ||
/// </summary> | ||
internal sealed class AzureKeyVaultCertificatesComponent : AbstractAzureKeyVaultComponent<CertificateClient, CertificateClientOptions> | ||
{ | ||
internal override CertificateClient CreateComponentClient(Uri vaultUri, CertificateClientOptions options, TokenCredential cred) | ||
=> new(vaultUri, cred, options); | ||
|
||
protected override bool GetHealthCheckEnabled(AzureSecurityKeyVaultSettings settings) | ||
=> false; | ||
|
||
protected override IHealthCheck CreateHealthCheck(CertificateClient client, AzureSecurityKeyVaultSettings settings) | ||
=> throw new NotImplementedException(); | ||
|
||
protected override void BindClientOptionsToConfiguration(IAzureClientBuilder<CertificateClient, CertificateClientOptions> clientBuilder, IConfiguration configuration) | ||
#pragma warning disable IDE0200 // Remove unnecessary lambda expression - needed so the ConfigBinder Source Generator works | ||
=> clientBuilder.ConfigureOptions(options => configuration.Bind(options)); | ||
#pragma warning restore IDE0200 // Remove unnecessary lambda expression | ||
|
||
protected override void BindSettingsToConfiguration(AzureSecurityKeyVaultSettings settings, IConfiguration configuration) | ||
=> configuration.Bind(settings); | ||
james-gould marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Aspire.Azure.Security.KeyVault; | ||
using Azure.Core; | ||
using Azure.Core.Extensions; | ||
using Azure.Security.KeyVault.Keys; | ||
using Microsoft.Extensions.Azure; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
|
||
namespace Microsoft.Extensions.Hosting; | ||
|
||
internal sealed class AzureKeyVaultKeysComponent : AbstractAzureKeyVaultComponent<KeyClient, KeyClientOptions> | ||
{ | ||
protected override bool GetHealthCheckEnabled(AzureSecurityKeyVaultSettings settings) | ||
=> false; | ||
|
||
protected override IHealthCheck CreateHealthCheck(KeyClient client, AzureSecurityKeyVaultSettings settings) | ||
=> throw new NotImplementedException(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this going to throw if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @james-gould I think you need to add this is the two components that don't provide the health-check protected override bool GetHealthCheckEnabled(AzureSecurityKeyVaultSettings settings)
{
return false;
} I will add it myself and approve the PR, unless you think it's wrong and we can then change it. |
||
|
||
internal override KeyClient CreateComponentClient(Uri vaultUri, KeyClientOptions options, TokenCredential cred) | ||
=> new(vaultUri, cred, options); | ||
|
||
protected override void BindClientOptionsToConfiguration(IAzureClientBuilder<KeyClient, KeyClientOptions> clientBuilder, IConfiguration configuration) | ||
#pragma warning disable IDE0200 // Remove unnecessary lambda expression - needed so the ConfigBinder Source Generator works | ||
=> clientBuilder.ConfigureOptions(options => configuration.Bind(options)); | ||
#pragma warning restore IDE0200 // Remove unnecessary lambda expression | ||
|
||
protected override void BindSettingsToConfiguration(AzureSecurityKeyVaultSettings settings, IConfiguration configuration) | ||
=> configuration.Bind(settings); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Aspire.Azure.Security.KeyVault; | ||
using Azure.Core; | ||
using Azure.Core.Extensions; | ||
using Azure.Security.KeyVault.Secrets; | ||
using HealthChecks.Azure.KeyVault.Secrets; | ||
using Microsoft.Extensions.Azure; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
|
||
namespace Microsoft.Extensions.Hosting; | ||
|
||
internal sealed class AzureKeyVaultSecretsComponent : AbstractAzureKeyVaultComponent<SecretClient, SecretClientOptions> | ||
{ | ||
protected override void BindClientOptionsToConfiguration(IAzureClientBuilder<SecretClient, SecretClientOptions> clientBuilder, IConfiguration configuration) | ||
#pragma warning disable IDE0200 // Remove unnecessary lambda expression - needed so the ConfigBinder Source Generator works | ||
=> clientBuilder.ConfigureOptions(options => configuration.Bind(options)); | ||
#pragma warning restore IDE0200 // Remove unnecessary lambda expression | ||
|
||
protected override void BindSettingsToConfiguration(AzureSecurityKeyVaultSettings settings, IConfiguration configuration) | ||
=> configuration.Bind(settings); | ||
|
||
protected override IHealthCheck CreateHealthCheck(SecretClient client, AzureSecurityKeyVaultSettings settings) | ||
=> new AzureKeyVaultSecretsHealthCheck(client, new AzureKeyVaultSecretsHealthCheckOptions()); | ||
|
||
internal override SecretClient CreateComponentClient(Uri vaultUri, SecretClientOptions options, TokenCredential cred) | ||
=> new(vaultUri, cred, options); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol - lots of "key"s in this method name.