Skip to content

Commit 1de125f

Browse files
authored
Merge pull request dapr#123 from mikeee/implement-bulksecret-retrieval
Implement bulksecret retrieval
2 parents 930b40a + 0e08e91 commit 1de125f

File tree

7 files changed

+140
-15
lines changed

7 files changed

+140
-15
lines changed

.github/workflows/validate-examples.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ jobs:
144144
fail-fast: false
145145
matrix:
146146
examples:
147-
["actors", "client", "configuration", "invoke/grpc", "invoke/grpc-proxying", "pubsub"]
147+
["actors", "client", "configuration", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk"]
148148
steps:
149149
- name: Check out code
150150
uses: actions/checkout@v4

Cargo.toml

+18-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ readme = "README.md"
1010
keywords = ["microservices", "dapr"]
1111

1212
[dependencies]
13-
dapr-macros = {version="0.14.0", path = "macros" }
13+
dapr-macros = { version = "0.14.0", path = "macros" }
1414
futures = "0.3"
1515
tonic = "0.11.0"
1616
prost = "0.12.3"
@@ -33,25 +33,25 @@ axum-test = "14.3.0"
3333
once_cell = "1.18.0"
3434
tokio = { version = "1", features = ["full"] }
3535
uuid = { version = "1.4.0", features = ["v4"] }
36-
dapr = {path="./"}
36+
dapr = { path = "./" }
3737
tokio-test = "0.4.2"
3838
tokio-stream = { version = "0.1" }
3939

4040
[[example]]
41-
name = "client"
42-
path = "examples/client/client.rs"
41+
name = "actor-client"
42+
path = "examples/actors/client.rs"
4343

4444
[[example]]
45-
name = "configuration"
46-
path = "examples/configuration/main.rs"
45+
name = "actor-server"
46+
path = "examples/actors/server.rs"
4747

4848
[[example]]
49-
name = "publisher"
50-
path = "examples/pubsub/publisher.rs"
49+
name = "configuration"
50+
path = "examples/configuration/main.rs"
5151

5252
[[example]]
53-
name = "subscriber"
54-
path = "examples/pubsub/subscriber.rs"
53+
name = "client"
54+
path = "examples/client/client.rs"
5555

5656
[[example]]
5757
name = "invoke-grpc-client"
@@ -70,9 +70,13 @@ name = "invoke-grpc-proxying-server"
7070
path = "examples/invoke/grpc-proxying/server.rs"
7171

7272
[[example]]
73-
name = "actor-client"
74-
path = "examples/actors/client.rs"
73+
name = "publisher"
74+
path = "examples/pubsub/publisher.rs"
7575

7676
[[example]]
77-
name = "actor-server"
78-
path = "examples/actors/server.rs"
77+
name = "subscriber"
78+
path = "examples/pubsub/subscriber.rs"
79+
80+
[[example]]
81+
name = "secrets-bulk"
82+
path = "examples/secrets-bulk/app.rs"

examples/secrets-bulk/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Before you run the example make sure local redis state store is running by executing:
2+
```
3+
docker ps
4+
```
5+
6+
1. To run the example we need to first build the examples using the following command:
7+
8+
```
9+
cargo build --examples
10+
```
11+
12+
2. Run the example with dapr using the following command:
13+
14+
<!-- STEP
15+
name: Run app example
16+
output_match_mode: substring
17+
match_order: none
18+
expected_stdout_lines:
19+
- '== APP == Found secret1 with value: TestSecret1'
20+
- '== APP == Found secret2 with value: TestSecret2'
21+
- '== APP == Found secret3 with value: TestSecret3'
22+
background: true
23+
sleep: 15
24+
timeout_seconds: 30
25+
-->
26+
27+
```bash
28+
dapr run --app-id=rustapp --dapr-grpc-port 3500 --resources-path ./resources/ cargo run -- --example secrets-bulk
29+
```
30+
31+
<!-- END_STEP -->
32+
33+
If everything went well you should see the following output along with dapr logs:
34+
```
35+
== APP == Found secret1 with value: TestSecret1
36+
== APP == Found secret2 with value: TestSecret2
37+
== APP == Found secret3 with value: TestSecret3
38+
```
39+
_Note: The order of the secrets returned is not ordered_

examples/secrets-bulk/app.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#[tokio::main]
2+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
3+
// Get the Dapr port and create a connection
4+
let port: u16 = std::env::var("DAPR_GRPC_PORT")?.parse()?;
5+
let addr = format!("https://127.0.0.1:{}", port);
6+
7+
// Create the client
8+
let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;
9+
10+
let secret_store = "localsecretstore";
11+
12+
let secrets_response = client.get_bulk_secret(secret_store, None).await?;
13+
14+
for (secret_name, secret_content) in &secrets_response.data {
15+
println!(
16+
"Found {} with value: {}",
17+
secret_name,
18+
&secret_content.secrets.get(secret_name).unwrap()
19+
);
20+
}
21+
22+
Ok(())
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: localsecretstore
5+
namespace: default
6+
spec:
7+
type: secretstores.local.file
8+
version: v1
9+
metadata:
10+
- name: secretsFile
11+
value: secrets.json
12+
- name: nestedSeparator
13+
value: ":"

examples/secrets-bulk/secrets.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"secret1": "TestSecret1",
3+
"secret2": "TestSecret2",
4+
"secret3": "TestSecret3"
5+
}

src/client.rs

+41
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,27 @@ impl<T: DaprInterface> Client<T> {
128128
.await
129129
}
130130

131+
/// Get all secrets for a given store
132+
///
133+
/// # Arguments
134+
///
135+
/// * `store_name` - The name of the secret store.
136+
pub async fn get_bulk_secret<S>(
137+
&mut self,
138+
store_name: S,
139+
metadata: Option<HashMap<String, String>>,
140+
) -> Result<GetBulkSecretResponse, Error>
141+
where
142+
S: Into<String>,
143+
{
144+
self.0
145+
.get_bulk_secret(GetBulkSecretRequest {
146+
store_name: store_name.into(),
147+
metadata: metadata.unwrap_or_default(),
148+
})
149+
.await
150+
}
151+
131152
/// Get the state for a specific key.
132153
///
133154
/// # Arguments
@@ -373,6 +394,10 @@ pub trait DaprInterface: Sized {
373394
request: InvokeBindingRequest,
374395
) -> Result<InvokeBindingResponse, Error>;
375396
async fn get_secret(&mut self, request: GetSecretRequest) -> Result<GetSecretResponse, Error>;
397+
async fn get_bulk_secret(
398+
&mut self,
399+
request: GetBulkSecretRequest,
400+
) -> Result<GetBulkSecretResponse, Error>;
376401
async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error>;
377402
async fn save_state(&mut self, request: SaveStateRequest) -> Result<(), Error>;
378403
async fn delete_state(&mut self, request: DeleteStateRequest) -> Result<(), Error>;
@@ -434,6 +459,16 @@ impl DaprInterface for dapr_v1::dapr_client::DaprClient<TonicChannel> {
434459
Ok(self.get_secret(Request::new(request)).await?.into_inner())
435460
}
436461

462+
async fn get_bulk_secret(
463+
&mut self,
464+
request: GetBulkSecretRequest,
465+
) -> Result<GetBulkSecretResponse, Error> {
466+
Ok(self
467+
.get_bulk_secret(Request::new(request))
468+
.await?
469+
.into_inner())
470+
}
471+
437472
async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error> {
438473
Ok(self.get_state(Request::new(request)).await?.into_inner())
439474
}
@@ -538,6 +573,12 @@ pub type GetSecretRequest = dapr_v1::GetSecretRequest;
538573
/// A response from getting secret
539574
pub type GetSecretResponse = dapr_v1::GetSecretResponse;
540575

576+
/// A request for getting bulk secrets
577+
pub type GetBulkSecretRequest = dapr_v1::GetBulkSecretRequest;
578+
579+
/// A response for getting bulk secrets
580+
pub type GetBulkSecretResponse = dapr_v1::GetBulkSecretResponse;
581+
541582
/// A response from getting metadata
542583
pub type GetMetadataResponse = dapr_v1::GetMetadataResponse;
543584

0 commit comments

Comments
 (0)