-
Notifications
You must be signed in to change notification settings - Fork 6
feat/secretstore #42
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
base: main
Are you sure you want to change the base?
feat/secretstore #42
Conversation
Signed-off-by: Pravin Pushkar <[email protected]>
Signed-off-by: Pravin Pushkar <[email protected]>
Signed-off-by: Pravin Pushkar <[email protected]>
samples/LocalEnvSecretStoreSample/LocalEnvSecretStoreSample.csproj
Outdated
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreGetResponse.cs
Outdated
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreBulkGetResponse.cs
Outdated
Show resolved
Hide resolved
|
||
public sealed record SecretStoreBulkGetResponse | ||
{ | ||
//public IReadOnlyDictionary<string, Dictionary<string, string>> responseData = new Dictionary<string, Dictionary<string, string>>(); |
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.
IReadOnlyDictionary<string, IReadonlyDictionary<string, string>>
would be the most raw way to expose the bulk data, but I'm not sure if that'd be the best way, as it doesn't easily allow for changes to the API in the future. (E.g. suppose the bulk request returns both values and other metadata for each individual secret). It'd probably be better to expose something like IReadOnlyDictionary<string, GetSecretResponse> Data
(which is actually closer to the .proto
definition anyway).
I think it's fine to try to simplify some of the .proto
APIs where it makes sense (e.g. where it contains unnecessary layers), but we also want to walk that fine line of being true to the .proto
as well so that the .NET APIs are still conceptually similar to the other SDKs.
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.
I think we can use the SecretResponse()
constructor from the proto defintion.
src/Dapr.PluggableComponents/Components/SecretStores/ISecretStore.cs
Outdated
Show resolved
Hide resolved
/// <param name="request">Properties related to the secret to be retrieved.</param> | ||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param> | ||
/// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation, resulting in the retrieved secret, if any.</returns> | ||
Task<SecretStoreGetResponse?> GetAsync(SecretStoreGetRequest request, CancellationToken cancellationToken = default); |
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.
What's the Dapr semantics for getting a secret key that doesn't exist? Is that an error or should a "does not exist" value be returned? In the case of state stores, we return null
in that case.
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.
in case of env secret store we return empty value like {somsecret: ""}
. I think it can depend on specific implementation.
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreGetRequest.cs
Outdated
Show resolved
Hide resolved
@@ -22,7 +23,7 @@ | |||
</PropertyGroup> | |||
|
|||
<ItemGroup> | |||
<Protobuf Include="@(Protos->'$(ProtosComponentsDir)/%(Identity)')" ProtoRoot="$(ProtosRootDir)" GrpcServices="Client,Server" /> | |||
<Protobuf Include="@(Protos->'$(ProtosComponentsDir)/%(Identity)')" ProtoRoot="$(ProtosRootDir)" GrpcServices="Client,Server" /> |
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.
Not sure what happened here...
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.
I think the XML editor is getting too aggressive about escaping characters; ->
is what it should be.
Signed-off-by: Pravin Pushkar <[email protected]>
Signed-off-by: Pravin Pushkar <[email protected]>
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreBulkGetResponse.cs
Outdated
Show resolved
Hide resolved
{ | ||
public IReadOnlyDictionary<string, string> Data = new Dictionary<string, string>(); | ||
|
||
internal static BulkGetSecretResponse ToBulkGetResponse(SecretStoreBulkGetResponse? response) |
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.
Remove the nullability (?
) from the response argument? We would always expect the implementation to give us one, right?
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreGetResponse.cs
Outdated
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreGetResponse.cs
Outdated
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStores/SecretStoreBulkGetResponse.cs
Outdated
Show resolved
Hide resolved
|
||
<PropertyGroup> | ||
<ProtosVersion>v1</ProtosVersion> | ||
<ProtosTag>v1.11.0</ProtosTag> | ||
<ProtosTag>master</ProtosTag> |
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.
We'll want to defer committing this PR until (at least) a v1.12.0
tag exists in dapr/dapr
, as we don't want builds picking up whatever happens to be in the master
branch at the time.
samples/LocalEnvSecretStoreSample/LocalEnvSecretStoreSample.csproj
Outdated
Show resolved
Hide resolved
data = ""; | ||
} | ||
Dictionary<string, string> resp = new Dictionary<string, string>(); | ||
resp.Add(request.SecretName, data); |
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.
C# allows Add()
methods to be inlined:
var resp = new Dictionary<string, string>
{
{ request.SecretName, data }
}
} | ||
Dictionary<string, string> resp = new Dictionary<string, string>(); | ||
resp.Add(request.SecretName, data); | ||
response = new SecretStoreGetResponse |
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.
Nit: var response = new SecretStoreGetResponse
allows you to eliminate the nullable response
created above.
this.logger.LogInformation("Get request for secret {key}", request.SecretName); | ||
|
||
SecretStoreGetResponse? response = null; | ||
string data = Environment.GetEnvironmentVariable(request.SecretName); |
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.
Nit: should be string? data = ...
?
I'd expect a build warning about nullability otherwise (as GetEnvironmentVariable()
returns string?
).
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.
GetEnvironmentVariable
returns string when environment variable is not found or set.
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.
GetEnvironmentVariable()
returns string?
(a potentially null
string). An alternative would be:
string data = Environment.GetEnvironmentVariable() ?? String.Empty;
...which assigns ""
only if the return value is null
.
Dictionary<string, string> resp = new Dictionary<string, string>(); | ||
foreach (string key in Environment.GetEnvironmentVariables().Keys) | ||
{ | ||
resp.Add(key, Environment.GetEnvironmentVariable(key)); |
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.
GetEnvironmentVariables()
returns a dictionary of both names and values; there shouldn't be a reason to later call GetEnvironmentVariable()
for each variable name.
/// <param name="request">Properties related to the secret to be retrieved.</param> | ||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param> | ||
/// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation, resulting in the retrieved secret, if any.</returns> | ||
Task<SecretStoreGetResponse> GetAsync(SecretStoreGetRequest request, CancellationToken cancellationToken = default); |
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.
It might be good to add <remarks>
that describe the expected behavior for secrets that don't exist as well as differences between stores that support multiple values per secret and those that don't.
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.
Generally on the right track. There's a question for how to represent bulk secret responses, and it'd be helpful to include unit tests for the new components and data types. (I just committed a change that switches tests to NSubstitute from Moq, so be sure to merge in the main
branch.)
Signed-off-by: Pravin Pushkar <[email protected]>
foreach (var sec in item.Value.Data) | ||
{ | ||
secretResp.Secrets.Add(sec.Key, sec.Value); | ||
grpcResponse.Data.Add(sec.Key, secretResp); |
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.
This should only happen once, right, outside the foreach
and for the item.Key
key?
|
||
// NOTE: in case of not found, you should not return any error. | ||
|
||
if (response != null) |
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.
response
should be non-null (by nullability contract). While the implementor could still technically return null
at runtime, I'd say that's their problem and not something to explicitly account for.
|
||
// NOTE: in case of not found, you should not return any error. | ||
|
||
if (response != null) |
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.
response
should be non-null (by nullability contract). While the implementor could still technically return null
at runtime, I'd say that's their problem and not something to explicitly account for.
@pravinpushkar With 1.12 now out the door, we should be able to pick this PR back up, right? |
@philliphoff Yes, I will plan to complete this in coming weeks. |
Signed-off-by: Phillip Hoff <[email protected]>
1d62a95
to
8be3241
Compare
Signed-off-by: Phillip Hoff <[email protected]>
Signed-off-by: Phillip Hoff <[email protected]>
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.
Several changes. Mostly around naming consistency questions, a potentially unnecessary type and some assignment/nullability nits.
samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Outdated
Show resolved
Hide resolved
samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Outdated
Show resolved
Hide resolved
samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Outdated
Show resolved
Hide resolved
samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Outdated
Show resolved
Hide resolved
samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Outdated
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStore/SecretStoreBulkGetRequest.cs
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStore/SecretStoreBulkGetResponse.cs
Show resolved
Hide resolved
src/Dapr.PluggableComponents/Components/SecretStore/SecretStoreResponse.cs
Outdated
Show resolved
Hide resolved
Signed-off-by: Phillip Hoff <[email protected]>
Signed-off-by: Phillip Hoff <[email protected]>
@philliphoff Good to merge? |
Description
Please explain the changes you've made
Issue reference
We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.
Please reference the issue this PR will close: #43
Checklist
Please make sure you've completed the relevant tasks for this PR, out of the following list: