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

Implement bulksecret retrieval #123

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/validate-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jobs:
fail-fast: false
matrix:
examples:
["actors", "client", "configuration", "invoke/grpc", "invoke/grpc-proxying", "pubsub"]
["actors", "client", "configuration", "invoke/grpc", "invoke/grpc-proxying", "pubsub", "secrets-bulk"]
steps:
- name: Check out code
uses: actions/checkout@v4
Expand Down
32 changes: 18 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ readme = "README.md"
keywords = ["microservices", "dapr"]

[dependencies]
dapr-macros = {version="0.14.0", path = "macros" }
dapr-macros = { version = "0.14.0", path = "macros" }
futures = "0.3"
tonic = "0.11.0"
prost = "0.12.3"
Expand All @@ -33,25 +33,25 @@ axum-test = "14.3.0"
once_cell = "1.18.0"
tokio = { version = "1", features = ["full"] }
uuid = { version = "1.4.0", features = ["v4"] }
dapr = {path="./"}
dapr = { path = "./" }
tokio-test = "0.4.2"
tokio-stream = { version = "0.1" }

[[example]]
name = "client"
path = "examples/client/client.rs"
name = "actor-client"
path = "examples/actors/client.rs"

[[example]]
name = "configuration"
path = "examples/configuration/main.rs"
name = "actor-server"
path = "examples/actors/server.rs"

[[example]]
name = "publisher"
path = "examples/pubsub/publisher.rs"
name = "configuration"
path = "examples/configuration/main.rs"

[[example]]
name = "subscriber"
path = "examples/pubsub/subscriber.rs"
name = "client"
path = "examples/client/client.rs"

[[example]]
name = "invoke-grpc-client"
Expand All @@ -70,9 +70,13 @@ name = "invoke-grpc-proxying-server"
path = "examples/invoke/grpc-proxying/server.rs"

[[example]]
name = "actor-client"
path = "examples/actors/client.rs"
name = "publisher"
path = "examples/pubsub/publisher.rs"

[[example]]
name = "actor-server"
path = "examples/actors/server.rs"
name = "subscriber"
path = "examples/pubsub/subscriber.rs"

[[example]]
name = "secrets-bulk"
path = "examples/secrets-bulk/app.rs"
39 changes: 39 additions & 0 deletions examples/secrets-bulk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Before you run the example make sure local redis state store is running by executing:
```
docker ps
```

1. To run the example we need to first build the examples using the following command:

```
cargo build --examples
```

2. Run the example with dapr using the following command:

<!-- STEP
name: Run app example
output_match_mode: substring
match_order: none
expected_stdout_lines:
- '== APP == Found secret1 with value: TestSecret1'
- '== APP == Found secret2 with value: TestSecret2'
- '== APP == Found secret3 with value: TestSecret3'
background: true
sleep: 15
timeout_seconds: 30
-->

```bash
dapr run --app-id=rustapp --dapr-grpc-port 3500 --resources-path ./resources/ cargo run -- --example secrets-bulk
```

<!-- END_STEP -->

If everything went well you should see the following output along with dapr logs:
```
== APP == Found secret1 with value: TestSecret1
== APP == Found secret2 with value: TestSecret2
== APP == Found secret3 with value: TestSecret3
```
_Note: The order of the secrets returned is not ordered_
23 changes: 23 additions & 0 deletions examples/secrets-bulk/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get the Dapr port and create a connection
let port: u16 = std::env::var("DAPR_GRPC_PORT")?.parse()?;
let addr = format!("https://127.0.0.1:{}", port);

// Create the client
let mut client = dapr::Client::<dapr::client::TonicClient>::connect(addr).await?;

let secret_store = "localsecretstore";

let secrets_response = client.get_bulk_secret(secret_store, None).await?;

for (secret_name, secret_content) in &secrets_response.data {
println!(
"Found {} with value: {}",
secret_name,
&secret_content.secrets.get(secret_name).unwrap()
);
}

Ok(())
}
13 changes: 13 additions & 0 deletions examples/secrets-bulk/resources/local-secret-store.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localsecretstore
namespace: default
spec:
type: secretstores.local.file
version: v1
metadata:
- name: secretsFile
value: secrets.json
- name: nestedSeparator
value: ":"
5 changes: 5 additions & 0 deletions examples/secrets-bulk/secrets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"secret1": "TestSecret1",
"secret2": "TestSecret2",
"secret3": "TestSecret3"
}
41 changes: 41 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,27 @@ impl<T: DaprInterface> Client<T> {
.await
}

/// Get all secrets for a given store
///
/// # Arguments
///
/// * `store_name` - The name of the secret store.
pub async fn get_bulk_secret<S>(
&mut self,
store_name: S,
metadata: Option<HashMap<String, String>>,
) -> Result<GetBulkSecretResponse, Error>
where
S: Into<String>,
{
self.0
.get_bulk_secret(GetBulkSecretRequest {
store_name: store_name.into(),
metadata: metadata.unwrap_or_default(),
})
.await
}

/// Get the state for a specific key.
///
/// # Arguments
Expand Down Expand Up @@ -373,6 +394,10 @@ pub trait DaprInterface: Sized {
request: InvokeBindingRequest,
) -> Result<InvokeBindingResponse, Error>;
async fn get_secret(&mut self, request: GetSecretRequest) -> Result<GetSecretResponse, Error>;
async fn get_bulk_secret(
&mut self,
request: GetBulkSecretRequest,
) -> Result<GetBulkSecretResponse, Error>;
async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error>;
async fn save_state(&mut self, request: SaveStateRequest) -> Result<(), Error>;
async fn delete_state(&mut self, request: DeleteStateRequest) -> Result<(), Error>;
Expand Down Expand Up @@ -434,6 +459,16 @@ impl DaprInterface for dapr_v1::dapr_client::DaprClient<TonicChannel> {
Ok(self.get_secret(Request::new(request)).await?.into_inner())
}

async fn get_bulk_secret(
&mut self,
request: GetBulkSecretRequest,
) -> Result<GetBulkSecretResponse, Error> {
Ok(self
.get_bulk_secret(Request::new(request))
.await?
.into_inner())
}

async fn get_state(&mut self, request: GetStateRequest) -> Result<GetStateResponse, Error> {
Ok(self.get_state(Request::new(request)).await?.into_inner())
}
Expand Down Expand Up @@ -538,6 +573,12 @@ pub type GetSecretRequest = dapr_v1::GetSecretRequest;
/// A response from getting secret
pub type GetSecretResponse = dapr_v1::GetSecretResponse;

/// A request for getting bulk secrets
pub type GetBulkSecretRequest = dapr_v1::GetBulkSecretRequest;

/// A response for getting bulk secrets
pub type GetBulkSecretResponse = dapr_v1::GetBulkSecretResponse;

/// A response from getting metadata
pub type GetMetadataResponse = dapr_v1::GetMetadataResponse;

Expand Down
Loading