replace vault to local (#719)

* replace vault to local

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* change secret store name style

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* delete vault token file

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* remove vault int validate.yml

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* fix it secret case

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* replace vault to local

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* change secret store name style

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* delete vault token file

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* remove vault int validate.yml

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* fix it secret case

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

* fix it dead loop

Signed-off-by: zjx244729 <zjx244729@alibaba-inc.com>

Co-authored-by: zjx244729 <zjx244729@alibaba-inc.com>
Co-authored-by: Mukundan Sundararajan <65565396+mukundansundar@users.noreply.github.com>
This commit is contained in:
www 2022-05-05 16:25:13 +08:00 committed by GitHub
parent 65936ee963
commit e2d4d1e1ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 166 additions and 285 deletions

View File

@ -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
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

View File

@ -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

View File

@ -1 +0,0 @@
myroot

View File

@ -1,16 +0,0 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: vault
spec:
type: secretstores.hashicorp.vault
version: v1
metadata:
- name: vaultAddr
value: "http://127.0.0.1:8200"
- name: skipVerify
value : true
- name: vaultTokenMountPath
value : ".hashicorp_vault_token"
- name: vaultKVPrefix
value : "dapr"

View File

@ -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"

View File

@ -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
@ -49,157 +46,80 @@ Then get into the examples directory:
cd examples
```
### Setting Vault locally
### Creating a JSON secret file 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 ... -->
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: Start vault
expected_stderr_lines:
- 'Creating network "secrets_default" with the default driver'
sleep: 10
name: create local file
-->
```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
echo '{"redisPassword":"root123","randomKey":"value"}' > ./components/secrets/secret.json
```
<!-- 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 -->
Create random secret:
<!-- STEP
name: Create random vault secret
expected_stdout_lines:
- "version 1"
env:
VAULT_ADDR: "http://127.0.0.1:8200/"
-->
```bash
vault kv put secret/dapr/randomKey testVal="value"
```
<!-- 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));
} catch (Exception ex) {
System.out.println(ex.getMessage());
/**
* 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());
}
}
}
///...
}
```
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 -->
@ -207,9 +127,8 @@ dapr run --components-path ./components/secrets --app-id secrets1 -- java -jar t
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
@ -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
@ -234,28 +153,26 @@ 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 -->
@ -263,9 +180,8 @@ dapr run --components-path ./components/secrets --config ./src/main/java/io/dapr
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
@ -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 -->

View File

@ -21,21 +21,16 @@ import java.util.Map;
/**
* 1. Build and install jars:
* mvn clean install
* mvn clean install
* 2. cd to [repo-root]/examples
* 3. Add secret to vault:
* vault kv put secret/dapr/movie title="[my favorite movie]"
* 3. Creating a JSON secret file that contains two keys: redisPassword and randomKey locally:
* 4. Read secret from example:
* dapr run --components-path ./components/secrets -- \
* java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient movie
* dapr run --components-path ./components/secrets -- \
* java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.secrets.SecretClient \
* localSecretStore redisPassword randomKey
*/
public class SecretClient {
/**
* Identifier in Dapr for the secret store.
*/
private static final String SECRET_STORE_NAME = "vault";
/**
* JSON Serializer to print output.
*/
@ -47,21 +42,26 @@ public class SecretClient {
* @param args Unused arguments.
*/
public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException("Use one argument: secret's key to be retrieved.");
if (args.length < 2) {
throw new IllegalArgumentException("Required two argument at least: "
+ "one's the secret store name, and the others are secret keys.");
}
String secretKey = args[0];
final String secretStoreName = 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));
} catch (Exception ex) {
System.out.println(ex.getMessage());
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());
}
}
}

View File

@ -5,6 +5,6 @@ metadata:
spec:
secrets:
scopes:
- storeName: "vault"
- storeName: "localSecretStore"
defaultAccess: "deny"
allowedSecrets: ["movie",]
allowedSecrets: ["redisPassword"]

View File

@ -1,10 +0,0 @@
version: '2'
services:
hashicorp_vault:
image: vault
ports:
- "8200:8200"
cap_add:
- IPC_LOCK
environment:
VAULT_DEV_ROOT_TOKEN_ID: "myroot"

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,14 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localSecretStore
spec:
type: secretstores.local.file
version: v1
metadata:
- name: secretsFile
value: "./components/secret.json"
- name: nestedSeparator
value: ":"
- name: multiValued
value: "true"

View File

@ -1,16 +0,0 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: vault
spec:
type: secretstores.hashicorp.vault
version: v1
metadata:
- name: vaultAddr
value: "http://127.0.0.1:8200"
- name: skipVerify
value : true
- name: vaultTokenMountPath
value : ".hashicorp_vault_token"
- name: vaultKVPrefix
value : "dapr"

View File

@ -1,10 +0,0 @@
version: '2'
services:
hashicorp_vault:
image: vault
ports:
- "8200:8200"
cap_add:
- IPC_LOCK
environment:
VAULT_DEV_ROOT_TOKEN_ID: "myroot"

View File

@ -116,13 +116,6 @@
<artifactId>json-path</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- This is need for us to programmatically add secrets in integration tests. -->
<groupId>com.bettercloud</groupId>
<artifactId>vault-java-driver</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>

View File

@ -13,12 +13,12 @@ limitations under the License.
package io.dapr.it.secrets;
import com.bettercloud.vault.Vault;
import com.bettercloud.vault.VaultConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.client.DaprClient;
import io.dapr.client.DaprClientBuilder;
import io.dapr.it.BaseIT;
import io.dapr.it.DaprRun;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
@ -26,9 +26,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@ -37,28 +39,28 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Test Secrets Store APIs using Harshicorp's vault.
* Test Secrets Store APIs using local file.
*
* 1. Start harshicorp vault locally:
* docker run --cap-add=IPC_LOCK -e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' --name=dev-vault -p 8200:8200 -d vault
* 2. Create token file (path defined in integration test's vault.yaml):
* echo myroot > /tmp/.hashicorp_vault_token
* 1. create secret file locally:
*/
@RunWith(Parameterized.class)
public class SecretsClientIT extends BaseIT {
private static final String LOCAL_VAULT_ADDRESS = "http://127.0.0.1:8200";
/**
* JSON Serializer to print output.
*/
private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper();
private static final String LOCAL_VAULT_TOKEN = "myroot";
private static final String SECRETS_STORE_NAME = "localSecretStore";
private static final String PREFIX = "dapr";
private static final String LOCAL_SECRET_FILE_PATH = "./components/secret.json";
private static final String SECRETS_STORE_NAME = "vault";
private static final String KEY1 = UUID.randomUUID().toString();
private static final String KYE2 = UUID.randomUUID().toString();
private static DaprRun daprRun;
private static Vault vault;
/**
* Parameters for this test.
* Param #1: useGrpc.
@ -70,20 +72,21 @@ public class SecretsClientIT extends BaseIT {
}
@Parameterized.Parameter
public boolean useGrpc;
public boolean useGrpc = true;
private DaprClient daprClient;
private static File localSecretFile;
@BeforeClass
public static void init() throws Exception {
daprRun = startDaprApp(SecretsClientIT.class.getSimpleName(), 5000);
VaultConfig vaultConfig = new VaultConfig()
.address(LOCAL_VAULT_ADDRESS)
.token(LOCAL_VAULT_TOKEN)
.prefixPath(PREFIX)
.build();
vault = new Vault(vaultConfig);
localSecretFile = new File(LOCAL_SECRET_FILE_PATH);
boolean existed = localSecretFile.exists();
assertTrue(existed);
initSecretFile();
daprRun = startDaprApp(SecretsClientIT.class.getSimpleName(), 5000);
}
@Before
@ -100,38 +103,29 @@ public class SecretsClientIT extends BaseIT {
@After
public void tearDown() throws Exception {
daprClient.close();
clearSecretFile();
}
@Test
public void getSecret() throws Exception {
String key = UUID.randomUUID().toString();
String attributeKey = "title";
String attributeValue = "The Metrics IV";
writeSecret(key, attributeKey, attributeValue);
Map<String, String> data = daprClient.getSecret(SECRETS_STORE_NAME, key).block();
assertEquals(1, data.size());
Map<String, String> data = daprClient.getSecret(SECRETS_STORE_NAME, KEY1).block();
assertEquals(2, data.size());
assertEquals("The Metrics IV", data.get("title"));
assertEquals("2020", data.get("year"));
}
@Test
public void getBulkSecret() throws Exception {
String key1 = UUID.randomUUID().toString();
writeSecret(key1, new HashMap<>() {{
put("title", "The Metrics IV");
put("year", "2020");
}});
String key2 = UUID.randomUUID().toString();
writeSecret(key2, "name", "Jon Doe");
Map<String, Map<String, String>> data = daprClient.getBulkSecret(SECRETS_STORE_NAME).block();
// There can be other keys from other runs or test cases, so we are good with at least two.
assertTrue(data.size() >= 2);
assertEquals(2, data.get(key1).size());
assertEquals("The Metrics IV", data.get(key1).get("title"));
assertEquals("2020", data.get(key1).get("year"));
assertEquals(1, data.get(key2).size());
assertEquals("Jon Doe", data.get(key2).get("name"));
assertEquals(2, data.get(KEY1).size());
assertEquals("The Metrics IV", data.get(KEY1).get("title"));
assertEquals("2020", data.get(KEY1).get("year"));
assertEquals(1, data.get(KYE2).size());
assertEquals("Jon Doe", data.get(KYE2).get("name"));
}
@Test(expected = RuntimeException.class)
@ -144,12 +138,26 @@ public class SecretsClientIT extends BaseIT {
daprClient.getSecret("unknownStore", "unknownKey").block();
}
private static void writeSecret(String secretName, String key, String value) throws Exception {
writeSecret(secretName, Collections.singletonMap(key, value));
private static void initSecretFile() throws Exception {
Map<String, Object> key2 = new HashMap(){{
put("name", "Jon Doe");
}};
Map<String, Object> key1 = new HashMap(){{
put("title", "The Metrics IV");
put("year", "2020");
}};
Map<String, Map<String, Object>> secret = new HashMap<>(){{
put(KEY1, key1);
put(KYE2, key2);
}};
try (FileOutputStream fos = new FileOutputStream(localSecretFile)) {
JSON_SERIALIZER.writeValue(fos, secret);
}
}
private static void writeSecret(String secretName, Map<String, Object> secrets) throws Exception {
vault.logical().write("secret/" + PREFIX + "/" + secretName, secrets);
private static void clearSecretFile() throws IOException {
try (FileOutputStream fos = new FileOutputStream(localSecretFile)) {
IOUtils.write("{}", fos);
}
}
}