Skip to content
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
4 changes: 0 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ jobs:
run: |
docker-compose -f ./sdk-tests/deploy/local-test-kafka.yml up -d
docker ps
- name: Install Local Hashicorp Vault using docker-compose

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have the vault install in the build.yaml and remove it from the validate.yaml file ....

@fackee fackee Mar 30, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, and the Integration Test is vault secret. should i fix it ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please @dntbeSris
cc @artursouza

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

run: |
docker-compose -f ./sdk-tests/deploy/local-test-vault.yml up -d
docker ps
- name: Install Local mongo database using docker-compose
run: |
docker-compose -f ./sdk-tests/deploy/local-test-mongo.yml up -d
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,6 @@ jobs:
echo "PATH=$PATH:$HOME/.local/bin" >> $GITHUB_ENV
pip3 install setuptools wheel
pip3 install mechanical-markdown
- name: Install Vault CLI
run: |
# From the installtion page of vault https://learn.hashicorp.com/tutorials/vault/getting-started-install?in=vault/getting-started
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update
sudo apt-get install vault
# Verify vault is installed
vault -h
- name: Install Local mongo database using docker-compose
run: |
docker-compose -f ./sdk-tests/deploy/local-test-mongo.yml up -d
Expand Down
1 change: 0 additions & 1 deletion examples/.hashicorp_vault_token

This file was deleted.

16 changes: 0 additions & 16 deletions examples/components/secrets/hashicorp_vault.yaml

This file was deleted.

15 changes: 15 additions & 0 deletions examples/components/secrets/local_file.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localSecretStore
namespace: default
spec:
type: secretstores.local.file
version: v1
metadata:
- name: secretsFile
value: "./components/secrets/secret.json"
- name: nestedSeparator
value: ":"
- name: multiValued
value: "false"
206 changes: 61 additions & 145 deletions examples/src/main/java/io/dapr/examples/secrets/README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
# Dapr's Secret Store Sample

In this sample, we'll see how to retrieve a secret using Dapr's Java SDK.
In this sample, we'll see how to retrieve a secret using Dapr's Java SDK.
This sample includes two files:

* docker-compose-vault.yml (Starts Hashicorp's Vault as a container)
* SecretClient.java (Reads a secret from Dapr's Secret Store)
* Existing Dapr component file in `< repo dir >/examples/components/hashicorp_vault.yaml`
* Existing token file in `< repo dir >/examples/.hashicorp_vault_token` (Consumed by `daprd`'s vault component above)
* Existing Dapr component file in `< repo dir >/examples/components/local_file.yaml`

Visit [this](https://docs.dapr.io/developing-applications/building-blocks/secrets/secrets-overview/) link for more information about secret stores in Dapr.

## Secret store sample using the Java-SDK

In this example, the component used is Hashicorp Vault, but others are also available.
In this example, the component used is local file(not recommended for production use), but others are also available.

Visit [this](https://github.com/dapr/components-contrib/tree/master/secretstores) link for more information about secret stores implementations.
Visit [this](https://github.com/dapr/components-contrib/tree/master/secretstores) link for more information about secret store implementations.


## Pre-requisites

* [Dapr and Dapr Cli](https://docs.dapr.io/getting-started/install-dapr/).
* Java JDK 11 (or greater):
* [Microsoft JDK 11](https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-11)
* [Oracle JDK 11](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11)
* [OpenJDK 11](https://jdk.java.net/11/)
* [Microsoft JDK 11](https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-11)
* [Oracle JDK 11](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11)
* [OpenJDK 11](https://jdk.java.net/11/)
* [Apache Maven](https://maven.apache.org/install.html) version 3.x.
* Hashicorp's vault client [installed](https://www.vaultproject.io/docs/install/).

### Checking out the code

Expand All @@ -49,167 +46,89 @@ Then get into the examples directory:
cd examples
```

### Setting Vault locally

Before getting into the application code, follow these steps in order to set up a local instance of Vault. This is needed for the local instances. Steps are:

1. To run the vault container locally run:
<!-- Docker is writing output to stderr ... -->

<!-- STEP
name: Start vault
expected_stderr_lines:
- 'Creating network "secrets_default" with the default driver'
sleep: 10
-->

```bash
docker-compose -f ./src/main/java/io/dapr/examples/secrets/docker-compose-vault.yml up -d
```

<!-- END_STEP -->

2. Run `docker ps` to see the container running locally:

```bash
342d3522ca14 vault "docker-entrypoint.s…" 34 seconds ago Up About
a minute 0.0.0.0:8200->8200/tcp secrets_hashicorp_vault_1
```
Click [here](https://hub.docker.com/_/vault/) for more information about the container image for Hashicorp's Vault.

### Create a secret in Vault
Dapr's API for secret store only support read operations. For this sample to run, we will first create a secret via the Vault's cli commands:

Export the `VAULT_ADDR` for vault CLI:
```bash
export VAULT_ADDR=http://127.0.0.1:8200/
```

Login to Hashicorp's Vault:

<!-- STEP
name: Vault login
expected_stdout_lines:
- "Success! You are now authenticated. The token information displayed below"
- "token myroot"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
-->

```bash
vault login myroot
```

<!-- END_STEP -->

Create secret (replace `$MY_FAVORITE_MOVIE` with a title of our choice):

<!-- STEP
name: Create movie vault secret
expected_stdout_lines:
- "version 1"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
MY_FAVORITE_MOVIE: "Star Wars"
-->

```bash
vault kv put secret/dapr/movie title="$MY_FAVORITE_MOVIE"
```

<!-- END_STEP -->
### Creating a JSON secret file locally

Create random secret:
Dapr's API for secret store only support read operations. For this sample to run, we will first create a secret file with a JSON string that contains two keys: `redisPassword` and `randomKey`.

<!-- STEP
name: Create random vault secret
expected_stdout_lines:
- "version 1"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
name: create local file
-->

```bash
vault kv put secret/dapr/randomKey testVal="value"
echo '{"redisPassword":"root123","randomKey":"value"}' > ./components/secrets/secret.json
```

<!-- END_STEP -->

In the command above, `secret` means the secret engine in Hashicorp's Vault.
Then, `dapr` is the prefix as defined in `< repo dir >/examples/components/hashicorp_vault.yaml`.
Finally, `movie` and `randomKey` are the secret names with the value set in the form of `key=value` pair.

A secret in Dapr is a dictionary.

### Running the secret store sample

The example's main function is in `SecretClient.java`.

```java
public class SecretClient {
/**
* Identifier in Dapr for the secret store.
*/
private static final String SECRET_STORE_NAME = "vault";


/**
* JSON Serializer to print output.
*/
private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper();

///...

public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException("Use one argument: secret's key to be retrieved.");
}

String secretKey = args[0];
try (DaprClient client = (new DaprClientBuilder()).build()) {
Map<String, String> secret = client.getSecret(SECRET_STORE_NAME, secretKey).block();
System.out.println(JSON_SERIALIZER.writeValueAsString(secret));

try {
secret = client.getSecret(SECRET_STORE_NAME, "randomKey").block();
System.out.println(JSON_SERIALIZER.writeValueAsString(secret));

/**
* Client to read a secret.
*
* @param args Unused arguments.
*/
public static void main(String[] args) throws Exception {
if (args.length < 2) {
throw new IllegalArgumentException("Required two argument at least: "
+ "one's the secret store name, and the others are secret keys.");
}

final String secretStoreName = args[0];
try (DaprClient client = (new DaprClientBuilder()).build()) {

for (int i = 1; i < args.length; i++) {
String secretKey = args[i];

try {
Map<String, String> secret = client.getSecret(secretStoreName, secretKey).block();
System.out.println(JSON_SERIALIZER.writeValueAsString(secret));
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
System.out.println(ex.getMessage());
}
}
}
///...
}
```
The program receives one and only one argument: the secret's key to be fetched.
After identifying the key to be fetched, it will retrieve it from the pre-defined secret store: `vault`.
The secret store's name **must** match the component's name defined in `< repo dir >/examples/components/hashicorp_vault.yaml`.
The program receives two arguments at least: one's the secret store name and the others are secret's keys to be fetched.
After identifying the secret store name that created and the keys to be fetched, it will retrieve them from the pre-defined secret store: `< repo dir >/examples/components/secrets/secret.json`.
The secret store's name **must** match the component's name defined in `< repo dir >/examples/components/secrets/local_file.yaml`.
The Dapr client is also within a try-with-resource block to properly close the client at the end.

Execute the following script in order to run the example:
Execute the following script in order to run the example:

<!-- STEP
name: Validate normal run
expected_stdout_lines:
- '== APP == {"title":"Star Wars"}'
- '== APP == {"testVal":"value"}'
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
- '== APP == {"redisPassword":"root123"}'
- '== APP == {"randomKey":"value"}'
background: true
sleep: 5
-->

```bash
dapr run --components-path ./components/secrets --app-id secrets1 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
dapr run --components-path ./components/secrets --app-id secrets1 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient localSecretStore redisPassword randomKey
```

<!-- END_STEP -->

Once running, the program should print the output as follows:

```
== APP == {"title":"$MY_FAVORITE_MOVIE"}

== APP == {"testVal":"value"}
== APP == {"redisPassword":"root123"}
== APP == {"randomKey":"value"}
```

To close the app either press `CTRL+C` or run
Expand All @@ -225,7 +144,7 @@ dapr stop --app-id secrets1
<!-- END_STEP -->


The example's `config.yaml` is as follows:
The example's `config.yaml` is as follows:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
Expand All @@ -234,38 +153,35 @@ metadata:
spec:
secrets:
scopes:
- storeName: "vault"
- storeName: "localSecretStore"
defaultAccess: "deny"
allowedSecrets: ["movie",]
allowedSecrets: ["redisPassword",]
```

The configuration defines, that the only allowed secret is `movie` and all other secrets are denied.
The configuration defines, that the only allowed secret is `redisPassword` and all other secrets are denied.

Execute the following script in order to run this example with additional secret scoping:
Execute the following script in order to run this example with additional secret scoping:

<!-- STEP
name: Validate error on querying random secret
expected_stdout_lines:
- '== APP == {"title":"Star Wars"}'
- '== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "vault"'
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
- '== APP == {"redisPassword":"root123"}'
- '== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "localSecretStore"'
background: true
sleep: 5
-->

```sh
dapr run --components-path ./components/secrets --config ./src/main/java/io/dapr/examples/secrets/config.yaml --app-id secrets2 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
dapr run --components-path ./components/secrets --config ./src/main/java/io/dapr/examples/secrets/config.yaml --app-id secrets2 -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient localSecretStore redisPassword randomKey
```

<!-- END_STEP -->

Once running, the program should print the output as follows:

```
== APP == {"title":"$MY_FAVORITE_MOVIE"}

== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "vault"
== APP == {"redisPassword":"root123"}
== APP == PERMISSION_DENIED: access denied by policy to get "randomKey" from "localSecretStore"
```

To close the app either press `CTRL+C` or run
Expand All @@ -281,14 +197,14 @@ dapr stop --app-id secrets2
<!-- END_STEP -->


To clean up and bring the vault container down, run
To clean up the local secret file

<!-- STEP
name: Cleanup vault container
name: Cleanup local secret file
-->

```sh
docker-compose -f ./src/main/java/io/dapr/examples/secrets/docker-compose-vault.yml down
rm -rf ./components/secrets/secret.json
```

<!-- END_STEP -->
Expand Down
Loading