mirror of https://github.com/dapr/docs.git
Merge branch 'v1.5' into feature/pub_sub
This commit is contained in:
commit
01f21391b8
|
@ -25,7 +25,7 @@ Virtual actor capabilities are one of the building blocks that Dapr provides in
|
||||||
|
|
||||||
Creating a new actor follows a local call like `http://localhost:3500/v1.0/actors/<actorType>/<actorId>/…`. For example, `http://localhost:3500/v1.0/actors/myactor/50/method/getData` calls the `getData` method on the newly created `myactor` with id `50`.
|
Creating a new actor follows a local call like `http://localhost:3500/v1.0/actors/<actorType>/<actorId>/…`. For example, `http://localhost:3500/v1.0/actors/myactor/50/method/getData` calls the `getData` method on the newly created `myactor` with id `50`.
|
||||||
|
|
||||||
The Dapr runtime SDKs have language-specific actor frameworks. For example, the .NET SDK has C# actors. The goal is for all the Dapr language SDKs to have an actor framework. Currently .NET, Java and Python SDK have actor frameworks.
|
The Dapr runtime SDKs have language-specific actor frameworks. For example, the .NET SDK has C# actors. The goal is for all the Dapr language SDKs to have an actor framework. Currently .NET, Java, Go and Python SDK have actor frameworks.
|
||||||
|
|
||||||
## Developer language SDKs and frameworks
|
## Developer language SDKs and frameworks
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,25 @@ description: "Use the secret store building block to securely retrieve a secret"
|
||||||
|
|
||||||
This article provides guidance on using Dapr's secrets API in your code to leverage the [secrets store building block]({{<ref secrets-overview>}}). The secrets API allows you to easily retrieve secrets in your application code from a configured secret store.
|
This article provides guidance on using Dapr's secrets API in your code to leverage the [secrets store building block]({{<ref secrets-overview>}}). The secrets API allows you to easily retrieve secrets in your application code from a configured secret store.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
The below code example loosely describes an application that processes orders. In the example, there is an order processing service, which has a Dapr sidecar. The order processing service uses Dapr to store a secret in a local secret store.
|
||||||
|
|
||||||
|
<img src="/images/building-block-secrets-management-example.png" width=1000 alt="Diagram showing secrets management of example service">
|
||||||
|
|
||||||
## Set up a secret store
|
## Set up a secret store
|
||||||
|
|
||||||
Before retrieving secrets in your application's code, you must have a secret store component configured. For the purposes of this guide, as an example you will configure a local secret store which uses a local JSON file to store secrets.
|
Before retrieving secrets in your application's code, you must have a secret store component configured. For the purposes of this guide, as an example you will configure a local secret store which uses a local JSON file to store secrets.
|
||||||
|
|
||||||
>Note: The component used in this example is not secured and is not recommended for production deployments. You can find other alternatives [here]({{<ref supported-secret-stores >}}).
|
{{% alert title="Warning" color="warning" %}}
|
||||||
|
In a production-grade application, local secret stores are not recommended. You can find other alternatives [here]({{<ref supported-secret-stores >}}) to securely manage your secrets.
|
||||||
|
{{% /alert %}}
|
||||||
|
|
||||||
Create a file named `mysecrets.json` with the following contents:
|
Create a file named `secrets.json` with the following contents:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"my-secret" : "I'm Batman"
|
"secret": "Order Processing pass key"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -28,146 +36,226 @@ Create a directory for your components file named `components` and inside it cre
|
||||||
apiVersion: dapr.io/v1alpha1
|
apiVersion: dapr.io/v1alpha1
|
||||||
kind: Component
|
kind: Component
|
||||||
metadata:
|
metadata:
|
||||||
name: my-secrets-store
|
name: localsecretstore
|
||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
type: secretstores.local.file
|
type: secretstores.local.file
|
||||||
version: v1
|
version: v1
|
||||||
metadata:
|
metadata:
|
||||||
- name: secretsFile
|
- name: secretsFile
|
||||||
value: <PATH TO SECRETS FILE>/mysecrets.json
|
value: secrets.json #path to secrets file
|
||||||
- name: nestedSeparator
|
- name: nestedSeparator
|
||||||
value: ":"
|
value: ":"
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure to replace `<PATH TO SECRETS FILE>` with the path to the JSON file you just created.
|
|
||||||
|
|
||||||
>Note: the path to the secret store JSON is relative to where you call `dapr run` from.
|
>Note: the path to the secret store JSON is relative to where you call `dapr run` from.
|
||||||
|
|
||||||
|
|
||||||
To configure a different kind of secret store see the guidance on [how to configure a secret store]({{<ref setup-secret-store>}}) and review [supported secret stores]({{<ref supported-secret-stores >}}) to see specific details required for different secret store solutions.
|
To configure a different kind of secret store see the guidance on [how to configure a secret store]({{<ref setup-secret-store>}}) and review [supported secret stores]({{<ref supported-secret-stores >}}) to see specific details required for different secret store solutions.
|
||||||
## Get a secret
|
## Get a secret
|
||||||
|
|
||||||
Now run the Dapr sidecar (with no application)
|
Run the Dapr sidecar with the application.
|
||||||
|
|
||||||
|
|
||||||
|
{{< tabs Dotnet Java Python Go Javascript>}}
|
||||||
|
|
||||||
|
{{% codetab %}}
|
||||||
```bash
|
```bash
|
||||||
dapr run --app-id my-app --dapr-http-port 3500 --components-path ./components
|
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components dotnet run
|
||||||
```
|
```
|
||||||
|
{{% /codetab %}}
|
||||||
|
|
||||||
And now you can get the secret by calling the Dapr sidecar using the secrets API:
|
|
||||||
|
{{% codetab %}}
|
||||||
|
```bash
|
||||||
|
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components mvn spring-boot:run
|
||||||
|
```
|
||||||
|
{{% /codetab %}}
|
||||||
|
|
||||||
|
|
||||||
|
{{% codetab %}}
|
||||||
|
```bash
|
||||||
|
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components python3 OrderProcessingService.py
|
||||||
|
```
|
||||||
|
{{% /codetab %}}
|
||||||
|
|
||||||
|
|
||||||
|
{{% codetab %}}
|
||||||
|
```bash
|
||||||
|
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components go run OrderProcessingService.go
|
||||||
|
```
|
||||||
|
{{% /codetab %}}
|
||||||
|
|
||||||
|
|
||||||
|
{{% codetab %}}
|
||||||
|
```bash
|
||||||
|
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components npm start
|
||||||
|
```
|
||||||
|
{{% /codetab %}}
|
||||||
|
|
||||||
|
{{< /tabs >}}
|
||||||
|
|
||||||
|
Get the secret by calling the Dapr sidecar using the secrets API:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret
|
curl http://localhost:3601/v1.0/secrets/localsecretstore/secret
|
||||||
```
|
```
|
||||||
|
|
||||||
For a full API reference, go [here]({{< ref secrets_api.md >}}).
|
For a full API reference, go [here]({{< ref secrets_api.md >}}).
|
||||||
|
|
||||||
## Calling the secrets API from your code
|
## Calling the secrets API from your code
|
||||||
|
|
||||||
Once you have a secret store set up, you can call Dapr to get the secrets from your application code. Here are a few examples in different programming languages:
|
Once you have a secret store, call Dapr to get the secrets from your application code. Below are code examples that leverage Dapr SDKs for retrieving a secret.
|
||||||
|
|
||||||
{{< tabs "Go" "Javascript" "Python" "Rust" "C#" "PHP" >}}
|
{{< tabs Dotnet Java Python Go Javascript>}}
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
```Go
|
```csharp
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
//dependencies
|
||||||
url := "http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret"
|
using Dapr.Client;
|
||||||
|
|
||||||
res, err := http.Get(url)
|
//code
|
||||||
if err != nil {
|
namespace EventService
|
||||||
panic(err)
|
{
|
||||||
}
|
class Program
|
||||||
defer res.Body.Close()
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
body, _ := ioutil.ReadAll(res.Body)
|
{
|
||||||
fmt.Println(string(body))
|
string SECRET_STORE_NAME = "localsecretstore";
|
||||||
|
using var client = new DaprClientBuilder().Build();
|
||||||
|
//Using Dapr SDK to get a secret
|
||||||
|
var secret = await client.GetSecretAsync(SECRET_STORE_NAME, "secret");
|
||||||
|
Console.WriteLine($"Result: {string.Join(", ", secret)}");
|
||||||
|
Console.WriteLine($"Result for bulk: {string.Join(", ", secret.Keys)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
|
```
|
||||||
{{% /codetab %}}
|
{{% /codetab %}}
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
|
|
||||||
```javascript
|
```java
|
||||||
require('isomorphic-fetch');
|
|
||||||
const secretsUrl = `http://localhost:3500/v1.0/secrets`;
|
//dependencies
|
||||||
|
import io.dapr.client.DaprClient;
|
||||||
|
import io.dapr.client.DaprClientBuilder;
|
||||||
|
|
||||||
|
//code
|
||||||
|
@SpringBootApplication
|
||||||
|
public class OrderProcessingServiceApplication {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class);
|
||||||
|
private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper();
|
||||||
|
|
||||||
|
private static final String SECRET_STORE_NAME = "localsecretstore";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException, JsonProcessingException {
|
||||||
|
DaprClient client = new DaprClientBuilder().build();
|
||||||
|
//Using Dapr SDK to get a secret
|
||||||
|
Map<String, String> secret = client.getSecret(SECRET_STORE_NAME, "secret").block();
|
||||||
|
log.info("Result: " + JSON_SERIALIZER.writeValueAsString(secret));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fetch(`${secretsUrl}/my-secrets-store/my-secret`)
|
|
||||||
.then((response) => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw "Could not get secret";
|
|
||||||
}
|
|
||||||
return response.text();
|
|
||||||
}).then((secret) => {
|
|
||||||
console.log(secret);
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /codetab %}}
|
{{% /codetab %}}
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import requests as req
|
|
||||||
|
|
||||||
resp = req.get("http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret")
|
#dependencies
|
||||||
print(resp.text)
|
from dapr.clients import DaprClient
|
||||||
|
from dapr.clients.grpc._state import StateItem
|
||||||
|
from dapr.clients.grpc._request import TransactionalStateOperation, TransactionOperationType
|
||||||
|
|
||||||
|
#code
|
||||||
|
logging.basicConfig(level = logging.INFO)
|
||||||
|
|
||||||
|
DAPR_STORE_NAME = "localsecretstore"
|
||||||
|
key = 'secret'
|
||||||
|
|
||||||
|
with DaprClient() as client:
|
||||||
|
#Using Dapr SDK to get a secret
|
||||||
|
secret = client.get_secret(store_name=DAPR_STORE_NAME, key=key)
|
||||||
|
logging.info('Result: ')
|
||||||
|
logging.info(secret.secret)
|
||||||
|
secret = client.get_bulk_secret(store_name=DAPR_STORE_NAME)
|
||||||
|
logging.info('Result for bulk secret: ')
|
||||||
|
logging.info(sorted(secret.secrets.items()))
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /codetab %}}
|
{{% /codetab %}}
|
||||||
|
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
|
|
||||||
```rust
|
```go
|
||||||
#![deny(warnings)]
|
|
||||||
use std::{thread};
|
|
||||||
|
|
||||||
#[tokio::main]
|
//dependencies
|
||||||
async fn main() -> Result<(), reqwest::Error> {
|
import (
|
||||||
let res = reqwest::get("http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret").await?;
|
"context"
|
||||||
let body = res.text().await?;
|
"log"
|
||||||
println!("Secret:{}", body);
|
dapr "github.com/dapr/go-sdk/client"
|
||||||
|
)
|
||||||
|
|
||||||
thread::park();
|
//code
|
||||||
|
func main() {
|
||||||
|
client, err := dapr.NewClient()
|
||||||
|
SECRET_STORE_NAME := "localsecretstore"
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
Ok(())
|
secret, err := client.GetSecret(ctx, SECRET_STORE_NAME, "secret", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Got error for accessing key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if secret != nil {
|
||||||
|
log.Println("Result : ")
|
||||||
|
log.Println(secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretRandom, err := client.GetBulkSecret(ctx, SECRET_STORE_NAME, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Got error for accessing key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if secret != nil {
|
||||||
|
log.Println("Result for bulk: ")
|
||||||
|
log.Println(secretRandom)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
{{% /codetab %}}
|
|
||||||
|
|
||||||
{{% codetab %}}
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
var client = new HttpClient();
|
|
||||||
var response = await client.GetAsync("http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret");
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
string secret = await response.Content.ReadAsStringAsync();
|
|
||||||
Console.WriteLine(secret);
|
|
||||||
```
|
```
|
||||||
{{% /codetab %}}
|
{{% /codetab %}}
|
||||||
|
|
||||||
{{% codetab %}}
|
{{% codetab %}}
|
||||||
|
|
||||||
```php
|
```javascript
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once __DIR__.'/vendor/autoload.php';
|
//dependencies
|
||||||
|
import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client';
|
||||||
|
|
||||||
|
//code
|
||||||
|
const daprHost = "127.0.0.1";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP);
|
||||||
|
const SECRET_STORE_NAME = "localsecretstore";
|
||||||
|
var secret = await client.secret.get(SECRET_STORE_NAME, "secret");
|
||||||
|
console.log("Result: " + secret);
|
||||||
|
secret = await client.secret.getBulk(SECRET_STORE_NAME);
|
||||||
|
console.log("Result for bulk: " + secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
|
|
||||||
$app = \Dapr\App::create();
|
|
||||||
$app->run(function(\Dapr\SecretManager $secretManager, \Psr\Log\LoggerInterface $logger) {
|
|
||||||
$secret = $secretManager->retrieve(secret_store: 'my-secret-store', name: 'my-secret');
|
|
||||||
$logger->alert('got secret: {secret}', ['secret' => $secret]);
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /codetab %}}
|
{{% /codetab %}}
|
||||||
|
|
||||||
{{< /tabs >}}
|
{{< /tabs >}}
|
||||||
|
@ -179,4 +267,4 @@ $app->run(function(\Dapr\SecretManager $secretManager, \Psr\Log\LoggerInterface
|
||||||
- [Configure a secret store]({{<ref setup-secret-store>}})
|
- [Configure a secret store]({{<ref setup-secret-store>}})
|
||||||
- [Supported secrets]({{<ref supported-secret-stores>}})
|
- [Supported secrets]({{<ref supported-secret-stores>}})
|
||||||
- [Using secrets in components]({{<ref component-secrets>}})
|
- [Using secrets in components]({{<ref component-secrets>}})
|
||||||
- [Secret stores quickstart](https://github.com/dapr/quickstarts/tree/master/secretstore)
|
- [Secret stores quickstart](https://github.com/dapr/quickstarts/tree/master/secretstore)
|
|
@ -38,7 +38,7 @@ spec:
|
||||||
| **spec** | - | **Detailed information on the component resource**
|
| **spec** | - | **Detailed information on the component resource**
|
||||||
| spec.type | Y | The type of the component | `state.redis`
|
| spec.type | Y | The type of the component | `state.redis`
|
||||||
| spec.version | Y | The version of the component | `v1`
|
| spec.version | Y | The version of the component | `v1`
|
||||||
| spec.initTimeout | N | The timeout duration for the initialization of the component. Default is 30s | `5m`, `1h`, `20s`
|
| spec.initTimeout | N | The timeout duration for the initialization of the component. Default is 5s | `5m`, `1h`, `20s`
|
||||||
| spec.ignoreErrors | N | Tells the Dapr sidecar to continue initialization if the component fails to load. Default is false | `false`
|
| spec.ignoreErrors | N | Tells the Dapr sidecar to continue initialization if the component fails to load. Default is false | `false`
|
||||||
| **spec.metadata** | - | **A key/value pair of component specific configuration. See your component definition for fields**|
|
| **spec.metadata** | - | **A key/value pair of component specific configuration. See your component definition for fields**|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ Logs have different, configurable verbosity levels.
|
||||||
The levels outlined below are the same for both system components and the Dapr sidecar process/container:
|
The levels outlined below are the same for both system components and the Dapr sidecar process/container:
|
||||||
|
|
||||||
1. error
|
1. error
|
||||||
2. warning
|
2. warn
|
||||||
3. info
|
3. info
|
||||||
4. debug
|
4. debug
|
||||||
|
|
||||||
|
@ -34,13 +34,13 @@ This will start the Dapr runtime binary with a log level of `error` and the Dapr
|
||||||
To set the log level when running your app with the Dapr CLI, pass the `log-level` param:
|
To set the log level when running your app with the Dapr CLI, pass the `log-level` param:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dapr run --log-level warning node myapp.js
|
dapr run --log-level warn node myapp.js
|
||||||
```
|
```
|
||||||
|
|
||||||
As outlined above, every Dapr binary takes a `--log-level` argument. For example, to launch the placement service with a log level of warning:
|
As outlined above, every Dapr binary takes a `--log-level` argument. For example, to launch the placement service with a log level of warning:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./placement --log-level warning
|
./placement --log-level warn
|
||||||
```
|
```
|
||||||
|
|
||||||
### Viewing Logs on Standalone Mode
|
### Viewing Logs on Standalone Mode
|
||||||
|
@ -62,7 +62,7 @@ dapr run node myapp.js
|
||||||
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component messagebus (pubsub.redis)"
|
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component messagebus (pubsub.redis)"
|
||||||
== DAPR == 2019/09/05 12:26:43 redis: connecting to localhost:6379
|
== DAPR == 2019/09/05 12:26:43 redis: connecting to localhost:6379
|
||||||
== DAPR == 2019/09/05 12:26:43 redis: connected to localhost:6379 (localAddr: [::1]:56734, remAddr: [::1]:6379)
|
== DAPR == 2019/09/05 12:26:43 redis: connected to localhost:6379 (localAddr: [::1]:56734, remAddr: [::1]:6379)
|
||||||
== DAPR == time="2019-09-05T12:26:43-07:00" level=warning msg="failed to init input bindings: app channel not initialized"
|
== DAPR == time="2019-09-05T12:26:43-07:00" level=warn msg="failed to init input bindings: app channel not initialized"
|
||||||
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
|
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
|
||||||
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: starting connection attempt to placement service at localhost:50005"
|
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: starting connection attempt to placement service at localhost:50005"
|
||||||
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="http server is running on port 56730"
|
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="http server is running on port 56730"
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
Loading…
Reference in New Issue