-
Notifications
You must be signed in to change notification settings - Fork 340
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
Error Suppression and Vault Name Mapping #887
Comments
@BCoskun - Thanks for opening this issue! Just to clarify for myself, what we're trying to do here is:
I can see the value of this, but I don't know if I agree with using the reserved metadata values. The metadata here is actually sent to the secretstore so instead I'd rather just add the direct fields to the /// <summary>
/// Gets or sets the secret name.
/// </summary>
public string SecretName { get; }
/// <summary>
/// A collection of metadata key-value pairs that will be provided to the secret store. The valid metadata keys and values are determined by the type of secret store used.
/// </summary>
public IReadOnlyDictionary<string, string> Metadata { get; }
public bool IsRequired { get; }
public string SecretKey { get; }
/// <summary>
/// Secret Descriptor Construcutor
/// </summary>
public DaprSecretDescriptor(string secretName) : this(secretName, new Dictionary<string, string>(), true, secretName)
{
}
public DaprSecretDescriptor(string secretName, IReadOnlyDictionary<string, string> metadata, bool isRequired, string secretKey)
{
...
} Thoughts? |
This seems more elegant solution for the required feature. This simplifies to LoadAsync Method as well; if (secretDescriptors != null)
{
foreach (var secretDescriptor in secretDescriptors)
{
Dictionary<string, string> result = new Dictionary<string, string>();
try
{
result = await client
.GetSecretAsync(store, secretDescriptor.SecretKey, secretDescriptor.Metadata)
.ConfigureAwait(false);
}
catch (DaprException e)
{
if (secretDescriptor.IsRequired)
{
throw e;
}
Console.WriteLine($"'{secretDescriptor.SecretName}' doesn't exists in Key Vault but because it doesn't require existence so all errors suppressed!");
result = new Dictionary<string, string>();
}
foreach (var key in result.Keys)
{
if (data.ContainsKey(key))
{
throw new InvalidOperationException(
$"A duplicate key '{key}' was found in the secret store '{store}'. Please remove any duplicates from your secret store.");
}
data.Add(normalizeKey ? NormalizeKey(secretDescriptor.SecretName) : secretDescriptor.SecretName, result[key]);
}
}
Data = data;
} The Program.cs will change as var secretDescriptors = new List<DaprSecretDescriptor>
{
// Mapped with Vault name with old exception behavior.
// The Secret name should exist on Keyvault otherwise it will throw the exception.
new DaprSecretDescriptor("ConnectionStrings:DatabaseConnStr", new Dictionary<string, string>(),
true, "Microsservice-DatabaseConnStr"),
// The exception will be suppressed
new DaprSecretDescriptor("ConnectionStrings:StorageLocalFolder",new Dictionary<string, string>(),
false, "Object-Storage-ContainerName-CfgNotExists"),
// Old Behavior
new DaprSecretDescriptor("Old-Beahvior-StorageAzureConnectionString")
};
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddDaprSecretStore("azurekeyvault", secretDescriptors, daprClient, TimeSpan.FromSeconds(10) )
.AddEnvironmentVariables()
.Build();
var connectionString = config.GetConnectionString("DatabaseConnStr");
var fileStorageConnectionString = config.GetConnectionString("StorageLocalFolder");
var azureStorageConnectionString = config.GetConfig("Old-Beahvior-StorageAzureConnectionString"); |
/assign |
@BCoskun I'm not sure if I understand why we need this change.
Will this help in any way ? What exactly are you trying to accomplish ? What do you mean by "Key Vault Secret name doesn't have match with application configuration name" ? Are you talking about Azure App Configuration ? In the draft PR, we are potentially just querying the secret store with a different key. Also, in this case:
Are you fetching |
Also, I think Azure Key Vault doesn't allow in key vault secret names by definition so I strongly feel it would be up to the client to bridge the gap of parity between the key vault secret name and the application configuration name. The SDK/Dapr is just a means of querying the Azure Key Vault and fetching the secret. |
Hi @yash-nisar , One of the main issue was SDK was not allowing Dapr Secret Block to retrieve the secret(s) without throwing exception when the some secret(s) not exists on the vault. This proposal offering way get list of secrets that some of them might not be exists in vault without throwing exception. Also with this change we are giving way to retrieve the secret and map the name as developer configured DaprSecretDescriptor so that he/she don't need to re-map the values again. Well, I understand you have some strong feeling about mapping is responsibility for client but from my point of view the developer explicitly defining this mapping on configuration and additional functions could help developer for these type of extra works. In our case we were storing secrets appliction.json files and when we start using Dapr we had to add additional mapping section because Azure Key Vault was not supporting ":" character. |
@BCoskun Thanks for the prompt response. Can you explain what do you mean by "we are giving way to retrieve the secret and map the name as developer configured DaprSecretDescriptor so that he/she don't need to re-map the values again" ? |
Sorry I was keep updating my original answer above. Let me know if that is not converging your question. |
@BCoskun Also, with regards to throwing an exception if the secret is not found is expected. See the responses here: https://docs.dapr.io/reference/api/secrets_api/#response-codes I think it should be up to the client to make sure they're querying with the correct secret name. I'm trying to understand the hurdles that you are facing while implementing this. |
I understand that is expected from DAPR API but my interpration of "204 Secret not found" might not be exception. especially for multiple secret(s) retrieval. In my mind we don't need to throw exception for Secret not found or allow the developer to control the behavior, Another point is DAPR API doesn't have multiple secret retrival functionality but SDK has it so we are providing more functionality in SDK which means they are not functionally map 1 to 1 and SDK doesn't allow us gracefully handle errors for retrieving multiple secrets from the vault. Having said that I think this is matter of taste and style. If this explanation is not good enough we can close the proposal. Thanks. |
We do have an option for multiple secret retrievals in dapr (https://docs.dapr.io/reference/api/secrets_api/#get-bulk-secret) and the dotnet-sdk (https://github.com/dapr/dotnet-sdk/blob/master/src/Dapr.Client/DaprClientGrpc.cs#L1253) if that's what you are looking for. There can never be a feature that exists in the SDK but not in the Dapr runtime because the SDK makes calls to the runtime APIs itself via HTTP/GPRC. As for gracefully handling errors, how about including this block in a try catch block itself ?
|
Thanks for your feedback. |
@yash-nisar is this enhancement still expected to be worked on? I feel there are valid scenarios where you want to have a nullable configuration value where by if it does not exist in vault, then ignore it instead of throwing an exception. |
Hey @jamesmcroft, sorry I have been involved in other high priority stuff. I am happy to hand it over to whoever wants to work on it. |
@yash-nisar I can look at finalizing this from your previous PR |
@yash-nisar thanks for supporting on the original work for this issue. This has now been merged in with additional changes to finish up the previous PR you opened. #1051 can now be closed also. Looking forward to taking advantage of this change in a future release of the SDK, and I hope that @BCoskun and others find this useful also. |
Describe the proposal
We are working on Azure Key Vault in our project and notice that there is no error suppression functionality (or not granular enough for certain use case) when there the Key Vault Secret name doesn't have match with application configuration name.
For example;
We couldn't define .NET configuration hierarchy in Azure KeyVault due to naming convention limitation for secret names. Key Vault only accepts dash and Alphanumeric values for the names so we can't use "ConnectionStrings:DatabaseConnStr" or "ConnectionStrings__DatabaseConnStr" as name.
Purposed solution
Allocate special metadata prefix like "Dapr." in metadata keys and use them to control library behavior.
Example Solution in Library
Example usage in Program.cs
var daprClientBuilder = new DaprClientBuilder();
var daprClient = daprClientBuilder.Build();
The text was updated successfully, but these errors were encountered: